Skip to content

Commit 3831056

Browse files
committed
Refactor FrodoMatrixGenerator (performance)
1 parent 2f62955 commit 3831056

File tree

1 file changed

+14
-17
lines changed

1 file changed

+14
-17
lines changed

core/src/main/java/org/bouncycastle/pqc/crypto/frodo/FrodoMatrixGenerator.java

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import org.bouncycastle.crypto.digests.SHAKEDigest;
66
import org.bouncycastle.crypto.engines.AESEngine;
77
import org.bouncycastle.crypto.params.KeyParameter;
8-
import org.bouncycastle.util.Arrays;
98
import org.bouncycastle.util.Pack;
109

1110
abstract 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

Comments
 (0)