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)
|