diff --git a/crypto/src/pqc/crypto/hqc/GF2PolynomialCalculator.cs b/crypto/src/pqc/crypto/hqc/GF2PolynomialCalculator.cs
index 0c01ade96..48774cde3 100644
--- a/crypto/src/pqc/crypto/hqc/GF2PolynomialCalculator.cs
+++ b/crypto/src/pqc/crypto/hqc/GF2PolynomialCalculator.cs
@@ -1,129 +1,223 @@
-using System;
-#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
-using System.Buffers.Binary;
-using System.Runtime.InteropServices;
-#endif
-
-using Org.BouncyCastle.Math.Raw;
-
-namespace Org.BouncyCastle.Pqc.Crypto.Hqc
+namespace Org.BouncyCastle.Pqc.Crypto.Hqc
{
internal class GF2PolynomialCalculator
{
- private const int TABLE = 16;
+ private readonly int _vecNSize64;
+ private readonly int _paramN;
+ private readonly long _redMask;
- static void Mod(ulong[] res, ulong[] a, int n, int nByte64)
+ public GF2PolynomialCalculator(int vecNSize64, int paramN, ulong redMask)
{
- for (int i = 0; i < nByte64; i++)
- {
- ulong r = a[i + nByte64 - 1] >> (n & 0x3F);
- ulong carry = a[i + nByte64] << (64 - (n & 0x3F));
- res[i] = a[i] ^ r ^ carry;
- }
- res[nByte64 - 1] &= Utils.BitMask((ulong)n, 64);
+ _vecNSize64 = vecNSize64;
+ _paramN = paramN;
+ _redMask = (long)redMask;
}
- static void Swap(int[] table, int firstIndex, int secondIndex)
+ internal void MultLongs(long[] res, long[] a, long[] b)
{
- int tmp = table[firstIndex];
- table[firstIndex] = table[secondIndex];
- table[secondIndex] = tmp;
+ long[] stack = new long[_vecNSize64 << 3];
+ long[] oKarat = new long[(_vecNSize64 << 1) + 1];
+
+ karatsuba(oKarat, 0, a, 0, b, 0, _vecNSize64, stack, 0);
+ reduce(res, oKarat);
}
- static void FastConvolutionMult(ulong[] res, int[] a, ulong[] b, int weight, int nByte64, int we,
- HqcKeccakRandomGenerator random)
+
+ private void base_mul(long[] c, int cOffset, long a, long b)
{
- int[] permutedTable = new int[TABLE];
- for (int i = 0; i < 16; i++)
+ long h = 0;
+ long l = 0;
+ long g;
+ long[] u = new long[16];
+ long[] maskTab = new long[4];
+
+ // Step 1
+ u[0] = 0;
+ u[1] = b & ((1L << (64 - 4)) - 1L);
+ u[2] = u[1] << 1;
+ u[3] = u[2] ^ u[1];
+ u[4] = u[2] << 1;
+ u[5] = u[4] ^ u[1];
+ u[6] = u[3] << 1;
+ u[7] = u[6] ^ u[1];
+ u[8] = u[4] << 1;
+ u[9] = u[8] ^ u[1];
+ u[10] = u[5] << 1;
+ u[11] = u[10] ^ u[1];
+ u[12] = u[6] << 1;
+ u[13] = u[12] ^ u[1];
+ u[14] = u[7] << 1;
+ u[15] = u[14] ^ u[1];
+
+ g=0;
+ long tmp1 = a & 15;
+
+ for(int i = 0; i < 16; i++)
{
- permutedTable[i] = i;
+ long tmp2 = tmp1 - i;
+ g ^= (u[i] & -(1 - (long)((ulong)(tmp2 | -tmp2) >> 63)));
}
+ l = g;
+ h = 0;
- byte[] permutationTableByte = new byte[TABLE*2];
- random.ExpandSeed(permutationTableByte, TABLE << 1);
-
- int[] permutationTable = new int[TABLE];
- Utils.FromByteArrayToByte16Array(permutationTable, permutationTableByte);
-
- for (int i = 0; i < TABLE - 1; i++)
+ // Step 2
+ for (byte i = 4; i < 64; i += 4)
{
- Swap(permutedTable, i, i + permutationTable[i] % (TABLE - i));
+ g = 0;
+ long temp1 = (a >> i) & 15;
+ for (int j = 0; j < 16; ++j)
+ {
+ long tmp2 = temp1 - j;
+ g ^= (u[j] & -(1 - (long)((ulong)(tmp2 | -tmp2) >> 63)));
+ }
+
+ l ^= g << i;
+ h ^= (long)((ulong)g) >> (64 - i);
}
- ulong[] table = new ulong[TABLE * (nByte64 + 1)];
- int idx = permutedTable[0] * (nByte64 + 1);
- Array.Copy(b, 0, table, idx, nByte64);
- table[idx + nByte64] = 0UL;
+ // Step 3
+ maskTab [0] = -((b >> 60) & 1);
+ maskTab [1] = -((b >> 61) & 1);
+ maskTab [2] = -((b >> 62) & 1);
+ maskTab [3] = -((b >> 63) & 1);
+
+ l ^= ((a << 60) & maskTab[0]);
+ h ^= ((long)((ulong)a >> 4) & maskTab[0]);
+
+ l ^= ((a << 61) & maskTab[1]);
+ h ^= ((long)((ulong)a >> 3) & maskTab[1]);
- for (int i = 1; i < TABLE; i++)
+ l ^= ((a << 62) & maskTab[2]);
+ h ^= ((long)((ulong)a >> 2) & maskTab[2]);
+
+ l ^= ((a << 63) & maskTab[3]);
+ h ^= ((long)((ulong)a >> 1) & maskTab[3]);
+
+ c[0 + cOffset] = l;
+ c[1 + cOffset] = h;
+ }
+
+
+
+
+ private void karatsuba_add1(long[] alh, int alhOffset,
+ long[] blh, int blhOffset,
+ long[] a, int aOffset,
+ long[] b, int bOffset,
+ int size_l, int size_h)
+ {
+ for (int i = 0; i < size_h; i++)
{
- idx = permutedTable[i] * (nByte64 + 1);
- table[idx + nByte64] = Nat.ShiftUpBits64(nByte64, b, 0, i, 0UL, table, idx);
+ alh[i + alhOffset] = a[i+ aOffset] ^ a[i + size_l + aOffset];
+ blh[i + blhOffset] = b[i+ bOffset] ^ b[i + size_l + bOffset];
}
- int[] permutedSparseVect = new int[we];
- for (int i = 0; i < weight; i++)
+ if (size_h < size_l)
{
- permutedSparseVect[i] = i;
+ alh[size_h + alhOffset] = a[size_h + aOffset];
+ blh[size_h + blhOffset] = b[size_h + bOffset];
}
+ }
- byte[] permutationSparseVectBytes = new byte[we * 2];
- random.ExpandSeed(permutationSparseVectBytes, weight << 1);
- int[] permutationSparseVect = new int[we];
- Utils.FromByteArrayToByte16Array(permutationSparseVect, permutationSparseVectBytes);
- for (int i = 0; i < (weight - 1); i++)
+ private void karatsuba_add2(long[] o, int oOffset,
+ long[] tmp1, int tmp1Offset,
+ long[] tmp2, int tmp2Offset,
+ int size_l, int size_h)
+ {
+ for (int i = 0; i < (2 * size_l) ; i++)
{
- Swap(permutedSparseVect, i, i + permutationSparseVect[i] % (weight - i));
+ tmp1[i + tmp1Offset] = tmp1[i + tmp1Offset] ^ o[i + oOffset];
}
-#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
- Span<byte> resBytes = MemoryMarshal.AsBytes(res.AsSpan());
- for (int i = 0; i < weight; i++)
+ for (int i = 0; i < ( 2 * size_h); i++)
{
- int dec = a[permutedSparseVect[i]] & 0xf;
- int s = a[permutedSparseVect[i]] >> 4;
-
- idx = permutedTable[dec] * (nByte64 + 1);
-
- int count = s * 2 + nByte64 * 8;
- for (int j = nByte64; j >= 0; --j)
- {
- ulong tmp = BinaryPrimitives.ReadUInt64LittleEndian(resBytes[count..]);
- BinaryPrimitives.WriteUInt64LittleEndian(resBytes[count..], tmp ^ table[idx + j]);
- count -= 8;
- }
+ tmp1[i + tmp1Offset] = tmp1[i + tmp1Offset] ^ tmp2[i + tmp2Offset];
}
-#else
- ushort[] resByte16 = new ushort[res.Length * 4];
- for (int i = 0; i < weight; i++)
+
+ for (int i = 0; i < (2 * size_l); i++)
{
- int dec = a[permutedSparseVect[i]] & 0xf;
- int s = a[permutedSparseVect[i]] >> 4;
+ o[i + size_l + oOffset] = o[i + size_l + oOffset] ^ tmp1[i + tmp1Offset];
+ }
+ }
- idx = permutedTable[dec] * (nByte64 + 1);
- int count = s;
- for (int j = 0; j <= nByte64; j++)
- {
- Utils.XorULongToByte16Array(resByte16, count, table[idx + j]);
- count += 4;
- }
+
+ /**
+ * Karatsuba multiplication of a and b, Implementation inspired from the NTL library.
+ *
+ * \param[out] o Polynomial
+ * \param[in] a Polynomial
+ * \param[in] b Polynomial
+ * \param[in] size Length of polynomial
+ * \param[in] stack Length of polynomial
+ */
+ private void karatsuba(long[] o, int oOffset, long[] a, int aOffset, long[] b, int bOffset, int size, long[] stack, int stackOffset)
+ {
+ int size_l, size_h;
+ int ahOffset, bhOffset;
+
+ if (size == 1)
+ {
+ base_mul(o, oOffset, a[0 + aOffset], b[0 + bOffset]);
+ return;
}
- Utils.FromByte16ArrayToULongArray(res, resByte16);
-#endif
+
+ size_h = size / 2;
+ size_l = (size + 1) / 2;
+
+ // alh = stack
+ int alhOffset = stackOffset;
+ // blh = stack with size_l offset
+ int blhOffset = alhOffset + size_l;
+ // tmp1 = stack with size_l * 2 offset;
+ int tmp1Offset = blhOffset + size_l;
+ // tmp2 = o with size_l * 2 offset;
+ int tmp2Offset = oOffset + size_l*2;
+
+ stackOffset += 4 * size_l;
+
+ ahOffset = aOffset + size_l;
+ bhOffset = bOffset + size_l;
+
+ karatsuba(o, oOffset, a, aOffset, b, bOffset, size_l, stack, stackOffset);
+
+ karatsuba(o, tmp2Offset, a, ahOffset, b, bhOffset, size_h, stack, stackOffset);
+
+ karatsuba_add1(stack, alhOffset, stack, blhOffset, a, aOffset, b, bOffset, size_l, size_h);
+
+ karatsuba(stack, tmp1Offset, stack, alhOffset, stack, blhOffset, size_l, stack, stackOffset);
+
+ karatsuba_add2(o, oOffset, stack, tmp1Offset, o, tmp2Offset, size_l, size_h);
}
- internal static void ModMult(ulong[] res, int[] a, ulong[] b, int weight,int n, int nByte64, int we,
- HqcKeccakRandomGenerator random)
+
+
+ /**
+ * @brief Compute o(x) = a(x) mod \f$ X^n - 1\f$
+ *
+ * This function computes the modular reduction of the polynomial a(x)
+ *
+ * @param[in] a Pointer to the polynomial a(x)
+ * @param[out] o Pointer to the result
+ */
+ private void reduce(long[] o, long[] a)
{
- ulong[] tmp = new ulong[(nByte64 << 1) + 1];
- FastConvolutionMult(tmp, a, b, weight, nByte64, we, random);
- Mod(res, tmp, n, nByte64);
+ int i;
+ long r;
+ long carry;
+
+ for (i = 0; i < _vecNSize64; i++)
+ {
+ r = (long)((ulong)a[i + _vecNSize64 - 1] >> (_paramN & 0x3F));
+ carry = a[i + _vecNSize64 ] << (int)(64 - (_paramN & 0x3FL));
+ o[i] = a[i] ^ r ^ carry;
+ }
+ o[_vecNSize64 - 1] &= _redMask;
}
- internal static void AddULongs(ulong[] res, ulong[] a, ulong[] b)
+ internal static void AddLongs(long[] res, long[] a, long[] b)
{
for (int i = 0; i < a.Length; i++)
{
diff --git a/crypto/src/pqc/crypto/hqc/GFCalculator.cs b/crypto/src/pqc/crypto/hqc/GFCalculator.cs
index d63e70513..ab0359b3b 100644
--- a/crypto/src/pqc/crypto/hqc/GFCalculator.cs
+++ b/crypto/src/pqc/crypto/hqc/GFCalculator.cs
@@ -2,8 +2,8 @@
{
internal class GFCalculator
{
- static int[] exp = new int[] { 1, 2, 4, 8, 16, 32, 64, 128, 29, 58, 116, 232, 205, 135, 19, 38, 76, 152, 45, 90, 180, 117, 234, 201, 143, 3, 6, 12, 24, 48, 96, 192, 157, 39, 78, 156, 37, 74, 148, 53, 106, 212, 181, 119, 238, 193, 159, 35, 70, 140, 5, 10, 20, 40, 80, 160, 93, 186, 105, 210, 185, 111, 222, 161, 95, 190, 97, 194, 153, 47, 94, 188, 101, 202, 137, 15, 30, 60, 120, 240, 253, 231, 211, 187, 107, 214, 177, 127, 254, 225, 223, 163, 91, 182, 113, 226, 217, 175, 67, 134, 17, 34, 68, 136, 13, 26, 52, 104, 208, 189, 103, 206, 129, 31, 62, 124, 248, 237, 199, 147, 59, 118, 236, 197, 151, 51, 102, 204, 133, 23, 46, 92, 184, 109, 218, 169, 79, 158, 33, 66, 132, 21, 42, 84, 168, 77, 154, 41, 82, 164, 85, 170, 73, 146, 57, 114, 228, 213, 183, 115, 230, 209, 191, 99, 198, 145, 63, 126, 252, 229, 215, 179, 123, 246, 241, 255, 227, 219, 171, 75, 150, 49, 98, 196, 149, 55, 110, 220, 165, 87, 174, 65, 130, 25, 50, 100, 200, 141, 7, 14, 28, 56, 112, 224, 221, 167, 83, 166, 81, 162, 89, 178, 121, 242, 249, 239, 195, 155, 43, 86, 172, 69, 138, 9, 18, 36, 72, 144, 61, 122, 244, 245, 247, 243, 251, 235, 203, 139, 11, 22, 44, 88, 176, 125, 250, 233, 207, 131, 27, 54, 108, 216, 173, 71, 142, 1, 2, 4 };
- static int[] log = new int[] { 0, 0, 1, 25, 2, 50, 26, 198, 3, 223, 51, 238, 27, 104, 199, 75, 4, 100, 224, 14, 52, 141, 239, 129, 28, 193, 105, 248, 200, 8, 76, 113, 5, 138, 101, 47, 225, 36, 15, 33, 53, 147, 142, 218, 240, 18, 130, 69, 29, 181, 194, 125, 106, 39, 249, 185, 201, 154, 9, 120, 77, 228, 114, 166, 6, 191, 139, 98, 102, 221, 48, 253, 226, 152, 37, 179, 16, 145, 34, 136, 54, 208, 148, 206, 143, 150, 219, 189, 241, 210, 19, 92, 131, 56, 70, 64, 30, 66, 182, 163, 195, 72, 126, 110, 107, 58, 40, 84, 250, 133, 186, 61, 202, 94, 155, 159, 10, 21, 121, 43, 78, 212, 229, 172, 115, 243, 167, 87, 7, 112, 192, 247, 140, 128, 99, 13, 103, 74, 222, 237, 49, 197, 254, 24, 227, 165, 153, 119, 38, 184, 180, 124, 17, 68, 146, 217, 35, 32, 137, 46, 55, 63, 209, 91, 149, 188, 207, 205, 144, 135, 151, 178, 220, 252, 190, 97, 242, 86, 211, 171, 20, 42, 93, 158, 132, 60, 57, 83, 71, 109, 65, 162, 31, 45, 67, 216, 183, 123, 164, 118, 196, 23, 73, 236, 127, 12, 111, 246, 108, 161, 59, 82, 41, 157, 85, 170, 251, 96, 134, 177, 187, 204, 62, 90, 203, 89, 95, 176, 156, 169, 160, 81, 11, 245, 22, 235, 122, 117, 44, 215, 79, 174, 213, 233, 230, 231, 173, 232, 116, 214, 244, 234, 168, 80, 88, 175 };
+ static int[] exp = { 1, 2, 4, 8, 16, 32, 64, 128, 29, 58, 116, 232, 205, 135, 19, 38, 76, 152, 45, 90, 180, 117, 234, 201, 143, 3, 6, 12, 24, 48, 96, 192, 157, 39, 78, 156, 37, 74, 148, 53, 106, 212, 181, 119, 238, 193, 159, 35, 70, 140, 5, 10, 20, 40, 80, 160, 93, 186, 105, 210, 185, 111, 222, 161, 95, 190, 97, 194, 153, 47, 94, 188, 101, 202, 137, 15, 30, 60, 120, 240, 253, 231, 211, 187, 107, 214, 177, 127, 254, 225, 223, 163, 91, 182, 113, 226, 217, 175, 67, 134, 17, 34, 68, 136, 13, 26, 52, 104, 208, 189, 103, 206, 129, 31, 62, 124, 248, 237, 199, 147, 59, 118, 236, 197, 151, 51, 102, 204, 133, 23, 46, 92, 184, 109, 218, 169, 79, 158, 33, 66, 132, 21, 42, 84, 168, 77, 154, 41, 82, 164, 85, 170, 73, 146, 57, 114, 228, 213, 183, 115, 230, 209, 191, 99, 198, 145, 63, 126, 252, 229, 215, 179, 123, 246, 241, 255, 227, 219, 171, 75, 150, 49, 98, 196, 149, 55, 110, 220, 165, 87, 174, 65, 130, 25, 50, 100, 200, 141, 7, 14, 28, 56, 112, 224, 221, 167, 83, 166, 81, 162, 89, 178, 121, 242, 249, 239, 195, 155, 43, 86, 172, 69, 138, 9, 18, 36, 72, 144, 61, 122, 244, 245, 247, 243, 251, 235, 203, 139, 11, 22, 44, 88, 176, 125, 250, 233, 207, 131, 27, 54, 108, 216, 173, 71, 142, 1, 2, 4 };
+ static int[] log = { 0, 0, 1, 25, 2, 50, 26, 198, 3, 223, 51, 238, 27, 104, 199, 75, 4, 100, 224, 14, 52, 141, 239, 129, 28, 193, 105, 248, 200, 8, 76, 113, 5, 138, 101, 47, 225, 36, 15, 33, 53, 147, 142, 218, 240, 18, 130, 69, 29, 181, 194, 125, 106, 39, 249, 185, 201, 154, 9, 120, 77, 228, 114, 166, 6, 191, 139, 98, 102, 221, 48, 253, 226, 152, 37, 179, 16, 145, 34, 136, 54, 208, 148, 206, 143, 150, 219, 189, 241, 210, 19, 92, 131, 56, 70, 64, 30, 66, 182, 163, 195, 72, 126, 110, 107, 58, 40, 84, 250, 133, 186, 61, 202, 94, 155, 159, 10, 21, 121, 43, 78, 212, 229, 172, 115, 243, 167, 87, 7, 112, 192, 247, 140, 128, 99, 13, 103, 74, 222, 237, 49, 197, 254, 24, 227, 165, 153, 119, 38, 184, 180, 124, 17, 68, 146, 217, 35, 32, 137, 46, 55, 63, 209, 91, 149, 188, 207, 205, 144, 135, 151, 178, 220, 252, 190, 97, 242, 86, 211, 171, 20, 42, 93, 158, 132, 60, 57, 83, 71, 109, 65, 162, 31, 45, 67, 216, 183, 123, 164, 118, 196, 23, 73, 236, 127, 12, 111, 246, 108, 161, 59, 82, 41, 157, 85, 170, 251, 96, 134, 177, 187, 204, 62, 90, 203, 89, 95, 176, 156, 169, 160, 81, 11, 245, 22, 235, 122, 117, 44, 215, 79, 174, 213, 233, 230, 231, 173, 232, 116, 214, 244, 234, 168, 80, 88, 175 };
internal static int mult(int a, int b)
{
diff --git a/crypto/src/pqc/crypto/hqc/HqcEngine.cs b/crypto/src/pqc/crypto/hqc/HqcEngine.cs
index ac1a96f00..ee628e843 100644
--- a/crypto/src/pqc/crypto/hqc/HqcEngine.cs
+++ b/crypto/src/pqc/crypto/hqc/HqcEngine.cs
@@ -1,5 +1,5 @@
using System;
-
+using Org.BouncyCastle.Crypto.Utilities;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Pqc.Crypto.Hqc
@@ -33,10 +33,18 @@ namespace Org.BouncyCastle.Pqc.Crypto.Hqc
private int N1N2_BYTE_64;
private int N1N2_BYTE;
private int N1_BYTE;
+
+ private int GF_POLY_WT = 5;
+ private int GF_POLY_M2 = 4;
+ private int SALT_SIZE_BYTES = 16;
+ private int SALT_SIZE_64 = 2;
private int[] generatorPoly;
private int SHA512_BYTES = 512 / 8;
+ private ulong RED_MASK;
+ private GF2PolynomialCalculator gfCalculator;
+
public HqcEngine(int n, int n1, int n2, int k, int g, int delta, int w, int wr, int we, int rejectionThreshold, int fft, int[] generatorPoly)
{
this.n = n;
@@ -47,21 +55,25 @@ namespace Org.BouncyCastle.Pqc.Crypto.Hqc
this.we = we;
this.n1 = n1;
this.n2 = n2;
- this.n1n2 = n1 * n2;
+ n1n2 = n1 * n2;
this.generatorPoly = generatorPoly;
this.g = g;
this.rejectionThreshold = rejectionThreshold;
this.fft = fft;
- this.mulParam = (n2 + 127) / 128;
- this.N_BYTE = Utils.GetByteSizeFromBitSize(n);
- this.K_BYTE = k;
- this.N_BYTE_64 = Utils.GetByte64SizeFromBitSize(n);
- this.K_BYTE_64 = Utils.GetByteSizeFromBitSize(k);
- this.N1_BYTE_64 = Utils.GetByteSizeFromBitSize(n1);
- this.N1N2_BYTE_64 = Utils.GetByte64SizeFromBitSize(n1 * n2);
- this.N1N2_BYTE = Utils.GetByteSizeFromBitSize(n1 * n2);
- this.N1_BYTE = Utils.GetByteSizeFromBitSize(n1);
+ mulParam = (n2 + 127) / 128;
+ N_BYTE = Utils.GetByteSizeFromBitSize(n);
+ K_BYTE = k;
+ N_BYTE_64 = Utils.GetByte64SizeFromBitSize(n);
+ K_BYTE_64 = Utils.GetByteSizeFromBitSize(k);
+ N1_BYTE_64 = Utils.GetByteSizeFromBitSize(n1);
+ N1N2_BYTE_64 = Utils.GetByte64SizeFromBitSize(n1 * n2);
+ N1N2_BYTE = Utils.GetByteSizeFromBitSize(n1 * n2);
+ N1_BYTE = Utils.GetByteSizeFromBitSize(n1);
+
+ RED_MASK = ((1UL << (n % 64)) - 1);
+
+ gfCalculator = new GF2PolynomialCalculator(N_BYTE_64, n, RED_MASK);
}
/**
@@ -84,11 +96,11 @@ namespace Org.BouncyCastle.Pqc.Crypto.Hqc
HqcKeccakRandomGenerator secretKeySeedExpander = new HqcKeccakRandomGenerator(256);
secretKeySeedExpander.SeedExpanderInit(secretKeySeed, secretKeySeed.Length);
- ulong[] xLongBytes = new ulong[N_BYTE_64];
- int[] yPos = new int[this.w];
+ long[] xLongBytes = new long[N_BYTE_64];
+ long[] yLongBytes = new long[N_BYTE_64];
- GenerateSecretKey(xLongBytes, secretKeySeedExpander, w);
- GenerateSecretKeyByCoordinates(yPos, secretKeySeedExpander, w);
+ GenerateRandomFixedWeight(xLongBytes, secretKeySeedExpander, w);
+ GenerateRandomFixedWeight(yLongBytes, secretKeySeedExpander, w);
// 2. Randomly generate h
byte[] publicKeySeed = new byte[SEED_SIZE];
@@ -97,15 +109,15 @@ namespace Org.BouncyCastle.Pqc.Crypto.Hqc
HqcKeccakRandomGenerator randomPublic = new HqcKeccakRandomGenerator(256);
randomPublic.SeedExpanderInit(publicKeySeed, publicKeySeed.Length);
- ulong[] hLongBytes = new ulong[N_BYTE_64];
+ long[] hLongBytes = new long[N_BYTE_64];
GeneratePublicKeyH(hLongBytes, randomPublic);
// 3. Compute s
- ulong[] s = new ulong[N_BYTE_64];
- GF2PolynomialCalculator.ModMult(s, yPos, hLongBytes, w, n, N_BYTE_64, we, secretKeySeedExpander);
- GF2PolynomialCalculator.AddULongs(s, s, xLongBytes);
+ long[] s = new long[N_BYTE_64];
+ gfCalculator.MultLongs(s, yLongBytes, hLongBytes);
+ GF2PolynomialCalculator.AddLongs(s, s, xLongBytes);
byte[] sBytes = new byte[N_BYTE];
- Utils.FromULongArrayToByteArray(sBytes, s);
+ Utils.FromLongArrayToByteArray(sBytes, s);
byte[] tmpPk = Arrays.Concatenate(publicKeySeed, sBytes);
byte[] tmpSk = Arrays.Concatenate(secretKeySeed, tmpPk);
@@ -126,7 +138,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Hqc
* @param pk public key
* @param seed seed
**/
- public void Encaps(byte[] u, byte[] v, byte[] K, byte[] d, byte[] pk, byte[] seed)
+ public void Encaps(byte[] u, byte[] v, byte[] K, byte[] d, byte[] pk, byte[] seed, byte[] salt)
{
// 1. Randomly generate m
byte[] m = new byte[K_BYTE];
@@ -145,27 +157,33 @@ namespace Org.BouncyCastle.Pqc.Crypto.Hqc
// 2. Generate theta
byte[] theta = new byte[SHA512_BYTES];
+ byte[] tmp = new byte[K_BYTE + SEED_SIZE + SALT_SIZE_BYTES];
+ randomGenerator.Squeeze(salt, SALT_SIZE_BYTES);
+
+ Array.Copy(m, 0, tmp, 0, m.Length);
+ Array.Copy(pk, 0, tmp, K_BYTE, SEED_SIZE);
+ Array.Copy(salt, 0, tmp, K_BYTE + SEED_SIZE, SALT_SIZE_BYTES);
HqcKeccakRandomGenerator shakeDigest = new HqcKeccakRandomGenerator(256);
- shakeDigest.SHAKE256_512_ds(theta, m, m.Length, new byte[] { G_FCT_DOMAIN });
+ shakeDigest.SHAKE256_512_ds(theta, tmp, tmp.Length, new[] { G_FCT_DOMAIN });
// 3. Generate ciphertext c = (u,v)
// Extract public keys
- ulong[] h = new ulong[N_BYTE_64];
+ long[] h = new long[N_BYTE_64];
byte[] s = new byte[N_BYTE];
ExtractPublicKeys(h, s, pk);
- ulong[] vTmp = new ulong[N1N2_BYTE_64];
+ long[] vTmp = new long[N1N2_BYTE_64];
Encrypt(u, vTmp, h, s, m, theta);
- Utils.FromULongArrayToByteArray(v, vTmp);
+ Utils.FromLongArrayToByteArray(v, vTmp);
// 4. Compute d
- shakeDigest.SHAKE256_512_ds(d, m, m.Length, new byte[] { H_FCT_DOMAIN });
+ shakeDigest.SHAKE256_512_ds(d, m, m.Length, new[] { H_FCT_DOMAIN });
// 5. Compute session key K
byte[] hashInputK = new byte[K_BYTE + N_BYTE + N1N2_BYTE];
hashInputK = Arrays.Concatenate(m, u);
hashInputK = Arrays.Concatenate(hashInputK, v);
- shakeDigest.SHAKE256_512_ds(K, hashInputK, hashInputK.Length, new byte[] { K_FCT_DOMAIN });
+ shakeDigest.SHAKE256_512_ds(K, hashInputK, hashInputK.Length, new[] { K_FCT_DOMAIN });
}
/**
@@ -180,46 +198,52 @@ namespace Org.BouncyCastle.Pqc.Crypto.Hqc
public void Decaps(byte[] ss, byte[] ct, byte[] sk)
{
//Extract Y and Public Keys from sk
- int[] yPos = new int[this.w];
+ long[] x = new long[N_BYTE_64];
+ long[] y = new long[N_BYTE_64];
byte[] pk = new byte[40 + N_BYTE];
- ExtractKeysFromSecretKeys(yPos, pk, sk);
+ ExtractKeysFromSecretKeys(x, y, pk, sk);
// Extract u, v, d from ciphertext
byte[] u = new byte[N_BYTE];
byte[] v = new byte[N1N2_BYTE];
byte[] d = new byte[SHA512_BYTES];
- HqcEngine.ExtractCiphertexts(u, v, d, ct);
+ byte[] salt = new byte[SALT_SIZE_BYTES];
+ ExtractCiphertexts(u, v, d, salt, ct);
// 1. Decrypt -> m'
byte[] mPrimeBytes = new byte[k];
- Decrypt(mPrimeBytes, mPrimeBytes, u, v, yPos);
+ Decrypt(mPrimeBytes, mPrimeBytes, u, v, y);
// 2. Compute theta'
byte[] theta = new byte[SHA512_BYTES];
+ byte[] tmp = new byte[K_BYTE + SALT_SIZE_BYTES + SEED_SIZE];
+ Array.Copy(mPrimeBytes, 0, tmp, 0, mPrimeBytes.Length);
+ Array.Copy(pk, 0, tmp, K_BYTE, SEED_SIZE);
+ Array.Copy(salt, 0, tmp, K_BYTE + SEED_SIZE, SALT_SIZE_BYTES);
HqcKeccakRandomGenerator shakeDigest = new HqcKeccakRandomGenerator(256);
- shakeDigest.SHAKE256_512_ds(theta, mPrimeBytes, mPrimeBytes.Length, new byte[] { G_FCT_DOMAIN });
+ shakeDigest.SHAKE256_512_ds(theta, tmp, tmp.Length, new[] { G_FCT_DOMAIN });
// 3. Compute c' = Enc(pk, m', theta')
// Extract public keys
- ulong[] h = new ulong[N_BYTE_64];
+ long[] h = new long[N_BYTE_64];
byte[] s = new byte[N_BYTE];
ExtractPublicKeys(h, s, pk);
byte[] u2Bytes = new byte[N_BYTE];
byte[] v2Bytes = new byte[N1N2_BYTE];
- ulong[] vTmp = new ulong[N1N2_BYTE_64];
+ long[] vTmp = new long[N1N2_BYTE_64];
Encrypt(u2Bytes, vTmp, h, s, mPrimeBytes, theta);
- Utils.FromULongArrayToByteArray(v2Bytes, vTmp);
+ Utils.FromLongArrayToByteArray(v2Bytes, vTmp);
// 4. Compute d' = H(m')
byte[] dPrime = new byte[SHA512_BYTES];
- shakeDigest.SHAKE256_512_ds(dPrime, mPrimeBytes, mPrimeBytes.Length, new byte[] { H_FCT_DOMAIN });
+ shakeDigest.SHAKE256_512_ds(dPrime, mPrimeBytes, mPrimeBytes.Length, new[] { H_FCT_DOMAIN });
// 5. Compute session key KPrime
byte[] hashInputK = new byte[K_BYTE + N_BYTE + N1N2_BYTE];
hashInputK = Arrays.Concatenate(mPrimeBytes, u);
hashInputK = Arrays.Concatenate(hashInputK, v);
- shakeDigest.SHAKE256_512_ds(ss, hashInputK, hashInputK.Length, new byte[] { K_FCT_DOMAIN });
+ shakeDigest.SHAKE256_512_ds(ss, hashInputK, hashInputK.Length, new[] { K_FCT_DOMAIN });
int result = 1;
// Compare u, v, d
@@ -263,63 +287,59 @@ namespace Org.BouncyCastle.Pqc.Crypto.Hqc
* @param u ciphertext
* @param v ciphertext
**/
- private void Encrypt(byte[] u, ulong[] v, ulong[] h, byte[] s, byte[] m, byte[] theta)
+ private void Encrypt(byte[] u, long[] v, long[] h, byte[] s, byte[] m, byte[] theta)
{
// Randomly generate e, r1, r2
HqcKeccakRandomGenerator randomGenerator = new HqcKeccakRandomGenerator(256);
randomGenerator.SeedExpanderInit(theta, SEED_SIZE);
- ulong[] e = new ulong[N_BYTE_64];
- ulong[] r1 = new ulong[N_BYTE_64];
- int[] r2 = new int[wr];
- GenerateSecretKey(r1, randomGenerator, wr);
- GenerateSecretKeyByCoordinates(r2, randomGenerator, wr);
- GenerateSecretKey(e, randomGenerator, we);
+ long[] e = new long[N_BYTE_64];
+ long[] r1 = new long[N_BYTE_64];
+ long[] r2 = new long[N_BYTE_64];
+ GenerateRandomFixedWeight(r1, randomGenerator, wr);
+ GenerateRandomFixedWeight(r2, randomGenerator, wr);
+ GenerateRandomFixedWeight(e, randomGenerator, we);
// Calculate u
- ulong[] uLong = new ulong[N_BYTE_64];
- GF2PolynomialCalculator.ModMult(uLong, r2, h, wr, n, N_BYTE_64, we, randomGenerator);
- GF2PolynomialCalculator.AddULongs(uLong, uLong, r1);
- Utils.FromULongArrayToByteArray(u, uLong);
+ long[] uLong = new long[N_BYTE_64];
+ gfCalculator.MultLongs(uLong, r2, h);
+ GF2PolynomialCalculator.AddLongs(uLong, uLong, r1);
+ Utils.FromLongArrayToByteArray(u, uLong);
// Calculate v
// encode m
byte[] res = new byte[n1];
- ulong[] vLong = new ulong[N1N2_BYTE_64];
- ulong[] tmpVLong = new ulong[N_BYTE_64];
+ long[] vLong = new long[N1N2_BYTE_64];
+ long[] tmpVLong = new long[N_BYTE_64];
ReedSolomon.Encode(res, m, K_BYTE * 8, n1, k, g, generatorPoly);
ReedMuller.Encode(vLong, res, n1, mulParam);
Array.Copy(vLong, 0, tmpVLong, 0, vLong.Length);
//Compute v
- ulong[] sLong = new ulong[N_BYTE_64];
- Utils.FromByteArrayToULongArray(sLong, s);
+ long[] sLong = new long[N_BYTE_64];
+ Utils.FromByteArrayToLongArray(sLong, s);
- ulong[] tmpLong = new ulong[N_BYTE_64];
- GF2PolynomialCalculator.ModMult(tmpLong, r2, sLong, wr, n, N_BYTE_64, we, randomGenerator);
- GF2PolynomialCalculator.AddULongs(tmpLong, tmpLong, tmpVLong);
- GF2PolynomialCalculator.AddULongs(tmpLong, tmpLong, e);
+ long[] tmpLong = new long[N_BYTE_64];
+ gfCalculator.MultLongs(tmpLong, r2, sLong);
+ GF2PolynomialCalculator.AddLongs(tmpLong, tmpLong, tmpVLong);
+ GF2PolynomialCalculator.AddLongs(tmpLong, tmpLong, e);
Utils.ResizeArray(v, n1n2, tmpLong, n, N1N2_BYTE_64, N1N2_BYTE_64);
}
- private void Decrypt(byte[] output, byte[] m, byte[] u, byte[] v, int[] y)
+ private void Decrypt(byte[] output, byte[] m, byte[] u, byte[] v, long[] y)
{
- byte[] tmpSeed = new byte[SEED_SIZE];
- HqcKeccakRandomGenerator randomGenerator = new HqcKeccakRandomGenerator(256);
- randomGenerator.SeedExpanderInit(tmpSeed, SEED_SIZE);
-
- ulong[] uLongs = new ulong[N_BYTE_64];
- Utils.FromByteArrayToULongArray(uLongs, u);
+ long[] uLongs = new long[N_BYTE_64];
+ Utils.FromByteArrayToLongArray(uLongs, u);
- ulong[] vLongs = new ulong[N1N2_BYTE_64];
- Utils.FromByteArrayToULongArray(vLongs, v);
+ long[] vLongs = new long[N1N2_BYTE_64];
+ Utils.FromByteArrayToLongArray(vLongs, v);
- ulong[] tmpV = new ulong[N_BYTE_64];
+ long[] tmpV = new long[N_BYTE_64];
Array.Copy(vLongs, 0, tmpV, 0, vLongs.Length);
- ulong[] tmpLong = new ulong[N_BYTE_64];
- GF2PolynomialCalculator.ModMult(tmpLong, y, uLongs, w, n, N_BYTE_64, we, randomGenerator);
- GF2PolynomialCalculator.AddULongs(tmpLong, tmpLong, tmpV);
+ long[] tmpLong = new long[N_BYTE_64];
+ gfCalculator.MultLongs(tmpLong, y, uLongs);
+ GF2PolynomialCalculator.AddLongs(tmpLong, tmpLong, tmpV);
// Decode res
byte[] tmp = new byte[n1];
@@ -329,70 +349,69 @@ namespace Org.BouncyCastle.Pqc.Crypto.Hqc
Array.Copy(m, 0, output, 0, output.Length);
}
- private void GenerateSecretKey(ulong[] output, HqcKeccakRandomGenerator random, int w)
+ private void GenerateRandomFixedWeight(long[] output, HqcKeccakRandomGenerator random, int weight)
{
- int[] tmp = new int[w];
- GenerateSecretKeyByCoordinates(tmp, random, w);
+ uint[] rand_u32 = new uint[wr];
+ byte[] rand_bytes = new byte[wr * 4];
+ int[] support = new int[wr];
+ int[] index_tab = new int[wr];
+ long[] bit_tab = new long[wr];
+
+ random.ExpandSeed(rand_bytes, 4 * weight);
+ Pack.LE_To_UInt32(rand_bytes, 0, rand_u32, 0, rand_u32.Length);
- for (int i = 0; i < w; ++i)
+ for (int i = 0; i < weight; i++)
{
- int index = tmp[i] / 64;
- int pos = tmp[i] % 64;
- ulong t = 1UL << pos;
- output[index] |= t;
+ support[i] = (int) (i + ((rand_u32[i]&0xFFFFFFFFL) % (n - i)));
}
- }
-
- private void GenerateSecretKeyByCoordinates(int[] output, HqcKeccakRandomGenerator random, int w)
- {
- int randomByteSize = 3 * w;
- byte[] randomBytes = new byte[3 * this.wr];
- int inc;
- int i = 0;
- int j = randomByteSize;
- while (i < w)
+ for (int i = (weight - 1); i >= 0; i--)
{
- do
+ int found = 0;
+ for (int j = i + 1; j < weight; j++)
{
- if (j == randomByteSize)
+ if (support[j] == support[i])
{
- random.ExpandSeed(randomBytes, randomByteSize);
-
- j = 0;
+ found |= 1;
}
-
- output[i] = (randomBytes[j++] & 0xff) << 16;
- output[i] |= (randomBytes[j++] & 0xff) << 8;
- output[i] |= (randomBytes[j++] & 0xff);
-
}
- while (output[i] >= this.rejectionThreshold);
- output[i] = output[i] % this.n;
- inc = 1;
- for (int k = 0; k < i; k++)
+ int mask = -found;
+ support[i] = (mask & i) ^ (~mask & support[i]);
+ }
+
+ for (int i = 0; i < weight; i++)
+ {
+ index_tab[i] = (int)((uint)support[i] >> 6);
+ int pos = support[i] & 0x3f;
+ bit_tab[i] = (1L) << pos;
+ }
+ long val = 0;
+ for (int i = 0; i < N_BYTE_64; i++)
+ {
+ val = 0;
+ for (int j = 0; j < weight; j++)
{
- if (output[k] == output[i])
- {
- inc = 0;
- }
+ int tmp = i - index_tab[j];
+ int val1 = 1 ^ ((int)((uint)(tmp | -tmp) >> 31));
+ long mask = -val1;
+ val |= (bit_tab[j] & mask);
}
- i += inc;
+ output[i] |= val;
}
}
-
- void GeneratePublicKeyH(ulong[] output, HqcKeccakRandomGenerator random)
+
+ void GeneratePublicKeyH(long[] output, HqcKeccakRandomGenerator random)
{
byte[] randBytes = new byte[N_BYTE];
random.ExpandSeed(randBytes, N_BYTE);
- ulong[] tmp = new ulong[N_BYTE_64];
- Utils.FromByteArrayToULongArray(tmp, randBytes);
+ long[] tmp = new long[N_BYTE_64];
+ Utils.FromByteArrayToLongArray(tmp, randBytes);
tmp[N_BYTE_64 - 1] &= Utils.BitMask((ulong)n, 64);
Array.Copy(tmp, 0, output, 0, output.Length);
}
- private void ExtractPublicKeys(ulong[] h, byte[] s, byte[] pk)
+ private void ExtractPublicKeys(long[] h, byte[] s, byte[] pk)
{
byte[] publicKeySeed = new byte[SEED_SIZE];
Array.Copy(pk, 0, publicKeySeed, 0, publicKeySeed.Length);
@@ -400,14 +419,14 @@ namespace Org.BouncyCastle.Pqc.Crypto.Hqc
HqcKeccakRandomGenerator randomPublic = new HqcKeccakRandomGenerator(256);
randomPublic.SeedExpanderInit(publicKeySeed, publicKeySeed.Length);
- ulong[] hLongBytes = new ulong[N_BYTE_64];
+ long[] hLongBytes = new long[N_BYTE_64];
GeneratePublicKeyH(hLongBytes, randomPublic);
Array.Copy(hLongBytes, 0, h, 0, h.Length);
Array.Copy(pk, 40, s, 0, s.Length);
}
- private void ExtractKeysFromSecretKeys(int[] y, byte[] pk, byte[] sk)
+ private void ExtractKeysFromSecretKeys(long[] x, long[] y, byte[] pk, byte[] sk)
{
byte[] secretKeySeed = new byte[SEED_SIZE];
Array.Copy(sk, 0, secretKeySeed, 0, secretKeySeed.Length);
@@ -415,22 +434,19 @@ namespace Org.BouncyCastle.Pqc.Crypto.Hqc
// Randomly generate secret keys x, y
HqcKeccakRandomGenerator secretKeySeedExpander = new HqcKeccakRandomGenerator(256);
secretKeySeedExpander.SeedExpanderInit(secretKeySeed, secretKeySeed.Length);
+
+ GenerateRandomFixedWeight(x, secretKeySeedExpander, w);
+ GenerateRandomFixedWeight(y, secretKeySeedExpander, w);
- ulong[] xLongBytes = new ulong[N_BYTE_64];
- int[] yPos = new int[this.w];
-
- GenerateSecretKey(xLongBytes, secretKeySeedExpander, w);
- GenerateSecretKeyByCoordinates(yPos, secretKeySeedExpander, w);
-
- Array.Copy(yPos, 0, y, 0, yPos.Length);
Array.Copy(sk, SEED_SIZE, pk, 0, pk.Length);
}
- private static void ExtractCiphertexts(byte[] u, byte[] v, byte[] d, byte[] ct)
+ private static void ExtractCiphertexts(byte[] u, byte[] v, byte[] d, byte[] salt, byte[] ct)
{
Array.Copy(ct, 0, u, 0, u.Length);
Array.Copy(ct, u.Length, v, 0, v.Length);
Array.Copy(ct, u.Length + v.Length, d, 0, d.Length);
+ Array.Copy(ct, u.Length + v.Length + d.Length, salt, 0, salt.Length);
}
}
}
diff --git a/crypto/src/pqc/crypto/hqc/HqcKeccakRandomGenerator.cs b/crypto/src/pqc/crypto/hqc/HqcKeccakRandomGenerator.cs
index 090f5a9c0..3ecbef633 100644
--- a/crypto/src/pqc/crypto/hqc/HqcKeccakRandomGenerator.cs
+++ b/crypto/src/pqc/crypto/hqc/HqcKeccakRandomGenerator.cs
@@ -1,5 +1,4 @@
using System;
-
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Pqc.Crypto.Hqc
@@ -60,10 +59,10 @@ namespace Org.BouncyCastle.Pqc.Crypto.Hqc
{
state[i] = 0L;
}
- Arrays.Fill(this.dataQueue, 0);
- this.bitsInQueue = 0;
- this.squeezing = false;
- this.fixedOutputLength = (1600 - rate) / 2;
+ Arrays.Fill(dataQueue, 0);
+ bitsInQueue = 0;
+ squeezing = false;
+ fixedOutputLength = (1600 - rate) / 2;
}
private void KeccakPermutation()
@@ -273,7 +272,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Hqc
public void RandomGeneratorInit(byte[] entropyInput, byte[] personalizationString, int entropyLen, int perLen)
{
- byte[] domain = new byte[] { 1 };
+ byte[] domain = { 1 };
KeccakIncAbsorb(entropyInput, entropyLen);
KeccakIncAbsorb(personalizationString, perLen);
KeccakIncAbsorb(domain, domain.Length);
@@ -282,7 +281,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Hqc
public void SeedExpanderInit(byte[] seed, int seedLen)
{
- byte[] domain = new byte[] { 2 };
+ byte[] domain = { 2 };
KeccakIncAbsorb(seed, seedLen);
KeccakIncAbsorb(domain, 1);
KeccakIncFinalize(0x1F);
diff --git a/crypto/src/pqc/crypto/hqc/HqcKemExtractor.cs b/crypto/src/pqc/crypto/hqc/HqcKemExtractor.cs
index 32890f80b..b18c532fa 100644
--- a/crypto/src/pqc/crypto/hqc/HqcKemExtractor.cs
+++ b/crypto/src/pqc/crypto/hqc/HqcKemExtractor.cs
@@ -10,7 +10,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Hqc
public HqcKemExtractor(HqcPrivateKeyParameters privParams)
{
- this.key = privParams;
+ key = privParams;
InitCipher(key.Parameters);
}
diff --git a/crypto/src/pqc/crypto/hqc/HqcKemGenerator.cs b/crypto/src/pqc/crypto/hqc/HqcKemGenerator.cs
index 918dadd38..53f59be16 100644
--- a/crypto/src/pqc/crypto/hqc/HqcKemGenerator.cs
+++ b/crypto/src/pqc/crypto/hqc/HqcKemGenerator.cs
@@ -1,5 +1,4 @@
using System;
-
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
@@ -11,7 +10,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Hqc
private SecureRandom sr;
public HqcKemGenerator(SecureRandom random)
{
- this.sr = random;
+ sr = random;
}
public ISecretWithEncapsulation GenerateEncapsulated(AsymmetricKeyParameter recipientKey)
@@ -23,22 +22,22 @@ namespace Org.BouncyCastle.Pqc.Crypto.Hqc
byte[] u = new byte[key.Parameters.NBytes];
byte[] v = new byte[key.Parameters.N1n2Bytes];
byte[] d = new byte[key.Parameters.Sha512Bytes];
+ byte[] salt = new byte[key.Parameters.SaltSizeBytes];
byte[] pk = key.PublicKey;
byte[] seed = new byte[48];
sr.NextBytes(seed);
- engine.Encaps(u, v, K, d, pk, seed);
+ engine.Encaps(u, v, K, d, pk, seed, salt);
- byte[] cipherText = Arrays.Concatenate(u, v);
- cipherText = Arrays.Concatenate(cipherText, d);
+ byte[] cipherText = Arrays.ConcatenateAll(u, v, d, salt);
- return new HqcKemGenerator.SecretWithEncapsulationImpl(K, cipherText);
+ return new SecretWithEncapsulationImpl(K, cipherText);
}
private class SecretWithEncapsulationImpl : ISecretWithEncapsulation
{
- private volatile bool hasBeenDestroyed = false;
+ private volatile bool hasBeenDestroyed;
private byte[] sessionKey;
private byte[] cipher_text;
diff --git a/crypto/src/pqc/crypto/hqc/HqcKeyPairGenerator.cs b/crypto/src/pqc/crypto/hqc/HqcKeyPairGenerator.cs
index 243b0d850..50882f432 100644
--- a/crypto/src/pqc/crypto/hqc/HqcKeyPairGenerator.cs
+++ b/crypto/src/pqc/crypto/hqc/HqcKeyPairGenerator.cs
@@ -36,17 +36,17 @@ namespace Org.BouncyCastle.Pqc.Crypto.Hqc
public void Init(KeyGenerationParameters parameters)
{
- this.hqcKeyGenerationParameters = (HqcKeyGenerationParameters)parameters;
- this.random = parameters.Random;
+ hqcKeyGenerationParameters = (HqcKeyGenerationParameters)parameters;
+ random = parameters.Random;
// get parameters
- this.n = this.hqcKeyGenerationParameters.Parameters.N;
- this.k = this.hqcKeyGenerationParameters.Parameters.K;
- this.delta = this.hqcKeyGenerationParameters.Parameters.Delta;
- this.w = this.hqcKeyGenerationParameters.Parameters.W;
- this.wr = this.hqcKeyGenerationParameters.Parameters.Wr;
- this.we = this.hqcKeyGenerationParameters.Parameters.We;
- this.N_BYTE = (n + 7) / 8;
+ n = hqcKeyGenerationParameters.Parameters.N;
+ k = hqcKeyGenerationParameters.Parameters.K;
+ delta = hqcKeyGenerationParameters.Parameters.Delta;
+ w = hqcKeyGenerationParameters.Parameters.W;
+ wr = hqcKeyGenerationParameters.Parameters.Wr;
+ we = hqcKeyGenerationParameters.Parameters.We;
+ N_BYTE = (n + 7) / 8;
}
private AsymmetricCipherKeyPair GenKeyPair(byte[] seed)
{
diff --git a/crypto/src/pqc/crypto/hqc/HqcParameters.cs b/crypto/src/pqc/crypto/hqc/HqcParameters.cs
index c397f65b1..d01c6fe9f 100644
--- a/crypto/src/pqc/crypto/hqc/HqcParameters.cs
+++ b/crypto/src/pqc/crypto/hqc/HqcParameters.cs
@@ -6,13 +6,13 @@ namespace Org.BouncyCastle.Pqc.Crypto.Hqc
: ICipherParameters
{
// 128 bits security
- public static HqcParameters hqc128 = new HqcParameters("hqc128", 17669, 46, 384, 16, 31, 15, 66, 75, 75, 16767881, 4, new int[] { 89, 69, 153, 116, 176, 117, 111, 75, 73, 233, 242, 233, 65, 210, 21, 139, 103, 173, 67, 118, 105, 210, 174, 110, 74, 69, 228, 82, 255, 181, 1 }, 128);
+ public static HqcParameters hqc128 = new HqcParameters("hqc128", 17669, 46, 384, 16, 31, 15, 66, 75, 75, 16767881, 4, new[] { 89, 69, 153, 116, 176, 117, 111, 75, 73, 233, 242, 233, 65, 210, 21, 139, 103, 173, 67, 118, 105, 210, 174, 110, 74, 69, 228, 82, 255, 181, 1 }, 128);
// 192 bits security
- public static HqcParameters hqc192 = new HqcParameters("hqc192", 35851, 56, 640, 24, 33, 16, 100, 114, 114, 16742417, 5, new int[] { 45, 216, 239, 24, 253, 104, 27, 40, 107, 50, 163, 210, 227, 134, 224, 158, 119, 13, 158, 1, 238, 164, 82, 43, 15, 232, 246, 142, 50, 189, 29, 232, 1 }, 192);
+ public static HqcParameters hqc192 = new HqcParameters("hqc192", 35851, 56, 640, 24, 33, 16, 100, 114, 114, 16742417, 5, new[] { 45, 216, 239, 24, 253, 104, 27, 40, 107, 50, 163, 210, 227, 134, 224, 158, 119, 13, 158, 1, 238, 164, 82, 43, 15, 232, 246, 142, 50, 189, 29, 232, 1 }, 192);
// 256 bits security
- public static HqcParameters hqc256 = new HqcParameters("hqc256", 57637, 90, 640, 32, 59, 29, 131, 149, 149, 16772367, 5, new int[] { 49, 167, 49, 39, 200, 121, 124, 91, 240, 63, 148, 71, 150, 123, 87, 101, 32, 215, 159, 71, 201, 115, 97, 210, 186, 183, 141, 217, 123, 12, 31, 243, 180, 219, 152, 239, 99, 141, 4, 246, 191, 144, 8, 232, 47, 27, 141, 178, 130, 64, 124, 47, 39, 188, 216, 48, 199, 187, 1 }, 256);
+ public static HqcParameters hqc256 = new HqcParameters("hqc256", 57637, 90, 640, 32, 59, 29, 131, 149, 149, 16772367, 5, new[] { 49, 167, 49, 39, 200, 121, 124, 91, 240, 63, 148, 71, 150, 123, 87, 101, 32, 215, 159, 71, 201, 115, 97, 210, 186, 183, 141, 217, 123, 12, 31, 243, 180, 219, 152, 239, 99, 141, 4, 246, 191, 144, 8, 232, 47, 27, 141, 178, 130, 64, 124, 47, 39, 188, 216, 48, 199, 187, 1 }, 256);
private string name;
private int n;
@@ -66,6 +66,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Hqc
public int NBytes => (n + 7) / 8;
public int N1n2Bytes => (n1 * n2 + 7) / 8;
public int DefaultKeySize => defaultKeySize;
+ public int SaltSizeBytes => 16;
internal HqcEngine Engine => hqcEngine;
}
}
diff --git a/crypto/src/pqc/crypto/hqc/ReedMuller.cs b/crypto/src/pqc/crypto/hqc/ReedMuller.cs
index 5f1f8e2bf..a39f403e6 100644
--- a/crypto/src/pqc/crypto/hqc/ReedMuller.cs
+++ b/crypto/src/pqc/crypto/hqc/ReedMuller.cs
@@ -1,5 +1,4 @@
using System;
-
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Pqc.Crypto.Hqc
@@ -13,8 +12,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Hqc
public Codeword()
{
- this.type32 = new int[4];
- this.type8 = new int[16];
+ type32 = new int[4];
+ type8 = new int[16];
}
}
@@ -117,7 +116,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Hqc
return (int) ((-(b & 1)) & 0xffffffff);
}
- public static void Encode(ulong[] codeword, byte[] m, int n1, int mulParam)
+ public static void Encode(long[] codeword, byte[] m, int n1, int mulParam)
{
byte[] mBytes = Arrays.Clone(m);
@@ -147,16 +146,16 @@ namespace Org.BouncyCastle.Pqc.Crypto.Hqc
off += 4;
}
- Utils.FromByte32ArrayToULongArray(codeword, cwd64);
+ Utils.FromByte32ArrayToLongArray(codeword, cwd64);
}
- public static void Decode(byte[] m, ulong[] codeword, int n1, int mulParam)
+ public static void Decode(byte[] m, long[] codeword, int n1, int mulParam)
{
byte[] mBytes = Arrays.Clone(m);
Codeword[] codewordCopy = new Codeword[codeword.Length / 2]; // because each codewordCopy has a 32 bit array size 4
int[] byteCodeWords = new int[codeword.Length * 2];
- Utils.FromULongArrayToByte32Array(byteCodeWords, codeword);
+ Utils.FromLongArrayToByte32Array(byteCodeWords, codeword);
for (int i = 0; i < codewordCopy.Length; i++)
{
@@ -189,7 +188,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Hqc
Array.Copy(codewordCopy[i].type32, 0, cwd64, off, codewordCopy[i].type32.Length);
off += 4;
}
- Utils.FromByte32ArrayToULongArray(codeword, cwd64);
+ Utils.FromByte32ArrayToLongArray(codeword, cwd64);
Array.Copy(mBytes, 0, m, 0, m.Length);
}
}
diff --git a/crypto/src/pqc/crypto/hqc/ReedSolomon.cs b/crypto/src/pqc/crypto/hqc/ReedSolomon.cs
index 25a8c7997..4024b0a38 100644
--- a/crypto/src/pqc/crypto/hqc/ReedSolomon.cs
+++ b/crypto/src/pqc/crypto/hqc/ReedSolomon.cs
@@ -1,5 +1,4 @@
using System;
-
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Pqc.Crypto.Hqc
diff --git a/crypto/src/pqc/crypto/hqc/Utils.cs b/crypto/src/pqc/crypto/hqc/Utils.cs
index 4d44db07c..993def057 100644
--- a/crypto/src/pqc/crypto/hqc/Utils.cs
+++ b/crypto/src/pqc/crypto/hqc/Utils.cs
@@ -1,15 +1,14 @@
using System;
-
using Org.BouncyCastle.Crypto.Utilities;
namespace Org.BouncyCastle.Pqc.Crypto.Hqc
{
internal class Utils
{
- internal static void ResizeArray(ulong[] output, int sizeOutBits, ulong[] input, int sizeInBits,
+ internal static void ResizeArray(long[] output, int sizeOutBits, long[] input, int sizeInBits,
int n1n2ByteSize, int n1n2Byte64Size)
{
- ulong mask = 0x7FFFFFFFFFFFFFFFUL;
+ long mask = 0x7FFFFFFFFFFFFFFFL;
int val = 0;
if (sizeOutBits < sizeInBits)
{
@@ -31,12 +30,12 @@ namespace Org.BouncyCastle.Pqc.Crypto.Hqc
}
}
- internal static void FromULongArrayToByteArray(byte[] output, ulong[] input)
+ internal static void FromLongArrayToByteArray(byte[] output, long[] input)
{
int max = output.Length / 8;
for (int i = 0; i != max; i++)
{
- Pack.UInt64_To_LE(input[i], output, i * 8);
+ Pack.UInt64_To_LE((ulong)input[i], output, i * 8);
}
if (output.Length % 8 != 0)
@@ -50,13 +49,13 @@ namespace Org.BouncyCastle.Pqc.Crypto.Hqc
}
}
- internal static ulong BitMask(ulong a, ulong b)
+ internal static long BitMask(ulong a, ulong b)
{
uint tmp = (uint)(a % b);
- return ((1UL << (int)tmp) - 1);
+ return ((1L << (int)tmp) - 1);
}
- internal static void FromByteArrayToULongArray(ulong[] output, byte[] input)
+ internal static void FromByteArrayToLongArray(long[] output, byte[] input)
{
byte[] tmp = input;
if (input.Length % 8 != 0)
@@ -68,7 +67,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Hqc
int off = 0;
for (int i = 0; i < output.Length; i++)
{
- output[i] = Pack.LE_To_UInt64(tmp, off);
+ output[i] = (long)Pack.LE_To_UInt64(tmp, off);
off += 8;
}
}
@@ -85,17 +84,17 @@ namespace Org.BouncyCastle.Pqc.Crypto.Hqc
int off = 0;
for (int i = 0; i < output.Length; i++)
{
- output[i] = (int)Pack.LE_To_UInt16(tmp, off);
+ output[i] = Pack.LE_To_UInt16(tmp, off);
off += 2;
}
}
- internal static void FromByte32ArrayToULongArray(ulong[] output, int[] input)
+ internal static void FromByte32ArrayToLongArray(long[] output, int[] input)
{
for (int i = 0; i != input.Length; i += 2)
{
output[i / 2] = (uint)input[i];
- output[i / 2] |= (ulong)input[i + 1] << 32;
+ output[i / 2] |= (long)input[i + 1] << 32;
}
}
@@ -110,7 +109,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Hqc
}
}
- internal static void FromULongArrayToByte32Array(int[] output, ulong[] input)
+ internal static void FromLongArrayToByte32Array(int[] output, long[] input)
{
for (int i = 0; i != input.Length; i++)
{
|