~brian-thomason/+junk/bouncycastle

« back to all changes in this revision

Viewing changes to src/org/bouncycastle/crypto/digests/LongDigest.java

  • Committer: Brian Thomason
  • Date: 2011-12-20 17:20:32 UTC
  • Revision ID: brian.thomason@canonical.com-20111220172032-rdtm13jgdxtksacr
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package org.bouncycastle.crypto.digests;
 
2
 
 
3
import org.bouncycastle.crypto.ExtendedDigest;
 
4
import org.bouncycastle.crypto.util.Pack;
 
5
 
 
6
/**
 
7
 * Base class for SHA-384 and SHA-512.
 
8
 */
 
9
public abstract class LongDigest
 
10
    implements ExtendedDigest
 
11
{
 
12
    private static final int BYTE_LENGTH = 128;
 
13
    
 
14
    private byte[]  xBuf;
 
15
    private int     xBufOff;
 
16
 
 
17
    private long    byteCount1;
 
18
    private long    byteCount2;
 
19
 
 
20
    protected long    H1, H2, H3, H4, H5, H6, H7, H8;
 
21
 
 
22
    private long[]  W = new long[80];
 
23
    private int     wOff;
 
24
 
 
25
    /**
 
26
     * Constructor for variable length word
 
27
     */
 
28
    protected LongDigest()
 
29
    {
 
30
        xBuf = new byte[8];
 
31
        xBufOff = 0;
 
32
 
 
33
        reset();
 
34
    }
 
35
 
 
36
    /**
 
37
     * Copy constructor.  We are using copy constructors in place
 
38
     * of the Object.clone() interface as this interface is not
 
39
     * supported by J2ME.
 
40
     */
 
41
    protected LongDigest(LongDigest t)
 
42
    {
 
43
        xBuf = new byte[t.xBuf.length];
 
44
        System.arraycopy(t.xBuf, 0, xBuf, 0, t.xBuf.length);
 
45
 
 
46
        xBufOff = t.xBufOff;
 
47
        byteCount1 = t.byteCount1;
 
48
        byteCount2 = t.byteCount2;
 
49
 
 
50
        H1 = t.H1;
 
51
        H2 = t.H2;
 
52
        H3 = t.H3;
 
53
        H4 = t.H4;
 
54
        H5 = t.H5;
 
55
        H6 = t.H6;
 
56
        H7 = t.H7;
 
57
        H8 = t.H8;
 
58
 
 
59
        System.arraycopy(t.W, 0, W, 0, t.W.length);
 
60
        wOff = t.wOff;
 
61
    }
 
62
 
 
63
    public void update(
 
64
        byte in)
 
65
    {
 
66
        xBuf[xBufOff++] = in;
 
67
 
 
68
        if (xBufOff == xBuf.length)
 
69
        {
 
70
            processWord(xBuf, 0);
 
71
            xBufOff = 0;
 
72
        }
 
73
 
 
74
        byteCount1++;
 
75
    }
 
76
 
 
77
    public void update(
 
78
        byte[]  in,
 
79
        int     inOff,
 
80
        int     len)
 
81
    {
 
82
        //
 
83
        // fill the current word
 
84
        //
 
85
        while ((xBufOff != 0) && (len > 0))
 
86
        {
 
87
            update(in[inOff]);
 
88
 
 
89
            inOff++;
 
90
            len--;
 
91
        }
 
92
 
 
93
        //
 
94
        // process whole words.
 
95
        //
 
96
        while (len > xBuf.length)
 
97
        {
 
98
            processWord(in, inOff);
 
99
 
 
100
            inOff += xBuf.length;
 
101
            len -= xBuf.length;
 
102
            byteCount1 += xBuf.length;
 
103
        }
 
104
 
 
105
        //
 
106
        // load in the remainder.
 
107
        //
 
108
        while (len > 0)
 
109
        {
 
110
            update(in[inOff]);
 
111
 
 
112
            inOff++;
 
113
            len--;
 
114
        }
 
115
    }
 
116
 
 
117
    public void finish()
 
118
    {
 
119
        adjustByteCounts();
 
120
 
 
121
        long    lowBitLength = byteCount1 << 3;
 
122
        long    hiBitLength = byteCount2;
 
123
 
 
124
        //
 
125
        // add the pad bytes.
 
126
        //
 
127
        update((byte)128);
 
128
 
 
129
        while (xBufOff != 0)
 
130
        {
 
131
            update((byte)0);
 
132
        }
 
133
 
 
134
        processLength(lowBitLength, hiBitLength);
 
135
 
 
136
        processBlock();
 
137
    }
 
138
 
 
139
    public void reset()
 
140
    {
 
141
        byteCount1 = 0;
 
142
        byteCount2 = 0;
 
143
 
 
144
        xBufOff = 0;
 
145
        for (int i = 0; i < xBuf.length; i++)
 
146
        {
 
147
            xBuf[i] = 0;
 
148
        }
 
149
 
 
150
        wOff = 0;
 
151
        for (int i = 0; i != W.length; i++)
 
152
        {
 
153
            W[i] = 0;
 
154
        }
 
155
    }
 
156
 
 
157
    public int getByteLength()
 
158
    {
 
159
        return BYTE_LENGTH;
 
160
    }
 
161
    
 
162
    protected void processWord(
 
163
        byte[]  in,
 
164
        int     inOff)
 
165
    {
 
166
        W[wOff] = Pack.bigEndianToLong(in, inOff);
 
167
 
 
168
        if (++wOff == 16)
 
169
        {
 
170
            processBlock();
 
171
        }
 
172
    }
 
173
 
 
174
    /**
 
175
     * adjust the byte counts so that byteCount2 represents the
 
176
     * upper long (less 3 bits) word of the byte count.
 
177
     */
 
178
    private void adjustByteCounts()
 
179
    {
 
180
        if (byteCount1 > 0x1fffffffffffffffL)
 
181
        {
 
182
            byteCount2 += (byteCount1 >>> 61);
 
183
            byteCount1 &= 0x1fffffffffffffffL;
 
184
        }
 
185
    }
 
186
 
 
187
    protected void processLength(
 
188
        long    lowW,
 
189
        long    hiW)
 
190
    {
 
191
        if (wOff > 14)
 
192
        {
 
193
            processBlock();
 
194
        }
 
195
 
 
196
        W[14] = hiW;
 
197
        W[15] = lowW;
 
198
    }
 
199
 
 
200
    protected void processBlock()
 
201
    {
 
202
        adjustByteCounts();
 
203
 
 
204
        //
 
205
        // expand 16 word block into 80 word blocks.
 
206
        //
 
207
        for (int t = 16; t <= 79; t++)
 
208
        {
 
209
            W[t] = Sigma1(W[t - 2]) + W[t - 7] + Sigma0(W[t - 15]) + W[t - 16];
 
210
        }
 
211
 
 
212
        //
 
213
        // set up working variables.
 
214
        //
 
215
        long     a = H1;
 
216
        long     b = H2;
 
217
        long     c = H3;
 
218
        long     d = H4;
 
219
        long     e = H5;
 
220
        long     f = H6;
 
221
        long     g = H7;
 
222
        long     h = H8;
 
223
 
 
224
        int t = 0;     
 
225
        for(int i = 0; i < 10; i ++)
 
226
        {
 
227
          // t = 8 * i
 
228
          h += Sum1(e) + Ch(e, f, g) + K[t] + W[t++];
 
229
          d += h;
 
230
          h += Sum0(a) + Maj(a, b, c);
 
231
 
 
232
          // t = 8 * i + 1
 
233
          g += Sum1(d) + Ch(d, e, f) + K[t] + W[t++];
 
234
          c += g;
 
235
          g += Sum0(h) + Maj(h, a, b);
 
236
 
 
237
          // t = 8 * i + 2
 
238
          f += Sum1(c) + Ch(c, d, e) + K[t] + W[t++];
 
239
          b += f;
 
240
          f += Sum0(g) + Maj(g, h, a);
 
241
 
 
242
          // t = 8 * i + 3
 
243
          e += Sum1(b) + Ch(b, c, d) + K[t] + W[t++];
 
244
          a += e;
 
245
          e += Sum0(f) + Maj(f, g, h);
 
246
 
 
247
          // t = 8 * i + 4
 
248
          d += Sum1(a) + Ch(a, b, c) + K[t] + W[t++];
 
249
          h += d;
 
250
          d += Sum0(e) + Maj(e, f, g);
 
251
 
 
252
          // t = 8 * i + 5
 
253
          c += Sum1(h) + Ch(h, a, b) + K[t] + W[t++];
 
254
          g += c;
 
255
          c += Sum0(d) + Maj(d, e, f);
 
256
 
 
257
          // t = 8 * i + 6
 
258
          b += Sum1(g) + Ch(g, h, a) + K[t] + W[t++];
 
259
          f += b;
 
260
          b += Sum0(c) + Maj(c, d, e);
 
261
 
 
262
          // t = 8 * i + 7
 
263
          a += Sum1(f) + Ch(f, g, h) + K[t] + W[t++];
 
264
          e += a;
 
265
          a += Sum0(b) + Maj(b, c, d);
 
266
        }
 
267
 
 
268
        H1 += a;
 
269
        H2 += b;
 
270
        H3 += c;
 
271
        H4 += d;
 
272
        H5 += e;
 
273
        H6 += f;
 
274
        H7 += g;
 
275
        H8 += h;
 
276
 
 
277
        //
 
278
        // reset the offset and clean out the word buffer.
 
279
        //
 
280
        wOff = 0;
 
281
        for (int i = 0; i < 16; i++)
 
282
        {
 
283
            W[i] = 0;
 
284
        }
 
285
    }
 
286
 
 
287
    /* SHA-384 and SHA-512 functions (as for SHA-256 but for longs) */
 
288
    private long Ch(
 
289
        long    x,
 
290
        long    y,
 
291
        long    z)
 
292
    {
 
293
        return ((x & y) ^ ((~x) & z));
 
294
    }
 
295
 
 
296
    private long Maj(
 
297
        long    x,
 
298
        long    y,
 
299
        long    z)
 
300
    {
 
301
        return ((x & y) ^ (x & z) ^ (y & z));
 
302
    }
 
303
 
 
304
    private long Sum0(
 
305
        long    x)
 
306
    {
 
307
        return ((x << 36)|(x >>> 28)) ^ ((x << 30)|(x >>> 34)) ^ ((x << 25)|(x >>> 39));
 
308
    }
 
309
 
 
310
    private long Sum1(
 
311
        long    x)
 
312
    {
 
313
        return ((x << 50)|(x >>> 14)) ^ ((x << 46)|(x >>> 18)) ^ ((x << 23)|(x >>> 41));
 
314
    }
 
315
 
 
316
    private long Sigma0(
 
317
        long    x)
 
318
    {
 
319
        return ((x << 63)|(x >>> 1)) ^ ((x << 56)|(x >>> 8)) ^ (x >>> 7);
 
320
    }
 
321
 
 
322
    private long Sigma1(
 
323
        long    x)
 
324
    {
 
325
        return ((x << 45)|(x >>> 19)) ^ ((x << 3)|(x >>> 61)) ^ (x >>> 6);
 
326
    }
 
327
 
 
328
    /* SHA-384 and SHA-512 Constants
 
329
     * (represent the first 64 bits of the fractional parts of the
 
330
     * cube roots of the first sixty-four prime numbers)
 
331
     */
 
332
    static final long K[] = {
 
333
0x428a2f98d728ae22L, 0x7137449123ef65cdL, 0xb5c0fbcfec4d3b2fL, 0xe9b5dba58189dbbcL,
 
334
0x3956c25bf348b538L, 0x59f111f1b605d019L, 0x923f82a4af194f9bL, 0xab1c5ed5da6d8118L,
 
335
0xd807aa98a3030242L, 0x12835b0145706fbeL, 0x243185be4ee4b28cL, 0x550c7dc3d5ffb4e2L,
 
336
0x72be5d74f27b896fL, 0x80deb1fe3b1696b1L, 0x9bdc06a725c71235L, 0xc19bf174cf692694L,
 
337
0xe49b69c19ef14ad2L, 0xefbe4786384f25e3L, 0x0fc19dc68b8cd5b5L, 0x240ca1cc77ac9c65L,
 
338
0x2de92c6f592b0275L, 0x4a7484aa6ea6e483L, 0x5cb0a9dcbd41fbd4L, 0x76f988da831153b5L,
 
339
0x983e5152ee66dfabL, 0xa831c66d2db43210L, 0xb00327c898fb213fL, 0xbf597fc7beef0ee4L,
 
340
0xc6e00bf33da88fc2L, 0xd5a79147930aa725L, 0x06ca6351e003826fL, 0x142929670a0e6e70L,
 
341
0x27b70a8546d22ffcL, 0x2e1b21385c26c926L, 0x4d2c6dfc5ac42aedL, 0x53380d139d95b3dfL,
 
342
0x650a73548baf63deL, 0x766a0abb3c77b2a8L, 0x81c2c92e47edaee6L, 0x92722c851482353bL,
 
343
0xa2bfe8a14cf10364L, 0xa81a664bbc423001L, 0xc24b8b70d0f89791L, 0xc76c51a30654be30L,
 
344
0xd192e819d6ef5218L, 0xd69906245565a910L, 0xf40e35855771202aL, 0x106aa07032bbd1b8L,
 
345
0x19a4c116b8d2d0c8L, 0x1e376c085141ab53L, 0x2748774cdf8eeb99L, 0x34b0bcb5e19b48a8L,
 
346
0x391c0cb3c5c95a63L, 0x4ed8aa4ae3418acbL, 0x5b9cca4f7763e373L, 0x682e6ff3d6b2b8a3L,
 
347
0x748f82ee5defb2fcL, 0x78a5636f43172f60L, 0x84c87814a1f0ab72L, 0x8cc702081a6439ecL,
 
348
0x90befffa23631e28L, 0xa4506cebde82bde9L, 0xbef9a3f7b2c67915L, 0xc67178f2e372532bL,
 
349
0xca273eceea26619cL, 0xd186b8c721c0c207L, 0xeada7dd6cde0eb1eL, 0xf57d4f7fee6ed178L,
 
350
0x06f067aa72176fbaL, 0x0a637dc5a2c898a6L, 0x113f9804bef90daeL, 0x1b710b35131c471bL,
 
351
0x28db77f523047d84L, 0x32caab7b40c72493L, 0x3c9ebe0a15c9bebcL, 0x431d67c49c100d4cL,
 
352
0x4cc5d4becb3e42b6L, 0x597f299cfc657e2aL, 0x5fcb6fab3ad6faecL, 0x6c44198c4a475817L
 
353
    };
 
354
}