1 public class JGFCryptBenchSizeA extends Thread{
6 public JGFCryptBenchSizeA(JGFCryptBench cb, int id, byte [] text1, byte [] text2, int [] key) {
16 // IDEA encryption/decryption algorithm. It processes plaintext in
17 // 64-bit blocks, one at a time, breaking the block into four 16-bit
18 // unsigned subblocks. It goes through eight rounds of processing
19 // using 6 new subkeys each time, plus four for last step. The source
20 // text is in array text1, the destination text goes into array text2
21 // The routine represents 16-bit subblocks and subkeys as type int so
22 // that they can be treated more easily as unsigned. Multiplication
23 // modulo 0x10001 interprets a zero sub-block as 0x10000; it must to
28 int ilow, iupper, slice, tslice, ttslice;
30 tslice = text1.length / 8;
31 ttslice = (tslice + cb.nthreads-1) / cb.nthreads;
35 iupper = (id+1)*slice;
36 if(iupper > text1.length) iupper = text1.length;
38 int i1 = ilow; // Index into first text array.
39 int i2 = ilow; // Index into second text array.
40 int ik; // Index into key array.
41 int x1, x2, x3, x4, t1, t2; // Four "16-bit" blocks, two temps.
42 int r; // Eight rounds of processing.
44 for (int i =ilow ; i <iupper ; i +=8)
47 ik = 0; // Restart key index.
48 r = 8; // Eight rounds of processing.
50 // Load eight plain1 bytes as four 16-bit "unsigned" integers.
51 // Masking with 0xff prevents sign extension with cast to int.
53 x1 = text1[i1++] & 0xff; // Build 16-bit x1 from 2 bytes,
54 x1 |= (text1[i1++] & 0xff) << 8; // assuming low-order byte first.
55 x2 = text1[i1++] & 0xff;
56 x2 |= (text1[i1++] & 0xff) << 8;
57 x3 = text1[i1++] & 0xff;
58 x3 |= (text1[i1++] & 0xff) << 8;
59 x4 = text1[i1++] & 0xff;
60 x4 |= (text1[i1++] & 0xff) << 8;
63 // 1) Multiply (modulo 0x10001), 1st text sub-block
64 // with 1st key sub-block.
66 x1 = (int) ((long) x1 * key[ik++] % 0x10001L & 0xffff);
67 // 2) Add (modulo 0x10000), 2nd text sub-block
68 // with 2nd key sub-block.
70 x2 = x2 + key[ik++] & 0xffff;
72 // 3) Add (modulo 0x10000), 3rd text sub-block
73 // with 3rd key sub-block.
75 x3 = x3 + key[ik++] & 0xffff;
77 // 4) Multiply (modulo 0x10001), 4th text sub-block
78 // with 4th key sub-block.
80 x4 = (int) ((long) x4 * key[ik++] % 0x10001L & 0xffff);
82 // 5) XOR results from steps 1 and 3.
86 // 6) XOR results from steps 2 and 4.
87 // Included in step 8.
89 // 7) Multiply (modulo 0x10001), result of step 5
90 // with 5th key sub-block.
92 t2 = (int) ((long) t2 * key[ik++] % 0x10001L & 0xffff);
94 // 8) Add (modulo 0x10000), results of steps 6 and 7.
96 t1 = t2 + (x2 ^ x4) & 0xffff;
98 // 9) Multiply (modulo 0x10001), result of step 8
99 // with 6th key sub-block.
101 t1 = (int) ((long) t1 * key[ik++] % 0x10001L & 0xffff);
103 // 10) Add (modulo 0x10000), results of steps 7 and 9.
105 t2 = t1 + t2 & 0xffff;
107 // 11) XOR results from steps 1 and 9.
111 // 14) XOR results from steps 4 and 10. (Out of order).
115 // 13) XOR results from steps 2 and 10. (Out of order).
119 // 12) XOR results from steps 3 and 9. (Out of order).
123 x3 = t2; // Results of x2 and x3 now swapped.
125 } while(--r != 0); // Repeats seven more rounds.
127 // Final output transform (4 steps).
129 // 1) Multiply (modulo 0x10001), 1st text-block
130 // with 1st key sub-block.
132 x1 = (int) ((long) x1 * key[ik++] % 0x10001L & 0xffff);
134 // 2) Add (modulo 0x10000), 2nd text sub-block
135 // with 2nd key sub-block. It says x3, but that is to undo swap
136 // of subblocks 2 and 3 in 8th processing round.
138 x3 = x3 + key[ik++] & 0xffff;
140 // 3) Add (modulo 0x10000), 3rd text sub-block
141 // with 3rd key sub-block. It says x2, but that is to undo swap
142 // of subblocks 2 and 3 in 8th processing round.
144 x2 = x2 + key[ik++] & 0xffff;
146 // 4) Multiply (modulo 0x10001), 4th text-block
147 // with 4th key sub-block.
149 x4 = (int) ((long) x4 * key[ik++] % 0x10001L & 0xffff);
151 // Repackage from 16-bit sub-blocks to 8-bit byte array text2.
153 text2[i2++] = (byte) x1;
154 text2[i2++] = (byte) (x1 >>> 8);
155 text2[i2++] = (byte) x3; // x3 and x2 are switched
156 text2[i2++] = (byte) (x3 >>> 8); // only in name.
157 text2[i2++] = (byte) x2;
158 text2[i2++] = (byte) (x2 >>> 8);
159 text2[i2++] = (byte) x4;
160 text2[i2++] = (byte) (x4 >>> 8);
166 public static void main(String argv[]){
168 if(argv.length != 0 ) {
169 nthreads = Integer.parseInt(argv[0]);
171 System.out.println("The no of threads has not been specified, defaulting to 1");
172 System.out.println(" ");
176 /* Instruments output messages */
177 JGFInstrumentor instr = new JGFInstrumentor();
178 instr.printHeader(2,0,nthreads);
182 instr.addTimer("Section2:Crypt:Kernel", "Kbyte",size);
183 cb = new JGFCryptBench(nthreads);
187 /* Start computation */
188 JGFCryptBenchSizeA[] th;
189 th = new JGFCryptBenchSizeA [nthreads];
191 // Start the stopwatch.
192 instr.startTimer("Section2:Crypt:Kernel");
195 JGFCryptBenchSizeA tmp;
196 for(int i=1;i<nthreads;i++) {
197 th[i] = new JGFCryptBenchSizeA(cb, i, cb.plain1, cb.crypt1, cb.Z);
202 th[0] = new JGFCryptBenchSizeA(cb, 0, cb.plain1, cb.crypt1, cb.Z);
207 for(int i=1;i<nthreads;i++) {
211 } catch (InterruptedException e) {}
215 for(int i=1;i<nthreads;i++) {
216 th[i] = new JGFCryptBenchSizeA(cb, i, cb.crypt1, cb.plain2, cb.DK);
221 th[0] = new JGFCryptBenchSizeA(cb, 0, cb.crypt1, cb.plain2, cb.DK);
226 for(int i=1;i<nthreads;i++) {
230 } catch (InterruptedException e) {}
233 // Stop the stopwatch.
234 instr.stopTimer("Section2:Crypt:Kernel");
240 arows = cb.array_rows;
242 instr.addOpsToTimer("Section2:Crypt:Kernel", (2*arows)/1000.);
243 instr.printTimer("Section2:Crypt:Kernel");
245 System.out.println("Done\n");