]> git.cryptolib.org Git - avr-crypto-lib.git/blob - jh/jh_tablegen.rb
new and more compact aes
[avr-crypto-lib.git] / jh / jh_tablegen.rb
1 #!/usr/bin/ruby
2 # jh_tablegen.rb
3 =begin
4     This file is part of the AVR-Crypto-Lib.
5     Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
6
7     This program is free software: you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation, either version 3 of the License, or
10     (at your option) any later version.
11
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16
17     You should have received a copy of the GNU General Public License
18     along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 =end
20
21 $sbox0 = [  9,  0,  4, 11, 13, 12,  3, 15,  1, 10,  2,  6,  7,  5,  8, 14]
22 $sbox1 = [  3, 12,  6, 13,  5,  7,  1,  9, 15,  2,  0,  4, 11, 10, 14,  8]
23
24 # (b) ^= ( ( (a) << 1) ^ ( (a) >> 3) ^ (( (a) >> 2) & 2) ) & 0xf;   
25 # (a) ^= ( ( (b) << 1) ^ ( (b) >> 3) ^ (( (b) >> 2) & 2) ) & 0xf;     
26
27 def L_transform(v,w)
28   v = v&0x0f; w = w&0x0f
29  # a = ((v<<1)|(v>>3))&0xf
30  # d = a^w^((v>>2)&2)
31  # d_ = ((d<<1)|(d>>3))&0xf
32  # c = v^d_^((d>>2)&2)
33  # return c, d
34  w ^= ((v<<1)^(v>>3)^((v>>2)&2))&0x0f
35  v ^= ((w<<1)^(w>>3)^((w>>2)&2))&0x0f
36  return v,w
37 end
38
39 def L_transform_inv(v,w)
40   a,b = L_transform(w,v)
41   return b,a
42 end
43
44
45 def pi_permute(a, d=8)
46   b=Array.new
47   (2**(d-2)).times{ |i| b[4*i+0] = a[4*i+0]}
48   (2**(d-2)).times{ |i| b[4*i+1] = a[4*i+1]}
49   (2**(d-2)).times{ |i| b[4*i+2] = a[4*i+3]}
50   (2**(d-2)).times{ |i| b[4*i+3] = a[4*i+2]}
51   return b
52 end
53
54 def p_permute(a, d=8)
55   b=Array.new
56   (2**(d-1)).times{ |i| b[i] = a[2*i]}
57   (2**(d-1)).times{ |i| b[i+2**(d-1)] = a[2*i+1]}
58   return b
59 end
60
61 def phi_permute(a, d=8)
62   b=Array.new
63   (2**(d-1)).times{ |i| b[i] = a[i]}
64   (2**(d-2)).times{ |i| b[2**(d-1)+2*i+0] = a[2**(d-1)+2*i+1]}
65   (2**(d-2)).times{ |i| b[2**(d-1)+2*i+1] = a[2**(d-1)+2*i+0]}
66   return b
67 end
68
69 def test_permutations
70   a = Array.new
71   16.times{|i| a[i]=i}
72   puts a.inspect
73   b = pi_permute(a,4)
74   puts b.inspect
75   b = p_permute(a,4)
76   puts b.inspect
77   b = phi_permute(a,4)
78   puts b.inspect
79 end
80
81 def permutation(a, d=8)
82   return phi_permute(p_permute(pi_permute(a,d),d),d)
83 end
84
85 $permutation_table=Array.new
86
87 def gen_permutation_table
88   a = Array.new
89   256.times {|i| a<<i}
90   $permutation_table=permutation(a,8)
91 end
92
93 def print_permute_table
94   printf("\npermutation table:\n\t")
95   16.times do |y|
96     16.times do |x| 
97       printf("0x%02X, ", $permutation_table[y*16+x])
98     end
99     printf("\n\t")
100   end
101   puts("")
102 end
103
104 $nibble_invert=false
105
106
107 def split_byte(v)
108   a = (v>>4)&0xf
109   b = v&0xf
110   return b,a if $nibble_invert
111   return a,b
112 end
113
114 def join_nibbles(a,b)
115   if($nibble_invert)
116     v = ((b<<4)|(a&0xf))&0xff
117   else
118     v = ((a<<4)|(b&0xf))&0xff
119   end
120   return v
121 end
122
123 $lutbox=Array.new
124
125 def gen_lutboxes
126   4.times do |box|
127     $lutbox[box]=Array.new
128     256.times do |i|
129       a,b = split_byte(i)
130       a = ((box&2)==2)?$sbox1[a]:$sbox0[a]
131       b = ((box&1)==1)?$sbox1[b]:$sbox0[b]
132       c,d = L_transform(a,b)
133       $lutbox[box]<<join_nibbles(c,d)
134     end
135   end
136 end
137
138 def print_lutbox(n)
139   printf("\nSBOX%d:\n\t",n)
140   256.times do |i|
141     printf("0x%02X, ",$lutbox[n][i])
142     print("\n\t") if(i%16==15)
143   end
144 end
145
146
147
148 $round_const = [
149   0x6a09e667f3bcc908b2fb1366ea957d3e3adec17512775099da2f590b0667322a,
150   0xbb896bf05955abcd5281828d66e7d99ac4203494f89bf12817deb43288712231,
151   0x1836e76b12d79c55118a1139d2417df52a2021225ff6350063d88e5f1f91631c,
152   0x263085a7000fa9c3317c6ca8ab65f7a7713cf4201060ce886af855a90d6a4eed,
153   0x1cebafd51a156aeb62a11fb3be2e14f60b7e48de85814270fd62e97614d7b441,
154   0xe5564cb574f7e09c75e2e244929e9549279ab224a28e445d57185e7d7a09fdc1,
155   0x5820f0f0d764cff3a5552a5e41a82b9eff6ee0aa615773bb07e8603424c3cf8a,
156   0xb126fb741733c5bfcef6f43a62e8e5706a26656028aa897ec1ea4616ce8fd510,
157   0xdbf0de32bca77254bb4f562581a3bc991cf94f225652c27f14eae958ae6aa616,
158   0xe6113be617f45f3de53cff03919a94c32c927b093ac8f23b47f7189aadb9bc67,
159   0x80d0d26052ca45d593ab5fb3102506390083afb5ffe107dacfcba7dbe601a12b,
160   0x43af1c76126714dfa950c368787c81ae3beecf956c85c962086ae16e40ebb0b4,
161   0x9aee8994d2d74a5cdb7b1ef294eed5c1520724dd8ed58c92d3f0e174b0c32045,
162   0x0b2aa58ceb3bdb9e1eef66b376e0c565d5d8fe7bacb8da866f859ac521f3d571,
163   0x7a1523ef3d970a3a9b0b4d610e02749d37b8d57c1885fe4206a7f338e8356866,
164   0x2c2db8f7876685f2cd9a2e0ddb64c9d5bf13905371fc39e0fa86e1477234a297,
165   0x9df085eb2544ebf62b50686a71e6e828dfed9dbe0b106c9452ceddff3d138990,
166   0xe6e5c42cb2d460c9d6e4791a1681bb2e222e54558eb78d5244e217d1bfcf5058,
167   0x8f1f57e44e126210f00763ff57da208a5093b8ff7947534a4c260a17642f72b2,
168   0xae4ef4792ea148608cf116cb2bff66e8fc74811266cd641112cd17801ed38b59,
169   0x91a744efbf68b192d0549b608bdb3191fc12a0e83543cec5f882250b244f78e4,
170   0x4b5d27d3368f9c17d4b2a2b216c7e74e7714d2cc03e1e44588cd9936de74357c,
171   0x0ea17cafb8286131bda9e3757b3610aa3f77a6d0575053fc926eea7e237df289,
172   0x848af9f57eb1a616e2c342c8cea528b8a95a5d16d9d87be9bb3784d0c351c32b,
173   0xc0435cc3654fb85dd9335ba91ac3dbde1f85d567d7ad16f9de6e009bca3f95b5,
174   0x927547fe5e5e45e2fe99f1651ea1cbf097dc3a3d40ddd21cee260543c288ec6b,
175   0xc117a3770d3a34469d50dfa7db020300d306a365374fa828c8b780ee1b9d7a34,
176   0x8ff2178ae2dbe5e872fac789a34bc228debf54a882743caad14f3a550fdbe68f,
177   0xabd06c52ed58ff091205d0f627574c8cbc1fe7cf79210f5a2286f6e23a27efa0,
178   0x631f4acb8d3ca4253e301849f157571d3211b6c1045347befb7c77df3c6ca7bd,
179   0xae88f2342c23344590be2014fab4f179fd4bf7c90db14fa4018fcce689d2127b,
180   0x93b89385546d71379fe41c39bc602e8b7c8b2f78ee914d1f0af0d437a189a8a4,
181   0x1d1e036abeef3f44848cd76ef6baa889fcec56cd7967eb909a464bfc23c72435,
182   0xa8e4ede4c5fe5e88d4fb192e0a0821e935ba145bbfc59c2508282755a5df53a5,
183   0x8e4e37a3b970f079ae9d22a499a714c875760273f74a9398995d32c05027d810,
184   0x61cfa42792f93b9fde36eb163e978709fafa7616ec3c7dad0135806c3d91a21b
185 ]
186
187 def group(a)
188   q = Array.new
189   128.times do |i|
190     q[2*i] = ((a[i/8])>>4)&0x8 | ((a[i/8+32])>>5)&0x4 | ((a[i/8+64])>>6)&0x2 | ((a[i/8+96])>>7)&0x1
191     a[i/8] <<= 1; a[i/8+32]<<=1; a[i/8+64]<<=1; a[i/8+96]<<=1;
192     q[2*i+1] = ((a[i/8+16])>>4)&0x8 | ((a[i/8+48])>>5)&0x4 | ((a[i/8+80])>>6)&0x2 | ((a[i/8+112])>>7)&0x1
193     a[i/8+16] <<= 1; a[i/8+48]<<=1; a[i/8+80]<<=1; a[i/8+112]<<=1;  
194   end
195   b = Array.new
196   128.times {|i| b<<join_nibbles(q[2*i], q[2*i+1])}
197   return b
198 end
199
200 def degroup(a)
201   b = Array.new
202   128.times {|i| b[i]=0}
203   128.times do |i|
204     b[i/8+  0]<<=1; b[i/8+  0] |= (a[i]>>7)&1; a[i]<<=1
205     b[i/8+ 32]<<=1; b[i/8+ 32] |= (a[i]>>7)&1; a[i]<<=1
206     b[i/8+ 64]<<=1; b[i/8+ 64] |= (a[i]>>7)&1; a[i]<<=1
207     b[i/8+ 96]<<=1; b[i/8+ 96] |= (a[i]>>7)&1; a[i]<<=1
208     b[i/8+ 16]<<=1; b[i/8+ 16] |= (a[i]>>7)&1; a[i]<<=1
209     b[i/8+ 48]<<=1; b[i/8+ 48] |= (a[i]>>7)&1; a[i]<<=1
210     b[i/8+ 80]<<=1; b[i/8+ 80] |= (a[i]>>7)&1; a[i]<<=1
211     b[i/8+112]<<=1; b[i/8+112] |= (a[i]>>7)&1; a[i]<<=1
212   end
213   return b
214 end
215
216 # data is an array of bytes
217 #
218 def single_round(data, round)
219   a = Array.new
220   rc = $round_const[round]
221 =begin
222   printf("\n== round %2d==\n\t", round)
223   16.times do |y|
224     8.times do |x|
225       printf("%02X ", data[8*y+x])
226     end
227     print("\n\t")
228   end
229 =end
230   128.times do |idx| 
231     x,y=split_byte($lutbox[((rc)>>(254))&0x3][data[idx]])
232     rc <<= 2
233     a << x << y
234   end 
235   a = permutation(a)
236   b = Array.new
237   128.times {|idx| b << join_nibbles(a[2*idx],a[2*idx+1])}
238   return b
239 end
240
241 def next_rc(data)
242   a = Array.new
243 =begin
244   printf("\n== rc round ==\n\t")
245   4.times do |y|
246     8.times do |x|
247       printf("%02X ", data[8*y+x])
248     end
249     print("\n\t")
250   end
251 =end
252   32.times do |idx| 
253     x,y=split_byte($lutbox[0][data[idx]])
254     a << x << y
255 #    if(x==nil)or(y==nil)
256 #      printf("DBG: idx=%2d, x=%2x, y=%2x", idx, x, y)
257 #    end
258   end 
259   a = permutation(a, 6)
260   b = Array.new
261   32.times {|idx| b << join_nibbles(a[2*idx],a[2*idx+1])}
262   return b
263 end
264
265 def encrypt(data)
266 =begin  
267   print("\n== ENCRYPT ==\n")
268   print("=== pre group: ===\n\t")
269   16.times do |y|
270     8.times do |x|
271       printf("%02X ", data[8*y+x])
272     end
273     print("\n\t")
274   end
275   puts("")
276 =end
277   data = group(data)
278 =begin
279   print("=== post group: ===\n\t")
280   16.times do |y|
281     8.times do |x|
282       printf("%02X ", data[8*y+x])
283     end
284     print("\n\t")
285   end
286   puts("")
287 =end
288   35.times do |round|
289     data = single_round(data, round)
290   end
291   a = Array.new
292   rc = $round_const[35]
293   data.length.times do |idx| 
294     x, y = split_byte($lutbox[(rc>>254)&3][data[idx]])
295     rc <<= 2
296     v, w = L_transform_inv(x, y)
297     a << join_nibbles(v,w)
298   end  
299   a = degroup(a)
300 =begin
301   print("\n=== post enc: ===\n\t")
302   16.times do |y|
303     8.times do |x|
304       printf("%02X ", a[8*y+x])
305     end
306     print("\n\t")
307   end
308   puts("")
309 =end
310   return a
311 end
312
313 def hash_block(state_a, block)
314   64.times { |i| state_a[i] ^= block[i]}
315   state_a = encrypt(state_a)
316   64.times { |i| state_a[64+i] ^= block[i]}
317   return state_a
318 end
319
320 def test_L_inverse
321   print("\nL_inv_test:\n\t")
322   256.times do |i|
323     a,b = split_byte(i)
324     c,d = L_transform(a, b)
325     a,b = L_transform_inv(c, d)
326     if join_nibbles(a,b)==i
327       print('*')
328     else
329       print('!')
330     end
331     print("\n\t") if(i%16==15)
332   end
333 end
334 #test_permutations
335
336 gen_lutboxes
337 gen_permutation_table
338 print_permute_table
339 4.times{ |i| print_lutbox(i) }
340 test_L_inverse
341 print("\nsingle round:\n\t")
342 h =  single_round([0,0,0,0,0,0,0,0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
343               0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
344               0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
345               0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],0)
346 16.times do |y|
347   8.times do |x|
348     printf("%02X, ",h[y*8+x])
349   end
350   print("\n\t")
351 end
352 #=begin
353 print("\nH(0):\n\t")
354 h =  hash_block([0x01,0,0,0,0,0,0,0x0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
355                  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
356                  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
357                  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
358                 [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
359                  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0])
360 h =  hash_block(h,
361                 [0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
362                  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0])
363 16.times do |y|
364   8.times do |x|
365     printf("%02X, ",h[y*8+x])
366   end
367   print("\n\t")
368 end
369 #=end
370 puts("")
371
372 c0 = [  0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08, 
373         0xb2, 0xfb, 0x13, 0x66, 0xea, 0x95, 0x7d, 0x3e, 
374         0x3a, 0xde, 0xc1, 0x75, 0x12, 0x77, 0x50, 0x99, 
375         0xda, 0x2f, 0x59, 0x0b, 0x06, 0x67, 0x32, 0x2a ]
376
377 rc = c0
378 42.times do |i|
379   printf("/* C_%02d: */\n", i)
380   4.times do |y|
381     printf("\t")
382     8.times do |x|
383       printf("0x%02x, ", rc[y*8+x])
384     end
385     printf("\n")
386   end
387   rc = next_rc(rc)
388 end