From 3dd71ff81c11b01950779fbc849dbf43cc809afd Mon Sep 17 00:00:00 2001 From: Roy Basmacier Date: Thu, 23 Jun 2022 16:53:09 -0400 Subject: sphincs plus v3.1 --- crypto/src/pqc/crypto/sphincsplus/Adrs.cs | 11 +- crypto/src/pqc/crypto/sphincsplus/Fors.cs | 24 ++- crypto/src/pqc/crypto/sphincsplus/HT.cs | 13 +- .../pqc/crypto/sphincsplus/SPHINCSPlusEngine.cs | 181 ++++++++++------ .../crypto/sphincsplus/SPHINCSPlusParameters.cs | 230 ++++++++++----------- .../pqc/crypto/sphincsplus/SPHINCSPlusSigner.cs | 10 +- crypto/src/pqc/crypto/sphincsplus/WotsPlus.cs | 14 ++ 7 files changed, 298 insertions(+), 185 deletions(-) (limited to 'crypto/src') diff --git a/crypto/src/pqc/crypto/sphincsplus/Adrs.cs b/crypto/src/pqc/crypto/sphincsplus/Adrs.cs index a500d5375..80f2e7159 100644 --- a/crypto/src/pqc/crypto/sphincsplus/Adrs.cs +++ b/crypto/src/pqc/crypto/sphincsplus/Adrs.cs @@ -12,7 +12,9 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus public static uint WOTS_PK = 1; public static uint TREE = 2; public static uint FORS_TREE = 3; - public static uint FORS_ROOTS = 4; + public static uint FORS_PK = 4; + public static uint WOTS_PRF = 5; + public static uint FORS_PRF = 6; internal static int OFFSET_LAYER = 0; internal static int OFFSET_TREE = 4; @@ -82,7 +84,12 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus Arrays.Fill(value, 20, value.Length, (byte) 0); } - + + public void ChangeType(uint type) + { + Pack.UInt32_To_BE(type, value, OFFSET_TYPE); + } + public uint GetType() { return Pack.BE_To_UInt32(value, OFFSET_TYPE); diff --git a/crypto/src/pqc/crypto/sphincsplus/Fors.cs b/crypto/src/pqc/crypto/sphincsplus/Fors.cs index 30ae2fcff..164a6e9f0 100644 --- a/crypto/src/pqc/crypto/sphincsplus/Fors.cs +++ b/crypto/src/pqc/crypto/sphincsplus/Fors.cs @@ -17,7 +17,6 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus // Output: n-byte root node - top node on Stack byte[] TreeHash(byte[] skSeed, uint s, int z, byte[] pkSeed, Adrs adrsParam) { - Adrs adrs = new Adrs(adrsParam); IList stack = Platform.CreateArrayList(); @@ -26,16 +25,22 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus return null; } + Adrs adrs = new Adrs(adrsParam); + for (uint idx = 0; idx < (1 << z); idx++) { + adrs.SetType(Adrs.FORS_PRF); + adrs.SetKeyPairAddress(adrsParam.GetKeyPairAddress()); adrs.SetTreeHeight(0); adrs.SetTreeIndex(s + idx); byte[] sk = engine.PRF(pkSeed, skSeed, adrs); - byte[] node = engine.F(pkSeed, adrs, sk); + + adrs.ChangeType(Adrs.FORS_TREE); + byte[] node = engine.F(pkSeed, adrs, sk); + adrs.SetTreeHeight(1); - adrs.SetTreeIndex(s + idx); // while ( Top node on Stack has same height as node ) while (stack.Count != 0 @@ -56,8 +61,9 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus return ((NodeEntry) stack[0]).nodeValue; } - public SIG_FORS[] Sign(byte[] md, byte[] skSeed, byte[] pkSeed, Adrs adrs) + public SIG_FORS[] Sign(byte[] md, byte[] skSeed, byte[] pkSeed, Adrs paramAdrs) { + Adrs adrs = new Adrs(paramAdrs); uint[] idxs = MessageToIdxs(md, engine.K, engine.A); SIG_FORS[] sig_fors = new SIG_FORS[engine.K]; // compute signature elements @@ -67,10 +73,16 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus // get next index uint idx = idxs[i]; // pick private key element - + + adrs.SetType(Adrs.FORS_PRF); + adrs.SetKeyPairAddress(paramAdrs.GetKeyPairAddress()); adrs.SetTreeHeight(0); adrs.SetTreeIndex((uint) (i * t + idx)); + byte[] sk = engine.PRF(pkSeed, skSeed, adrs); + + adrs.ChangeType(Adrs.FORS_TREE); + byte[][] authPath = new byte[engine.A][]; // compute auth path for (int j = 0; j < engine.A; j++) @@ -127,7 +139,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus } Adrs forspkAdrs = new Adrs(adrs); // copy address to create FTS public key address - forspkAdrs.SetType(Adrs.FORS_ROOTS); + forspkAdrs.SetType(Adrs.FORS_PK); forspkAdrs.SetKeyPairAddress(adrs.GetKeyPairAddress()); return engine.T_l(pkSeed, forspkAdrs, Arrays.ConcatenateAll(root)); } diff --git a/crypto/src/pqc/crypto/sphincsplus/HT.cs b/crypto/src/pqc/crypto/sphincsplus/HT.cs index 37469f8a9..765fb8d4a 100644 --- a/crypto/src/pqc/crypto/sphincsplus/HT.cs +++ b/crypto/src/pqc/crypto/sphincsplus/HT.cs @@ -121,9 +121,16 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus // # Input: n-byte message M, secret seed SK.seed, index idx, public seed PK.seed, // address Adrs // # Output: XMSS signature SIG_XMSS = (sig || AUTH) - SIG_XMSS xmss_sign(byte[] M, byte[] skSeed, uint idx, byte[] pkSeed, Adrs adrs) + SIG_XMSS xmss_sign(byte[] M, byte[] skSeed, uint idx, byte[] pkSeed, Adrs paramAdrs) { byte[][] AUTH = new byte[engine.H_PRIME][]; + + Adrs adrs = new Adrs(paramAdrs); + + adrs.SetType(Adrs.TREE); + adrs.SetLayerAddress(paramAdrs.GetLayerAddress()); + adrs.SetTreeAddress(paramAdrs.GetTreeAddress()); + // build authentication path for (int j = 0; j < engine.H_PRIME; j++) @@ -132,8 +139,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus AUTH[j] = TreeHash(skSeed, k * (uint) (1 << j), (uint)j, pkSeed, adrs); } - adrs = new Adrs(adrs); - adrs.SetType(Adrs.WOTS_HASH); + adrs = new Adrs(paramAdrs); + adrs.SetType(Adrs.WOTS_PK); adrs.SetKeyPairAddress(idx); byte[] sig = wots.Sign(M, skSeed, pkSeed, adrs); diff --git a/crypto/src/pqc/crypto/sphincsplus/SPHINCSPlusEngine.cs b/crypto/src/pqc/crypto/sphincsplus/SPHINCSPlusEngine.cs index 09546c383..56f3cda48 100644 --- a/crypto/src/pqc/crypto/sphincsplus/SPHINCSPlusEngine.cs +++ b/crypto/src/pqc/crypto/sphincsplus/SPHINCSPlusEngine.cs @@ -1,5 +1,6 @@ using System; +using System.Security.Cryptography; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Digests; using Org.BouncyCastle.Crypto.Generators; @@ -113,36 +114,44 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus public abstract byte[] PRF_msg(byte[] prf, byte[] randomiser, byte[] message); - internal class Sha256Engine + internal class Sha2Engine : SPHINCSPlusEngine { - private byte[] padding = new byte[64]; + private byte[] padding = new byte[128]; private IDigest treeDigest; - private byte[] digestBuf; private HMac treeHMac; private Mgf1BytesGenerator mgf1; private byte[] hmacBuf; private IDigest msgDigest; + private byte[] msgDigestBuf; + private int bl; + private IDigest sha256; + private byte[] sha256Buf; - public Sha256Engine(bool robust, int n, uint w, uint d, int a, int k, uint h) + public Sha2Engine(bool robust, int n, uint w, uint d, int a, int k, uint h) : base(robust, n, w, d, a, k, h) { + sha256 = new Sha256Digest(); + sha256Buf = new byte[sha256.GetDigestSize()]; + this.treeDigest = new Sha256Digest(); - if (n == 32) - { - this.msgDigest = new Sha512Digest(); - this.treeHMac = new HMac(new Sha512Digest()); - this.mgf1 = new Mgf1BytesGenerator(new Sha512Digest()); - } - else + if (n == 16) { this.msgDigest = new Sha256Digest(); this.treeHMac = new HMac(new Sha256Digest()); this.mgf1 = new Mgf1BytesGenerator(new Sha256Digest()); + this.bl = 64; + } + else + { + this.msgDigest = new Sha512Digest(); + this.treeHMac = new HMac(new Sha512Digest()); + this.mgf1 = new Mgf1BytesGenerator(new Sha512Digest()); + this.bl = 128; } - this.digestBuf = new byte[treeDigest.GetDigestSize()]; this.hmacBuf = new byte[treeHMac.GetMacSize()]; + this.msgDigestBuf = new byte[msgDigest.GetDigestSize()]; } @@ -155,32 +164,39 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus m1 = Bitmask256(Arrays.Concatenate(pkSeed, compressedAdrs), m1); } - treeDigest.BlockUpdate(pkSeed, 0, pkSeed.Length); - treeDigest.BlockUpdate(padding, 0, 64 - pkSeed.Length); // toByte(0, 64 - n) - treeDigest.BlockUpdate(compressedAdrs, 0, compressedAdrs.Length); - treeDigest.BlockUpdate(m1, 0, m1.Length); - treeDigest.DoFinal(digestBuf, 0); + sha256.BlockUpdate(pkSeed, 0, pkSeed.Length); + sha256.BlockUpdate(padding, 0, 64 - pkSeed.Length); // toByte(0, 64 - n) + sha256.BlockUpdate(compressedAdrs, 0, compressedAdrs.Length); + sha256.BlockUpdate(m1, 0, m1.Length); + sha256.DoFinal(sha256Buf, 0); - return Arrays.CopyOfRange(digestBuf, 0, N); + return Arrays.CopyOfRange(sha256Buf, 0, N); } public override byte[] H(byte[] pkSeed, Adrs adrs, byte[] m1, byte[] m2) { - byte[] m1m2 = Arrays.Concatenate(m1, m2); byte[] compressedAdrs = CompressedAdrs(adrs); + + msgDigest.BlockUpdate(pkSeed, 0, pkSeed.Length); + msgDigest.BlockUpdate(padding, 0, bl - N); // toByte(0, 64 - n) + msgDigest.BlockUpdate(compressedAdrs, 0, compressedAdrs.Length); if (robust) { - m1m2 = Bitmask256(Arrays.Concatenate(pkSeed, compressedAdrs), m1m2); + byte[] m1m2 = Bitmask(Arrays.Concatenate(pkSeed, compressedAdrs), m1, m2); + msgDigest.BlockUpdate(m1m2, 0, m1m2.Length); + } + else + { + msgDigest.BlockUpdate(m1, 0, m1.Length); + msgDigest.BlockUpdate(m2, 0, m2.Length); } - treeDigest.BlockUpdate(pkSeed, 0, pkSeed.Length); - treeDigest.BlockUpdate(padding, 0, 64 - N); // toByte(0, 64 - n) - treeDigest.BlockUpdate(compressedAdrs, 0, compressedAdrs.Length); - treeDigest.BlockUpdate(m1m2, 0, m1m2.Length); - treeDigest.DoFinal(digestBuf, 0); + + + msgDigest.DoFinal(msgDigestBuf, 0); - return Arrays.CopyOfRange(digestBuf, 0, N); + return Arrays.CopyOfRange(msgDigestBuf, 0, N); } public override IndexedDigest H_msg(byte[] prf, byte[] pkSeed, byte[] pkRoot, byte[] message) @@ -226,33 +242,33 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus byte[] compressedAdrs = CompressedAdrs(adrs); if (robust) { - m = Bitmask256(Arrays.Concatenate(pkSeed, compressedAdrs), m); + m = Bitmask(Arrays.Concatenate(pkSeed, compressedAdrs), m); } - treeDigest.BlockUpdate(pkSeed, 0, pkSeed.Length); - treeDigest.BlockUpdate(padding, 0, 64 - N); // toByte(0, 64 - n) - treeDigest.BlockUpdate(compressedAdrs, 0, compressedAdrs.Length); - treeDigest.BlockUpdate(m, 0, m.Length); - treeDigest.DoFinal(digestBuf, 0); - return Arrays.CopyOfRange(digestBuf, 0, N); + msgDigest.BlockUpdate(pkSeed, 0, pkSeed.Length); + msgDigest.BlockUpdate(padding, 0, bl - N); // toByte(0, 64 - n) + msgDigest.BlockUpdate(compressedAdrs, 0, compressedAdrs.Length); + msgDigest.BlockUpdate(m, 0, m.Length); + msgDigest.DoFinal(msgDigestBuf, 0); + + return Arrays.CopyOfRange(msgDigestBuf, 0, N); } public override byte[] PRF(byte[] pkSeed, byte[] skSeed, Adrs adrs) { int n = skSeed.Length; - - // TODO: #UPDATE submission update announced 17/1/2022 - // treeDigest.Update(pkSeed, 0, pkSeed.Length); - // treeDigest.Update(padding, 0, 64 - pkSeed.Length); // toByte(0, 64 - n) - - treeDigest.BlockUpdate(skSeed, 0, skSeed.Length); + + sha256.BlockUpdate(pkSeed, 0, pkSeed.Length); + sha256.BlockUpdate(padding, 0, 64 - pkSeed.Length); // toByte(0, 64 - n) + byte[] compressedAdrs = CompressedAdrs(adrs); - treeDigest.BlockUpdate(compressedAdrs, 0, compressedAdrs.Length); - treeDigest.DoFinal(digestBuf, 0); + sha256.BlockUpdate(compressedAdrs, 0, compressedAdrs.Length); + sha256.BlockUpdate(skSeed, 0, skSeed.Length); + sha256.DoFinal(sha256Buf, 0); - return Arrays.CopyOfRange(digestBuf, 0, n); + return Arrays.CopyOfRange(sha256Buf, 0, n); } public override byte[] PRF_msg(byte[] prf, byte[] randomiser, byte[] message) @@ -275,7 +291,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus return rv; } - + protected byte[] Bitmask(byte[] key, byte[] m) { byte[] mask = new byte[m.Length]; @@ -292,6 +308,28 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus return mask; } + + protected byte[] Bitmask(byte[] key, byte[] m1, byte[] m2) + { + byte[] mask = new byte[m1.Length + m2.Length]; + + mgf1.Init(new MgfParameters(key)); + + mgf1.GenerateBytes(mask, 0, mask.Length); + + for (int i = 0; i < m1.Length; ++i) + { + mask[i] ^= m1[i]; + } + for (int i = 0; i < m2.Length; ++i) + { + mask[i + m1.Length] ^= m2[i]; + } + + + return mask; + } + protected byte[] Bitmask256(byte[] key, byte[] m) { byte[] mask = new byte[m.Length]; @@ -309,18 +347,21 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus return mask; } + } internal class Shake256Engine : SPHINCSPlusEngine { private IXof treeDigest; + private IXof maskDigest; public Shake256Engine(bool robust, int n, uint w, uint d, int a, int k, uint h) : base(robust, n, w, d, a, k, h) { this.treeDigest = new ShakeDigest(256); + this.maskDigest = new ShakeDigest(256); } public override byte[] F(byte[] pkSeed, Adrs adrs, byte[] m1) @@ -343,19 +384,22 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus public override byte[] H(byte[] pkSeed, Adrs adrs, byte[] m1, byte[] m2) { - byte[] m1m2 = Arrays.Concatenate(m1, m2); + byte[] rv = new byte[N]; + treeDigest.BlockUpdate(pkSeed, 0, pkSeed.Length); + treeDigest.BlockUpdate(adrs.value, 0, adrs.value.Length); if (robust) { - m1m2 = Bitmask(pkSeed, adrs, m1m2); - } - + byte[] m1m2 = Bitmask(pkSeed, adrs, m1, m2); - byte[] rv = new byte[N]; - - treeDigest.BlockUpdate(pkSeed, 0, pkSeed.Length); - treeDigest.BlockUpdate(adrs.value, 0, adrs.value.Length); - treeDigest.BlockUpdate(m1m2, 0, m1m2.Length); + treeDigest.BlockUpdate(m1m2, 0, m1m2.Length); + } + else + { + treeDigest.BlockUpdate(m1, 0, m1.Length); + treeDigest.BlockUpdate(m2, 0, m2.Length); + } + treeDigest.DoFinal(rv, 0, rv.Length); return rv; @@ -417,10 +461,10 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus public override byte[] PRF(byte[] pkSeed, byte[] skSeed, Adrs adrs) { - // TODO: #UPDATE submission update announced 17/1/2022 - //treeDigest.Update(pkSeed, 0, pkSeed.Length); - treeDigest.BlockUpdate(skSeed, 0, skSeed.Length); + treeDigest.BlockUpdate(pkSeed, 0, pkSeed.Length); treeDigest.BlockUpdate(adrs.value, 0, adrs.value.Length); + treeDigest.BlockUpdate(skSeed, 0, skSeed.Length); + byte[] prf = new byte[N]; treeDigest.DoFinal(prf, 0, N); return prf; @@ -440,10 +484,10 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus { byte[] mask = new byte[m.Length]; - treeDigest.BlockUpdate(pkSeed, 0, pkSeed.Length); - treeDigest.BlockUpdate(adrs.value, 0, adrs.value.Length); + maskDigest.BlockUpdate(pkSeed, 0, pkSeed.Length); + maskDigest.BlockUpdate(adrs.value, 0, adrs.value.Length); - treeDigest.DoFinal(mask, 0, mask.Length); + maskDigest.DoFinal(mask, 0, mask.Length); for (int i = 0; i < m.Length; ++i) { @@ -452,6 +496,27 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus return mask; } + protected byte[] Bitmask(byte[] pkSeed, Adrs adrs, byte[] m1, byte[] m2) + { + byte[] mask = new byte[m1.Length + m2.Length]; + + maskDigest.BlockUpdate(pkSeed, 0, pkSeed.Length); + maskDigest.BlockUpdate(adrs.value, 0, adrs.value.Length); + + maskDigest.DoFinal(mask, 0, mask.Length); + + for (int i = 0; i < m1.Length; ++i) + { + mask[i] ^= m1[i]; + } + for (int i = 0; i < m2.Length; ++i) + { + mask[i + m1.Length] ^= m2[i]; + } + + return mask; + } + } } } \ No newline at end of file diff --git a/crypto/src/pqc/crypto/sphincsplus/SPHINCSPlusParameters.cs b/crypto/src/pqc/crypto/sphincsplus/SPHINCSPlusParameters.cs index 5268dce78..b99df864f 100644 --- a/crypto/src/pqc/crypto/sphincsplus/SPHINCSPlusParameters.cs +++ b/crypto/src/pqc/crypto/sphincsplus/SPHINCSPlusParameters.cs @@ -6,168 +6,168 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus { public class SPHINCSPlusParameters { - public static SPHINCSPlusParameters sha256_128f = new SPHINCSPlusParameters("sha256-128f-robust", - new SPHINCSPlusEngine.Sha256Engine(true, 16, 16, 22, 6, 33, 66)); + public static SPHINCSPlusParameters sha2_128f = new SPHINCSPlusParameters("sha2-128f-robust", + new SPHINCSPlusEngine.Sha2Engine(true, 16, 16, 22, 6, 33, 66)); - public static SPHINCSPlusParameters sha256_128s = new SPHINCSPlusParameters("sha256-128s-robust", - new SPHINCSPlusEngine.Sha256Engine(true, 16, 16, 7, 12, 14, 63)); + public static SPHINCSPlusParameters sha2_128s = new SPHINCSPlusParameters("sha2-128s-robust", + new SPHINCSPlusEngine.Sha2Engine(true, 16, 16, 7, 12, 14, 63)); - public static SPHINCSPlusParameters sha256_192f = new SPHINCSPlusParameters("sha256-192f-robust", - new SPHINCSPlusEngine.Sha256Engine(true, 24, 16, 22, 8, 33, 66)); + public static SPHINCSPlusParameters sha2_192f = new SPHINCSPlusParameters("sha2-192f-robust", + new SPHINCSPlusEngine.Sha2Engine(true, 24, 16, 22, 8, 33, 66)); - public static SPHINCSPlusParameters sha256_192s = new SPHINCSPlusParameters("sha256-192s-robust", - new SPHINCSPlusEngine.Sha256Engine(true, 24, 16, 7, 14, 17, 63)); + public static SPHINCSPlusParameters sha2_192s = new SPHINCSPlusParameters("sha2-192s-robust", + new SPHINCSPlusEngine.Sha2Engine(true, 24, 16, 7, 14, 17, 63)); - public static SPHINCSPlusParameters sha256_256f = new SPHINCSPlusParameters("sha256-256f-robust", - new SPHINCSPlusEngine.Sha256Engine(true, 32, 16, 17, 9, 35, 68)); + public static SPHINCSPlusParameters sha2_256f = new SPHINCSPlusParameters("sha2-256f-robust", + new SPHINCSPlusEngine.Sha2Engine(true, 32, 16, 17, 9, 35, 68)); - public static SPHINCSPlusParameters sha256_256s = new SPHINCSPlusParameters("sha256-256s-robust", - new SPHINCSPlusEngine.Sha256Engine(true, 32, 16, 8, 14, 22, 64)); + public static SPHINCSPlusParameters sha2_256s = new SPHINCSPlusParameters("sha2-256s-robust", + new SPHINCSPlusEngine.Sha2Engine(true, 32, 16, 8, 14, 22, 64)); - public static SPHINCSPlusParameters sha256_128f_simple = new SPHINCSPlusParameters("sha256-128f-simple", - new SPHINCSPlusEngine.Sha256Engine(false, 16, 16, 22, 6, 33, 66)); + public static SPHINCSPlusParameters sha2_128f_simple = new SPHINCSPlusParameters("sha2-128f-simple", + new SPHINCSPlusEngine.Sha2Engine(false, 16, 16, 22, 6, 33, 66)); - public static SPHINCSPlusParameters sha256_128s_simple = new SPHINCSPlusParameters("sha256-128s-simple", - new SPHINCSPlusEngine.Sha256Engine(false, 16, 16, 7, 12, 14, 63)); + public static SPHINCSPlusParameters sha2_128s_simple = new SPHINCSPlusParameters("sha2-128s-simple", + new SPHINCSPlusEngine.Sha2Engine(false, 16, 16, 7, 12, 14, 63)); - public static SPHINCSPlusParameters sha256_192f_simple = new SPHINCSPlusParameters("sha256-192f-simple", - new SPHINCSPlusEngine.Sha256Engine(false, 24, 16, 22, 8, 33, 66)); + public static SPHINCSPlusParameters sha2_192f_simple = new SPHINCSPlusParameters("sha2-192f-simple", + new SPHINCSPlusEngine.Sha2Engine(false, 24, 16, 22, 8, 33, 66)); - public static SPHINCSPlusParameters sha256_192s_simple = new SPHINCSPlusParameters("sha256-192s-simple", - new SPHINCSPlusEngine.Sha256Engine(false, 24, 16, 7, 14, 17, 63)); + public static SPHINCSPlusParameters sha2_192s_simple = new SPHINCSPlusParameters("sha2-192s-simple", + new SPHINCSPlusEngine.Sha2Engine(false, 24, 16, 7, 14, 17, 63)); - public static SPHINCSPlusParameters sha256_256f_simple = new SPHINCSPlusParameters("sha256-256f-simple", - new SPHINCSPlusEngine.Sha256Engine(false, 32, 16, 17, 9, 35, 68)); + public static SPHINCSPlusParameters sha2_256f_simple = new SPHINCSPlusParameters("sha2-256f-simple", + new SPHINCSPlusEngine.Sha2Engine(false, 32, 16, 17, 9, 35, 68)); - public static SPHINCSPlusParameters sha256_256s_simple = new SPHINCSPlusParameters("sha256-256s-simple", - new SPHINCSPlusEngine.Sha256Engine(false, 32, 16, 8, 14, 22, 64)); + public static SPHINCSPlusParameters sha2_256s_simple = new SPHINCSPlusParameters("sha2-256s-simple", + new SPHINCSPlusEngine.Sha2Engine(false, 32, 16, 8, 14, 22, 64)); // SHAKE-256. - public static SPHINCSPlusParameters shake256_128f = new SPHINCSPlusParameters("shake256-128f-robust", + public static SPHINCSPlusParameters shake_128f = new SPHINCSPlusParameters("shake-128f-robust", new SPHINCSPlusEngine.Shake256Engine(true, 16, 16, 22, 6, 33, 66)); - public static SPHINCSPlusParameters shake256_128s = new SPHINCSPlusParameters("shake256-128s-robust", + public static SPHINCSPlusParameters shake_128s = new SPHINCSPlusParameters("shake-128s-robust", new SPHINCSPlusEngine.Shake256Engine(true, 16, 16, 7, 12, 14, 63)); - public static SPHINCSPlusParameters shake256_192f = new SPHINCSPlusParameters("shake256-192f-robust", + public static SPHINCSPlusParameters shake_192f = new SPHINCSPlusParameters("shake-192f-robust", new SPHINCSPlusEngine.Shake256Engine(true, 24, 16, 22, 8, 33, 66)); - public static SPHINCSPlusParameters shake256_192s = new SPHINCSPlusParameters("shake256-192s-robust", + public static SPHINCSPlusParameters shake_192s = new SPHINCSPlusParameters("shake-192s-robust", new SPHINCSPlusEngine.Shake256Engine(true, 24, 16, 7, 14, 17, 63)); - public static SPHINCSPlusParameters shake256_256f = new SPHINCSPlusParameters("shake256-256f-robust", + public static SPHINCSPlusParameters shake_256f = new SPHINCSPlusParameters("shake-256f-robust", new SPHINCSPlusEngine.Shake256Engine(true, 32, 16, 17, 9, 35, 68)); - public static SPHINCSPlusParameters shake256_256s = new SPHINCSPlusParameters("shake256-256s-robust", + public static SPHINCSPlusParameters shake_256s = new SPHINCSPlusParameters("shake-256s-robust", new SPHINCSPlusEngine.Shake256Engine(true, 32, 16, 8, 14, 22, 64)); - public static SPHINCSPlusParameters shake256_128f_simple = new SPHINCSPlusParameters("shake256-128f-simple", + public static SPHINCSPlusParameters shake_128f_simple = new SPHINCSPlusParameters("shake-128f-simple", new SPHINCSPlusEngine.Shake256Engine(false, 16, 16, 22, 6, 33, 66)); - public static SPHINCSPlusParameters shake256_128s_simple = new SPHINCSPlusParameters("shake256-128s-simple", + public static SPHINCSPlusParameters shake_128s_simple = new SPHINCSPlusParameters("shake-128s-simple", new SPHINCSPlusEngine.Shake256Engine(false, 16, 16, 7, 12, 14, 63)); - public static SPHINCSPlusParameters shake256_192f_simple = new SPHINCSPlusParameters("shake256-192f-simple", + public static SPHINCSPlusParameters shake_192f_simple = new SPHINCSPlusParameters("shake-192f-simple", new SPHINCSPlusEngine.Shake256Engine(false, 24, 16, 22, 8, 33, 66)); - public static SPHINCSPlusParameters shake256_192s_simple = new SPHINCSPlusParameters("shake256-192s-simple", + public static SPHINCSPlusParameters shake_192s_simple = new SPHINCSPlusParameters("shake-192s-simple", new SPHINCSPlusEngine.Shake256Engine(false, 24, 16, 7, 14, 17, 63)); - public static SPHINCSPlusParameters shake256_256f_simple = new SPHINCSPlusParameters("shake256-256f-simple", + public static SPHINCSPlusParameters shake_256f_simple = new SPHINCSPlusParameters("shake-256f-simple", new SPHINCSPlusEngine.Shake256Engine(false, 32, 16, 17, 9, 35, 68)); - public static SPHINCSPlusParameters shake256_256s_simple = new SPHINCSPlusParameters("shake256-256s-simple", + public static SPHINCSPlusParameters shake_256s_simple = new SPHINCSPlusParameters("shake-256s-simple", new SPHINCSPlusEngine.Shake256Engine(false, 32, 16, 8, 14, 22, 64)); - private static uint sphincsPlus_sha256_128f_robust = 0x010101; - private static uint sphincsPlus_sha256_128s_robust = 0x010102; - private static uint sphincsPlus_sha256_192f_robust = 0x010103; - private static uint sphincsPlus_sha256_192s_robust = 0x010104; - private static uint sphincsPlus_sha256_256f_robust = 0x010105; - private static uint sphincsPlus_sha256_256s_robust = 0x010106; + private static uint sphincsPlus_sha2_128f_robust = 0x010101; + private static uint sphincsPlus_sha2_128s_robust = 0x010102; + private static uint sphincsPlus_sha2_192f_robust = 0x010103; + private static uint sphincsPlus_sha2_192s_robust = 0x010104; + private static uint sphincsPlus_sha2_256f_robust = 0x010105; + private static uint sphincsPlus_sha2_256s_robust = 0x010106; - private static uint sphincsPlus_sha256_128f_simple = 0x010201; - private static uint sphincsPlus_sha256_128s_simple = 0x010202; - private static uint sphincsPlus_sha256_192f_simple = 0x010203; - private static uint sphincsPlus_sha256_192s_simple = 0x010204; - private static uint sphincsPlus_sha256_256f_simple = 0x010205; - private static uint sphincsPlus_sha256_256s_simple = 0x010206; + private static uint sphincsPlus_sha2_128f_simple = 0x010201; + private static uint sphincsPlus_sha2_128s_simple = 0x010202; + private static uint sphincsPlus_sha2_192f_simple = 0x010203; + private static uint sphincsPlus_sha2_192s_simple = 0x010204; + private static uint sphincsPlus_sha2_256f_simple = 0x010205; + private static uint sphincsPlus_sha2_256s_simple = 0x010206; - private static uint sphincsPlus_shake256_128f_robust = 0x020101; - private static uint sphincsPlus_shake256_128s_robust = 0x020102; - private static uint sphincsPlus_shake256_192f_robust = 0x020103; - private static uint sphincsPlus_shake256_192s_robust = 0x020104; - private static uint sphincsPlus_shake256_256f_robust = 0x020105; - private static uint sphincsPlus_shake256_256s_robust = 0x020106; + private static uint sphincsPlus_shake_128f_robust = 0x020101; + private static uint sphincsPlus_shake_128s_robust = 0x020102; + private static uint sphincsPlus_shake_192f_robust = 0x020103; + private static uint sphincsPlus_shake_192s_robust = 0x020104; + private static uint sphincsPlus_shake_256f_robust = 0x020105; + private static uint sphincsPlus_shake_256s_robust = 0x020106; - private static uint sphincsPlus_shake256_128f_simple = 0x020201; - private static uint sphincsPlus_shake256_128s_simple = 0x020202; - private static uint sphincsPlus_shake256_192f_simple = 0x020203; - private static uint sphincsPlus_shake256_192s_simple = 0x020204; - private static uint sphincsPlus_shake256_256f_simple = 0x020205; - private static uint sphincsPlus_shake256_256s_simple = 0x020206; + private static uint sphincsPlus_shake_128f_simple = 0x020201; + private static uint sphincsPlus_shake_128s_simple = 0x020202; + private static uint sphincsPlus_shake_192f_simple = 0x020203; + private static uint sphincsPlus_shake_192s_simple = 0x020204; + private static uint sphincsPlus_shake_256f_simple = 0x020205; + private static uint sphincsPlus_shake_256s_simple = 0x020206; private static Dictionary oidToParams = new Dictionary(); private static Dictionary paramsToOid = new Dictionary(); static SPHINCSPlusParameters() { - oidToParams[sphincsPlus_sha256_128f_robust] = SPHINCSPlusParameters.sha256_128f; - oidToParams[sphincsPlus_sha256_128s_robust] = SPHINCSPlusParameters.sha256_128s; - oidToParams[sphincsPlus_sha256_192f_robust] = SPHINCSPlusParameters.sha256_192f; - oidToParams[sphincsPlus_sha256_192s_robust] = SPHINCSPlusParameters.sha256_192s; - oidToParams[sphincsPlus_sha256_256f_robust] = SPHINCSPlusParameters.sha256_256f; - oidToParams[sphincsPlus_sha256_256s_robust] = SPHINCSPlusParameters.sha256_256s; - - oidToParams[sphincsPlus_sha256_128f_simple] = SPHINCSPlusParameters.sha256_128f_simple; - oidToParams[sphincsPlus_sha256_128s_simple] = SPHINCSPlusParameters.sha256_128s_simple; - oidToParams[sphincsPlus_sha256_192f_simple] = SPHINCSPlusParameters.sha256_192f_simple; - oidToParams[sphincsPlus_sha256_192s_simple] = SPHINCSPlusParameters.sha256_192s_simple; - oidToParams[sphincsPlus_sha256_256f_simple] = SPHINCSPlusParameters.sha256_256f_simple; - oidToParams[sphincsPlus_sha256_256s_simple] = SPHINCSPlusParameters.sha256_256s_simple; - - oidToParams[sphincsPlus_shake256_128f_robust] = SPHINCSPlusParameters.shake256_128f; - oidToParams[sphincsPlus_shake256_128s_robust] = SPHINCSPlusParameters.shake256_128s; - oidToParams[sphincsPlus_shake256_192f_robust] = SPHINCSPlusParameters.shake256_192f; - oidToParams[sphincsPlus_shake256_192s_robust] = SPHINCSPlusParameters.shake256_192s; - oidToParams[sphincsPlus_shake256_256f_robust] = SPHINCSPlusParameters.shake256_256f; - oidToParams[sphincsPlus_shake256_256s_robust] = SPHINCSPlusParameters.shake256_256s; - - oidToParams[sphincsPlus_shake256_128f_simple] = SPHINCSPlusParameters.shake256_128f_simple; - oidToParams[sphincsPlus_shake256_128s_simple] = SPHINCSPlusParameters.shake256_128s_simple; - oidToParams[sphincsPlus_shake256_192f_simple] = SPHINCSPlusParameters.shake256_192f_simple; - oidToParams[sphincsPlus_shake256_192s_simple] = SPHINCSPlusParameters.shake256_192s_simple; - oidToParams[sphincsPlus_shake256_256f_simple] = SPHINCSPlusParameters.shake256_256f_simple; - oidToParams[sphincsPlus_shake256_256s_simple] = SPHINCSPlusParameters.shake256_256s_simple; - - paramsToOid[SPHINCSPlusParameters.sha256_128f] = sphincsPlus_sha256_128f_robust; - paramsToOid[SPHINCSPlusParameters.sha256_128s] = sphincsPlus_sha256_128s_robust; - paramsToOid[SPHINCSPlusParameters.sha256_192f] = sphincsPlus_sha256_192f_robust; - paramsToOid[SPHINCSPlusParameters.sha256_192s] = sphincsPlus_sha256_192s_robust; - paramsToOid[SPHINCSPlusParameters.sha256_256f] = sphincsPlus_sha256_256f_robust; - paramsToOid[SPHINCSPlusParameters.sha256_256s] = sphincsPlus_sha256_256s_robust; - - paramsToOid[SPHINCSPlusParameters.sha256_128f_simple] = sphincsPlus_sha256_128f_simple; - paramsToOid[SPHINCSPlusParameters.sha256_128s_simple] = sphincsPlus_sha256_128s_simple; - paramsToOid[SPHINCSPlusParameters.sha256_192f_simple] = sphincsPlus_sha256_192f_simple; - paramsToOid[SPHINCSPlusParameters.sha256_192s_simple] = sphincsPlus_sha256_192s_simple; - paramsToOid[SPHINCSPlusParameters.sha256_256f_simple] = sphincsPlus_sha256_256f_simple; - paramsToOid[SPHINCSPlusParameters.sha256_256s_simple] = sphincsPlus_sha256_256s_simple; - - paramsToOid[SPHINCSPlusParameters.shake256_128f] = sphincsPlus_shake256_128f_robust; - paramsToOid[SPHINCSPlusParameters.shake256_128s] = sphincsPlus_shake256_128s_robust; - paramsToOid[SPHINCSPlusParameters.shake256_192f] = sphincsPlus_shake256_192f_robust; - paramsToOid[SPHINCSPlusParameters.shake256_192s] = sphincsPlus_shake256_192s_robust; - paramsToOid[SPHINCSPlusParameters.shake256_256f] = sphincsPlus_shake256_256f_robust; - paramsToOid[SPHINCSPlusParameters.shake256_256s] = sphincsPlus_shake256_256s_robust; - - paramsToOid[SPHINCSPlusParameters.shake256_128f_simple] = sphincsPlus_shake256_128f_simple; - paramsToOid[SPHINCSPlusParameters.shake256_128s_simple] = sphincsPlus_shake256_128s_simple; - paramsToOid[SPHINCSPlusParameters.shake256_192f_simple] = sphincsPlus_shake256_192f_simple; - paramsToOid[SPHINCSPlusParameters.shake256_192s_simple] = sphincsPlus_shake256_192s_simple; - paramsToOid[SPHINCSPlusParameters.shake256_256f_simple] = sphincsPlus_shake256_256f_simple; - paramsToOid[SPHINCSPlusParameters.shake256_256s_simple] = sphincsPlus_shake256_256s_simple; + oidToParams[sphincsPlus_sha2_128f_robust] = SPHINCSPlusParameters.sha2_128f; + oidToParams[sphincsPlus_sha2_128s_robust] = SPHINCSPlusParameters.sha2_128s; + oidToParams[sphincsPlus_sha2_192f_robust] = SPHINCSPlusParameters.sha2_192f; + oidToParams[sphincsPlus_sha2_192s_robust] = SPHINCSPlusParameters.sha2_192s; + oidToParams[sphincsPlus_sha2_256f_robust] = SPHINCSPlusParameters.sha2_256f; + oidToParams[sphincsPlus_sha2_256s_robust] = SPHINCSPlusParameters.sha2_256s; + + oidToParams[sphincsPlus_sha2_128f_simple] = SPHINCSPlusParameters.sha2_128f_simple; + oidToParams[sphincsPlus_sha2_128s_simple] = SPHINCSPlusParameters.sha2_128s_simple; + oidToParams[sphincsPlus_sha2_192f_simple] = SPHINCSPlusParameters.sha2_192f_simple; + oidToParams[sphincsPlus_sha2_192s_simple] = SPHINCSPlusParameters.sha2_192s_simple; + oidToParams[sphincsPlus_sha2_256f_simple] = SPHINCSPlusParameters.sha2_256f_simple; + oidToParams[sphincsPlus_sha2_256s_simple] = SPHINCSPlusParameters.sha2_256s_simple; + + oidToParams[sphincsPlus_shake_128f_robust] = SPHINCSPlusParameters.shake_128f; + oidToParams[sphincsPlus_shake_128s_robust] = SPHINCSPlusParameters.shake_128s; + oidToParams[sphincsPlus_shake_192f_robust] = SPHINCSPlusParameters.shake_192f; + oidToParams[sphincsPlus_shake_192s_robust] = SPHINCSPlusParameters.shake_192s; + oidToParams[sphincsPlus_shake_256f_robust] = SPHINCSPlusParameters.shake_256f; + oidToParams[sphincsPlus_shake_256s_robust] = SPHINCSPlusParameters.shake_256s; + + oidToParams[sphincsPlus_shake_128f_simple] = SPHINCSPlusParameters.shake_128f_simple; + oidToParams[sphincsPlus_shake_128s_simple] = SPHINCSPlusParameters.shake_128s_simple; + oidToParams[sphincsPlus_shake_192f_simple] = SPHINCSPlusParameters.shake_192f_simple; + oidToParams[sphincsPlus_shake_192s_simple] = SPHINCSPlusParameters.shake_192s_simple; + oidToParams[sphincsPlus_shake_256f_simple] = SPHINCSPlusParameters.shake_256f_simple; + oidToParams[sphincsPlus_shake_256s_simple] = SPHINCSPlusParameters.shake_256s_simple; + + paramsToOid[SPHINCSPlusParameters.sha2_128f] = sphincsPlus_sha2_128f_robust; + paramsToOid[SPHINCSPlusParameters.sha2_128s] = sphincsPlus_sha2_128s_robust; + paramsToOid[SPHINCSPlusParameters.sha2_192f] = sphincsPlus_sha2_192f_robust; + paramsToOid[SPHINCSPlusParameters.sha2_192s] = sphincsPlus_sha2_192s_robust; + paramsToOid[SPHINCSPlusParameters.sha2_256f] = sphincsPlus_sha2_256f_robust; + paramsToOid[SPHINCSPlusParameters.sha2_256s] = sphincsPlus_sha2_256s_robust; + + paramsToOid[SPHINCSPlusParameters.sha2_128f_simple] = sphincsPlus_sha2_128f_simple; + paramsToOid[SPHINCSPlusParameters.sha2_128s_simple] = sphincsPlus_sha2_128s_simple; + paramsToOid[SPHINCSPlusParameters.sha2_192f_simple] = sphincsPlus_sha2_192f_simple; + paramsToOid[SPHINCSPlusParameters.sha2_192s_simple] = sphincsPlus_sha2_192s_simple; + paramsToOid[SPHINCSPlusParameters.sha2_256f_simple] = sphincsPlus_sha2_256f_simple; + paramsToOid[SPHINCSPlusParameters.sha2_256s_simple] = sphincsPlus_sha2_256s_simple; + + paramsToOid[SPHINCSPlusParameters.shake_128f] = sphincsPlus_shake_128f_robust; + paramsToOid[SPHINCSPlusParameters.shake_128s] = sphincsPlus_shake_128s_robust; + paramsToOid[SPHINCSPlusParameters.shake_192f] = sphincsPlus_shake_192f_robust; + paramsToOid[SPHINCSPlusParameters.shake_192s] = sphincsPlus_shake_192s_robust; + paramsToOid[SPHINCSPlusParameters.shake_256f] = sphincsPlus_shake_256f_robust; + paramsToOid[SPHINCSPlusParameters.shake_256s] = sphincsPlus_shake_256s_robust; + + paramsToOid[SPHINCSPlusParameters.shake_128f_simple] = sphincsPlus_shake_128f_simple; + paramsToOid[SPHINCSPlusParameters.shake_128s_simple] = sphincsPlus_shake_128s_simple; + paramsToOid[SPHINCSPlusParameters.shake_192f_simple] = sphincsPlus_shake_192f_simple; + paramsToOid[SPHINCSPlusParameters.shake_192s_simple] = sphincsPlus_shake_192s_simple; + paramsToOid[SPHINCSPlusParameters.shake_256f_simple] = sphincsPlus_shake_256f_simple; + paramsToOid[SPHINCSPlusParameters.shake_256s_simple] = sphincsPlus_shake_256s_simple; } private String name; diff --git a/crypto/src/pqc/crypto/sphincsplus/SPHINCSPlusSigner.cs b/crypto/src/pqc/crypto/sphincsplus/SPHINCSPlusSigner.cs index be371bb63..f6260e692 100644 --- a/crypto/src/pqc/crypto/sphincsplus/SPHINCSPlusSigner.cs +++ b/crypto/src/pqc/crypto/sphincsplus/SPHINCSPlusSigner.cs @@ -86,6 +86,11 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus adrs.SetKeyPairAddress(idx_leaf); SIG_FORS[] sig_fors = fors.Sign(mHash, privKey.sk.seed, privKey.pk.seed, adrs); // get FORS public key - spec shows M? + adrs = new Adrs(); + adrs.SetType(Adrs.FORS_TREE); + adrs.SetTreeAddress(idx_tree); + adrs.SetKeyPairAddress(idx_leaf); + byte[] PK_FORS = fors.PKFromSig(sig_fors, mHash, privKey.pk.seed, adrs); // sign FORS public key with HT @@ -129,13 +134,16 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus uint idx_leaf = idxDigest.idx_leaf; // compute FORS public key + adrs.SetType(Adrs.FORS_TREE); adrs.SetLayerAddress(0); adrs.SetTreeAddress(idx_tree); - adrs.SetType(Adrs.FORS_TREE); adrs.SetKeyPairAddress(idx_leaf); byte[] PK_FORS = new Fors(engine).PKFromSig(sig_fors, mHash, pubKey.GetSeed(), adrs); // verify HT signature adrs.SetType(Adrs.TREE); + adrs.SetLayerAddress(0); + adrs.SetTreeAddress(idx_tree); + adrs.SetKeyPairAddress(idx_leaf); HT ht = new HT(engine, null, pubKey.GetSeed()); return ht.Verify(PK_FORS, SIG_HT, pubKey.GetSeed(), idx_tree, idx_leaf, pubKey.GetRoot()); } diff --git a/crypto/src/pqc/crypto/sphincsplus/WotsPlus.cs b/crypto/src/pqc/crypto/sphincsplus/WotsPlus.cs index 053bf84c9..508accc06 100644 --- a/crypto/src/pqc/crypto/sphincsplus/WotsPlus.cs +++ b/crypto/src/pqc/crypto/sphincsplus/WotsPlus.cs @@ -24,9 +24,16 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus for (uint i = 0; i < engine.WOTS_LEN; i++) { Adrs adrs = new Adrs(paramAdrs); + adrs.SetType(Adrs.WOTS_PRF); + adrs.SetKeyPairAddress(paramAdrs.GetKeyPairAddress()); adrs.SetChainAddress(i); adrs.SetHashAddress(0); + byte[] sk = engine.PRF(pkSeed, skSeed, adrs); + adrs.SetType(Adrs.WOTS_HASH); + adrs.SetKeyPairAddress(paramAdrs.GetKeyPairAddress()); + adrs.SetChainAddress(i); + adrs.SetHashAddress(0); tmp[i] = Chain(sk, 0, w - 1, pkSeed, adrs); } @@ -88,9 +95,16 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus byte[][] sig = new byte[engine.WOTS_LEN][]; for (uint i = 0; i < engine.WOTS_LEN; i++) { + adrs.SetType(Adrs.WOTS_PRF); + adrs.SetKeyPairAddress(paramAdrs.GetKeyPairAddress()); adrs.SetChainAddress(i); adrs.SetHashAddress(0); byte[] sk = engine.PRF(pkSeed, skSeed, adrs); + adrs.SetType(Adrs.WOTS_HASH); + adrs.SetKeyPairAddress(paramAdrs.GetKeyPairAddress()); + adrs.SetChainAddress(i); + adrs.SetHashAddress(0); + sig[i] = Chain(sk, 0, msg[i], pkSeed, adrs); } -- cgit 1.4.1