X-Git-Url: https://git.cryptolib.org/?p=avr-crypto-lib.git;a=blobdiff_plain;f=jh%2Fjh_tablegen.rb;fp=jh%2Fjh_tablegen.rb;h=5862a0e21193e5f325124a24e711c590b238b927;hp=0000000000000000000000000000000000000000;hb=bd740a03aa9137d46277a2eee05ac6be538ef69d;hpb=b8d6b2bd3ddea45506f584c7d44fe5fff0557ed1 diff --git a/jh/jh_tablegen.rb b/jh/jh_tablegen.rb new file mode 100644 index 0000000..5862a0e --- /dev/null +++ b/jh/jh_tablegen.rb @@ -0,0 +1,347 @@ +#!/usr/bin/ruby +# jh_tablegen.rb +=begin + This file is part of the AVR-Crypto-Lib. + Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +=end + +$sbox0 = [ 9, 0, 4, 11, 13, 12, 3, 15, 1, 10, 2, 6, 7, 5, 8, 14] +$sbox1 = [ 3, 12, 6, 13, 5, 7, 1, 9, 15, 2, 0, 4, 11, 10, 14, 8] + +# (b) ^= ( ( (a) << 1) ^ ( (a) >> 3) ^ (( (a) >> 2) & 2) ) & 0xf; +# (a) ^= ( ( (b) << 1) ^ ( (b) >> 3) ^ (( (b) >> 2) & 2) ) & 0xf; + +def L_transform(v,w) + v = v&0x0f; w = w&0x0f + # a = ((v<<1)|(v>>3))&0xf + # d = a^w^((v>>2)&2) + # d_ = ((d<<1)|(d>>3))&0xf + # c = v^d_^((d>>2)&2) + # return c, d + w ^= ((v<<1)^(v>>3)^((v>>2)&2))&0x0f + v ^= ((w<<1)^(w>>3)^((w>>2)&2))&0x0f + return v,w +end + +def L_transform_inv(v,w) + a,b = L_transform(w,v) + return b,a +end + + +def pi_permute(a, d=8) + b=Array.new + (2**(d-2)).times{ |i| b[4*i+0] = a[4*i+0]} + (2**(d-2)).times{ |i| b[4*i+1] = a[4*i+1]} + (2**(d-2)).times{ |i| b[4*i+2] = a[4*i+3]} + (2**(d-2)).times{ |i| b[4*i+3] = a[4*i+2]} + return b +end + +def p_permute(a, d=8) + b=Array.new + (2**(d-1)).times{ |i| b[i] = a[2*i]} + (2**(d-1)).times{ |i| b[i+2**(d-1)] = a[2*i+1]} + return b +end + +def phi_permute(a, d=8) + b=Array.new + (2**(d-1)).times{ |i| b[i] = a[i]} + (2**(d-2)).times{ |i| b[2**(d-1)+2*i+0] = a[2**(d-1)+2*i+1]} + (2**(d-2)).times{ |i| b[2**(d-1)+2*i+1] = a[2**(d-1)+2*i+0]} + return b +end + +def test_permutations + a = Array.new + 16.times{|i| a[i]=i} + puts a.inspect + b = pi_permute(a,4) + puts b.inspect + b = p_permute(a,4) + puts b.inspect + b = phi_permute(a,4) + puts b.inspect +end + +def permutation(a, d=8) + return phi_permute(p_permute(pi_permute(a,d),d),d) +end + +$permutation_table=Array.new + +def gen_permutation_table + a = Array.new + 256.times {|i| a<>4)&0xf + b = v&0xf + return b,a if $nibble_invert + return a,b +end + +def join_nibbles(a,b) + if($nibble_invert) + v = ((b<<4)|(a&0xf))&0xff + else + v = ((a<<4)|(b&0xf))&0xff + end + return v +end + +$lutbox=Array.new + +def gen_lutboxes + 4.times do |box| + $lutbox[box]=Array.new + 256.times do |i| + a,b = split_byte(i) + a = ((box&2)==2)?$sbox1[a]:$sbox0[a] + b = ((box&1)==1)?$sbox1[b]:$sbox0[b] + c,d = L_transform(a,b) + $lutbox[box]<>4)&0x8 | ((a[i/8+32])>>5)&0x4 | ((a[i/8+64])>>6)&0x2 | ((a[i/8+96])>>7)&0x1 + a[i/8] <<= 1; a[i/8+32]<<=1; a[i/8+64]<<=1; a[i/8+96]<<=1; + 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 + a[i/8+16] <<= 1; a[i/8+48]<<=1; a[i/8+80]<<=1; a[i/8+112]<<=1; + end + b = Array.new + 128.times {|i| b<>7)&1; a[i]<<=1 + b[i/8+ 32]<<=1; b[i/8+ 32] |= (a[i]>>7)&1; a[i]<<=1 + b[i/8+ 64]<<=1; b[i/8+ 64] |= (a[i]>>7)&1; a[i]<<=1 + b[i/8+ 96]<<=1; b[i/8+ 96] |= (a[i]>>7)&1; a[i]<<=1 + b[i/8+ 16]<<=1; b[i/8+ 16] |= (a[i]>>7)&1; a[i]<<=1 + b[i/8+ 48]<<=1; b[i/8+ 48] |= (a[i]>>7)&1; a[i]<<=1 + b[i/8+ 80]<<=1; b[i/8+ 80] |= (a[i]>>7)&1; a[i]<<=1 + b[i/8+112]<<=1; b[i/8+112] |= (a[i]>>7)&1; a[i]<<=1 + end + return b +end + +# data is an array of bytes +# +def single_round(data, round) + a = Array.new + rc = $round_const[round] +=begin + printf("\n== round %2d==\n\t", round) + 16.times do |y| + 8.times do |x| + printf("%02X ", data[8*y+x]) + end + print("\n\t") + end +=end + 128.times do |idx| + x,y=split_byte($lutbox[((rc)>>(254))&0x3][data[idx]]) + rc <<= 2 + a << x << y + end + a = permutation(a) + b = Array.new + 128.times {|idx| b << join_nibbles(a[2*idx],a[2*idx+1])} + return b +end + +def encrypt(data) +=begin + print("\n== ENCRYPT ==\n") + print("=== pre group: ===\n\t") + 16.times do |y| + 8.times do |x| + printf("%02X ", data[8*y+x]) + end + print("\n\t") + end + puts("") +=end + data = group(data) +=begin + print("=== post group: ===\n\t") + 16.times do |y| + 8.times do |x| + printf("%02X ", data[8*y+x]) + end + print("\n\t") + end + puts("") +=end + 35.times do |round| + data = single_round(data, round) + end + a = Array.new + rc = $round_const[35] + data.length.times do |idx| + x, y = split_byte($lutbox[(rc>>254)&3][data[idx]]) + rc <<= 2 + v, w = L_transform_inv(x, y) + a << join_nibbles(v,w) + end + a = degroup(a) +=begin + print("\n=== post enc: ===\n\t") + 16.times do |y| + 8.times do |x| + printf("%02X ", a[8*y+x]) + end + print("\n\t") + end + puts("") +=end + return a +end + +def hash_block(state_a, block) + 64.times { |i| state_a[i] ^= block[i]} + state_a = encrypt(state_a) + 64.times { |i| state_a[64+i] ^= block[i]} + return state_a +end + +def test_L_inverse + print("\nL_inv_test:\n\t") + 256.times do |i| + a,b = split_byte(i) + c,d = L_transform(a, b) + a,b = L_transform_inv(c, d) + if join_nibbles(a,b)==i + print('*') + else + print('!') + end + print("\n\t") if(i%16==15) + end +end +#test_permutations + +gen_lutboxes +gen_permutation_table +print_permute_table +4.times{ |i| print_lutbox(i) } +test_L_inverse +print("\nsingle round:\n\t") +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, + 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,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,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) +16.times do |y| + 8.times do |x| + printf("%02X, ",h[y*8+x]) + end + print("\n\t") +end +#=begin +print("\nH(0):\n\t") +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, + 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,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,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,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,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]) +h = hash_block(h, + [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, + 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]) +16.times do |y| + 8.times do |x| + printf("%02X, ",h[y*8+x]) + end + print("\n\t") +end +#=end +puts("") +