diff --git a/crypto/src/asn1/bc/BCObjectIdentifiers.cs b/crypto/src/asn1/bc/BCObjectIdentifiers.cs
index d526980e5..face6f8d3 100644
--- a/crypto/src/asn1/bc/BCObjectIdentifiers.cs
+++ b/crypto/src/asn1/bc/BCObjectIdentifiers.cs
@@ -178,7 +178,19 @@ namespace Org.BouncyCastle.Asn1.BC
public static readonly DerObjectIdentifier mceliece6960119f_r3 = pqc_kem_mceliece.Branch("8");
public static readonly DerObjectIdentifier mceliece8192128_r3 = pqc_kem_mceliece.Branch("9");
public static readonly DerObjectIdentifier mceliece8192128f_r3 = pqc_kem_mceliece.Branch("10");
-
+
+ /**
+ * Frodo
+ */
+ public static readonly DerObjectIdentifier pqc_kem_frodo = bc_kem.Branch("2");
+
+ public static readonly DerObjectIdentifier frodokem640aes = pqc_kem_frodo.Branch("1");
+ public static readonly DerObjectIdentifier frodokem640shake = pqc_kem_frodo.Branch("2");
+ public static readonly DerObjectIdentifier frodokem976aes = pqc_kem_frodo.Branch("3");
+ public static readonly DerObjectIdentifier frodokem976shake = pqc_kem_frodo.Branch("4");
+ public static readonly DerObjectIdentifier frodokem1344aes = pqc_kem_frodo.Branch("5");
+ public static readonly DerObjectIdentifier frodokem1344shake = pqc_kem_frodo.Branch("6");
+
/**
* SABER
*/
diff --git a/crypto/src/pqc/crypto/frodo/FrodoEngine.cs b/crypto/src/pqc/crypto/frodo/FrodoEngine.cs
index 6aa3c8d89..905274cc3 100644
--- a/crypto/src/pqc/crypto/frodo/FrodoEngine.cs
+++ b/crypto/src/pqc/crypto/frodo/FrodoEngine.cs
@@ -59,6 +59,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Frodo
public int PrivateKeySize => len_sk_bytes;
public int PublicKeySize => len_pk_bytes;
+ // TODO[api] IDigest should be IXof?
public FrodoEngine(int n, int D, int B, short[] cdf_table, IDigest digest, FrodoMatrixGenerator mGen)
{
this.n = n;
@@ -380,18 +381,17 @@ namespace Org.BouncyCastle.Pqc.Crypto.Frodo
((IXof) digest).OutputFinal(pkh, 0, len_pkh_bytes);
// 3. seedSE || k = SHAKE(pkh || mu, len_seedSE + len_k) (length in bits)
- byte[] seedSE_k = new byte[len_seedSE + len_k];
+ byte[] x96_seedSE_k = new byte[len_seedSE + len_k];
+ x96_seedSE_k[0] = 0x96;
+
digest.BlockUpdate(pkh, 0, len_pkh_bytes);
digest.BlockUpdate(mu, 0, len_mu_bytes);
- ((IXof) digest).OutputFinal(seedSE_k, 0, len_seedSE_bytes + len_k_bytes);
-
- byte[] seedSE = Arrays.CopyOfRange(seedSE_k, 0, len_seedSE_bytes);
- byte[] k = Arrays.CopyOfRange(seedSE_k, len_seedSE_bytes, len_seedSE_bytes + len_k_bytes);
+ ((IXof) digest).OutputFinal(x96_seedSE_k, 1, len_seedSE_bytes + len_k_bytes);
// 4. r = SHAKE(0x96 || seedSE, 2*mbar*n + mbar*nbar*len_chi) (length in bits)
byte[] rbytes = new byte[(2 * mbar * n + mbar * nbar) * len_chi_bytes];
- digest.Update((byte) 0x96);
- digest.BlockUpdate(seedSE, 0, seedSE.Length);
+
+ digest.BlockUpdate(x96_seedSE_k, 0, 1 + len_seedSE_bytes);
((IXof) digest).OutputFinal(rbytes, 0, rbytes.Length);
short[] r = new short[rbytes.Length / 2];
@@ -435,7 +435,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Frodo
Array.Copy(Arrays.Concatenate(c1, c2), 0, ct, 0, len_ct_bytes);
digest.BlockUpdate(c1, 0, c1.Length);
digest.BlockUpdate(c2, 0, c2.Length);
- digest.BlockUpdate(k, 0, len_k_bytes);
+ digest.BlockUpdate(x96_seedSE_k, 1 + len_seedSE_bytes, len_k_bytes);
((IXof) digest).OutputFinal(ss, 0, len_s_bytes);
}
diff --git a/crypto/src/pqc/crypto/frodo/FrodoKEMExtractor.cs b/crypto/src/pqc/crypto/frodo/FrodoKEMExtractor.cs
index 8a26e90a4..a3805e39d 100644
--- a/crypto/src/pqc/crypto/frodo/FrodoKEMExtractor.cs
+++ b/crypto/src/pqc/crypto/frodo/FrodoKEMExtractor.cs
@@ -1,34 +1,29 @@
-
using Org.BouncyCastle.Crypto;
namespace Org.BouncyCastle.Pqc.Crypto.Frodo
{
-
+ // TODO[api] FrodoKemExtractor
public class FrodoKEMExtractor
: IEncapsulatedSecretExtractor
{
- private FrodoEngine engine;
-
- private FrodoKeyParameters key;
+ private readonly FrodoKeyParameters m_key;
+ private readonly FrodoEngine m_engine;
public FrodoKEMExtractor(FrodoKeyParameters privParams)
{
- this.key = privParams;
- InitCipher(key.Parameters);
- }
-
- private void InitCipher(FrodoParameters param)
- {
- engine = param.Engine;
+ m_key = privParams;
+#pragma warning disable CS0618 // Type or member is obsolete
+ m_engine = privParams.Parameters.Engine;
+#pragma warning restore CS0618 // Type or member is obsolete
}
public byte[] ExtractSecret(byte[] encapsulation)
{
- byte[] session_key = new byte[engine.SessionKeySize];
- engine.kem_dec(session_key, encapsulation, ((FrodoPrivateKeyParameters)key).privateKey);
+ byte[] session_key = new byte[m_engine.SessionKeySize];
+ m_engine.kem_dec(session_key, encapsulation, ((FrodoPrivateKeyParameters)m_key).privateKey);
return session_key;
}
- public int EncapsulationLength => (int)engine.CipherTextSize;
+ public int EncapsulationLength => m_engine.CipherTextSize;
}
-}
\ No newline at end of file
+}
diff --git a/crypto/src/pqc/crypto/frodo/FrodoKEMGenerator.cs b/crypto/src/pqc/crypto/frodo/FrodoKEMGenerator.cs
index 4cfde03fb..cf764ef25 100644
--- a/crypto/src/pqc/crypto/frodo/FrodoKEMGenerator.cs
+++ b/crypto/src/pqc/crypto/frodo/FrodoKEMGenerator.cs
@@ -4,24 +4,27 @@ using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Pqc.Crypto.Frodo
{
+ // TODO[api] FrodoKemGenerator
public class FrodoKEMGenerator
: IEncapsulatedSecretGenerator
{
// the source of randomness
- private readonly SecureRandom sr;
+ private readonly SecureRandom m_random;
public FrodoKEMGenerator(SecureRandom random)
{
- this.sr = random;
+ m_random = random;
}
public ISecretWithEncapsulation GenerateEncapsulated(AsymmetricKeyParameter recipientKey)
{
- FrodoPublicKeyParameters key = (FrodoPublicKeyParameters) recipientKey;
+ FrodoPublicKeyParameters key = (FrodoPublicKeyParameters)recipientKey;
+#pragma warning disable CS0618 // Type or member is obsolete
FrodoEngine engine = key.Parameters.Engine;
+#pragma warning restore CS0618 // Type or member is obsolete
byte[] cipher_text = new byte[engine.CipherTextSize];
byte[] sessionKey = new byte[engine.SessionKeySize];
- engine.kem_enc(cipher_text, sessionKey, key.m_publicKey, sr);
+ engine.kem_enc(cipher_text, sessionKey, key.m_publicKey, m_random);
return new SecretWithEncapsulationImpl(sessionKey, cipher_text);
}
}
diff --git a/crypto/src/pqc/crypto/frodo/FrodoKeyGenerationParameters.cs b/crypto/src/pqc/crypto/frodo/FrodoKeyGenerationParameters.cs
index 062441b8f..e10ee6395 100644
--- a/crypto/src/pqc/crypto/frodo/FrodoKeyGenerationParameters.cs
+++ b/crypto/src/pqc/crypto/frodo/FrodoKeyGenerationParameters.cs
@@ -1,4 +1,3 @@
-
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Security;
@@ -7,16 +6,14 @@ namespace Org.BouncyCastle.Pqc.Crypto.Frodo
public class FrodoKeyGenerationParameters
: KeyGenerationParameters
{
- private FrodoParameters parameters;
+ private readonly FrodoParameters m_parameters;
- public FrodoKeyGenerationParameters(
- SecureRandom random,
- FrodoParameters frodoParameters)
+ public FrodoKeyGenerationParameters(SecureRandom random, FrodoParameters frodoParameters)
: base(random, 256)
{
- this.parameters = frodoParameters;
+ m_parameters = frodoParameters;
}
- public FrodoParameters Parameters => parameters;
+ public FrodoParameters Parameters => m_parameters;
}
-}
\ No newline at end of file
+}
diff --git a/crypto/src/pqc/crypto/frodo/FrodoKeyPairGenerator.cs b/crypto/src/pqc/crypto/frodo/FrodoKeyPairGenerator.cs
index 464161444..c10087ea2 100644
--- a/crypto/src/pqc/crypto/frodo/FrodoKeyPairGenerator.cs
+++ b/crypto/src/pqc/crypto/frodo/FrodoKeyPairGenerator.cs
@@ -1,4 +1,3 @@
-
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Security;
@@ -7,46 +6,29 @@ namespace Org.BouncyCastle.Pqc.Crypto.Frodo
public class FrodoKeyPairGenerator
: IAsymmetricCipherKeyPairGenerator
{
- private FrodoKeyGenerationParameters frodoParams;
-
- private int n;
- private int D;
- private int B;
+ private FrodoParameters m_parameters;
+ private SecureRandom m_random;
- private SecureRandom random;
-
- private void Initialize(
- KeyGenerationParameters param)
+ public void Init(KeyGenerationParameters param)
{
- frodoParams = (FrodoKeyGenerationParameters) param;
- random = param.Random;
+ FrodoKeyGenerationParameters frodoParams = (FrodoKeyGenerationParameters)param;
- n = frodoParams.Parameters.N;
- D = frodoParams.Parameters.D;
- B = frodoParams.Parameters.B;
+ m_parameters = frodoParams.Parameters;
+ m_random = frodoParams.Random;
}
- private AsymmetricCipherKeyPair GenKeyPair()
+ public AsymmetricCipherKeyPair GenerateKeyPair()
{
- FrodoEngine engine = frodoParams.Parameters.Engine;
+#pragma warning disable CS0618 // Type or member is obsolete
+ FrodoEngine engine = m_parameters.Engine;
+#pragma warning restore CS0618 // Type or member is obsolete
byte[] sk = new byte[engine.PrivateKeySize];
byte[] pk = new byte[engine.PublicKeySize];
- engine.kem_keypair(pk, sk, random);
-
- FrodoPublicKeyParameters pubKey = new FrodoPublicKeyParameters(frodoParams.Parameters, pk);
- FrodoPrivateKeyParameters privKey = new FrodoPrivateKeyParameters(frodoParams.Parameters, sk);
- return new AsymmetricCipherKeyPair(pubKey, privKey);
- }
+ engine.kem_keypair(pk, sk, m_random);
- public void Init(KeyGenerationParameters param)
- {
- this.Initialize(param);
+ return new AsymmetricCipherKeyPair(
+ new FrodoPublicKeyParameters(m_parameters, pk),
+ new FrodoPrivateKeyParameters(m_parameters, sk));
}
-
- public AsymmetricCipherKeyPair GenerateKeyPair()
- {
- return GenKeyPair();
- }
-
}
-}
\ No newline at end of file
+}
diff --git a/crypto/src/pqc/crypto/frodo/FrodoKeyParameters.cs b/crypto/src/pqc/crypto/frodo/FrodoKeyParameters.cs
index d195eba2b..4b9e4f1d9 100644
--- a/crypto/src/pqc/crypto/frodo/FrodoKeyParameters.cs
+++ b/crypto/src/pqc/crypto/frodo/FrodoKeyParameters.cs
@@ -10,7 +10,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Frodo
internal FrodoKeyParameters(bool isPrivate, FrodoParameters parameters)
: base(isPrivate)
{
- this.m_parameters = parameters;
+ m_parameters = parameters;
}
public FrodoParameters Parameters => m_parameters;
diff --git a/crypto/src/pqc/crypto/frodo/FrodoParameters.cs b/crypto/src/pqc/crypto/frodo/FrodoParameters.cs
index 3f8fe254d..6f84f1b0c 100644
--- a/crypto/src/pqc/crypto/frodo/FrodoParameters.cs
+++ b/crypto/src/pqc/crypto/frodo/FrodoParameters.cs
@@ -1,35 +1,53 @@
+using System;
+
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Digests;
+using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Pqc.Crypto.Frodo
{
public sealed class FrodoParameters
: ICipherParameters
{
- private static short[] cdf_table640 = {4643, 13363, 20579, 25843, 29227, 31145, 32103, 32525, 32689, 32745, 32762, 32766, 32767};
- private static short[] cdf_table976 = {5638, 15915, 23689, 28571, 31116, 32217, 32613, 32731, 32760, 32766, 32767};
- private static short[] cdf_table1344 = {9142, 23462, 30338, 32361, 32725, 32765, 32767};
-
- public static FrodoParameters frodokem19888r3 = new FrodoParameters("frodokem19888", 640, 15, 2, cdf_table640, new ShakeDigest(128), new FrodoMatrixGenerator.Aes128MatrixGenerator(640, (1<<15)));
- public static FrodoParameters frodokem19888shaker3 = new FrodoParameters("frodokem19888shake", 640, 15, 2, cdf_table640, new ShakeDigest(128), new FrodoMatrixGenerator.Shake128MatrixGenerator(640, (1<<15)));
-
- public static FrodoParameters frodokem31296r3 = new FrodoParameters("frodokem31296", 976, 16, 3, cdf_table976, new ShakeDigest(256), new FrodoMatrixGenerator.Aes128MatrixGenerator(976, (1<<16)));
- public static FrodoParameters frodokem31296shaker3 = new FrodoParameters("frodokem31296shake", 976, 16, 3, cdf_table976, new ShakeDigest(256), new FrodoMatrixGenerator.Shake128MatrixGenerator(976, (1<<16)));
-
- public static FrodoParameters frodokem43088r3 = new FrodoParameters("frodokem43088", 1344, 16, 4, cdf_table1344, new ShakeDigest(256), new FrodoMatrixGenerator.Aes128MatrixGenerator(1344, (1<<16)));
- public static FrodoParameters frodokem43088shaker3 = new FrodoParameters("frodokem43088shake", 1344, 16, 4, cdf_table1344, new ShakeDigest(256), new FrodoMatrixGenerator.Shake128MatrixGenerator(1344, (1<<16)));
-
- private string name;
- private int n;
- private int d;
- private int b;
- private short[] cdf_table;
- private IDigest digest;
- private FrodoMatrixGenerator mGen;
- private int defaultKeySize;
- private FrodoEngine engine;
-
- private FrodoParameters(string name, int n, int d, int b, short[] cdf_table, IDigest digest,
+ private static readonly short[] cdf_table640 = {4643, 13363, 20579, 25843, 29227, 31145, 32103, 32525, 32689, 32745, 32762, 32766, 32767};
+ private static readonly short[] cdf_table976 = {5638, 15915, 23689, 28571, 31116, 32217, 32613, 32731, 32760, 32766, 32767};
+ private static readonly short[] cdf_table1344 = {9142, 23462, 30338, 32361, 32725, 32765, 32767};
+
+ public static readonly FrodoParameters frodokem640aes = new FrodoParameters("frodokem19888", 640, 15, 2, cdf_table640, new ShakeDigest(128), new FrodoMatrixGenerator.Aes128MatrixGenerator(640, (1 << 15)));
+ public static readonly FrodoParameters frodokem640shake = new FrodoParameters("frodokem19888shake", 640, 15, 2, cdf_table640, new ShakeDigest(128), new FrodoMatrixGenerator.Shake128MatrixGenerator(640, (1 << 15)));
+
+ public static readonly FrodoParameters frodokem976aes = new FrodoParameters("frodokem31296", 976, 16, 3, cdf_table976, new ShakeDigest(256), new FrodoMatrixGenerator.Aes128MatrixGenerator(976, (1 << 16)));
+ public static readonly FrodoParameters frodokem976shake = new FrodoParameters("frodokem31296shake", 976, 16, 3, cdf_table976, new ShakeDigest(256), new FrodoMatrixGenerator.Shake128MatrixGenerator(976, (1 << 16)));
+
+ public static readonly FrodoParameters frodokem1344aes = new FrodoParameters("frodokem43088", 1344, 16, 4, cdf_table1344, new ShakeDigest(256), new FrodoMatrixGenerator.Aes128MatrixGenerator(1344, (1 << 16)));
+ public static readonly FrodoParameters frodokem1344shake = new FrodoParameters("frodokem43088shake", 1344, 16, 4, cdf_table1344, new ShakeDigest(256), new FrodoMatrixGenerator.Shake128MatrixGenerator(1344, (1 << 16)));
+
+ [Obsolete("Use 'frodokem640aes' instead")]
+ public static FrodoParameters frodokem19888r3 = frodokem640aes;
+ [Obsolete("Use 'frodokem640shake' instead")]
+ public static FrodoParameters frodokem19888shaker3 = frodokem640shake;
+
+ [Obsolete("Use 'frodokem976aes' instead")]
+ public static FrodoParameters frodokem31296r3 = frodokem976aes;
+ [Obsolete("Use 'frodokem976shake' instead")]
+ public static FrodoParameters frodokem31296shaker3 = frodokem976shake;
+
+ [Obsolete("Use 'frodokem1344aes' instead")]
+ public static FrodoParameters frodokem43088r3 = frodokem1344aes;
+ [Obsolete("Use 'frodokem1344shake' instead")]
+ public static FrodoParameters frodokem43088shaker3 = frodokem1344shake;
+
+ private readonly string name;
+ private readonly int n;
+ private readonly int d;
+ private readonly int b;
+ private readonly short[] cdf_table;
+ private readonly ShakeDigest digest;
+ private readonly FrodoMatrixGenerator mGen;
+ private readonly int defaultKeySize;
+ private readonly FrodoEngine engine;
+
+ private FrodoParameters(string name, int n, int d, int b, short[] cdf_table, ShakeDigest digest,
FrodoMatrixGenerator mGen)
{
this.name = name;
@@ -39,26 +57,33 @@ namespace Org.BouncyCastle.Pqc.Crypto.Frodo
this.cdf_table = cdf_table;
this.digest = digest;
this.mGen = mGen;
- this.defaultKeySize = B * FrodoEngine.nbar * FrodoEngine.nbar;
+ this.defaultKeySize = b * FrodoEngine.nbar * FrodoEngine.nbar;
this.engine = new FrodoEngine(n, d, b, cdf_table, digest, mGen);
}
+ public string Name => name;
+
+ public int DefaultKeySize => defaultKeySize;
+
+ [Obsolete("Will be removed")]
public FrodoEngine Engine => engine;
+ [Obsolete("Will be removed")]
public int N => n;
- public string Name => name;
-
+ [Obsolete("Will be removed")]
public int D => d;
+ [Obsolete("Will be removed")]
public int B => b;
- public short[] CdfTable => cdf_table;
+ [Obsolete("Will be removed")]
+ public short[] CdfTable => Arrays.Clone(cdf_table);
- public IDigest Digest => digest;
-
- public int DefaultKeySize => defaultKeySize;
+ [Obsolete("Will be removed")]
+ public IDigest Digest => new ShakeDigest(digest);
+ [Obsolete("Will be removed")]
public FrodoMatrixGenerator MGen => mGen;
}
}
diff --git a/crypto/src/pqc/crypto/frodo/FrodoPrivateKeyParameters.cs b/crypto/src/pqc/crypto/frodo/FrodoPrivateKeyParameters.cs
index cfbf1c3ea..cc3d1e182 100644
--- a/crypto/src/pqc/crypto/frodo/FrodoPrivateKeyParameters.cs
+++ b/crypto/src/pqc/crypto/frodo/FrodoPrivateKeyParameters.cs
@@ -5,7 +5,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Frodo
public sealed class FrodoPrivateKeyParameters
: FrodoKeyParameters
{
- internal byte[] privateKey;
+ internal readonly byte[] privateKey;
public FrodoPrivateKeyParameters(FrodoParameters parameters, byte[] privateKey)
: base(true, parameters)
diff --git a/crypto/src/pqc/crypto/utils/PqcPrivateKeyFactory.cs b/crypto/src/pqc/crypto/utils/PqcPrivateKeyFactory.cs
index f01988169..01566c8b0 100644
--- a/crypto/src/pqc/crypto/utils/PqcPrivateKeyFactory.cs
+++ b/crypto/src/pqc/crypto/utils/PqcPrivateKeyFactory.cs
@@ -14,6 +14,7 @@ using Org.BouncyCastle.Pqc.Crypto.Cmce;
using Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium;
using Org.BouncyCastle.Pqc.Crypto.Crystals.Kyber;
using Org.BouncyCastle.Pqc.Crypto.Falcon;
+using Org.BouncyCastle.Pqc.Crypto.Frodo;
using Org.BouncyCastle.Pqc.Crypto.Hqc;
using Org.BouncyCastle.Pqc.Crypto.Lms;
using Org.BouncyCastle.Pqc.Crypto.Picnic;
@@ -78,6 +79,13 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities
return new CmcePrivateKeyParameters(spParams, cmceKey.Delta, cmceKey.C, cmceKey.G, cmceKey.Alpha, cmceKey.S);
}
+ if (algOID.On(BCObjectIdentifiers.pqc_kem_frodo))
+ {
+ byte[] keyEnc = Asn1OctetString.GetInstance(keyInfo.ParsePrivateKey()).GetOctets();
+ FrodoParameters spParams = PqcUtilities.FrodoParamsLookup(keyInfo.PrivateKeyAlgorithm.Algorithm);
+
+ return new FrodoPrivateKeyParameters(spParams, keyEnc);
+ }
if (algOID.On(BCObjectIdentifiers.sphincsPlus))
{
byte[] keyEnc = Asn1OctetString.GetInstance(keyInfo.ParsePrivateKey()).GetOctets();
diff --git a/crypto/src/pqc/crypto/utils/PqcPrivateKeyInfoFactory.cs b/crypto/src/pqc/crypto/utils/PqcPrivateKeyInfoFactory.cs
index 3d1b1b679..6f7bed2ca 100644
--- a/crypto/src/pqc/crypto/utils/PqcPrivateKeyInfoFactory.cs
+++ b/crypto/src/pqc/crypto/utils/PqcPrivateKeyInfoFactory.cs
@@ -10,6 +10,7 @@ using Org.BouncyCastle.Pqc.Crypto.Cmce;
using Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium;
using Org.BouncyCastle.Pqc.Crypto.Crystals.Kyber;
using Org.BouncyCastle.Pqc.Crypto.Falcon;
+using Org.BouncyCastle.Pqc.Crypto.Frodo;
using Org.BouncyCastle.Pqc.Crypto.Hqc;
using Org.BouncyCastle.Pqc.Crypto.Lms;
using Org.BouncyCastle.Pqc.Crypto.Picnic;
@@ -67,8 +68,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities
if (privateKey is CmcePrivateKeyParameters cmcePrivateKeyParameters)
{
byte[] encoding = cmcePrivateKeyParameters.GetEncoded();
- AlgorithmIdentifier algorithmIdentifier =
- new AlgorithmIdentifier(PqcUtilities.McElieceOidLookup(cmcePrivateKeyParameters.Parameters));
+ AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(
+ PqcUtilities.McElieceOidLookup(cmcePrivateKeyParameters.Parameters));
CmcePublicKey CmcePub = new CmcePublicKey(cmcePrivateKeyParameters.ReconstructPublicKey());
CmcePrivateKey CmcePriv = new CmcePrivateKey(0, cmcePrivateKeyParameters.Delta,
@@ -76,6 +77,15 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities
cmcePrivateKeyParameters.S, CmcePub);
return new PrivateKeyInfo(algorithmIdentifier, CmcePriv, attributes);
}
+ if (privateKey is FrodoPrivateKeyParameters frodoPrivateKeyParameters)
+ {
+ byte[] encoding = frodoPrivateKeyParameters.GetEncoded();
+
+ AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(
+ PqcUtilities.FrodoOidLookup(frodoPrivateKeyParameters.Parameters));
+
+ return new PrivateKeyInfo(algorithmIdentifier, new DerOctetString(encoding), attributes);
+ }
if (privateKey is SaberPrivateKeyParameters saberPrivateKeyParameters)
{
byte[] encoding = saberPrivateKeyParameters.GetEncoded();
diff --git a/crypto/src/pqc/crypto/utils/PqcPublicKeyFactory.cs b/crypto/src/pqc/crypto/utils/PqcPublicKeyFactory.cs
index 909b93577..899ebc28e 100644
--- a/crypto/src/pqc/crypto/utils/PqcPublicKeyFactory.cs
+++ b/crypto/src/pqc/crypto/utils/PqcPublicKeyFactory.cs
@@ -14,6 +14,7 @@ using Org.BouncyCastle.Pqc.Crypto.Cmce;
using Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium;
using Org.BouncyCastle.Pqc.Crypto.Crystals.Kyber;
using Org.BouncyCastle.Pqc.Crypto.Falcon;
+using Org.BouncyCastle.Pqc.Crypto.Frodo;
using Org.BouncyCastle.Pqc.Crypto.Hqc;
using Org.BouncyCastle.Pqc.Crypto.Lms;
using Org.BouncyCastle.Pqc.Crypto.Picnic;
@@ -49,7 +50,14 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities
Converters[BCObjectIdentifiers.mceliece6960119f_r3] = new CmceConverter();
Converters[BCObjectIdentifiers.mceliece8192128_r3] = new CmceConverter();
Converters[BCObjectIdentifiers.mceliece8192128f_r3] = new CmceConverter();
-
+
+ Converters[BCObjectIdentifiers.frodokem640aes] = new FrodoConverter();
+ Converters[BCObjectIdentifiers.frodokem640shake] = new FrodoConverter();
+ Converters[BCObjectIdentifiers.frodokem976aes] = new FrodoConverter();
+ Converters[BCObjectIdentifiers.frodokem976shake] = new FrodoConverter();
+ Converters[BCObjectIdentifiers.frodokem1344aes] = new FrodoConverter();
+ Converters[BCObjectIdentifiers.frodokem1344shake] = new FrodoConverter();
+
Converters[BCObjectIdentifiers.lightsaberkem128r3] = new SaberConverter();
Converters[BCObjectIdentifiers.saberkem128r3] = new SaberConverter();
Converters[BCObjectIdentifiers.firesaberkem128r3] = new SaberConverter();
@@ -217,6 +225,19 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities
}
}
+ private class FrodoConverter
+ : SubjectPublicKeyInfoConverter
+ {
+ internal override AsymmetricKeyParameter GetPublicKeyParameters(SubjectPublicKeyInfo keyInfo, object defaultParams)
+ {
+ byte[] keyEnc = Asn1OctetString.GetInstance(keyInfo.ParsePublicKey()).GetOctets();
+
+ FrodoParameters fParams = PqcUtilities.FrodoParamsLookup(keyInfo.AlgorithmID.Algorithm);
+
+ return new FrodoPublicKeyParameters(fParams, keyEnc);
+ }
+ }
+
private class SaberConverter
: SubjectPublicKeyInfoConverter
{
diff --git a/crypto/src/pqc/crypto/utils/PqcSubjectPublicKeyInfoFactory.cs b/crypto/src/pqc/crypto/utils/PqcSubjectPublicKeyInfoFactory.cs
index c13255c68..1bdf031f6 100644
--- a/crypto/src/pqc/crypto/utils/PqcSubjectPublicKeyInfoFactory.cs
+++ b/crypto/src/pqc/crypto/utils/PqcSubjectPublicKeyInfoFactory.cs
@@ -10,6 +10,7 @@ using Org.BouncyCastle.Pqc.Crypto.Cmce;
using Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium;
using Org.BouncyCastle.Pqc.Crypto.Crystals.Kyber;
using Org.BouncyCastle.Pqc.Crypto.Falcon;
+using Org.BouncyCastle.Pqc.Crypto.Frodo;
using Org.BouncyCastle.Pqc.Crypto.Hqc;
using Org.BouncyCastle.Pqc.Crypto.Lms;
using Org.BouncyCastle.Pqc.Crypto.Picnic;
@@ -71,6 +72,15 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities
// https://datatracker.ietf.org/doc/draft-uni-qsckeys/
return new SubjectPublicKeyInfo(algorithmIdentifier, new CmcePublicKey(encoding));
}
+ else if (publicKey is FrodoPublicKeyParameters frodoPublicKeyParameters)
+ {
+ byte[] encoding = frodoPublicKeyParameters.GetEncoded();
+
+ AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(
+ PqcUtilities.FrodoOidLookup(frodoPublicKeyParameters.Parameters));
+
+ return new SubjectPublicKeyInfo(algorithmIdentifier, new DerOctetString(encoding));
+ }
if (publicKey is SaberPublicKeyParameters saberPublicKeyParameters)
{
byte[] encoding = saberPublicKeyParameters.GetEncoded();
diff --git a/crypto/src/pqc/crypto/utils/PqcUtilities.cs b/crypto/src/pqc/crypto/utils/PqcUtilities.cs
index 67e58fd28..101e3c846 100644
--- a/crypto/src/pqc/crypto/utils/PqcUtilities.cs
+++ b/crypto/src/pqc/crypto/utils/PqcUtilities.cs
@@ -7,11 +7,13 @@ using Org.BouncyCastle.Pqc.Crypto.Cmce;
using Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium;
using Org.BouncyCastle.Pqc.Crypto.Crystals.Kyber;
using Org.BouncyCastle.Pqc.Crypto.Falcon;
+using Org.BouncyCastle.Pqc.Crypto.Frodo;
using Org.BouncyCastle.Pqc.Crypto.Hqc;
using Org.BouncyCastle.Pqc.Crypto.Picnic;
using Org.BouncyCastle.Pqc.Crypto.Saber;
using Org.BouncyCastle.Pqc.Crypto.Sike;
using Org.BouncyCastle.Pqc.Crypto.SphincsPlus;
+using Org.BouncyCastle.Utilities.Collections;
namespace Org.BouncyCastle.Pqc.Crypto.Utilities
{
@@ -19,7 +21,10 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities
{
private readonly static Dictionary<CmceParameters, DerObjectIdentifier> mcElieceOids = new Dictionary<CmceParameters, DerObjectIdentifier>();
private readonly static Dictionary<DerObjectIdentifier, CmceParameters> mcElieceParams = new Dictionary<DerObjectIdentifier, CmceParameters>();
-
+
+ private readonly static Dictionary<FrodoParameters, DerObjectIdentifier> frodoOids = new Dictionary<FrodoParameters, DerObjectIdentifier>();
+ private readonly static Dictionary<DerObjectIdentifier, FrodoParameters> frodoParams = new Dictionary<DerObjectIdentifier, FrodoParameters>();
+
private readonly static Dictionary<SaberParameters, DerObjectIdentifier> saberOids = new Dictionary<SaberParameters, DerObjectIdentifier>();
private readonly static Dictionary<DerObjectIdentifier, SaberParameters> saberParams = new Dictionary<DerObjectIdentifier, SaberParameters>();
@@ -70,7 +75,21 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities
mcElieceParams[BCObjectIdentifiers.mceliece6960119f_r3] = CmceParameters.mceliece6960119fr3;
mcElieceParams[BCObjectIdentifiers.mceliece8192128_r3] = CmceParameters.mceliece8192128r3;
mcElieceParams[BCObjectIdentifiers.mceliece8192128f_r3] = CmceParameters.mceliece8192128fr3;
-
+
+ frodoOids[FrodoParameters.frodokem640aes] = BCObjectIdentifiers.frodokem640aes;
+ frodoOids[FrodoParameters.frodokem640shake] = BCObjectIdentifiers.frodokem640shake;
+ frodoOids[FrodoParameters.frodokem976aes] = BCObjectIdentifiers.frodokem976aes;
+ frodoOids[FrodoParameters.frodokem976shake] = BCObjectIdentifiers.frodokem976shake;
+ frodoOids[FrodoParameters.frodokem1344aes] = BCObjectIdentifiers.frodokem1344aes;
+ frodoOids[FrodoParameters.frodokem1344shake] = BCObjectIdentifiers.frodokem1344shake;
+
+ frodoParams[BCObjectIdentifiers.frodokem640aes] = FrodoParameters.frodokem640aes;
+ frodoParams[BCObjectIdentifiers.frodokem640shake] = FrodoParameters.frodokem640shake;
+ frodoParams[BCObjectIdentifiers.frodokem976aes] = FrodoParameters.frodokem976aes;
+ frodoParams[BCObjectIdentifiers.frodokem976shake] = FrodoParameters.frodokem976shake;
+ frodoParams[BCObjectIdentifiers.frodokem1344aes] = FrodoParameters.frodokem1344aes;
+ frodoParams[BCObjectIdentifiers.frodokem1344shake] = FrodoParameters.frodokem1344shake;
+
saberOids[SaberParameters.lightsaberkem128r3] = BCObjectIdentifiers.lightsaberkem128r3;
saberOids[SaberParameters.saberkem128r3] = BCObjectIdentifiers.saberkem128r3;
saberOids[SaberParameters.firesaberkem128r3] = BCObjectIdentifiers.firesaberkem128r3;
@@ -209,45 +228,62 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities
internal static DerObjectIdentifier McElieceOidLookup(CmceParameters parameters)
{
- return mcElieceOids[parameters];
+ return CollectionUtilities.GetValueOrNull(mcElieceOids, parameters);
}
internal static CmceParameters McElieceParamsLookup(DerObjectIdentifier oid)
{
- return mcElieceParams[oid];
+ return CollectionUtilities.GetValueOrNull(mcElieceParams, oid);
+ }
+
+ internal static DerObjectIdentifier FrodoOidLookup(FrodoParameters parameters)
+ {
+ return CollectionUtilities.GetValueOrNull(frodoOids, parameters);
+ }
+
+ internal static FrodoParameters FrodoParamsLookup(DerObjectIdentifier oid)
+ {
+ return CollectionUtilities.GetValueOrNull(frodoParams, oid);
}
-
+
internal static DerObjectIdentifier SaberOidLookup(SaberParameters parameters)
{
- return saberOids[parameters];
+ return CollectionUtilities.GetValueOrNull(saberOids, parameters);
}
+
internal static SaberParameters SaberParamsLookup(DerObjectIdentifier oid)
{
- return saberParams[oid];
+ return CollectionUtilities.GetValueOrNull(saberParams, oid);
}
+
internal static KyberParameters KyberParamsLookup(DerObjectIdentifier oid)
{
- return kyberParams[oid];
- }
+ return CollectionUtilities.GetValueOrNull(kyberParams, oid);
+ }
+
internal static DerObjectIdentifier KyberOidLookup(KyberParameters parameters)
{
- return kyberOids[parameters];
+ return CollectionUtilities.GetValueOrNull(kyberOids, parameters);
}
+
internal static FalconParameters FalconParamsLookup(DerObjectIdentifier oid)
{
- return falconParams[oid];
+ return CollectionUtilities.GetValueOrNull(falconParams, oid);
}
+
internal static DerObjectIdentifier FalconOidLookup(FalconParameters parameters)
{
- return falconOids[parameters];
+ return CollectionUtilities.GetValueOrNull(falconOids, parameters);
}
+
internal static DilithiumParameters DilithiumParamsLookup(DerObjectIdentifier oid)
{
- return dilithiumParams[oid];
- }
+ return CollectionUtilities.GetValueOrNull(dilithiumParams, oid);
+ }
+
internal static DerObjectIdentifier DilithiumOidLookup(DilithiumParameters parameters)
{
- return dilithiumOids[parameters];
+ return CollectionUtilities.GetValueOrNull(dilithiumOids, parameters);
}
internal static DerObjectIdentifier SphincsPlusOidLookup(SphincsPlusParameters parameters)
@@ -265,44 +301,44 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities
internal static DerObjectIdentifier PicnicOidLookup(PicnicParameters parameters)
{
- return picnicOids[parameters];
+ return CollectionUtilities.GetValueOrNull(picnicOids, parameters);
}
internal static PicnicParameters PicnicParamsLookup(DerObjectIdentifier oid)
{
- return picnicParams[oid];
+ return CollectionUtilities.GetValueOrNull(picnicParams, oid);
}
#pragma warning disable CS0618 // Type or member is obsolete
internal static DerObjectIdentifier SikeOidLookup(SikeParameters parameters)
{
- return sikeOids[parameters];
+ return CollectionUtilities.GetValueOrNull(sikeOids, parameters);
}
internal static SikeParameters SikeParamsLookup(DerObjectIdentifier oid)
{
- return sikeParams[oid];
+ return CollectionUtilities.GetValueOrNull(sikeParams, oid);
}
#pragma warning restore CS0618 // Type or member is obsolete
internal static DerObjectIdentifier BikeOidLookup(BikeParameters parameters)
{
- return bikeOids[parameters];
+ return CollectionUtilities.GetValueOrNull(bikeOids, parameters);
}
internal static BikeParameters BikeParamsLookup(DerObjectIdentifier oid)
{
- return bikeParams[oid];
+ return CollectionUtilities.GetValueOrNull(bikeParams, oid);
}
internal static DerObjectIdentifier HqcOidLookup(HqcParameters parameters)
{
- return hqcOids[parameters];
+ return CollectionUtilities.GetValueOrNull(hqcOids, parameters);
}
internal static HqcParameters HqcParamsLookup(DerObjectIdentifier oid)
{
- return hqcParams[oid];
+ return CollectionUtilities.GetValueOrNull(hqcParams, oid);
}
}
}
diff --git a/crypto/test/src/pqc/crypto/test/FrodoVectorTest.cs b/crypto/test/src/pqc/crypto/test/FrodoVectorTest.cs
index a8133e524..a67424887 100644
--- a/crypto/test/src/pqc/crypto/test/FrodoVectorTest.cs
+++ b/crypto/test/src/pqc/crypto/test/FrodoVectorTest.cs
@@ -1,4 +1,3 @@
-using System;
using System.Collections.Generic;
using System.IO;
@@ -6,6 +5,7 @@ using NUnit.Framework;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Pqc.Crypto.Frodo;
+using Org.BouncyCastle.Pqc.Crypto.Utilities;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Encoders;
using Org.BouncyCastle.Utilities.Test;
@@ -17,12 +17,12 @@ namespace Org.BouncyCastle.Pqc.Crypto.Tests
{
private static readonly Dictionary<string, FrodoParameters> Parameters = new Dictionary<string, FrodoParameters>()
{
- { "PQCkemKAT_19888.rsp", FrodoParameters.frodokem19888r3 },
- { "PQCkemKAT_31296.rsp", FrodoParameters.frodokem31296r3 },
- { "PQCkemKAT_43088.rsp", FrodoParameters.frodokem43088r3 },
- { "PQCkemKAT_19888_shake.rsp", FrodoParameters.frodokem19888shaker3 },
- { "PQCkemKAT_31296_shake.rsp", FrodoParameters.frodokem31296shaker3 },
- { "PQCkemKAT_43088_shake.rsp", FrodoParameters.frodokem43088shaker3 },
+ { "PQCkemKAT_19888.rsp", FrodoParameters.frodokem640aes },
+ { "PQCkemKAT_31296.rsp", FrodoParameters.frodokem976aes },
+ { "PQCkemKAT_43088.rsp", FrodoParameters.frodokem1344aes },
+ { "PQCkemKAT_19888_shake.rsp", FrodoParameters.frodokem640shake },
+ { "PQCkemKAT_31296_shake.rsp", FrodoParameters.frodokem976shake },
+ { "PQCkemKAT_43088_shake.rsp", FrodoParameters.frodokem1344shake },
};
private static readonly string[] TestVectorFilesAes =
@@ -42,12 +42,12 @@ namespace Org.BouncyCastle.Pqc.Crypto.Tests
[Test]
public void TestParameters()
{
- Assert.AreEqual(128, FrodoParameters.frodokem19888r3.DefaultKeySize);
- Assert.AreEqual(128, FrodoParameters.frodokem19888shaker3.DefaultKeySize);
- Assert.AreEqual(192, FrodoParameters.frodokem31296r3.DefaultKeySize);
- Assert.AreEqual(192, FrodoParameters.frodokem31296shaker3.DefaultKeySize);
- Assert.AreEqual(256, FrodoParameters.frodokem43088r3.DefaultKeySize);
- Assert.AreEqual(256, FrodoParameters.frodokem43088shaker3.DefaultKeySize);
+ Assert.AreEqual(128, FrodoParameters.frodokem640aes.DefaultKeySize);
+ Assert.AreEqual(128, FrodoParameters.frodokem640shake.DefaultKeySize);
+ Assert.AreEqual(192, FrodoParameters.frodokem976aes.DefaultKeySize);
+ Assert.AreEqual(192, FrodoParameters.frodokem976shake.DefaultKeySize);
+ Assert.AreEqual(256, FrodoParameters.frodokem1344aes.DefaultKeySize);
+ Assert.AreEqual(256, FrodoParameters.frodokem1344shake.DefaultKeySize);
}
[TestCaseSource(nameof(TestVectorFilesAes))]
@@ -84,8 +84,10 @@ namespace Org.BouncyCastle.Pqc.Crypto.Tests
kpGen.Init(genParams);
AsymmetricCipherKeyPair kp = kpGen.GenerateKeyPair();
- FrodoPublicKeyParameters pubParams = (FrodoPublicKeyParameters)kp.Public;
- FrodoPrivateKeyParameters privParams = (FrodoPrivateKeyParameters)kp.Private;
+ FrodoPublicKeyParameters pubParams = (FrodoPublicKeyParameters)PqcPublicKeyFactory.CreateKey(
+ PqcSubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo((FrodoPublicKeyParameters)kp.Public));
+ FrodoPrivateKeyParameters privParams = (FrodoPrivateKeyParameters)PqcPrivateKeyFactory.CreateKey(
+ PqcPrivateKeyInfoFactory.CreatePrivateKeyInfo((FrodoPrivateKeyParameters)kp.Private));
Assert.True(Arrays.AreEqual(pk, pubParams.GetPublicKey()), $"{name} {count} : public key");
Assert.True(Arrays.AreEqual(sk, privParams.GetPrivateKey()), $"{name} {count} : secret key");
|