diff options
-rw-r--r-- | crypto/src/pqc/crypto/bike/BikeEngine.cs | 120 | ||||
-rw-r--r-- | crypto/src/pqc/crypto/bike/BikeKemExtractor.cs | 23 | ||||
-rw-r--r-- | crypto/src/pqc/crypto/bike/BikeKemGenerator.cs | 29 | ||||
-rw-r--r-- | crypto/src/pqc/crypto/bike/BikeKeyGenerationParameters.cs | 17 | ||||
-rw-r--r-- | crypto/src/pqc/crypto/bike/BikeKeyPairGenerator.cs | 21 | ||||
-rw-r--r-- | crypto/src/pqc/crypto/bike/BikeKeyParameters.cs | 17 | ||||
-rw-r--r-- | crypto/src/pqc/crypto/bike/BikeParameters.cs | 47 | ||||
-rw-r--r-- | crypto/src/pqc/crypto/bike/BikePolynomial.cs | 168 | ||||
-rw-r--r-- | crypto/src/pqc/crypto/bike/BikePrivateKeyParameters.cs | 11 | ||||
-rw-r--r-- | crypto/src/pqc/crypto/bike/BikePublicKeyParameters.cs | 16 | ||||
-rw-r--r-- | crypto/src/pqc/crypto/bike/BikeRandomGenerator.cs | 64 | ||||
-rw-r--r-- | crypto/src/pqc/crypto/bike/BikeUtilities.cs (renamed from crypto/src/pqc/crypto/bike/Utils.cs) | 37 | ||||
-rw-r--r-- | crypto/test/src/pqc/crypto/test/BikeVectorTest.cs | 10 |
13 files changed, 206 insertions, 374 deletions
diff --git a/crypto/src/pqc/crypto/bike/BikeEngine.cs b/crypto/src/pqc/crypto/bike/BikeEngine.cs index ecd7d7efe..a872c68a7 100644 --- a/crypto/src/pqc/crypto/bike/BikeEngine.cs +++ b/crypto/src/pqc/crypto/bike/BikeEngine.cs @@ -7,7 +7,7 @@ using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Pqc.Crypto.Bike { - public class BikeEngine + internal sealed class BikeEngine { // degree of R private int r; @@ -34,7 +34,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike private int L_BYTE; private int R_BYTE; - public BikeEngine(int r, int w, int t, int l, int nbIter, int tau) + internal BikeEngine(int r, int w, int t, int l, int nbIter, int tau) { this.r = r; this.w = w; @@ -50,17 +50,13 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike this.reductionPoly = new BikePolynomial(r); } - public int GetSessionKeySize() - { - return L_BYTE; - } + internal int SessionKeySize => L_BYTE; private byte[] FunctionH(byte[] seed) { IXof digest = new ShakeDigest(256); digest.BlockUpdate(seed, 0, seed.Length); - byte[] wlist = BikeRandomGenerator.GenerateRandomByteArray(r * 2, 2 * R_BYTE, t, digest); - return wlist; + return BikeUtilities.GenerateRandomByteArray(r * 2, 2 * R_BYTE, t, digest); } private byte[] FunctionL(byte[] e0, byte[] e1) @@ -68,7 +64,6 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike byte[] hashRes = new byte[48]; byte[] res = new byte[L_BYTE]; - Sha3Digest digest = new Sha3Digest(384); digest.BlockUpdate(e0, 0, e0.Length); digest.BlockUpdate(e1, 0, e1.Length); @@ -103,9 +98,9 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike * @param h h * @param random Secure Random **/ - public void GenKeyPair(byte[] h0, byte[] h1, byte[] sigma, byte[] h, SecureRandom random) + internal void GenKeyPair(byte[] h0, byte[] h1, byte[] sigma, byte[] h, SecureRandom random) { - // Randomly generate seeds + // Randomly generate seeds byte[] seeds = new byte[64]; random.NextBytes(seeds); @@ -117,9 +112,9 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike IXof digest = new ShakeDigest(256); digest.BlockUpdate(seed1, 0, seed1.Length); - // 1. Randomly generate h0, h1 - byte[] h0Tmp = BikeRandomGenerator.GenerateRandomByteArray(r, R_BYTE, hw, digest); - byte[] h1Tmp = BikeRandomGenerator.GenerateRandomByteArray(r, R_BYTE, hw, digest); + // 1. Randomly generate h0, h1 + byte[] h0Tmp = BikeUtilities.GenerateRandomByteArray(r, R_BYTE, hw, digest); + byte[] h1Tmp = BikeUtilities.GenerateRandomByteArray(r, R_BYTE, hw, digest); Array.Copy(h0Tmp, 0, h0, 0, h0.Length); Array.Copy(h1Tmp, 0, h1, 0, h1.Length); @@ -127,12 +122,12 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike byte[] h1Bits = new byte[r]; byte[] h0Bits = new byte[r]; - Utils.FromByteArrayToBitArray(h0Bits, h0Tmp); - Utils.FromByteArrayToBitArray(h1Bits, h1Tmp); + BikeUtilities.FromByteArrayToBitArray(h0Bits, h0Tmp); + BikeUtilities.FromByteArrayToBitArray(h1Bits, h1Tmp); // remove last 0 bits (most significant bits with 0 mean non-sense) - byte[] h0Cut = Utils.RemoveLast0Bits(h0Bits); - byte[] h1Cut = Utils.RemoveLast0Bits(h1Bits); + byte[] h0Cut = BikeUtilities.RemoveLast0Bits(h0Bits); + byte[] h1Cut = BikeUtilities.RemoveLast0Bits(h1Bits); // 2. Compute h BikePolynomial h0Poly = new BikePolynomial(h0Cut); @@ -144,7 +139,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike // Get coefficients of hPoly byte[] hTmp = hPoly.GetEncoded(); byte[] hByte = new byte[R_BYTE]; - Utils.FromBitArrayToByteArray(hByte, hTmp); + BikeUtilities.FromBitArrayToByteArray(hByte, hTmp); Array.Copy(hByte, 0, h, 0, h.Length); //3. Parse seed2 as sigma @@ -161,7 +156,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike * @param h public key * @param random Secure Random **/ - public void Encaps(byte[] c0, byte[] c1, byte[] k, byte[] h, SecureRandom random) + internal void Encaps(byte[] c0, byte[] c1, byte[] k, byte[] h, SecureRandom random) { byte[] seeds = new byte[64]; random.NextBytes(seeds); @@ -174,14 +169,14 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike byte[] eBytes = FunctionH(m); byte[] eBits = new byte[2 * r]; - Utils.FromByteArrayToBitArray(eBits, eBytes); + BikeUtilities.FromByteArrayToBitArray(eBits, eBytes); byte[] e0Bits = Arrays.CopyOfRange(eBits, 0, r); byte[] e1Bits = Arrays.CopyOfRange(eBits, r, eBits.Length); // remove last 0 bits (most significant bits with 0 mean no sense) - byte[] e0Cut = Utils.RemoveLast0Bits(e0Bits); - byte[] e1Cut = Utils.RemoveLast0Bits(e1Bits); + byte[] e0Cut = BikeUtilities.RemoveLast0Bits(e0Bits); + byte[] e1Cut = BikeUtilities.RemoveLast0Bits(e1Bits); BikePolynomial e0 = new BikePolynomial(e0Cut); BikePolynomial e1 = new BikePolynomial(e1Cut); @@ -189,23 +184,23 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike // 3. Calculate c // calculate c0 byte[] h0Bits = new byte[r]; - Utils.FromByteArrayToBitArray(h0Bits, h); - BikePolynomial hPoly = new BikePolynomial(Utils.RemoveLast0Bits(h0Bits)); + BikeUtilities.FromByteArrayToBitArray(h0Bits, h); + BikePolynomial hPoly = new BikePolynomial(BikeUtilities.RemoveLast0Bits(h0Bits)); BikePolynomial c0Poly = e0.Add(e1.ModKaratsubaMultiplyBigDeg(hPoly, reductionPoly)); byte[] c0Bits = c0Poly.GetEncoded(); byte[] c0Bytes = new byte[R_BYTE]; - Utils.FromBitArrayToByteArray(c0Bytes, c0Bits); + BikeUtilities.FromBitArrayToByteArray(c0Bytes, c0Bits); Array.Copy(c0Bytes, 0, c0, 0, c0.Length); //calculate c1 byte[] e0Bytes = new byte[R_BYTE]; - Utils.FromBitArrayToByteArray(e0Bytes, e0Bits); + BikeUtilities.FromBitArrayToByteArray(e0Bytes, e0Bits); byte[] e1Bytes = new byte[R_BYTE]; - Utils.FromBitArrayToByteArray(e1Bytes, e1Bits); + BikeUtilities.FromBitArrayToByteArray(e1Bytes, e1Bits); byte[] tmp = FunctionL(e0Bytes, e1Bytes); - byte[] c1Tmp = Utils.XorBytes(m, tmp, L_BYTE); + byte[] c1Tmp = BikeUtilities.XorBytes(m, tmp, L_BYTE); Array.Copy(c1Tmp, 0, c1, 0, c1.Length); // 4. Calculate K @@ -224,19 +219,19 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike * @param c1 ciphertext * @param k session key **/ - public void Decaps(byte[] k, byte[] h0, byte[] h1, byte[] sigma, byte[] c0, byte[] c1) + internal void Decaps(byte[] k, byte[] h0, byte[] h1, byte[] sigma, byte[] c0, byte[] c1) { //convert to bits byte[] c0Bits = new byte[this.r]; byte[] h0Bits = new byte[this.r]; byte[] sigmaBits = new byte[this.l]; - Utils.FromByteArrayToBitArray(c0Bits, c0); - Utils.FromByteArrayToBitArray(h0Bits, h0); - Utils.FromByteArrayToBitArray(sigmaBits, sigma); + BikeUtilities.FromByteArrayToBitArray(c0Bits, c0); + BikeUtilities.FromByteArrayToBitArray(h0Bits, h0); + BikeUtilities.FromByteArrayToBitArray(sigmaBits, sigma); - byte[] c0Cut = Utils.RemoveLast0Bits(c0Bits); - byte[] h0Cut = Utils.RemoveLast0Bits(h0Bits); + byte[] c0Cut = BikeUtilities.RemoveLast0Bits(c0Bits); + byte[] h0Cut = BikeUtilities.RemoveLast0Bits(h0Bits); // Get compact version of h0, h1 int[] h0Compact = new int[hw]; @@ -250,18 +245,18 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike // 1. Compute e' byte[] ePrimeBits = BGFDecoder(syndrome, h0Compact, h1Compact); byte[] ePrimeBytes = new byte[2 * R_BYTE]; - Utils.FromBitArrayToByteArray(ePrimeBytes, ePrimeBits); + BikeUtilities.FromBitArrayToByteArray(ePrimeBytes, ePrimeBits); byte[] e0Bits = Arrays.CopyOfRange(ePrimeBits, 0, r); byte[] e1Bits = Arrays.CopyOfRange(ePrimeBits, r, ePrimeBits.Length); byte[] e0Bytes = new byte[R_BYTE]; - Utils.FromBitArrayToByteArray(e0Bytes, e0Bits); + BikeUtilities.FromBitArrayToByteArray(e0Bytes, e0Bits); byte[] e1Bytes = new byte[R_BYTE]; - Utils.FromBitArrayToByteArray(e1Bytes, e1Bits); + BikeUtilities.FromBitArrayToByteArray(e1Bytes, e1Bits); // 2. Compute m' - byte[] mPrime = Utils.XorBytes(c1, FunctionL(e0Bytes, e1Bytes), L_BYTE); + byte[] mPrime = BikeUtilities.XorBytes(c1, FunctionL(e0Bytes, e1Bytes), L_BYTE); // 3. Compute K byte[] tmpK = new byte[l]; @@ -300,7 +295,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike byte[] black = new byte[2 * r]; byte[] gray = new byte[2 * r]; - int T = Threshold(Utils.GetHammingWeight(s), i, r); + int T = Threshold(BikeUtilities.GetHammingWeight(s), r); BFIter(s, e, T, h0Compact, h1Compact, h0CompactCol, h1CompactCol, black, gray); @@ -311,7 +306,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike } } - if (Utils.GetHammingWeight(s) == 0) + if (BikeUtilities.GetHammingWeight(s) == 0) return e; return null; @@ -319,7 +314,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike private byte[] Transpose(byte[] input) { - byte[] tmp = Utils.Append0s(input, r); // append zeros to s + byte[] tmp = BikeUtilities.Append0s(input, r); // append zeros to s byte[] output = new byte[r]; output[0] = tmp[0]; for (int i = 1; i < r; i++) @@ -329,7 +324,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike return output; } - private void BFIter(byte[] s, byte[] e, int T, int[] h0Compact, int[] h1Compact, int[] h0CompactCol, int[] h1CompactCol, byte[] black, byte[] gray) + private void BFIter(byte[] s, byte[] e, int T, int[] h0Compact, int[] h1Compact, int[] h0CompactCol, + int[] h1CompactCol, byte[] black, byte[] gray) { int[] updatedIndices = new int[2 * r]; @@ -405,28 +401,28 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike } } - private int Threshold(int hammingWeight, int i, int r) + private int Threshold(int hammingWeight, int r) { - double d = 0; - int floorD = 0; + double d; + int floorD; int res = 0; switch (r) { - case 12323: - d = 0.0069722 * hammingWeight + 13.530; - floorD = (int) System.Math.Floor(d); - res = floorD > 36 ? floorD : 36; - break; - case 24659: - d = 0.005265 * hammingWeight + 15.2588; - floorD = (int) System.Math.Floor(d); - res = floorD > 52 ? floorD : 52; - break; - case 40973: - d = 0.00402312 * hammingWeight + 17.8785; - floorD = (int) System.Math.Floor(d); - res = floorD > 69 ? floorD : 69; - break; + case 12323: + d = 0.0069722 * hammingWeight + 13.530; + floorD = (int) System.Math.Floor(d); + res = floorD > 36 ? floorD : 36; + break; + case 24659: + d = 0.005265 * hammingWeight + 15.2588; + floorD = (int) System.Math.Floor(d); + res = floorD > 52 ? floorD : 52; + break; + case 40973: + d = 0.00402312 * hammingWeight + 17.8785; + floorD = (int) System.Math.Floor(d); + res = floorD > 69 ? floorD : 69; + break; } return res; } @@ -454,9 +450,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike for (int j = 0; j < 8; j++) { if ((i * 8 + j) == this.r) - { break; - } if (((h[i] >> j) & 1) == 1) { diff --git a/crypto/src/pqc/crypto/bike/BikeKemExtractor.cs b/crypto/src/pqc/crypto/bike/BikeKemExtractor.cs index bcc0c124c..b6358e3d2 100644 --- a/crypto/src/pqc/crypto/bike/BikeKemExtractor.cs +++ b/crypto/src/pqc/crypto/bike/BikeKemExtractor.cs @@ -1,4 +1,5 @@ using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Pqc.Crypto.Sike; using Org.BouncyCastle.Utilities; using System; using System.Collections.Generic; @@ -6,28 +7,23 @@ using System.Text; namespace Org.BouncyCastle.Pqc.Crypto.Bike { - public class BikeKemExtractor : IEncapsulatedSecretExtractor + public sealed class BikeKemExtractor + : IEncapsulatedSecretExtractor { - private BikeEngine engine; - - private BikeKeyParameters key; - private int defaultKeySize; + private readonly BikeKeyParameters key; public BikeKemExtractor(BikePrivateKeyParameters privParams) { this.key = privParams; - initCipher(key.Parameters); - } - - private void initCipher(BikeParameters param) - { - engine = param.BIKEEngine; - defaultKeySize = param.DefaultKeySize; } public byte[] ExtractSecret(byte[] encapsulation) { - byte[] session_key = new byte[engine.GetSessionKeySize()]; + BikeParameters parameters = key.Parameters; + BikeEngine engine = parameters.BikeEngine; + int defaultKeySize = parameters.DefaultKeySize; + + byte[] session_key = new byte[engine.SessionKeySize]; BikePrivateKeyParameters secretKey = (BikePrivateKeyParameters)key; // Extract c0, c1 from encapsulation c @@ -43,6 +39,5 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike } public int EncapsulationLength => key.Parameters.RByte + key.Parameters.LByte; - } } diff --git a/crypto/src/pqc/crypto/bike/BikeKemGenerator.cs b/crypto/src/pqc/crypto/bike/BikeKemGenerator.cs index 461cdae97..da4221967 100644 --- a/crypto/src/pqc/crypto/bike/BikeKemGenerator.cs +++ b/crypto/src/pqc/crypto/bike/BikeKemGenerator.cs @@ -1,15 +1,16 @@ -using Org.BouncyCastle.Crypto; +using System; + +using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Security; using Org.BouncyCastle.Utilities; -using System; -using System.Collections.Generic; -using System.Text; namespace Org.BouncyCastle.Pqc.Crypto.Bike { - public class BikeKemGenerator : IEncapsulatedSecretGenerator + public sealed class BikeKemGenerator + : IEncapsulatedSecretGenerator { - private SecureRandom sr; + private readonly SecureRandom sr; + public BikeKemGenerator(SecureRandom random) { this.sr = random; @@ -18,21 +19,23 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike public ISecretWithEncapsulation GenerateEncapsulated(AsymmetricKeyParameter recipientKey) { BikePublicKeyParameters key = (BikePublicKeyParameters)recipientKey; - BikeEngine engine = key.Parameters.BIKEEngine; + BikeParameters parameters = key.Parameters; + BikeEngine engine = parameters.BikeEngine; - byte[] K = new byte[key.Parameters.LByte]; - byte[] c0 = new byte[key.Parameters.RByte]; - byte[] c1 = new byte[key.Parameters.LByte]; + byte[] K = new byte[parameters.LByte]; + byte[] c0 = new byte[parameters.RByte]; + byte[] c1 = new byte[parameters.LByte]; byte[] h = key.PublicKey; engine.Encaps(c0, c1, K, h, sr); byte[] cipherText = Arrays.Concatenate(c0, c1); - return new SecretWithEncapsulationImpl(Arrays.CopyOfRange(K, 0, key.Parameters.DefaultKeySize / 8), cipherText); + return new SecretWithEncapsulationImpl(Arrays.CopyOfRange(K, 0, parameters.DefaultKeySize / 8), cipherText); } - private class SecretWithEncapsulationImpl : ISecretWithEncapsulation + private class SecretWithEncapsulationImpl + : ISecretWithEncapsulation { private volatile bool hasBeenDestroyed = false; @@ -76,9 +79,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike void CheckDestroyed() { if (IsDestroyed()) - { throw new Exception("data has been destroyed"); - } } } } diff --git a/crypto/src/pqc/crypto/bike/BikeKeyGenerationParameters.cs b/crypto/src/pqc/crypto/bike/BikeKeyGenerationParameters.cs index 226d939fc..397c7bcdb 100644 --- a/crypto/src/pqc/crypto/bike/BikeKeyGenerationParameters.cs +++ b/crypto/src/pqc/crypto/bike/BikeKeyGenerationParameters.cs @@ -1,22 +1,19 @@ using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Security; -using System; -using System.Collections.Generic; -using System.Text; namespace Org.BouncyCastle.Pqc.Crypto.Bike { - public class BikeKeyGenerationParameters : KeyGenerationParameters + public sealed class BikeKeyGenerationParameters + : KeyGenerationParameters { - private BikeParameters param; + private readonly BikeParameters m_parameters; - public BikeKeyGenerationParameters( - SecureRandom random, - BikeParameters param) : base(random, 256) + public BikeKeyGenerationParameters(SecureRandom random, BikeParameters parameters) + : base(random, 256) { - this.param = param; + m_parameters = parameters; } - public BikeParameters Parameters => param; + public BikeParameters Parameters => m_parameters; } } diff --git a/crypto/src/pqc/crypto/bike/BikeKeyPairGenerator.cs b/crypto/src/pqc/crypto/bike/BikeKeyPairGenerator.cs index f1b786336..5636458fd 100644 --- a/crypto/src/pqc/crypto/bike/BikeKeyPairGenerator.cs +++ b/crypto/src/pqc/crypto/bike/BikeKeyPairGenerator.cs @@ -1,12 +1,10 @@ using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Security; -using System; -using System.Collections.Generic; -using System.Text; namespace Org.BouncyCastle.Pqc.Crypto.Bike { - public class BikeKeyPairGenerator : IAsymmetricCipherKeyPairGenerator + public sealed class BikeKeyPairGenerator + : IAsymmetricCipherKeyPairGenerator { private SecureRandom random; @@ -34,6 +32,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike private int R_BYTE; private BikeKeyGenerationParameters bikeKeyGenerationParameters; + public void Init(KeyGenerationParameters param) { this.bikeKeyGenerationParameters = (BikeKeyGenerationParameters)param; @@ -51,9 +50,10 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike this.R_BYTE = (r + 7) / 8; } - private AsymmetricCipherKeyPair GenKeyPair() + public AsymmetricCipherKeyPair GenerateKeyPair() { - BikeEngine engine = bikeKeyGenerationParameters.Parameters.BIKEEngine; + BikeParameters parameters = bikeKeyGenerationParameters.Parameters; + BikeEngine engine = parameters.BikeEngine; byte[] h0 = new byte[R_BYTE]; byte[] h1 = new byte[R_BYTE]; byte[] h = new byte[R_BYTE]; @@ -62,15 +62,10 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike engine.GenKeyPair(h0, h1, sigma, h, random); // form keys - BikePublicKeyParameters publicKey = new BikePublicKeyParameters(bikeKeyGenerationParameters.Parameters, h); - BikePrivateKeyParameters privateKey = new BikePrivateKeyParameters(bikeKeyGenerationParameters.Parameters, h0, h1, sigma); + BikePublicKeyParameters publicKey = new BikePublicKeyParameters(parameters, h); + BikePrivateKeyParameters privateKey = new BikePrivateKeyParameters(parameters, h0, h1, sigma); return new AsymmetricCipherKeyPair(publicKey, privateKey); } - - public AsymmetricCipherKeyPair GenerateKeyPair() - { - return GenKeyPair(); - } } } diff --git a/crypto/src/pqc/crypto/bike/BikeKeyParameters.cs b/crypto/src/pqc/crypto/bike/BikeKeyParameters.cs index 0ee8279a9..fd15138e4 100644 --- a/crypto/src/pqc/crypto/bike/BikeKeyParameters.cs +++ b/crypto/src/pqc/crypto/bike/BikeKeyParameters.cs @@ -1,21 +1,18 @@ using Org.BouncyCastle.Crypto; -using System; -using System.Collections.Generic; -using System.Text; namespace Org.BouncyCastle.Pqc.Crypto.Bike { - public class BikeKeyParameters : AsymmetricKeyParameter + public abstract class BikeKeyParameters + : AsymmetricKeyParameter { - private BikeParameters param; + private readonly BikeParameters m_parameters; - public BikeKeyParameters( - bool isPrivate, - BikeParameters param) : base(isPrivate) + public BikeKeyParameters(bool isPrivate, BikeParameters parameters) + : base(isPrivate) { - this.param = param; + this.m_parameters = parameters; } - public BikeParameters Parameters => param; + public BikeParameters Parameters => m_parameters; } } diff --git a/crypto/src/pqc/crypto/bike/BikeParameters.cs b/crypto/src/pqc/crypto/bike/BikeParameters.cs index e4d06b861..9fd658e0c 100644 --- a/crypto/src/pqc/crypto/bike/BikeParameters.cs +++ b/crypto/src/pqc/crypto/bike/BikeParameters.cs @@ -1,31 +1,29 @@ -using System; - -using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto; namespace Org.BouncyCastle.Pqc.Crypto.Bike { - public class BikeParameters + public sealed class BikeParameters : ICipherParameters { // 128 bits security public static BikeParameters bike128 = new BikeParameters("bike128", 12323, 142, 134, 256, 5, 3, 128); // 192 bits security - public static BikeParameters bike192 = new BikeParameters("bike192",24659, 206, 199, 256, 5, 3, 192); + public static BikeParameters bike192 = new BikeParameters("bike192", 24659, 206, 199, 256, 5, 3, 192); // 256 bits security - public static BikeParameters bike256 = new BikeParameters("bike256",40973, 274, 264, 256, 5, 3, 256); - - private String name; - private int r; - private int w; - private int t; - private int l; - private int nbIter; - private int tau; - private int defaultKeySize; + public static BikeParameters bike256 = new BikeParameters("bike256", 40973, 274, 264, 256, 5, 3, 256); + + private readonly string name; + private readonly int r; + private readonly int w; + private readonly int t; + private readonly int l; + private readonly int nbIter; + private readonly int tau; + private readonly int defaultKeySize; + private readonly BikeEngine bikeEngine; - private BikeEngine bikeEngine; internal BikeParameters(string name, int r, int w, int t, int l, int nbIter, int tau, int defaultKeySize) { this.name = name; @@ -39,19 +37,6 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike this.bikeEngine = new BikeEngine(r, w, t, l, nbIter, tau); } - internal BikeParameters(BikeParameters param) - { - this.name = param.name; - this.r = param.r; - this.w = param.w; - this.t = param.t; - this.l = param.l; - this.nbIter = param.nbIter; - this.tau = param.tau; - this.defaultKeySize = param.defaultKeySize; - this.bikeEngine = new BikeEngine(r, w, t, l, nbIter, tau); - } - public int R => r; public int RByte => (r + 7) / 8; public int LByte => l / 8; @@ -60,8 +45,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike public int L => l; public int NbIter => nbIter; public int Tau => tau; - public String Name => name; + public string Name => name; public int DefaultKeySize => defaultKeySize; - internal BikeEngine BIKEEngine => bikeEngine; + internal BikeEngine BikeEngine => bikeEngine; } } diff --git a/crypto/src/pqc/crypto/bike/BikePolynomial.cs b/crypto/src/pqc/crypto/bike/BikePolynomial.cs index 0d66fe433..eea34d838 100644 --- a/crypto/src/pqc/crypto/bike/BikePolynomial.cs +++ b/crypto/src/pqc/crypto/bike/BikePolynomial.cs @@ -23,7 +23,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike */ internal BikePolynomial(int degree) { - // Initial value (X^r + 1) + // Initial value (X^degree + 1) this.m_coefficients = new int[degree + 1]; this.m_coefficients[degree] = 1; this.m_coefficients[0] ^= 1; @@ -38,7 +38,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike */ private BikePolynomial(int[] coeffs) { - this.m_coefficients = NormalForm(coeffs); + this.m_coefficients = coeffs; } /** @@ -87,7 +87,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike internal BikePolynomial Add(BikePolynomial addend) { int[] resultCoeff = Add(m_coefficients, addend.m_coefficients); - return new BikePolynomial(resultCoeff); + return new BikePolynomial(NormalForm(resultCoeff)); } /** @@ -98,7 +98,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike * @param b the second polynomial * @return a + b */ - private int[] Add(int[] a, int[] b) + private static int[] Add(int[] a, int[] b) { int[] result, addend; if (a.Length < b.Length) @@ -122,35 +122,12 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike return result; } - /** - * Compute the product of a polynomial a with an element from the finite - * field <tt>GF(2^m)</tt>. - * - * @param a the polynomial - * @param element an element of the finite field GF(2^m) - * @return <tt>a * element</tt> - */ - private int[] MultWithElement(int[] a, int element) + private static void AddAt(int[] x, int[] z, int zPos) { - return element == 0 ? new int[1] : Arrays.Clone(a); - } - - /** - * Compute the product of a polynomial with a monomial X^k. - * - * @param a the polynomial - * @param k the degree of the monomial - * @return <tt>a * X^k</tt> - */ - private static int[] MultWithMonomial(int[] a, int k) - { - int d = ComputeDegree(a); - if (d == -1) - return new int[1]; - - int[] result = new int[k + d + 1]; - Array.Copy(a, 0, result, k, d + 1); - return result; + for (int i = 0; i < x.Length; ++i) + { + z[zPos + i] ^= x[i]; + } } /** @@ -161,7 +138,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike * @param f the second polynomial * @return int[][] {q,r}, where a = q*f+r and deg(r) < deg(f); */ - private int[][] Div(int[] a, int[] f) + private static int[][] Div(int[] a, int[] f) { int df = ComputeDegree(f); if (df == -1) @@ -169,93 +146,17 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike int degreeR1 = ComputeDegree(a); int[][] result = new int[2][]; - result[0] = new int[1]{ 0 }; + result[0] = new int[System.Math.Max(0, degreeR1 - df) + 1]; result[1] = Arrays.CopyOf(a, degreeR1 + 1); while (df <= degreeR1) { - int[] q; - int[] coeff = new int[1]; - coeff[0] = degreeR1 == -1 ? 0 : result[1][degreeR1]; - q = MultWithElement(f, coeff[0]); int n = degreeR1 - df; - q = MultWithMonomial(q, n); - coeff = MultWithMonomial(coeff, n); - result[0] = Add(coeff, result[0]); - result[1] = Add(q, result[1]); - degreeR1 = ComputeDegree(result[1]); + result[0][n] ^= 1; + AddAt(f, result[1], n); + degreeR1 = ComputeDegree(result[1], degreeR1 - 1); } - return result; - } - - /** - * Compute the product of two polynomials over the field <tt>GF(2^m)</tt> - * using a Karatzuba like multiplication. - * - * @param a the first polynomial - * @param b the second polynomial - * @return a * b - */ - private int[] Multiply(int[] a, int[] b) - { - int[] mult1, mult2; - if (ComputeDegree(a) < ComputeDegree(b)) - { - mult1 = b; - mult2 = a; - } - else - { - mult1 = a; - mult2 = b; - } - - mult1 = NormalForm(mult1); - mult2 = NormalForm(mult2); - - if (mult2.Length == 1) - return MultWithElement(mult1, mult2[0]); - - int d1 = mult1.Length; - int d2 = mult2.Length; - int[] result; - - if (d2 != d1) - { - int[] res1 = new int[d2]; - int[] res2 = new int[d1 - d2]; - Array.Copy(mult1, 0, res1, 0, res1.Length); - Array.Copy(mult1, d2, res2, 0, res2.Length); - res1 = Multiply(res1, mult2); - res2 = Multiply(res2, mult2); - res2 = MultWithMonomial(res2, d2); - result = Add(res1, res2); - } - else - { - d2 = (int)((uint)(d1 + 1) >> 1); - int d = d1 - d2; - int[] firstPartMult1 = new int[d2]; - int[] firstPartMult2 = new int[d2]; - int[] secondPartMult1 = new int[d]; - int[] secondPartMult2 = new int[d]; - Array.Copy(mult1, 0, firstPartMult1, 0, firstPartMult1.Length); - Array.Copy(mult1, d2, secondPartMult1, 0, secondPartMult1.Length); - Array.Copy(mult2, 0, firstPartMult2, 0, firstPartMult2.Length); - Array.Copy(mult2, d2, secondPartMult2, 0, secondPartMult2.Length); - int[] helpPoly1 = Add(firstPartMult1, secondPartMult1); - int[] helpPoly2 = Add(firstPartMult2, secondPartMult2); - int[] res1 = Multiply(firstPartMult1, firstPartMult2); - int[] res2 = Multiply(helpPoly1, helpPoly2); - int[] res3 = Multiply(secondPartMult1, secondPartMult2); - res2 = Add(res2, res1); - res2 = Add(res2, res3); - res3 = MultWithMonomial(res3, d2); - result = Add(res2, res3); - result = MultWithMonomial(result, d2); - result = Add(result, res1); - } - + result[1] = NormalForm(result[1]); return result; } @@ -266,7 +167,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike * @param f the reduction polynomial * @return <tt>a mod f</tt> */ - private int[] Mod(int[] a, int[] f) + private static int[] Mod(int[] a, int[] f) { int df = ComputeDegree(f); if (df == -1) @@ -277,13 +178,11 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike while (df <= degreeR) { - int coeff = degreeR == -1 ? 0 : result[degreeR]; - int[] q = MultWithMonomial(f, degreeR - df); - q = MultWithElement(q, coeff); - result = Add(q, result); - degreeR = ComputeDegree(result); + int n = degreeR - df; + AddAt(f, result, n); + degreeR = ComputeDegree(result, degreeR - 1); } - return result; + return NormalForm(result); } /** @@ -295,8 +194,13 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike */ private static int ComputeDegree(int[] a) { + return ComputeDegree(a, a.Length - 1); + } + + private static int ComputeDegree(int[] a, int from) + { int degree; - for (degree = a.Length - 1; degree >= 0 && a[degree] == 0; degree--) + for (degree = from; degree >= 0 && a[degree] == 0; degree--) { } return degree; @@ -358,7 +262,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike return new BikePolynomial(resultCoeff); } - private int[] ModInvBigDeg(int[] b, int[] g) + private static int[] ModInvBigDeg(int[] b, int[] g) { int[] r0 = NormalForm(g); int[] r1 = Mod(b, g); @@ -387,7 +291,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike * @param g the reduction polynomial * @return <tt>a * b mod g</tt> */ - private int[] ModKaratsubaMultiplyBigDeg(int[] aa, int[] bb, int[] g) + private static int[] ModKaratsubaMultiplyBigDeg(int[] aa, int[] bb, int[] g) { int[] a, b; if (aa.Length >= bb.Length) @@ -420,25 +324,17 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike for (int p = 0; p < pLimit; p++) { int q = i - p; - - int ap = a[p]; int aq = q < a.Length ? a[q] : 0; - int bp = b[p]; - int dp = D[p]; - if (q < m) { - int bq = b[q]; - int dq = D[q]; - - S[i] = S[i] + (ap + aq) * (bp + bq); - T[i] = T[i] + dp + dq; + S[i] += (a[p] + aq) * (b[p] + b[q]); + T[i] += D[p] + D[q]; } else if (q < n) { - S[i] = S[i] + ((ap + aq) * bp); - T[i] = T[i] + dp; + S[i] += (a[p] + aq) * b[p]; + T[i] += D[p]; } } } diff --git a/crypto/src/pqc/crypto/bike/BikePrivateKeyParameters.cs b/crypto/src/pqc/crypto/bike/BikePrivateKeyParameters.cs index d8c6e4613..dce003a7b 100644 --- a/crypto/src/pqc/crypto/bike/BikePrivateKeyParameters.cs +++ b/crypto/src/pqc/crypto/bike/BikePrivateKeyParameters.cs @@ -1,11 +1,9 @@ using Org.BouncyCastle.Utilities; -using System; -using System.Collections.Generic; -using System.Text; namespace Org.BouncyCastle.Pqc.Crypto.Bike { - public class BikePrivateKeyParameters : BikeKeyParameters + public class BikePrivateKeyParameters + : BikeKeyParameters { // h0 private byte[] h0; @@ -23,7 +21,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike * @param h1 h1 * @param sigma random bytes sigma */ - public BikePrivateKeyParameters(BikeParameters bikeParameters, byte[] h0, byte[] h1, byte[] sigma) : base(true, bikeParameters) + public BikePrivateKeyParameters(BikeParameters bikeParameters, byte[] h0, byte[] h1, byte[] sigma) + : base(true, bikeParameters) { this.h0 = Arrays.Clone(h0); this.h1 = Arrays.Clone(h1); @@ -45,7 +44,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike return sigma; } - public byte[] PrivateKey => Arrays.Concatenate(Arrays.Concatenate(h0, h1), sigma); + internal byte[] PrivateKey => Arrays.Concatenate(Arrays.Concatenate(h0, h1), sigma); public byte[] GetEncoded() { diff --git a/crypto/src/pqc/crypto/bike/BikePublicKeyParameters.cs b/crypto/src/pqc/crypto/bike/BikePublicKeyParameters.cs index 16370c3cf..dbbe2480c 100644 --- a/crypto/src/pqc/crypto/bike/BikePublicKeyParameters.cs +++ b/crypto/src/pqc/crypto/bike/BikePublicKeyParameters.cs @@ -1,28 +1,28 @@ using Org.BouncyCastle.Utilities; -using System; -using System.Collections.Generic; -using System.Text; namespace Org.BouncyCastle.Pqc.Crypto.Bike { - public class BikePublicKeyParameters : BikeKeyParameters + public class BikePublicKeyParameters + : BikeKeyParameters { - byte[] publicKey; + private readonly byte[] publicKey; /** * Constructor. * * @param publicKey byte */ - public BikePublicKeyParameters(BikeParameters param, byte[] publicKey) : base(false, param) + public BikePublicKeyParameters(BikeParameters param, byte[] publicKey) + : base(false, param) { this.publicKey = Arrays.Clone(publicKey); } - public byte[] PublicKey => Arrays.Clone(publicKey); + internal byte[] PublicKey => publicKey; + public byte[] GetEncoded() { - return PublicKey; + return Arrays.Clone(publicKey); } } } diff --git a/crypto/src/pqc/crypto/bike/BikeRandomGenerator.cs b/crypto/src/pqc/crypto/bike/BikeRandomGenerator.cs deleted file mode 100644 index 7117c1d9d..000000000 --- a/crypto/src/pqc/crypto/bike/BikeRandomGenerator.cs +++ /dev/null @@ -1,64 +0,0 @@ -using Org.BouncyCastle.Crypto; -using Org.BouncyCastle.Crypto.Utilities; -using Org.BouncyCastle.Utilities; - -namespace Org.BouncyCastle.Pqc.Crypto.Bike -{ - internal class BikeRandomGenerator - { - private static int GetRandomInMod(int mod, IXof digest) - { - int highest = Integers.HighestOneBit(mod); - int mask = highest | (highest - 1); - while (true) - { - int res = GetRandomNumber(digest) & mask; - if (res < mod) - return res; - } - } - - private static void GenerateRandomArray(byte[] res, int mod, int weight, IXof digest) - { - int index = 0; - while (index < weight) - { - int tmp = GetRandomInMod(mod, digest); - - if (CheckBit(res, tmp) == 0) - { // check for new index - SetBit(res, tmp); - index++; - } - } - } - - private static int CheckBit(byte[] a, int position) - { - int index = position / 8; - int pos = position % 8; - return ((a[index] >> (pos)) & 0x01); - } - - private static void SetBit(byte[] a, int position) - { - int index = position / 8; - int pos = position % 8; - a[index] |= (byte) (1 << (pos)); - } - - public static byte[] GenerateRandomByteArray(int mod, int size, int weight, IXof digest) - { - byte[] res = new byte[size]; - GenerateRandomArray(res, mod, weight, digest); - return res; - } - - private static int GetRandomNumber(IXof digest) - { - byte[] output = new byte[4]; - digest.Output(output, 0, output.Length); - return (int)Pack.LE_To_UInt32(output, 0); - } - } -} diff --git a/crypto/src/pqc/crypto/bike/Utils.cs b/crypto/src/pqc/crypto/bike/BikeUtilities.cs index 5d151f522..5facdaacf 100644 --- a/crypto/src/pqc/crypto/bike/Utils.cs +++ b/crypto/src/pqc/crypto/bike/BikeUtilities.cs @@ -1,8 +1,12 @@ using System; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Utilities; + namespace Org.BouncyCastle.Pqc.Crypto.Bike { - internal class Utils + internal class BikeUtilities { internal static byte[] XorBytes(byte[] a, byte[] b, int size) { @@ -100,5 +104,36 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike Array.Copy(input, 0, output, 0, input.Length); return output; } + + internal static byte[] GenerateRandomByteArray(int mod, int size, int weight, IXof digest) + { + byte[] buf = new byte[4]; + int highest = Integers.HighestOneBit(mod); + int mask = highest | (highest - 1); + + byte[] res = new byte[size]; + int count = 0; + while (count < weight) + { + digest.Output(buf, 0, 4); + int tmp = (int)Pack.LE_To_UInt32(buf) & mask; + + if (tmp < mod && SetBit(res, tmp)) + { + ++count; + } + } + return res; + } + + private static bool SetBit(byte[] a, int position) + { + int index = position / 8; + int pos = position % 8; + int selector = 1 << pos; + bool result = (a[index] & selector) == 0; + a[index] |= (byte)selector; + return result; + } } } diff --git a/crypto/test/src/pqc/crypto/test/BikeVectorTest.cs b/crypto/test/src/pqc/crypto/test/BikeVectorTest.cs index 723f6b554..a25a27fe1 100644 --- a/crypto/test/src/pqc/crypto/test/BikeVectorTest.cs +++ b/crypto/test/src/pqc/crypto/test/BikeVectorTest.cs @@ -64,11 +64,13 @@ namespace Org.BouncyCastle.Pqc.Crypto.Tests kpGen.Init(genParam); AsymmetricCipherKeyPair kp = kpGen.GenerateKeyPair(); - BikePublicKeyParameters pubParams = (BikePublicKeyParameters)PublicKeyFactory.CreateKey(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo((BikePublicKeyParameters) kp.Public)); - BikePrivateKeyParameters privParams = (BikePrivateKeyParameters)PrivateKeyFactory.CreateKey(PrivateKeyInfoFactory.CreatePrivateKeyInfo((BikePrivateKeyParameters) kp.Private)); + BikePublicKeyParameters pubParams = (BikePublicKeyParameters)PublicKeyFactory.CreateKey( + SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo((BikePublicKeyParameters) kp.Public)); + BikePrivateKeyParameters privParams = (BikePrivateKeyParameters)PrivateKeyFactory.CreateKey( + PrivateKeyInfoFactory.CreatePrivateKeyInfo((BikePrivateKeyParameters) kp.Private)); - Assert.True(Arrays.AreEqual(pk, pubParams.PublicKey), name + " " + count + ": public key"); - Assert.True(Arrays.AreEqual(sk, privParams.PrivateKey), name + " " + count + ": secret key"); + Assert.True(Arrays.AreEqual(pk, pubParams.GetEncoded()), name + " " + count + ": public key"); + Assert.True(Arrays.AreEqual(sk, privParams.GetEncoded()), name + " " + count + ": secret key"); // KEM Enc BikeKemGenerator BikeEncCipher = new BikeKemGenerator(random); |