55import org .bouncycastle .crypto .digests .SHAKEDigest ;
66import org .bouncycastle .crypto .engines .AESEngine ;
77import org .bouncycastle .crypto .params .KeyParameter ;
8- import org .bouncycastle .util .Arrays ;
98import org .bouncycastle .util .Pack ;
109
1110abstract class FrodoMatrixGenerator
@@ -33,33 +32,35 @@ short[] genMatrix(byte[] seedA)
3332 {
3433 short [] A = new short [n *n ];
3534 short i , j ;
36- byte [] b , tmp = new byte [(16 * n ) / 8 ];
35+ byte [] tmp = new byte [(16 * n ) / 8 ];
36+ byte [] b = new byte [2 + seedA .length ];
37+ System .arraycopy (seedA , 0 , b , 2 , seedA .length );
38+
39+ Xof digest = new SHAKEDigest (128 );
40+
3741 for (i = 0 ; i < n ; i ++)
3842 {
3943 // 1. b = i || seedA in {0,1}^{16 + len_seedA}, where i is encoded as a 16-bit integer in little-endian byte order
40- b = Arrays . concatenate ( Pack .shortToLittleEndian (i ), seedA );
44+ Pack .shortToLittleEndian (i , b , 0 );
4145
4246 // 2. c_{i,0} || c_{i,1} || ... || c_{i,n-1} = SHAKE128(b, 16n) (length in bits) where each c_{i,j} is parsed as a 16-bit integer in little-endian byte order format
43- Xof digest = new SHAKEDigest (128 );
4447 digest .update (b , 0 , b .length );
4548 digest .doFinal (tmp , 0 , tmp .length );
4649 for (j = 0 ; j < n ; j ++)
4750 {
48- A [i *n +j ] = (short ) (Pack .littleEndianToShort (tmp , 2 * j ) % q );
51+ A [i *n +j ] = (short ) (Pack .littleEndianToShort (tmp , 2 * j ) & ( q - 1 ) );
4952 }
5053 }
5154 return A ;
5255 }
53-
5456 }
57+
5558 static class Aes128MatrixGenerator
5659 extends FrodoMatrixGenerator
5760 {
58- private final BlockCipher cipher ;
5961 public Aes128MatrixGenerator (int n , int q )
6062 {
6163 super (n , q );
62- cipher = new AESEngine ();
6364 }
6465
6566 short [] genMatrix (byte [] seedA )
@@ -70,29 +71,25 @@ short[] genMatrix(byte[] seedA)
7071 byte [] b = new byte [16 ];
7172 byte [] c = new byte [16 ];
7273
73- KeyParameter kp = new KeyParameter ( seedA );
74- cipher .init (true , kp );
74+ BlockCipher cipher = new AESEngine ( );
75+ cipher .init (true , new KeyParameter ( seedA ) );
7576
7677 // 1. for i = 0; i < n; i += 1
7778 for (int i = 0 ; i < n ; i ++)
7879 {
7980 // 2. for j = 0; j < n; j += 8
8081 for (int j = 0 ; j < n ; j +=8 )
8182 {
82-
8383 // 3. b = i || j || 0 || ... || 0 in {0,1}^128, where i and j are encoded as 16-bit integers in little-endian byte order
84- System .arraycopy (Pack .shortToLittleEndian ((short ) (i &0xffff )), 0 , b , 0 , 2 );
85- System .arraycopy (Pack .shortToLittleEndian ((short ) (j &0xffff )), 0 , b , 2 , 2 );
86- // b = bytearray(16)
87- // struct.pack_into('<H', b, 0, i)
88- // struct.pack_into('<H', b, 2, j)
84+ Pack .shortToLittleEndian ((short )i , b , 0 );
85+ Pack .shortToLittleEndian ((short )j , b , 2 );
8986 // 4. c = AES128(seedA, b)
9087 cipher .processBlock (b , 0 , c , 0 );
9188 // 5. for k = 0; k < 8; k += 1
9289 for (int k = 0 ; k < 8 ; k ++)
9390 {
9491 // 6. A[i][j+k] = c[k] where c is treated as a sequence of 8 16-bit integers each in little-endian byte order
95- A [i *n + j + k ] = (short ) (Pack .littleEndianToShort (c , 2 * k ) % q );
92+ A [i *n + j + k ] = (short ) (Pack .littleEndianToShort (c , 2 * k ) & ( q - 1 ) );
9693 }
9794 }
9895 }
0 commit comments