start of new file
[IRC.git] / Robust / src / Benchmarks / Prefetch / Crypt / java / JGFCryptBenchSizeA.java
1 public class JGFCryptBenchSizeA extends Thread{
2   JGFCryptBench cb;
3   int id,key[];
4   byte text1[],text2[];
5
6   public JGFCryptBenchSizeA(JGFCryptBench cb, int id, byte [] text1, byte [] text2, int [] key) {
7     this.cb = cb;
8     this.id = id;
9     this.text1=text1;
10     this.text2=text2;
11     this.key=key;
12   }
13
14   // run()
15   // 
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
24   // fit in 16 bits.
25   //
26
27   public void run() {
28     int ilow, iupper, slice, tslice, ttslice;  
29
30     tslice = text1.length / 8;     
31     ttslice = (tslice + cb.nthreads-1) / cb.nthreads;
32     slice = ttslice*8;
33
34     ilow = id*slice;
35     iupper = (id+1)*slice;
36     if(iupper > text1.length) iupper = text1.length;
37
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.
43
44     for (int i =ilow ; i <iupper ; i +=8)
45     {
46
47       ik = 0;                 // Restart key index.
48       r = 8;                  // Eight rounds of processing.
49
50       // Load eight plain1 bytes as four 16-bit "unsigned" integers.
51       // Masking with 0xff prevents sign extension with cast to int.
52
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;
61
62       do {
63         // 1) Multiply (modulo 0x10001), 1st text sub-block
64         // with 1st key sub-block.
65
66         x1 = (int) ((long) x1 * key[ik++] % 0x10001L & 0xffff);
67         // 2) Add (modulo 0x10000), 2nd text sub-block
68         // with 2nd key sub-block.
69
70         x2 = x2 + key[ik++] & 0xffff;
71
72         // 3) Add (modulo 0x10000), 3rd text sub-block
73         // with 3rd key sub-block.
74
75         x3 = x3 + key[ik++] & 0xffff;
76
77         // 4) Multiply (modulo 0x10001), 4th text sub-block
78         // with 4th key sub-block.
79
80         x4 = (int) ((long) x4 * key[ik++] % 0x10001L & 0xffff);
81
82         // 5) XOR results from steps 1 and 3.
83
84         t2 = x1 ^ x3;
85
86         // 6) XOR results from steps 2 and 4.
87         // Included in step 8.
88
89         // 7) Multiply (modulo 0x10001), result of step 5
90         // with 5th key sub-block.
91
92         t2 = (int) ((long) t2 * key[ik++] % 0x10001L & 0xffff);
93
94         // 8) Add (modulo 0x10000), results of steps 6 and 7.
95
96         t1 = t2 + (x2 ^ x4) & 0xffff;
97
98         // 9) Multiply (modulo 0x10001), result of step 8
99         // with 6th key sub-block.
100
101         t1 = (int) ((long) t1 * key[ik++] % 0x10001L & 0xffff);
102
103         // 10) Add (modulo 0x10000), results of steps 7 and 9.
104
105         t2 = t1 + t2 & 0xffff;
106
107         // 11) XOR results from steps 1 and 9.
108
109         x1 ^= t1;
110
111         // 14) XOR results from steps 4 and 10. (Out of order).
112
113         x4 ^= t2;
114
115         // 13) XOR results from steps 2 and 10. (Out of order).
116
117         t2 ^= x2;
118
119         // 12) XOR results from steps 3 and 9. (Out of order).
120
121         x2 = x3 ^ t1;
122
123         x3 = t2;        // Results of x2 and x3 now swapped.
124
125       } while(--r != 0);  // Repeats seven more rounds.
126
127       // Final output transform (4 steps).
128
129       // 1) Multiply (modulo 0x10001), 1st text-block
130       // with 1st key sub-block.
131
132       x1 = (int) ((long) x1 * key[ik++] % 0x10001L & 0xffff);
133
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.
137
138       x3 = x3 + key[ik++] & 0xffff;
139
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.
143
144       x2 = x2 + key[ik++] & 0xffff;
145
146       // 4) Multiply (modulo 0x10001), 4th text-block
147       // with 4th key sub-block.
148
149       x4 = (int) ((long) x4 * key[ik++] % 0x10001L & 0xffff);
150
151       // Repackage from 16-bit sub-blocks to 8-bit byte array text2.
152
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);
161
162     }   // End for loop.
163
164   }   // End routine.
165
166   public static void main(String argv[]){
167     int nthreads;
168     if(argv.length != 0 ) {
169       nthreads = Integer.parseInt(argv[0]);
170     } else {
171       System.out.println("The no of threads has not been specified, defaulting to 1");
172       System.out.println("  ");
173       nthreads = 1;
174     }
175
176     /* Instruments output messages */
177     JGFInstrumentor instr = new JGFInstrumentor();
178     instr.printHeader(2,0,nthreads);
179
180     JGFCryptBench cb;
181     int size = 0;
182     instr.addTimer("Section2:Crypt:Kernel", "Kbyte",size);
183     cb = new JGFCryptBench(nthreads);
184     cb.JGFsetsize(size);
185     cb.JGFinitialise();
186
187     /* Start computation */
188     JGFCryptBenchSizeA[] th;
189     th = new JGFCryptBenchSizeA [nthreads];
190
191     // Start the stopwatch.       
192     instr.startTimer("Section2:Crypt:Kernel");        
193
194     // Encrypt plain1.
195     JGFCryptBenchSizeA tmp;
196     for(int i=1;i<nthreads;i++) {
197       th[i] = new JGFCryptBenchSizeA(cb, i, cb.plain1, cb.crypt1, cb.Z);
198       tmp = th[i];
199       tmp.start();
200     }
201
202     th[0] = new JGFCryptBenchSizeA(cb, 0, cb.plain1, cb.crypt1, cb.Z);
203     tmp = th[0];
204     tmp.start();
205
206
207     for(int i=1;i<nthreads;i++) {
208       tmp = th[i];
209       try {
210         tmp.join();
211       }  catch (InterruptedException e) {}
212     }
213
214     // Decrypt.
215     for(int i=1;i<nthreads;i++) {
216       th[i] = new JGFCryptBenchSizeA(cb, i, cb.crypt1, cb.plain2, cb.DK);
217       tmp = th[i];
218       tmp.start();
219     }
220
221     th[0] = new JGFCryptBenchSizeA(cb, 0, cb.crypt1, cb.plain2, cb.DK);
222     tmp = th[0];
223     tmp.start();
224
225
226     for(int i=1;i<nthreads;i++) {
227       tmp = th[i];
228       try {
229         tmp.join();
230       } catch (InterruptedException e) {}
231     }
232
233     // Stop the stopwatch.
234     instr.stopTimer("Section2:Crypt:Kernel");
235
236     cb.JGFvalidate();
237     cb.JGFtidyup();
238
239     int arows;
240     arows = cb.array_rows;
241
242     instr.addOpsToTimer("Section2:Crypt:Kernel", (2*arows)/1000.);
243     instr.printTimer("Section2:Crypt:Kernel");
244
245     System.out.println("Done\n");
246   }
247 }
248