diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2022-10-13 00:30:14 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2022-10-13 00:30:14 +0700 |
commit | a0513bc308839a6d6b3deb32ee76122181175569 (patch) | |
tree | 884db1c09bd048aac480d55a5515833b30f5f60d /crypto | |
parent | Reorganize FrodoVectorTest (diff) | |
download | BouncyCastle.NET-ed25519-a0513bc308839a6d6b3deb32ee76122181175569.tar.xz |
Refactor FrodoMatrixGenerator (performance)
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/src/pqc/crypto/frodo/FrodoMatrixGenerator.cs | 43 |
1 files changed, 15 insertions, 28 deletions
diff --git a/crypto/src/pqc/crypto/frodo/FrodoMatrixGenerator.cs b/crypto/src/pqc/crypto/frodo/FrodoMatrixGenerator.cs index ce985c9ab..95a7de18d 100644 --- a/crypto/src/pqc/crypto/frodo/FrodoMatrixGenerator.cs +++ b/crypto/src/pqc/crypto/frodo/FrodoMatrixGenerator.cs @@ -4,7 +4,6 @@ using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Digests; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Crypto.Utilities; -using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Pqc.Crypto.Frodo { @@ -33,52 +32,47 @@ namespace Org.BouncyCastle.Pqc.Crypto.Frodo { short[] A = new short[n * n]; ushort i, j; - byte[] b, tmp = new byte[(16 * n) / 8]; - byte[] temp = new byte[2]; + byte[] tmp = new byte[(16 * n) / 8]; + byte[] b = new byte[2 + seedA.Length]; + Array.Copy(seedA, 0, b, 2, seedA.Length); + + IXof digest = new ShakeDigest(128); + for (i = 0; i < n; i++) { // 1. b = i || seedA in {0,1}^{16 + len_seedA}, where i is encoded as a 16-bit integer in little-endian byte order - Pack.UInt16_To_LE(i, temp); - b = Arrays.Concatenate(temp, seedA); + Pack.UInt16_To_LE(i, b); // 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 - IXof digest = new ShakeDigest(128); digest.BlockUpdate(b, 0, b.Length); digest.OutputFinal(tmp, 0, tmp.Length); for (j = 0; j < n; j++) { - A[i * n + j] = (short) (Pack.LE_To_UInt16(tmp, 2 * j) % q);//todo add % q + A[i * n + j] = (short) (Pack.LE_To_UInt16(tmp, 2 * j) & (q - 1)); } - } - return A; } - } internal class Aes128MatrixGenerator : FrodoMatrixGenerator { - private readonly IBlockCipher m_cipher; - public Aes128MatrixGenerator(int n, int q) : base(n, q) { - m_cipher = AesUtilities.CreateEngine(); } internal override short[] GenMatrix(byte[] seedA) { - KeyParameter kp = new KeyParameter(seedA); - m_cipher.Init(true, kp); - // """Generate matrix A using AES-128 (FrodoKEM specification, Algorithm 7)""" // A = [[None for j in range(self.n)] for i in range(self.n)] short[] A = new short[n * n]; byte[] b = new byte[16]; byte[] c = new byte[16]; - byte[] temp = new byte[4]; + + IBlockCipher cipher = AesUtilities.CreateEngine(); + cipher.Init(true, new KeyParameter(seedA)); // 1. for i = 0; i < n; i += 1 for (int i = 0; i < n; i++) @@ -86,26 +80,19 @@ namespace Org.BouncyCastle.Pqc.Crypto.Frodo // 2. for j = 0; j < n; j += 8 for (int j = 0; j < n; j += 8) { - // 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 - Pack.UInt16_To_LE((ushort) (i & 0xffff), temp); - Array.Copy(temp, 0, b, 0, 2); - Pack.UInt16_To_LE((ushort) (j & 0xffff), temp); - Array.Copy(temp, 0, b, 2, 2); - // b = bytearray(16) - // struct.pack_into('<H', b, 0, i) - // struct.pack_into('<H', b, 2, j) + Pack.UInt16_To_LE((ushort)i, b, 0); + Pack.UInt16_To_LE((ushort)j, b, 2); // 4. c = AES128(seedA, b) - m_cipher.ProcessBlock(b, 0, c, 0); + cipher.ProcessBlock(b, 0, c, 0); // 5. for k = 0; k < 8; k += 1 for (int k = 0; k < 8; k++) { // 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 - A[i * n + j + k] = (short) (Pack.LE_To_UInt16(c, 2 * k) % q); //todo add % q + A[i * n + j + k] = (short)(Pack.LE_To_UInt16(c, 2 * k) & (q - 1)); } } } - return A; } } |