summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2022-10-10 00:20:01 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2022-10-10 00:20:01 +0700
commite9eb0ff3cf002bbba1b907afa296acc9d3c00166 (patch)
treea7664bdd5a24abb5361cfdbf3dbaf2eb963d90a1
parentHaraka refactoring (performance) (diff)
downloadBouncyCastle.NET-ed25519-e9eb0ff3cf002bbba1b907afa296acc9d3c00166.tar.xz
Fix Haraka digest API compliance
-rw-r--r--crypto/src/pqc/crypto/sphincsplus/HarakaS256Digest.cs10
-rw-r--r--crypto/src/pqc/crypto/sphincsplus/HarakaS512Digest.cs19
-rw-r--r--crypto/src/pqc/crypto/sphincsplus/HarakaSBase.cs13
-rw-r--r--crypto/src/pqc/crypto/sphincsplus/SPHINCSPlusEngine.cs14
4 files changed, 29 insertions, 27 deletions
diff --git a/crypto/src/pqc/crypto/sphincsplus/HarakaS256Digest.cs b/crypto/src/pqc/crypto/sphincsplus/HarakaS256Digest.cs
index 58086cede..2e22bfea1 100644
--- a/crypto/src/pqc/crypto/sphincsplus/HarakaS256Digest.cs
+++ b/crypto/src/pqc/crypto/sphincsplus/HarakaS256Digest.cs
@@ -19,7 +19,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus
 
         public void BlockUpdate(byte input)
         {
-            if (off + 1 > 32)
+            if (off > 32 - 1)
                 throw new ArgumentException("total input cannot be more than 32 bytes");
 
             buffer[off++] = input;
@@ -27,7 +27,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus
 
         public void BlockUpdate(byte[] input, int inOff, int len)
         {
-            if (off + len > 32)
+            if (off > 32 - len)
                 throw new ArgumentException("total input cannot be more than 32 bytes");
 
             Array.Copy(input, inOff, buffer, off, len);
@@ -36,9 +36,11 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus
 
         public int DoFinal(byte[] output, int outOff)
         {
-            byte[] s = new byte[64];
+            // TODO Check received all 32 bytes of input?
+
+            byte[] s = new byte[32];
             Haraka256Perm(s);
-            Array.Copy(s, 0, output, outOff, output.Length - outOff);
+            Xor(s, 0, buffer, 0, output, outOff, 32);
 
             Reset();
 
diff --git a/crypto/src/pqc/crypto/sphincsplus/HarakaS512Digest.cs b/crypto/src/pqc/crypto/sphincsplus/HarakaS512Digest.cs
index aa3adbc71..c83eb8d8c 100644
--- a/crypto/src/pqc/crypto/sphincsplus/HarakaS512Digest.cs
+++ b/crypto/src/pqc/crypto/sphincsplus/HarakaS512Digest.cs
@@ -20,12 +20,12 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus
 
         public int GetDigestSize()
         {
-            return 64;
+            return 32;
         }
 
         public void Update(byte input)
         {
-            if (off + 1 > 64)
+            if (off > 64 - 1)
                 throw new ArgumentException("total input cannot be more than 64 bytes");
 
             buffer[off++] = input;
@@ -33,7 +33,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus
 
         public void BlockUpdate(byte[] input, int inOff, int len)
         {
-            if (off + len > 64)
+            if (off > 64 - len)
                 throw new ArgumentException("total input cannot be more than 64 bytes");
 
             Array.Copy(input, inOff, buffer, off, len);
@@ -42,16 +42,13 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus
 
         public int DoFinal(byte[] output, int outOff)
         {
+            // TODO Check received all 64 bytes of input?
+
             byte[] s = new byte[64];
             Haraka512Perm(s);
-            for (int i = 0; i < 64; ++i)
-            {
-                s[i] ^= buffer[i];
-            }
-            Array.Copy(s, 8, output, outOff, 8);
-            Array.Copy(s, 24, output, outOff + 8, 8);
-            Array.Copy(s, 32, output, outOff + 16, 8);
-            Array.Copy(s, 48, output, outOff + 24, 8);
+            Xor(s,  8, buffer,  8, output, outOff     ,  8);
+            Xor(s, 24, buffer, 24, output, outOff +  8, 16);
+            Xor(s, 48, buffer, 48, output, outOff + 24,  8);
 
             Reset();
 
diff --git a/crypto/src/pqc/crypto/sphincsplus/HarakaSBase.cs b/crypto/src/pqc/crypto/sphincsplus/HarakaSBase.cs
index b7ee8e2aa..fa96512ea 100644
--- a/crypto/src/pqc/crypto/sphincsplus/HarakaSBase.cs
+++ b/crypto/src/pqc/crypto/sphincsplus/HarakaSBase.cs
@@ -141,11 +141,6 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus
                 Pack.UInt32_To_LE(q[i << 1], output, i << 2);
                 Pack.UInt32_To_LE(q[(i << 1) + 1], output, (i << 2) + 16);
             }
-
-            for (int i = 0; i < 32; i++)
-            {
-                output[i] ^= buffer[i];
-            }
         }
 
         private static void BrAesCt64InterleaveIn(ulong[] q, int qPos, uint[] w, int startPos)
@@ -675,5 +670,13 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus
             w[pos + 2] = (uint)(x2 | (x2 >> 16));
             w[pos + 3] = (uint)(x3 | (x3 >> 16));
         }
+
+        protected static void Xor(byte[] x, int xOff, byte[] y, int yOff, byte[] z, int zOff, int zLen)
+        {
+            for (int i = 0; i < zLen; i++)
+            {
+                z[zOff + i] = (byte)(x[xOff + i] ^ y[yOff + i]);
+            }
+        }
     }
 }
diff --git a/crypto/src/pqc/crypto/sphincsplus/SPHINCSPlusEngine.cs b/crypto/src/pqc/crypto/sphincsplus/SPHINCSPlusEngine.cs
index 778367a57..c9176ecaa 100644
--- a/crypto/src/pqc/crypto/sphincsplus/SPHINCSPlusEngine.cs
+++ b/crypto/src/pqc/crypto/sphincsplus/SPHINCSPlusEngine.cs
@@ -543,25 +543,25 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus
 
             public override byte[] F(byte[] pkSeed, Adrs adrs, byte[] m1)
             {
-                byte[] rv = new byte[64];
+                byte[] hash = new byte[32];
                 harakaS512Digest.BlockUpdate(adrs.value, 0, adrs.value.Length);
                 if (robust)
                 {
-                    byte[] mask = new byte[m1.Length];
                     harakaS256Digest.BlockUpdate(adrs.value, 0, adrs.value.Length);
-                    harakaS256Digest.DoFinal(mask, 0);
+                    harakaS256Digest.DoFinal(hash, 0);
                     for (int i = 0; i < m1.Length; ++i)
                     {
-                        mask[i] ^= m1[i];
+                        hash[i] ^= m1[i];
                     }
-                    harakaS512Digest.BlockUpdate(mask, 0, mask.Length);
+                    harakaS512Digest.BlockUpdate(hash, 0, m1.Length);
                 }
                 else
                 {
                     harakaS512Digest.BlockUpdate(m1, 0, m1.Length);
                 }
-                harakaS512Digest.DoFinal(rv, 0);
-                return Arrays.CopyOfRange(rv, 0, N);
+                // NOTE The digest implementation implicitly pads the input with zeros up to 64 length
+                harakaS512Digest.DoFinal(hash, 0);
+                return Arrays.CopyOfRange(hash, 0, N);
             }
 
             public override byte[] H(byte[] pkSeed, Adrs adrs, byte[] m1, byte[] m2)