diff options
author | royb <roy.basmacier@primekey.com> | 2022-10-24 15:57:57 -0400 |
---|---|---|
committer | royb <roy.basmacier@primekey.com> | 2022-10-24 15:57:57 -0400 |
commit | f506a6ad1ee03b2c950c76ba8e9d3e47f3a44d67 (patch) | |
tree | f9f79c9f5504dde6a8d4bf51ba724d26d20eea17 /crypto/src | |
parent | fixed refactored class names in pqc/utils (diff) | |
download | BouncyCastle.NET-ed25519-f506a6ad1ee03b2c950c76ba8e9d3e47f3a44d67.tar.xz |
Added Aes and Uniform variant to Saber
Diffstat (limited to 'crypto/src')
-rw-r--r-- | crypto/src/asn1/bc/BCObjectIdentifiers.cs | 11 | ||||
-rw-r--r-- | crypto/src/pqc/crypto/saber/Poly.cs | 25 | ||||
-rw-r--r-- | crypto/src/pqc/crypto/saber/SABEREngine.cs | 82 | ||||
-rw-r--r-- | crypto/src/pqc/crypto/saber/SABERParameters.cs | 35 | ||||
-rw-r--r-- | crypto/src/pqc/crypto/saber/SaberUtilities.cs | 122 | ||||
-rw-r--r-- | crypto/src/pqc/crypto/saber/Symmetric.cs | 96 | ||||
-rw-r--r-- | crypto/src/pqc/crypto/utils/PqcUtilities.cs | 21 | ||||
-rw-r--r-- | crypto/src/pqc/crypto/utils/PublicKeyFactory.cs | 9 |
8 files changed, 299 insertions, 102 deletions
diff --git a/crypto/src/asn1/bc/BCObjectIdentifiers.cs b/crypto/src/asn1/bc/BCObjectIdentifiers.cs index f3933af87..6bfebf132 100644 --- a/crypto/src/asn1/bc/BCObjectIdentifiers.cs +++ b/crypto/src/asn1/bc/BCObjectIdentifiers.cs @@ -192,7 +192,16 @@ namespace Org.BouncyCastle.Asn1.BC public static readonly DerObjectIdentifier lightsaberkem256r3 = pqc_kem_saber.Branch("7"); public static readonly DerObjectIdentifier saberkem256r3 = pqc_kem_saber.Branch("8"); public static readonly DerObjectIdentifier firesaberkem256r3 = pqc_kem_saber.Branch("9"); - + public static readonly DerObjectIdentifier ulightsaberkemr3 = pqc_kem_saber.Branch("10"); + public static readonly DerObjectIdentifier usaberkemr3 = pqc_kem_saber.Branch("11"); + public static readonly DerObjectIdentifier ufiresaberkemr3 = pqc_kem_saber.Branch("12"); + public static readonly DerObjectIdentifier lightsaberkem90sr3 = pqc_kem_saber.Branch("13"); + public static readonly DerObjectIdentifier saberkem90sr3 = pqc_kem_saber.Branch("14"); + public static readonly DerObjectIdentifier firesaberkem90sr3 = pqc_kem_saber.Branch("15"); + public static readonly DerObjectIdentifier ulightsaberkem90sr3 = pqc_kem_saber.Branch("16"); + public static readonly DerObjectIdentifier usaberkem90sr3 = pqc_kem_saber.Branch("17"); + public static readonly DerObjectIdentifier ufiresaberkem90sr3 = pqc_kem_saber.Branch("18"); + /** * SIKE */ diff --git a/crypto/src/pqc/crypto/saber/Poly.cs b/crypto/src/pqc/crypto/saber/Poly.cs index eaae6c9a5..1a7312201 100644 --- a/crypto/src/pqc/crypto/saber/Poly.cs +++ b/crypto/src/pqc/crypto/saber/Poly.cs @@ -32,9 +32,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber byte[] buf = new byte[SABER_L * engine.PolyVecBytes]; int i; - IXof digest = new ShakeDigest(128); - digest.BlockUpdate(seed, 0, engine.SeedBytes); - digest.OutputFinal(buf, 0, buf.Length); + engine.Symmetric.Prf(buf, seed, engine.SeedBytes, buf.Length); + for (i = 0; i < SABER_L; i++) { @@ -46,13 +45,25 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber { byte[] buf = new byte[SABER_L * engine.PolyCoinBytes]; - IXof digest = new ShakeDigest(128); - digest.BlockUpdate(seed, 0, engine.NoiseSeedBytes); - digest.OutputFinal(buf, 0, buf.Length); + engine.Symmetric.Prf(buf, seed, engine.NoiseSeedBytes, buf.Length); + for (int i = 0; i < SABER_L; i++) { - Cbd(s[i], buf, i * engine.PolyCoinBytes); + if (!engine.UsingEffectiveMasking) + { + Cbd(s[i], buf, i * engine.PolyCoinBytes); + } + else + { + for(int j = 0; j<SABER_N/4; j++) + { + s[i][4*j] = (short) ((((buf[j + i * engine.PolyCoinBytes]) & 0x03) ^ 2) - 2); + s[i][4*j+1] = (short) ((((buf[j + i * engine.PolyCoinBytes] >> 2) & 0x03) ^ 2) - 2); + s[i][4*j+2] = (short) ((((buf[j + i * engine.PolyCoinBytes] >> 4) & 0x03) ^ 2) - 2); + s[i][4*j+3] = (short) ((((buf[j + i * engine.PolyCoinBytes] >> 6) & 0x03) ^ 2) - 2); + } + } } } diff --git a/crypto/src/pqc/crypto/saber/SABEREngine.cs b/crypto/src/pqc/crypto/saber/SABEREngine.cs index c17efb123..e57c0a23f 100644 --- a/crypto/src/pqc/crypto/saber/SABEREngine.cs +++ b/crypto/src/pqc/crypto/saber/SABEREngine.cs @@ -10,7 +10,6 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber internal sealed class SaberEngine { // constant parameters - internal const int SABER_EQ = 13; internal const int SABER_EP = 10; internal const int SABER_N = 256; @@ -25,6 +24,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber private readonly int SABER_ET; private readonly int SABER_POLYCOINBYTES; + private readonly int SABER_EQ; private readonly int SABER_POLYBYTES; private readonly int SABER_POLYVECBYTES; private readonly int SABER_POLYCOMPRESSEDBYTES; @@ -41,9 +41,18 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber private int h1; private int h2; + private Symmetric symmetric; private SaberUtilities utils; private Poly poly; + private readonly bool usingAes; + private readonly bool usingEffectiveMasking; + + public bool UsingAes => usingAes; + public bool UsingEffectiveMasking => usingEffectiveMasking; + public Symmetric Symmetric => symmetric; + + public int EQ => SABER_EQ; public int N => SABER_N; public int EP => SABER_EP; @@ -89,10 +98,11 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber return SABER_SECRETKEYBYTES; } - internal SaberEngine(int l, int defaultKeySize) + internal SaberEngine(int l, int defaultKeySize, bool usingAes, bool usingEffectiveMasking) { this.defaultKeySize = defaultKeySize; - + this.usingAes = usingAes; + this.usingEffectiveMasking = usingEffectiveMasking; this.SABER_L = l; if (l == 2) { @@ -109,8 +119,25 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber this.SABER_MU = 6; this.SABER_ET = 6; } + if(usingAes) + { + symmetric = new Symmetric.AesSymmetric(); + } + else + { + symmetric = new Symmetric.ShakeSymmetric(); + } - this.SABER_POLYCOINBYTES = (SABER_MU * SABER_N / 8); + if(usingEffectiveMasking) + { + this.SABER_EQ = 12; + this.SABER_POLYCOINBYTES = (2 * SABER_N / 8); + } + else + { + this.SABER_EQ = 13; + this.SABER_POLYCOINBYTES = (SABER_MU * SABER_N / 8); + } this.SABER_POLYBYTES = (SABER_EQ * SABER_N / 8); this.SABER_POLYVECBYTES = (SABER_L * SABER_POLYBYTES); this.SABER_POLYCOMPRESSEDBYTES = (SABER_EP * SABER_N / 8); @@ -165,9 +192,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber random.NextBytes(seed_A); - IXof digest = new ShakeDigest(128); - digest.BlockUpdate(seed_A, 0, SABER_SEEDBYTES); - digest.OutputFinal(seed_A, 0, SABER_SEEDBYTES); + symmetric.Prf(seed_A, seed_A, SABER_SEEDBYTES, SABER_SEEDBYTES); random.NextBytes(seed_s); @@ -196,13 +221,12 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber int i; indcpa_kem_keypair(pk, sk, random); // sk[0:SABER_INDCPA_SECRETKEYBYTES-1] <-- sk for (i = 0; i < SABER_INDCPA_PUBLICKEYBYTES; i++) + { sk[i + SABER_INDCPA_SECRETKEYBYTES] = pk[i]; // sk[SABER_INDCPA_SECRETKEYBYTES:SABER_INDCPA_SECRETKEYBYTES+SABER_INDCPA_SECRETKEYBYTES-1] <-- pk - + } // Then hash(pk) is appended. - Sha3Digest digest = new Sha3Digest(256); - digest.BlockUpdate(pk, 0, SABER_INDCPA_PUBLICKEYBYTES); - digest.DoFinal(sk, SABER_SECRETKEYBYTES - 64); + symmetric.Hash_h(sk, pk, SABER_SECRETKEYBYTES - 64); // Remaining part of sk contains a pseudo-random number. byte[] nonce = new byte[SABER_KEYBYTES]; @@ -252,7 +276,6 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber } short[] mp = new short[SABER_N]; - ; short[] vp = new short[SABER_N]; byte[] seed_A = Arrays.CopyOfRange(pk, SABER_POLYVECCOMPRESSEDBYTES, pk.Length); @@ -290,35 +313,30 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber byte[] nonce = new byte[32]; random.NextBytes(nonce); - Sha3Digest digest_256 = new Sha3Digest(256); - Sha3Digest digest_512 = new Sha3Digest(512); + // BUF[0:31] <-- random message (will be used as the key for client) Note: hash doesnot release system RNG output - digest_256.BlockUpdate(nonce, 0, 32); - digest_256.DoFinal(nonce, 0); + symmetric.Hash_h(nonce, nonce, 0); + Array.Copy(nonce, 0, buf, 0, 32); // BUF[32:63] <-- Hash(public key); Multitarget countermeasure for coins + contributory KEM - digest_256.BlockUpdate(pk, 0, SABER_INDCPA_PUBLICKEYBYTES); - digest_256.DoFinal(buf, 32); + symmetric.Hash_h(buf, pk, 32); // kr[0:63] <-- Hash(buf[0:63]); - digest_512.BlockUpdate(buf, 0, 64); - digest_512.DoFinal(kr, 0); + symmetric.Hash_g(kr, buf); // K^ <-- kr[0:31] // noiseseed (r) <-- kr[32:63]; // buf[0:31] contains message; kr[32:63] contains randomness r; indcpa_kem_enc(buf, Arrays.CopyOfRange(kr, 32, kr.Length), pk, c); - digest_256.BlockUpdate(c, 0, SABER_BYTES_CCA_DEC); - digest_256.DoFinal(kr, 32); + symmetric.Hash_h(kr, c, 32); // hash concatenation of pre-k and h(c) to k //todo support 128 and 192 bit keys byte[] temp_k = new byte[32]; - digest_256.BlockUpdate(kr, 0, 64); - digest_256.DoFinal(temp_k, 0); + symmetric.Hash_h(temp_k, kr, 0); Array.Copy(temp_k, 0, k, 0, defaultKeySize / 8); @@ -370,14 +388,12 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber // Multitarget countermeasure for coins + contributory KEM for (i = 0; i < 32; i++) // Save hash by storing h(pk) in sk + { buf[32 + i] = sk[SABER_SECRETKEYBYTES - 64 + i]; + } - Sha3Digest digest_256 = new Sha3Digest(256); - Sha3Digest digest_512 = new Sha3Digest(512); - - digest_512.BlockUpdate(buf, 0, 64); - digest_512.DoFinal(kr, 0); + symmetric.Hash_g(kr, buf); indcpa_kem_enc(buf, Arrays.CopyOfRange(kr, 32, kr.Length), pk, cmp); @@ -385,16 +401,14 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber // overwrite coins in kr with h(c) - digest_256.BlockUpdate(c, 0, SABER_BYTES_CCA_DEC); - digest_256.DoFinal(kr, 32); - + symmetric.Hash_h(kr, c, 32); + cmov(kr, sk, SABER_SECRETKEYBYTES - SABER_KEYBYTES, SABER_KEYBYTES, (byte) fail); // hash concatenation of pre-k and h(c) to k //todo support 128 and 192 bit keys byte[] temp_k = new byte[32]; - digest_256.BlockUpdate(kr, 0, 64); - digest_256.DoFinal(temp_k, 0); + symmetric.Hash_h(temp_k, kr, 0); Array.Copy(temp_k, 0, k, 0, defaultKeySize / 8); return 0; diff --git a/crypto/src/pqc/crypto/saber/SABERParameters.cs b/crypto/src/pqc/crypto/saber/SABERParameters.cs index 8cc9b468c..e2992d4c4 100644 --- a/crypto/src/pqc/crypto/saber/SABERParameters.cs +++ b/crypto/src/pqc/crypto/saber/SABERParameters.cs @@ -5,29 +5,42 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber public sealed class SaberParameters : ICipherParameters { - public static SaberParameters lightsaberkem128r3 = new SaberParameters("lightsaberkem128r3", 2, 128); - public static SaberParameters saberkem128r3 = new SaberParameters("saberkem128r3", 3, 128); - public static SaberParameters firesaberkem128r3 = new SaberParameters("firesaberkem128r3", 4, 128); + public static SaberParameters lightsaberkem128r3 = new SaberParameters("lightsaberkem128r3", 2, 128, false, false); + public static SaberParameters saberkem128r3 = new SaberParameters("saberkem128r3", 3, 128, false, false); + public static SaberParameters firesaberkem128r3 = new SaberParameters("firesaberkem128r3", 4, 128, false, false); - public static SaberParameters lightsaberkem192r3 = new SaberParameters("lightsaberkem192r3", 2, 192); - public static SaberParameters saberkem192r3 = new SaberParameters("saberkem192r3", 3, 192); - public static SaberParameters firesaberkem192r3 = new SaberParameters("firesaberkem192r3", 4, 192); + public static SaberParameters lightsaberkem192r3 = new SaberParameters("lightsaberkem192r3", 2, 192, false, false); + public static SaberParameters saberkem192r3 = new SaberParameters("saberkem192r3", 3, 192, false, false); + public static SaberParameters firesaberkem192r3 = new SaberParameters("firesaberkem192r3", 4, 192, false, false); + + public static SaberParameters lightsaberkem256r3 = new SaberParameters("lightsaberkem256r3", 2, 256, false, false); + public static SaberParameters saberkem256r3 = new SaberParameters("saberkem256r3", 3, 256, false, false); + public static SaberParameters firesaberkem256r3 = new SaberParameters("firesaberkem256r3", 4, 256, false, false); + + public static SaberParameters lightsaberkem90sr3 = new SaberParameters("lightsaberkem90sr3", 2, 256, true, false); + public static SaberParameters saberkem90sr3 = new SaberParameters("saberkem90sr3", 3, 256, true, false); + public static SaberParameters firesaberkem90sr3 = new SaberParameters("firesaberkem90sr3", 4, 256, true, false); + + public static SaberParameters ulightsaberkemr3 = new SaberParameters("ulightsaberkemr3", 2, 256, false, true); + public static SaberParameters usaberkemr3 = new SaberParameters("usaberkemr3", 3, 256, false, true); + public static SaberParameters ufiresaberkemr3 = new SaberParameters("ufiresaberkemr3", 4, 256, false, true); + + public static SaberParameters ulightsaberkem90sr3 = new SaberParameters("ulightsaberkem90sr3", 2, 256, true, true); + public static SaberParameters usaberkem90sr3 = new SaberParameters("usaberkem90sr3", 3, 256, true, true); + public static SaberParameters ufiresaberkem90sr3 = new SaberParameters("ufiresaberkem90sr3", 4, 256, true, true); - public static SaberParameters lightsaberkem256r3 = new SaberParameters("lightsaberkem256r3", 2, 256); - public static SaberParameters saberkem256r3 = new SaberParameters("saberkem256r3", 3, 256); - public static SaberParameters firesaberkem256r3 = new SaberParameters("firesaberkem256r3", 4, 256); private readonly string name; private readonly int l; private readonly int defaultKeySize; private readonly SaberEngine engine; - private SaberParameters(string name, int l, int defaultKeySize) + private SaberParameters(string name, int l, int defaultKeySize, bool usingAes, bool usingEffectiveMasking) { this.name = name; this.l = l; this.defaultKeySize = defaultKeySize; - this.engine = new SaberEngine(l, defaultKeySize); + this.engine = new SaberEngine(l, defaultKeySize, usingAes, usingEffectiveMasking); } public string Name => name; diff --git a/crypto/src/pqc/crypto/saber/SaberUtilities.cs b/crypto/src/pqc/crypto/saber/SaberUtilities.cs index d25eb8d2d..90c2b4ea4 100644 --- a/crypto/src/pqc/crypto/saber/SaberUtilities.cs +++ b/crypto/src/pqc/crypto/saber/SaberUtilities.cs @@ -8,7 +8,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber private readonly int SABER_POLYBYTES; private readonly int SABER_EP; private readonly int SABER_KEYBYTES; - + private readonly bool usingEffectiveMasking; internal SaberUtilities(SaberEngine engine) { this.SABER_N = engine.N; @@ -17,6 +17,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber this.SABER_POLYBYTES = engine.PolyBytes; this.SABER_EP = engine.EP; this.SABER_KEYBYTES = engine.KeyBytes; + this.usingEffectiveMasking = engine.UsingEffectiveMasking; } public void POLT2BS(byte[] bytes, int byteIndex, short[] data) @@ -117,60 +118,87 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber private void POLq2BS(byte[] bytes, int byteIndex, short[] data) { short j, offset_byte, offset_data; - for (j = 0; j < SABER_N / 8; j++) + if (!usingEffectiveMasking) { - offset_byte = (short) (13 * j); - offset_data = (short) (8 * j); - bytes[byteIndex + offset_byte + 0] = (byte) (data[offset_data + 0] & (0xff)); - bytes[byteIndex + offset_byte + 1] = - (byte) (((data[offset_data + 0] >> 8) & 0x1f) | ((data[offset_data + 1] & 0x07) << 5)); - bytes[byteIndex + offset_byte + 2] = (byte) ((data[offset_data + 1] >> 3) & 0xff); - bytes[byteIndex + offset_byte + 3] = - (byte) (((data[offset_data + 1] >> 11) & 0x03) | ((data[offset_data + 2] & 0x3f) << 2)); - bytes[byteIndex + offset_byte + 4] = - (byte) (((data[offset_data + 2] >> 6) & 0x7f) | ((data[offset_data + 3] & 0x01) << 7)); - bytes[byteIndex + offset_byte + 5] = (byte) ((data[offset_data + 3] >> 1) & 0xff); - bytes[byteIndex + offset_byte + 6] = - (byte) (((data[offset_data + 3] >> 9) & 0x0f) | ((data[offset_data + 4] & 0x0f) << 4)); - bytes[byteIndex + offset_byte + 7] = (byte) ((data[offset_data + 4] >> 4) & 0xff); - bytes[byteIndex + offset_byte + 8] = - (byte) (((data[offset_data + 4] >> 12) & 0x01) | ((data[offset_data + 5] & 0x7f) << 1)); - bytes[byteIndex + offset_byte + 9] = - (byte) (((data[offset_data + 5] >> 7) & 0x3f) | ((data[offset_data + 6] & 0x03) << 6)); - bytes[byteIndex + offset_byte + 10] = (byte) ((data[offset_data + 6] >> 2) & 0xff); - bytes[byteIndex + offset_byte + 11] = - (byte) (((data[offset_data + 6] >> 10) & 0x07) | ((data[offset_data + 7] & 0x1f) << 3)); - bytes[byteIndex + offset_byte + 12] = (byte) ((data[offset_data + 7] >> 5) & 0xff); + for (j = 0; j < SABER_N / 8; j++) + { + offset_byte = (short)(13 * j); + offset_data = (short)(8 * j); + bytes[byteIndex + offset_byte + 0] = (byte)(data[offset_data + 0] & (0xff)); + bytes[byteIndex + offset_byte + 1] = + (byte)(((data[offset_data + 0] >> 8) & 0x1f) | ((data[offset_data + 1] & 0x07) << 5)); + bytes[byteIndex + offset_byte + 2] = (byte)((data[offset_data + 1] >> 3) & 0xff); + bytes[byteIndex + offset_byte + 3] = + (byte)(((data[offset_data + 1] >> 11) & 0x03) | ((data[offset_data + 2] & 0x3f) << 2)); + bytes[byteIndex + offset_byte + 4] = + (byte)(((data[offset_data + 2] >> 6) & 0x7f) | ((data[offset_data + 3] & 0x01) << 7)); + bytes[byteIndex + offset_byte + 5] = (byte)((data[offset_data + 3] >> 1) & 0xff); + bytes[byteIndex + offset_byte + 6] = + (byte)(((data[offset_data + 3] >> 9) & 0x0f) | ((data[offset_data + 4] & 0x0f) << 4)); + bytes[byteIndex + offset_byte + 7] = (byte)((data[offset_data + 4] >> 4) & 0xff); + bytes[byteIndex + offset_byte + 8] = + (byte)(((data[offset_data + 4] >> 12) & 0x01) | ((data[offset_data + 5] & 0x7f) << 1)); + bytes[byteIndex + offset_byte + 9] = + (byte)(((data[offset_data + 5] >> 7) & 0x3f) | ((data[offset_data + 6] & 0x03) << 6)); + bytes[byteIndex + offset_byte + 10] = (byte)((data[offset_data + 6] >> 2) & 0xff); + bytes[byteIndex + offset_byte + 11] = + (byte)(((data[offset_data + 6] >> 10) & 0x07) | ((data[offset_data + 7] & 0x1f) << 3)); + bytes[byteIndex + offset_byte + 12] = (byte)((data[offset_data + 7] >> 5) & 0xff); + } + } + else + { + for (j = 0; j < SABER_N / 2; j++) + { + offset_byte = (short) (3 * j); + offset_data = (short) (2 * j); + bytes[byteIndex + offset_byte + 0] = (byte) (data[offset_data + 0] & (0xff)); + bytes[byteIndex + offset_byte + 1] = (byte) (((data[offset_data + 0] >> 8) & 0xf) | ((data[offset_data + 1] & 0xf) << 4)); + bytes[byteIndex + offset_byte + 2] = (byte) ((data[offset_data + 1] >> 4) & 0xff); + } } } private void BS2POLq(byte[] bytes, int byteIndex, short[] data) { short j, offset_byte, offset_data; - for (j = 0; j < SABER_N / 8; j++) + if (!usingEffectiveMasking) { - offset_byte = (short) (13 * j); - offset_data = (short) (8 * j); - data[offset_data + 0] = (short) ((bytes[byteIndex + offset_byte + 0] & (0xff)) | - ((bytes[byteIndex + offset_byte + 1] & 0x1f) << 8)); - data[offset_data + 1] = (short) ((bytes[byteIndex + offset_byte + 1] >> 5 & (0x07)) | - ((bytes[byteIndex + offset_byte + 2] & 0xff) << 3) | - ((bytes[byteIndex + offset_byte + 3] & 0x03) << 11)); - data[offset_data + 2] = (short) ((bytes[byteIndex + offset_byte + 3] >> 2 & (0x3f)) | - ((bytes[byteIndex + offset_byte + 4] & 0x7f) << 6)); - data[offset_data + 3] = (short) ((bytes[byteIndex + offset_byte + 4] >> 7 & (0x01)) | - ((bytes[byteIndex + offset_byte + 5] & 0xff) << 1) | - ((bytes[byteIndex + offset_byte + 6] & 0x0f) << 9)); - data[offset_data + 4] = (short) ((bytes[byteIndex + offset_byte + 6] >> 4 & (0x0f)) | - ((bytes[byteIndex + offset_byte + 7] & 0xff) << 4) | - ((bytes[byteIndex + offset_byte + 8] & 0x01) << 12)); - data[offset_data + 5] = (short) ((bytes[byteIndex + offset_byte + 8] >> 1 & (0x7f)) | - ((bytes[byteIndex + offset_byte + 9] & 0x3f) << 7)); - data[offset_data + 6] = (short) ((bytes[byteIndex + offset_byte + 9] >> 6 & (0x03)) | - ((bytes[byteIndex + offset_byte + 10] & 0xff) << 2) | - ((bytes[byteIndex + offset_byte + 11] & 0x07) << 10)); - data[offset_data + 7] = (short) ((bytes[byteIndex + offset_byte + 11] >> 3 & (0x1f)) | - ((bytes[byteIndex + offset_byte + 12] & 0xff) << 5)); + for (j = 0; j < SABER_N / 8; j++) + { + offset_byte = (short)(13 * j); + offset_data = (short)(8 * j); + data[offset_data + 0] = (short)((bytes[byteIndex + offset_byte + 0] & (0xff)) | + ((bytes[byteIndex + offset_byte + 1] & 0x1f) << 8)); + data[offset_data + 1] = (short)((bytes[byteIndex + offset_byte + 1] >> 5 & (0x07)) | + ((bytes[byteIndex + offset_byte + 2] & 0xff) << 3) | + ((bytes[byteIndex + offset_byte + 3] & 0x03) << 11)); + data[offset_data + 2] = (short)((bytes[byteIndex + offset_byte + 3] >> 2 & (0x3f)) | + ((bytes[byteIndex + offset_byte + 4] & 0x7f) << 6)); + data[offset_data + 3] = (short)((bytes[byteIndex + offset_byte + 4] >> 7 & (0x01)) | + ((bytes[byteIndex + offset_byte + 5] & 0xff) << 1) | + ((bytes[byteIndex + offset_byte + 6] & 0x0f) << 9)); + data[offset_data + 4] = (short)((bytes[byteIndex + offset_byte + 6] >> 4 & (0x0f)) | + ((bytes[byteIndex + offset_byte + 7] & 0xff) << 4) | + ((bytes[byteIndex + offset_byte + 8] & 0x01) << 12)); + data[offset_data + 5] = (short)((bytes[byteIndex + offset_byte + 8] >> 1 & (0x7f)) | + ((bytes[byteIndex + offset_byte + 9] & 0x3f) << 7)); + data[offset_data + 6] = (short)((bytes[byteIndex + offset_byte + 9] >> 6 & (0x03)) | + ((bytes[byteIndex + offset_byte + 10] & 0xff) << 2) | + ((bytes[byteIndex + offset_byte + 11] & 0x07) << 10)); + data[offset_data + 7] = (short)((bytes[byteIndex + offset_byte + 11] >> 3 & (0x1f)) | + ((bytes[byteIndex + offset_byte + 12] & 0xff) << 5)); + } + } + else + { + for (j = 0; j < SABER_N / 2; j++) + { + offset_byte = (short) (3 * j); + offset_data = (short) (2 * j); + data[offset_data + 0] = (short) ((bytes[byteIndex + offset_byte + 0] & (0xff)) | ((bytes[byteIndex + offset_byte + 1] & 0xf) << 8)); + data[offset_data + 1] = (short) ((bytes[byteIndex + offset_byte + 1] >> 4 & (0xf)) | ((bytes[byteIndex + offset_byte + 2] & 0xff) << 4)); + } } } diff --git a/crypto/src/pqc/crypto/saber/Symmetric.cs b/crypto/src/pqc/crypto/saber/Symmetric.cs new file mode 100644 index 000000000..dc47b87bb --- /dev/null +++ b/crypto/src/pqc/crypto/saber/Symmetric.cs @@ -0,0 +1,96 @@ +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Pqc.Crypto.Saber; + +public abstract class Symmetric +{ + + internal abstract void Hash_h(byte[] output, byte[] input, int outputOffset); + + internal abstract void Hash_g(byte[] output, byte[] input); + + internal abstract void Prf(byte[] output, byte[] input, int inLen, int outputLen); + + protected internal class ShakeSymmetric + : Symmetric + { + + private readonly Sha3Digest sha3Digest256; + private readonly Sha3Digest sha3Digest512; + private readonly IXof shakeDigest; + + internal ShakeSymmetric() + { + shakeDigest = new ShakeDigest(128); + sha3Digest256 = new Sha3Digest(256); + sha3Digest512 = new Sha3Digest(512); + } + + internal override void Hash_h(byte[] output, byte[] input, int outputOffset) + { + sha3Digest256.BlockUpdate(input, 0, input.Length); + sha3Digest256.DoFinal(output, outputOffset); + } + + internal override void Hash_g(byte[] output, byte[] input) + { + sha3Digest512.BlockUpdate(input, 0, input.Length); + sha3Digest512.DoFinal(output, 0); + } + + internal override void Prf(byte[] output, byte[] input, int inLen, int outputLen) + { + shakeDigest.Reset(); + shakeDigest.BlockUpdate(input, 0, inLen); + shakeDigest.OutputFinal(output, 0, outputLen); + } + + + } + internal class AesSymmetric + : Symmetric + { + + private readonly Sha256Digest sha256Digest; + private readonly Sha512Digest sha512Digest; + + private readonly SicBlockCipher cipher; + + + protected internal AesSymmetric() + { + sha256Digest = new Sha256Digest(); + sha512Digest = new Sha512Digest(); + cipher = new SicBlockCipher(AesUtilities.CreateEngine()); + } + + internal override void Hash_h(byte[] output, byte[] input, int outputOffset) + { + sha256Digest.BlockUpdate(input, 0, input.Length); + sha256Digest.DoFinal(output, outputOffset); + } + + internal override void Hash_g(byte[] output, byte[] input) + { + sha512Digest.BlockUpdate(input, 0, input.Length); + sha512Digest.DoFinal(output, 0); + } + + internal override void Prf(byte[] output, byte[] input, int inLen, int outputLen) + { + ParametersWithIV kp = new ParametersWithIV(new KeyParameter(input, 0, inLen), new byte[16]); + cipher.Init(true, kp); + byte[] buf = new byte[outputLen]; // TODO: there might be a more efficient way of doing this... + for (int i = 0; i < outputLen; i+= 16) + { + cipher.ProcessBlock(buf, i, output, i); + } + } + + + } + +} \ No newline at end of file diff --git a/crypto/src/pqc/crypto/utils/PqcUtilities.cs b/crypto/src/pqc/crypto/utils/PqcUtilities.cs index ac9415b06..1f1da5e74 100644 --- a/crypto/src/pqc/crypto/utils/PqcUtilities.cs +++ b/crypto/src/pqc/crypto/utils/PqcUtilities.cs @@ -78,7 +78,16 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities saberOids[SaberParameters.lightsaberkem256r3] = BCObjectIdentifiers.lightsaberkem256r3; saberOids[SaberParameters.saberkem256r3] = BCObjectIdentifiers.saberkem256r3; saberOids[SaberParameters.firesaberkem256r3] = BCObjectIdentifiers.firesaberkem256r3; - + saberOids[SaberParameters.ulightsaberkemr3] = BCObjectIdentifiers.ulightsaberkemr3; + saberOids[SaberParameters.usaberkemr3] = BCObjectIdentifiers.usaberkemr3; + saberOids[SaberParameters.ufiresaberkemr3] = BCObjectIdentifiers.ufiresaberkemr3; + saberOids[SaberParameters.lightsaberkem90sr3] = BCObjectIdentifiers.lightsaberkem90sr3; + saberOids[SaberParameters.saberkem90sr3] = BCObjectIdentifiers.saberkem90sr3; + saberOids[SaberParameters.firesaberkem90sr3] = BCObjectIdentifiers.firesaberkem90sr3; + saberOids[SaberParameters.ulightsaberkem90sr3] = BCObjectIdentifiers.ulightsaberkem90sr3; + saberOids[SaberParameters.usaberkem90sr3] = BCObjectIdentifiers.usaberkem90sr3; + saberOids[SaberParameters.ufiresaberkem90sr3] = BCObjectIdentifiers.ufiresaberkem90sr3; + saberParams[BCObjectIdentifiers.lightsaberkem128r3] = SaberParameters.lightsaberkem128r3; saberParams[BCObjectIdentifiers.saberkem128r3] = SaberParameters.saberkem128r3; saberParams[BCObjectIdentifiers.firesaberkem128r3] = SaberParameters.firesaberkem128r3; @@ -88,7 +97,15 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities saberParams[BCObjectIdentifiers.lightsaberkem256r3] = SaberParameters.lightsaberkem256r3; saberParams[BCObjectIdentifiers.saberkem256r3] = SaberParameters.saberkem256r3; saberParams[BCObjectIdentifiers.firesaberkem256r3] = SaberParameters.firesaberkem256r3; - + saberParams[BCObjectIdentifiers.ulightsaberkemr3] = SaberParameters.ulightsaberkemr3; + saberParams[BCObjectIdentifiers.usaberkemr3] = SaberParameters.usaberkemr3; + saberParams[BCObjectIdentifiers.ufiresaberkemr3] = SaberParameters.ufiresaberkemr3; + saberParams[BCObjectIdentifiers.lightsaberkem90sr3] = SaberParameters.lightsaberkem90sr3; + saberParams[BCObjectIdentifiers.saberkem90sr3] = SaberParameters.saberkem90sr3; + saberParams[BCObjectIdentifiers.firesaberkem90sr3] = SaberParameters.firesaberkem90sr3; + saberParams[BCObjectIdentifiers.ulightsaberkem90sr3] = SaberParameters.ulightsaberkem90sr3; + saberParams[BCObjectIdentifiers.usaberkem90sr3] = SaberParameters.usaberkem90sr3; + saberParams[BCObjectIdentifiers.ufiresaberkem90sr3] = SaberParameters.ufiresaberkem90sr3; picnicOids[PicnicParameters.picnicl1fs] = BCObjectIdentifiers.picnicl1fs; picnicOids[PicnicParameters.picnicl1ur] = BCObjectIdentifiers.picnicl1ur; diff --git a/crypto/src/pqc/crypto/utils/PublicKeyFactory.cs b/crypto/src/pqc/crypto/utils/PublicKeyFactory.cs index 07df84ca1..bb33a3aa3 100644 --- a/crypto/src/pqc/crypto/utils/PublicKeyFactory.cs +++ b/crypto/src/pqc/crypto/utils/PublicKeyFactory.cs @@ -53,6 +53,15 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities converters[BCObjectIdentifiers.lightsaberkem256r3] = new SaberConverter(); converters[BCObjectIdentifiers.saberkem256r3] = new SaberConverter(); converters[BCObjectIdentifiers.firesaberkem256r3] = new SaberConverter(); + converters[BCObjectIdentifiers.ulightsaberkemr3] = new SaberConverter(); + converters[BCObjectIdentifiers.usaberkemr3] = new SaberConverter(); + converters[BCObjectIdentifiers.ufiresaberkemr3] = new SaberConverter(); + converters[BCObjectIdentifiers.lightsaberkem90sr3] = new SaberConverter(); + converters[BCObjectIdentifiers.saberkem90sr3] = new SaberConverter(); + converters[BCObjectIdentifiers.firesaberkem90sr3] = new SaberConverter(); + converters[BCObjectIdentifiers.ulightsaberkem90sr3] = new SaberConverter(); + converters[BCObjectIdentifiers.usaberkem90sr3] = new SaberConverter(); + converters[BCObjectIdentifiers.ufiresaberkem90sr3] = new SaberConverter(); converters[BCObjectIdentifiers.picnic] = new PicnicConverter(); converters[BCObjectIdentifiers.picnicl1fs] = new PicnicConverter(); |