1 public class JGFCryptBenchSizeA extends Thread{
7 public JGFCryptBenchSizeA(JGFCryptBench cb, int id, byte [] text1, byte [] text2, int [] key, int nthreads) {
13 this.nthreads = nthreads;
18 // IDEA encryption/decryption algorithm. It processes plaintext in
19 // 64-bit blocks, one at a time, breaking the block into four 16-bit
20 // unsigned subblocks. It goes through eight rounds of processing
21 // using 6 new subkeys each time, plus four for last step. The source
22 // text is in array text1, the destination text goes into array text2
23 // The routine represents 16-bit subblocks and subkeys as type int so
24 // that they can be treated more easily as unsigned. Multiplication
25 // modulo 0x10001 interprets a zero sub-block as 0x10000; it must to
30 int ilow, iupper, slice, tslice, ttslice;
33 tslice = text1.length / 8;
34 ttslice = (tslice + nthreads-1) / nthreads;
38 iupper = (id+1)*slice;
39 if(iupper > text1.length) iupper = text1.length;
42 int i1 = ilow; // Index into first text array.
43 int i2 = ilow; // Index into second text array.
44 int ik; // Index into key array.
45 int x1, x2, x3, x4, t1, t2; // Four "16-bit" blocks, two temps.
46 int r; // Eight rounds of processing.
48 for (int i =ilow ; i <iupper ; i +=8)
51 ik = 0; // Restart key index.
52 r = 8; // Eight rounds of processing.
54 // Load eight plain1 bytes as four 16-bit "unsigned" integers.
55 // Masking with 0xff prevents sign extension with cast to int.
58 x1 = text1[i1++] & 0xff; // Build 16-bit x1 from 2 bytes,
59 x1 |= (text1[i1++] & 0xff) << 8; // assuming low-order byte first.
60 x2 = text1[i1++] & 0xff;
61 x2 |= (text1[i1++] & 0xff) << 8;
62 x3 = text1[i1++] & 0xff;
63 x3 |= (text1[i1++] & 0xff) << 8;
64 x4 = text1[i1++] & 0xff;
65 x4 |= (text1[i1++] & 0xff) << 8;
69 // 1) Multiply (modulo 0x10001), 1st text sub-block
70 // with 1st key sub-block.
73 x1 = (int) ((long) x1 * key[ik++] % 0x10001L & 0xffff);
74 // 2) Add (modulo 0x10000), 2nd text sub-block
75 // with 2nd key sub-block.
77 x2 = x2 + key[ik++] & 0xffff;
79 // 3) Add (modulo 0x10000), 3rd text sub-block
80 // with 3rd key sub-block.
82 x3 = x3 + key[ik++] & 0xffff;
84 // 4) Multiply (modulo 0x10001), 4th text sub-block
85 // with 4th key sub-block.
87 x4 = (int) ((long) x4 * key[ik++] % 0x10001L & 0xffff);
90 // 5) XOR results from steps 1 and 3.
94 // 6) XOR results from steps 2 and 4.
95 // Included in step 8.
97 // 7) Multiply (modulo 0x10001), result of step 5
98 // with 5th key sub-block.
101 t2 = (int) ((long) t2 * key[ik++] % 0x10001L & 0xffff);
104 // 8) Add (modulo 0x10000), results of steps 6 and 7.
106 t1 = t2 + (x2 ^ x4) & 0xffff;
108 // 9) Multiply (modulo 0x10001), result of step 8
109 // with 6th key sub-block.
112 t1 = (int) ((long) t1 * key[ik++] % 0x10001L & 0xffff);
115 // 10) Add (modulo 0x10000), results of steps 7 and 9.
117 t2 = t1 + t2 & 0xffff;
119 // 11) XOR results from steps 1 and 9.
123 // 14) XOR results from steps 4 and 10. (Out of order).
127 // 13) XOR results from steps 2 and 10. (Out of order).
131 // 12) XOR results from steps 3 and 9. (Out of order).
135 x3 = t2; // Results of x2 and x3 now swapped.
137 } while(--r != 0); // Repeats seven more rounds.
139 // Final output transform (4 steps).
141 // 1) Multiply (modulo 0x10001), 1st text-block
142 // with 1st key sub-block.
145 x1 = (int) ((long) x1 * key[ik++] % 0x10001L & 0xffff);
147 // 2) Add (modulo 0x10000), 2nd text sub-block
148 // with 2nd key sub-block. It says x3, but that is to undo swap
149 // of subblocks 2 and 3 in 8th processing round.
151 x3 = x3 + key[ik++] & 0xffff;
153 // 3) Add (modulo 0x10000), 3rd text sub-block
154 // with 3rd key sub-block. It says x2, but that is to undo swap
155 // of subblocks 2 and 3 in 8th processing round.
157 x2 = x2 + key[ik++] & 0xffff;
159 // 4) Multiply (modulo 0x10001), 4th text-block
160 // with 4th key sub-block.
162 x4 = (int) ((long) x4 * key[ik++] % 0x10001L & 0xffff);
164 // Repackage from 16-bit sub-blocks to 8-bit byte array text2.
166 text2[i2++] = (byte) x1;
167 text2[i2++] = (byte) (x1 >>> 8);
168 text2[i2++] = (byte) x3; // x3 and x2 are switched
169 text2[i2++] = (byte) (x3 >>> 8); // only in name.
170 text2[i2++] = (byte) x2;
171 text2[i2++] = (byte) (x2 >>> 8);
172 text2[i2++] = (byte) x4;
173 text2[i2++] = (byte) (x4 >>> 8);
180 public static void main(String argv[]){
182 if(argv.length != 0 ) {
183 nthreads = Integer.parseInt(argv[0]);
185 System.printString("The no of threads has not been specified, defaulting to 1");
186 System.printString(" ");
190 /* Instruments output messages */
191 JGFInstrumentor instr = new JGFInstrumentor();
192 instr.printHeader(2,0,nthreads);
196 instr.addTimer("Section2:Crypt:Kernel", "Kbyte",size);
198 cb = global new JGFCryptBench();
204 /* Start computation */
205 int mid = (128<<24)|(195<<16)|(175<<8)|73;
207 JGFCryptBenchSizeA[] th;
209 th = global new JGFCryptBenchSizeA [nthreads];
212 // Start the stopwatch.
213 instr.startTimer("Section2:Crypt:Kernel");
216 JGFCryptBenchSizeA tmp;
217 for(int i=1;i<nthreads;i++) {
219 th[i] = global new JGFCryptBenchSizeA(cb, i, cb.plain1, cb.crypt1, cb.Z, nthreads);
226 th[0] = global new JGFCryptBenchSizeA(cb, 0, cb.plain1, cb.crypt1, cb.Z, nthreads);
232 for(int i=1;i<nthreads;i++) {
240 for(int i=1;i<nthreads;i++) {
242 th[i] = global new JGFCryptBenchSizeA(cb, i, cb.crypt1, cb.plain2, cb.DK, nthreads);
249 th[0] = global new JGFCryptBenchSizeA(cb, 0, cb.crypt1, cb.plain2, cb.DK, nthreads);
255 for(int i=1;i<nthreads;i++) {
262 // Stop the stopwatch.
263 instr.stopTimer("Section2:Crypt:Kernel");
272 arows = cb.array_rows;
275 instr.addOpsToTimer("Section2:Crypt:Kernel", (2*arows)/1000.);
276 instr.printTimer("Section2:Crypt:Kernel");
278 System.printString("Done\n");