001: package org.bouncycastle.crypto.engines;
002:
003: import org.bouncycastle.crypto.BlockCipher;
004: import org.bouncycastle.crypto.CipherParameters;
005: import org.bouncycastle.crypto.DataLengthException;
006: import org.bouncycastle.crypto.params.KeyParameter;
007:
008: /**
009: * Camellia - based on RFC 3713.
010: */
011: public class CamelliaEngine implements BlockCipher {
012: private boolean initialised;
013: private boolean _keyIs128;
014:
015: private static final int BLOCK_SIZE = 16;
016:
017: private static final long MASK8 = 0xff;
018: private static final long MASK32 = 0xffffffffL;
019:
020: private static final long SIGMA1 = 0xA09E667F3BCC908BL;
021: private static final long SIGMA2 = 0xB67AE8584CAA73B2L;
022: private static final long SIGMA3 = 0xC6EF372FE94F82BEL;
023: private static final long SIGMA4 = 0x54FF53A5F1D36F1CL;
024: private static final long SIGMA5 = 0x10E527FADE682D1DL;
025: private static final long SIGMA6 = 0xB05688C2B3E6C1FDL;
026:
027: private long _kw1, _kw2, _kw3, _kw4;
028: private long _k1, _k2, _k3, _k4, _k5, _k6, _k7, _k8, _k9, _k10,
029: _k11, _k12, _k13, _k14, _k15, _k16, _k17, _k18, _k19, _k20,
030: _k21, _k22, _k23, _k24;
031: private long _ke1, _ke2, _ke3, _ke4, _ke5, _ke6;
032:
033: private final byte[] SBOX1 = { (byte) 112, (byte) 130, (byte) 44,
034: (byte) 236, (byte) 179, (byte) 39, (byte) 192, (byte) 229,
035: (byte) 228, (byte) 133, (byte) 87, (byte) 53, (byte) 234,
036: (byte) 12, (byte) 174, (byte) 65, (byte) 35, (byte) 239,
037: (byte) 107, (byte) 147, (byte) 69, (byte) 25, (byte) 165,
038: (byte) 33, (byte) 237, (byte) 14, (byte) 79, (byte) 78,
039: (byte) 29, (byte) 101, (byte) 146, (byte) 189, (byte) 134,
040: (byte) 184, (byte) 175, (byte) 143, (byte) 124, (byte) 235,
041: (byte) 31, (byte) 206, (byte) 62, (byte) 48, (byte) 220,
042: (byte) 95, (byte) 94, (byte) 197, (byte) 11, (byte) 26,
043: (byte) 166, (byte) 225, (byte) 57, (byte) 202, (byte) 213,
044: (byte) 71, (byte) 93, (byte) 61, (byte) 217, (byte) 1,
045: (byte) 90, (byte) 214, (byte) 81, (byte) 86, (byte) 108,
046: (byte) 77, (byte) 139, (byte) 13, (byte) 154, (byte) 102,
047: (byte) 251, (byte) 204, (byte) 176, (byte) 45, (byte) 116,
048: (byte) 18, (byte) 43, (byte) 32, (byte) 240, (byte) 177,
049: (byte) 132, (byte) 153, (byte) 223, (byte) 76, (byte) 203,
050: (byte) 194, (byte) 52, (byte) 126, (byte) 118, (byte) 5,
051: (byte) 109, (byte) 183, (byte) 169, (byte) 49, (byte) 209,
052: (byte) 23, (byte) 4, (byte) 215, (byte) 20, (byte) 88,
053: (byte) 58, (byte) 97, (byte) 222, (byte) 27, (byte) 17,
054: (byte) 28, (byte) 50, (byte) 15, (byte) 156, (byte) 22,
055: (byte) 83, (byte) 24, (byte) 242, (byte) 34, (byte) 254,
056: (byte) 68, (byte) 207, (byte) 178, (byte) 195, (byte) 181,
057: (byte) 122, (byte) 145, (byte) 36, (byte) 8, (byte) 232,
058: (byte) 168, (byte) 96, (byte) 252, (byte) 105, (byte) 80,
059: (byte) 170, (byte) 208, (byte) 160, (byte) 125, (byte) 161,
060: (byte) 137, (byte) 98, (byte) 151, (byte) 84, (byte) 91,
061: (byte) 30, (byte) 149, (byte) 224, (byte) 255, (byte) 100,
062: (byte) 210, (byte) 16, (byte) 196, (byte) 0, (byte) 72,
063: (byte) 163, (byte) 247, (byte) 117, (byte) 219, (byte) 138,
064: (byte) 3, (byte) 230, (byte) 218, (byte) 9, (byte) 63,
065: (byte) 221, (byte) 148, (byte) 135, (byte) 92, (byte) 131,
066: (byte) 2, (byte) 205, (byte) 74, (byte) 144, (byte) 51,
067: (byte) 115, (byte) 103, (byte) 246, (byte) 243, (byte) 157,
068: (byte) 127, (byte) 191, (byte) 226, (byte) 82, (byte) 155,
069: (byte) 216, (byte) 38, (byte) 200, (byte) 55, (byte) 198,
070: (byte) 59, (byte) 129, (byte) 150, (byte) 111, (byte) 75,
071: (byte) 19, (byte) 190, (byte) 99, (byte) 46, (byte) 233,
072: (byte) 121, (byte) 167, (byte) 140, (byte) 159, (byte) 110,
073: (byte) 188, (byte) 142, (byte) 41, (byte) 245, (byte) 249,
074: (byte) 182, (byte) 47, (byte) 253, (byte) 180, (byte) 89,
075: (byte) 120, (byte) 152, (byte) 6, (byte) 106, (byte) 231,
076: (byte) 70, (byte) 113, (byte) 186, (byte) 212, (byte) 37,
077: (byte) 171, (byte) 66, (byte) 136, (byte) 162, (byte) 141,
078: (byte) 250, (byte) 114, (byte) 7, (byte) 185, (byte) 85,
079: (byte) 248, (byte) 238, (byte) 172, (byte) 10, (byte) 54,
080: (byte) 73, (byte) 42, (byte) 104, (byte) 60, (byte) 56,
081: (byte) 241, (byte) 164, (byte) 64, (byte) 40, (byte) 211,
082: (byte) 123, (byte) 187, (byte) 201, (byte) 67, (byte) 193,
083: (byte) 21, (byte) 227, (byte) 173, (byte) 244, (byte) 119,
084: (byte) 199, (byte) 128, (byte) 158 };
085:
086: private final byte[] SBOX2 = new byte[256];
087: private final byte[] SBOX3 = new byte[256];
088: private final byte[] SBOX4 = new byte[256];
089:
090: public CamelliaEngine() {
091: for (int x = 0; x != 256; x++) {
092: SBOX2[x] = lRot8(SBOX1[x], 1);
093: SBOX3[x] = lRot8(SBOX1[x], 7);
094: SBOX4[x] = SBOX1[lRot8((byte) x, 1) & 0xff];
095: }
096: }
097:
098: private void setKey(boolean forEncryption, byte[] key) {
099: long klA, klB;
100: long krA, krB;
101:
102: switch (key.length) {
103: case 16:
104: _keyIs128 = true;
105: klA = bytesToWord(key, 0);
106: klB = bytesToWord(key, 8);
107: krA = 0;
108: krB = 0;
109: break;
110: case 24:
111: klA = bytesToWord(key, 0);
112: klB = bytesToWord(key, 8);
113: krA = bytesToWord(key, 16);
114: krB = ~bytesToWord(key, 16);
115: _keyIs128 = false;
116: break;
117: case 32:
118: klA = bytesToWord(key, 0);
119: klB = bytesToWord(key, 8);
120: krA = bytesToWord(key, 16);
121: krB = bytesToWord(key, 24);
122: _keyIs128 = false;
123: break;
124: default:
125: throw new IllegalArgumentException(
126: "only a key sizes of 128/192/256 are acceptable.");
127: }
128:
129: long d1 = klA ^ krA;
130: long d2 = klB ^ krB;
131:
132: d2 = d2 ^ f(d1, SIGMA1);
133: d1 = d1 ^ f(d2, SIGMA2);
134: d1 = d1 ^ klA;
135: d2 = d2 ^ klB;
136: d2 = d2 ^ f(d1, SIGMA3);
137: d1 = d1 ^ f(d2, SIGMA4);
138:
139: long kaA = d1;
140: long kaB = d2;
141:
142: if (_keyIs128) {
143: if (forEncryption) {
144: _kw1 = klA;
145: _kw2 = klB;
146: _kw3 = lRot128high(kaA, kaB, 111);
147: _kw4 = lRot128low(kaA, kaB, 111);
148: _k1 = kaA;
149: _k2 = kaB;
150: _k3 = lRot128high(klA, klB, 15);
151: _k4 = lRot128low(klA, klB, 15);
152: _k5 = lRot128high(kaA, kaB, 15);
153: _k6 = lRot128low(kaA, kaB, 15);
154: _k7 = lRot128high(klA, klB, 45);
155: _k8 = lRot128low(klA, klB, 45);
156: _k9 = lRot128high(kaA, kaB, 45);
157: _k10 = lRot128low(klA, klB, 60);
158: _k11 = lRot128high(kaA, kaB, 60);
159: _k12 = lRot128low(kaA, kaB, 60);
160: _k13 = lRot128high(klA, klB, 94);
161: _k14 = lRot128low(klA, klB, 94);
162: _k15 = lRot128high(kaA, kaB, 94);
163: _k16 = lRot128low(kaA, kaB, 94);
164: _k17 = lRot128high(klA, klB, 111);
165: _k18 = lRot128low(klA, klB, 111);
166: _ke1 = lRot128high(kaA, kaB, 30);
167: _ke2 = lRot128low(kaA, kaB, 30);
168: _ke3 = lRot128high(klA, klB, 77);
169: _ke4 = lRot128low(klA, klB, 77);
170: } else {
171: _kw3 = klA;
172: _kw4 = klB;
173: _kw1 = lRot128high(kaA, kaB, 111);
174: _kw2 = lRot128low(kaA, kaB, 111);
175: _k18 = kaA;
176: _k17 = kaB;
177: _k16 = lRot128high(klA, klB, 15);
178: _k15 = lRot128low(klA, klB, 15);
179: _k14 = lRot128high(kaA, kaB, 15);
180: _k13 = lRot128low(kaA, kaB, 15);
181: _k12 = lRot128high(klA, klB, 45);
182: _k11 = lRot128low(klA, klB, 45);
183: _k10 = lRot128high(kaA, kaB, 45);
184: _k9 = lRot128low(klA, klB, 60);
185: _k8 = lRot128high(kaA, kaB, 60);
186: _k7 = lRot128low(kaA, kaB, 60);
187: _k6 = lRot128high(klA, klB, 94);
188: _k5 = lRot128low(klA, klB, 94);
189: _k4 = lRot128high(kaA, kaB, 94);
190: _k3 = lRot128low(kaA, kaB, 94);
191: _k2 = lRot128high(klA, klB, 111);
192: _k1 = lRot128low(klA, klB, 111);
193: _ke4 = lRot128high(kaA, kaB, 30);
194: _ke3 = lRot128low(kaA, kaB, 30);
195: _ke2 = lRot128high(klA, klB, 77);
196: _ke1 = lRot128low(klA, klB, 77);
197: }
198: } else {
199: d1 = kaA ^ krA;
200: d2 = kaB ^ krB;
201: d2 = d2 ^ f(d1, SIGMA5);
202: d1 = d1 ^ f(d2, SIGMA6);
203:
204: long kbA = d1;
205: long kbB = d2;
206:
207: if (forEncryption) {
208: _kw1 = klA;
209: _kw2 = klB;
210: _k1 = kbA;
211: _k2 = kbB;
212: _k3 = lRot128high(krA, krB, 15);
213: _k4 = lRot128low(krA, krB, 15);
214: _k5 = lRot128high(kaA, kaB, 15);
215: _k6 = lRot128low(kaA, kaB, 15);
216: _ke1 = lRot128high(krA, krB, 30);
217: _ke2 = lRot128low(krA, krB, 30);
218: _k7 = lRot128high(kbA, kbB, 30);
219: _k8 = lRot128low(kbA, kbB, 30);
220: _k9 = lRot128high(klA, klB, 45);
221: _k10 = lRot128low(klA, klB, 45);
222: _k11 = lRot128high(kaA, kaB, 45);
223: _k12 = lRot128low(kaA, kaB, 45);
224: _ke3 = lRot128high(klA, klB, 60);
225: _ke4 = lRot128low(klA, klB, 60);
226: _k13 = lRot128high(krA, krB, 60);
227: _k14 = lRot128low(krA, krB, 60);
228: _k15 = lRot128high(kbA, kbB, 60);
229: _k16 = lRot128low(kbA, kbB, 60);
230: _k17 = lRot128high(klA, klB, 77);
231: _k18 = lRot128low(klA, klB, 77);
232: _ke5 = lRot128high(kaA, kaB, 77);
233: _ke6 = lRot128low(kaA, kaB, 77);
234: _k19 = lRot128high(krA, krB, 94);
235: _k20 = lRot128low(krA, krB, 94);
236: _k21 = lRot128high(kaA, kaB, 94);
237: _k22 = lRot128low(kaA, kaB, 94);
238: _k23 = lRot128high(klA, klB, 111);
239: _k24 = lRot128low(klA, klB, 111);
240: _kw3 = lRot128high(kbA, kbB, 111);
241: _kw4 = lRot128low(kbA, kbB, 111);
242: } else {
243: _kw3 = klA;
244: _kw4 = klB;
245: _kw1 = lRot128high(kbA, kbB, 111);
246: _kw2 = lRot128low(kbA, kbB, 111);
247: _k24 = kbA;
248: _k23 = kbB;
249: _k22 = lRot128high(krA, krB, 15);
250: _k21 = lRot128low(krA, krB, 15);
251: _k20 = lRot128high(kaA, kaB, 15);
252: _k19 = lRot128low(kaA, kaB, 15);
253: _k18 = lRot128high(kbA, kbB, 30);
254: _k17 = lRot128low(kbA, kbB, 30);
255: _k16 = lRot128high(klA, klB, 45);
256: _k15 = lRot128low(klA, klB, 45);
257: _k14 = lRot128high(kaA, kaB, 45);
258: _k13 = lRot128low(kaA, kaB, 45);
259: _k12 = lRot128high(krA, krB, 60);
260: _k11 = lRot128low(krA, krB, 60);
261: _k10 = lRot128high(kbA, kbB, 60);
262: _k9 = lRot128low(kbA, kbB, 60);
263: _k8 = lRot128high(klA, klB, 77);
264: _k7 = lRot128low(klA, klB, 77);
265: _k6 = lRot128high(krA, krB, 94);
266: _k5 = lRot128low(krA, krB, 94);
267: _k4 = lRot128high(kaA, kaB, 94);
268: _k3 = lRot128low(kaA, kaB, 94);
269: _k2 = lRot128high(klA, klB, 111);
270: _k1 = lRot128low(klA, klB, 111);
271: _ke6 = lRot128high(krA, krB, 30);
272: _ke5 = lRot128low(krA, krB, 30);
273: _ke4 = lRot128high(klA, klB, 60);
274: _ke3 = lRot128low(klA, klB, 60);
275: _ke2 = lRot128high(kaA, kaB, 77);
276: _ke1 = lRot128low(kaA, kaB, 77);
277: }
278: }
279: }
280:
281: public void init(boolean forEncryption, CipherParameters params)
282: throws IllegalArgumentException {
283: if (!(params instanceof KeyParameter)) {
284: throw new IllegalArgumentException(
285: "only simple KeyParameter expected.");
286: }
287:
288: setKey(forEncryption, ((KeyParameter) params).getKey());
289: initialised = true;
290: }
291:
292: public String getAlgorithmName() {
293: return "Camellia";
294: }
295:
296: public int getBlockSize() {
297: return BLOCK_SIZE;
298: }
299:
300: public int processBlock(byte[] in, int inOff, byte[] out, int outOff)
301: throws DataLengthException, IllegalStateException {
302: if (!initialised) {
303: throw new IllegalStateException(
304: "Camellia engine not initialised");
305: }
306:
307: if ((inOff + BLOCK_SIZE) > in.length) {
308: throw new DataLengthException("input buffer too short");
309: }
310:
311: if ((outOff + BLOCK_SIZE) > out.length) {
312: throw new DataLengthException("output buffer too short");
313: }
314:
315: if (_keyIs128) {
316: return processBlock128(in, inOff, out, outOff);
317: } else {
318: return processBlock192or256(in, inOff, out, outOff);
319: }
320: }
321:
322: public void reset() {
323: // nothing
324:
325: }
326:
327: private byte lRot8(byte value, int rotation) {
328: return (byte) ((value << rotation) | ((value & 0xff) >>> (8 - rotation)));
329: }
330:
331: private int lRot32(int value, int rotation) {
332: return (value << rotation) | (value >>> -rotation);
333: }
334:
335: private long lRot128high(long a, long b, int rotation) {
336: if (rotation < 64) {
337: a = (a << rotation) | (b >>> -rotation);
338: } else if (rotation == 64) {
339: a = b;
340: } else {
341: a = (b << (rotation - 64)) | (a >>> -(rotation - 64));
342: }
343:
344: return a;
345: }
346:
347: private long lRot128low(long a, long b, int rotation) {
348: if (rotation < 64) {
349: b = (b << rotation) | (a >>> -rotation);
350: } else if (rotation == 64) {
351: b = a;
352: } else {
353: b = (a << (rotation - 64)) | (b >>> -(rotation - 64));
354: }
355:
356: return b;
357: }
358:
359: private long fl(long in, long ke) {
360: int x1 = (int) (in >> 32);
361: int x2 = (int) in;
362: int k1 = (int) (ke >> 32);
363: int k2 = (int) ke;
364:
365: x2 = x2 ^ lRot32((x1 & k1), 1);
366: x1 = x1 ^ (x2 | k2);
367:
368: return ((long) x1 << 32) | (x2 & MASK32);
369: }
370:
371: private long flInv(long in, long ke) {
372: int y1 = (int) (in >> 32);
373: int y2 = (int) in;
374: int k1 = (int) (ke >> 32);
375: int k2 = (int) ke;
376:
377: y1 = y1 ^ (y2 | k2);
378: y2 = y2 ^ lRot32((y1 & k1), 1);
379:
380: return ((long) y1 << 32) | (y2 & MASK32);
381: }
382:
383: private long f(long in, long ke) {
384: long x;
385: int a, b;
386: int t1, t2, t3, t4, t5, t6, t7, t8;
387: int y1, y2, y3, y4, y5, y6, y7, y8;
388:
389: x = in ^ ke;
390:
391: a = (int) (x >> 32);
392: b = (int) x;
393:
394: t1 = SBOX1[(a >> 24) & 0xff];
395: t2 = SBOX2[(a >> 16) & 0xff];
396: t3 = SBOX3[(a >> 8) & 0xff];
397: t4 = SBOX4[a & 0xff];
398: t5 = SBOX2[(b >> 24) & 0xff];
399: t6 = SBOX3[(b >> 16) & 0xff];
400: t7 = SBOX4[(b >> 8) & 0xff];
401: t8 = SBOX1[b & 0xff];
402:
403: y1 = (t1 ^ t3 ^ t4 ^ t6 ^ t7 ^ t8);
404: y2 = (t1 ^ t2 ^ t4 ^ t5 ^ t7 ^ t8);
405: y3 = (t1 ^ t2 ^ t3 ^ t5 ^ t6 ^ t8);
406: y4 = (t2 ^ t3 ^ t4 ^ t5 ^ t6 ^ t7);
407: y5 = (t1 ^ t2 ^ t6 ^ t7 ^ t8);
408: y6 = (t2 ^ t3 ^ t5 ^ t7 ^ t8);
409: y7 = (t3 ^ t4 ^ t5 ^ t6 ^ t8);
410: y8 = (t1 ^ t4 ^ t5 ^ t6 ^ t7);
411:
412: return ((long) y1 << 56) | (((long) y2 & MASK8) << 48)
413: | (((long) y3 & MASK8) << 40)
414: | (((long) y4 & MASK8) << 32)
415: | (((long) y5 & MASK8) << 24)
416: | (((long) y6 & MASK8) << 16)
417: | (((long) y7 & MASK8) << 8) | ((long) y8 & MASK8);
418: }
419:
420: private long bytesToWord(byte[] src, int srcOff) {
421: long word = 0;
422:
423: for (int i = 0; i < 8; i++) {
424: word = (word << 8) + (src[i + srcOff] & 0xff);
425: }
426:
427: return word;
428: }
429:
430: private void wordToBytes(long word, byte[] dst, int dstOff) {
431: for (int i = 0; i < 8; i++) {
432: dst[(7 - i) + dstOff] = (byte) word;
433: word >>>= 8;
434: }
435: }
436:
437: private int processBlock128(byte[] in, int inOff, byte[] out,
438: int outOff) throws DataLengthException,
439: IllegalStateException {
440: long d1 = bytesToWord(in, inOff);
441: long d2 = bytesToWord(in, inOff + 8);
442:
443: d1 = d1 ^ _kw1; // Prewhitening
444: d2 = d2 ^ _kw2;
445:
446: d2 = d2 ^ f(d1, _k1); // Round 1
447: d1 = d1 ^ f(d2, _k2); // Round 2
448: d2 = d2 ^ f(d1, _k3); // Round 3
449: d1 = d1 ^ f(d2, _k4); // Round 4
450: d2 = d2 ^ f(d1, _k5); // Round 5
451: d1 = d1 ^ f(d2, _k6); // Round 6
452: d1 = fl(d1, _ke1); // FL
453: d2 = flInv(d2, _ke2); // FLINV
454: d2 = d2 ^ f(d1, _k7); // Round 7
455: d1 = d1 ^ f(d2, _k8); // Round 8
456: d2 = d2 ^ f(d1, _k9); // Round 9
457: d1 = d1 ^ f(d2, _k10); // Round 10
458: d2 = d2 ^ f(d1, _k11); // Round 11
459: d1 = d1 ^ f(d2, _k12); // Round 12
460: d1 = fl(d1, _ke3); // FL
461: d2 = flInv(d2, _ke4); // FLINV
462:
463: d2 = d2 ^ f(d1, _k13); // Round 13
464: d1 = d1 ^ f(d2, _k14); // Round 14
465: d2 = d2 ^ f(d1, _k15); // Round 15
466: d1 = d1 ^ f(d2, _k16); // Round 16
467: d2 = d2 ^ f(d1, _k17); // Round 17
468: d1 = d1 ^ f(d2, _k18); // Round 18
469:
470: d2 = d2 ^ _kw3; // Postwhitening
471: d1 = d1 ^ _kw4;
472:
473: wordToBytes(d2, out, outOff);
474: wordToBytes(d1, out, outOff + 8);
475:
476: return BLOCK_SIZE;
477: }
478:
479: private int processBlock192or256(byte[] in, int inOff, byte[] out,
480: int outOff) throws DataLengthException,
481: IllegalStateException {
482: long d1 = bytesToWord(in, inOff);
483: long d2 = bytesToWord(in, inOff + 8);
484:
485: d1 = d1 ^ _kw1; // Prewhitening
486: d2 = d2 ^ _kw2;
487:
488: d2 = d2 ^ f(d1, _k1); // Round 1
489: d1 = d1 ^ f(d2, _k2); // Round 2
490: d2 = d2 ^ f(d1, _k3); // Round 3
491: d1 = d1 ^ f(d2, _k4); // Round 4
492: d2 = d2 ^ f(d1, _k5); // Round 5
493: d1 = d1 ^ f(d2, _k6); // Round 6
494: d1 = fl(d1, _ke1); // FL
495: d2 = flInv(d2, _ke2); // FLINV
496: d2 = d2 ^ f(d1, _k7); // Round 7
497: d1 = d1 ^ f(d2, _k8); // Round 8
498: d2 = d2 ^ f(d1, _k9); // Round 9
499: d1 = d1 ^ f(d2, _k10); // Round 10
500: d2 = d2 ^ f(d1, _k11); // Round 11
501: d1 = d1 ^ f(d2, _k12); // Round 12
502: d1 = fl(d1, _ke3); // FL
503: d2 = flInv(d2, _ke4); // FLINV
504: d2 = d2 ^ f(d1, _k13); // Round 13
505: d1 = d1 ^ f(d2, _k14); // Round 14
506: d2 = d2 ^ f(d1, _k15); // Round 15
507: d1 = d1 ^ f(d2, _k16); // Round 16
508: d2 = d2 ^ f(d1, _k17); // Round 17
509: d1 = d1 ^ f(d2, _k18); // Round 18
510: d1 = fl(d1, _ke5); // FL
511: d2 = flInv(d2, _ke6); // FLINV
512: d2 = d2 ^ f(d1, _k19); // Round 19
513: d1 = d1 ^ f(d2, _k20); // Round 20
514: d2 = d2 ^ f(d1, _k21); // Round 21
515: d1 = d1 ^ f(d2, _k22); // Round 22
516: d2 = d2 ^ f(d1, _k23); // Round 23
517: d1 = d1 ^ f(d2, _k24); // Round 24
518:
519: d2 = d2 ^ _kw3; // Postwhitening
520: d1 = d1 ^ _kw4;
521:
522: wordToBytes(d2, out, outOff);
523: wordToBytes(d1, out, outOff + 8);
524:
525: return BLOCK_SIZE;
526: }
527: }
|