diff --git a/crypto/src/pqc/crypto/sphincsplus/HarakaS256Digest.cs b/crypto/src/pqc/crypto/sphincsplus/HarakaS256Digest.cs
index 2e22bfea1..90a5a0dbb 100644
--- a/crypto/src/pqc/crypto/sphincsplus/HarakaS256Digest.cs
+++ b/crypto/src/pqc/crypto/sphincsplus/HarakaS256Digest.cs
@@ -17,7 +17,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus
return 32;
}
- public void BlockUpdate(byte input)
+ public void Update(byte input)
{
if (off > 32 - 1)
throw new ArgumentException("total input cannot be more than 32 bytes");
@@ -34,6 +34,17 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus
off += len;
}
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ public void BlockUpdate(ReadOnlySpan<byte> input)
+ {
+ if (off > 32 - input.Length)
+ throw new ArgumentException("total input cannot be more than 32 bytes");
+
+ input.CopyTo(buffer.AsSpan(off));
+ off += input.Length;
+ }
+#endif
+
public int DoFinal(byte[] output, int outOff)
{
// TODO Check received all 32 bytes of input?
@@ -44,7 +55,22 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus
Reset();
- return output.Length;
+ return 32;
+ }
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ public int DoFinal(Span<byte> output)
+ {
+ // TODO Check received all 32 bytes of input?
+
+ Span<byte> s = stackalloc byte[32];
+ Haraka256Perm(s);
+ Xor(s, buffer, output[..32]);
+
+ Reset();
+
+ return 32;
}
+#endif
}
}
diff --git a/crypto/src/pqc/crypto/sphincsplus/HarakaS512Digest.cs b/crypto/src/pqc/crypto/sphincsplus/HarakaS512Digest.cs
index c83eb8d8c..d96509f62 100644
--- a/crypto/src/pqc/crypto/sphincsplus/HarakaS512Digest.cs
+++ b/crypto/src/pqc/crypto/sphincsplus/HarakaS512Digest.cs
@@ -40,6 +40,17 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus
off += len;
}
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ public void BlockUpdate(ReadOnlySpan<byte> input)
+ {
+ if (off > 64 - input.Length)
+ throw new ArgumentException("total input cannot be more than 64 bytes");
+
+ input.CopyTo(buffer.AsSpan(off));
+ off += input.Length;
+ }
+#endif
+
public int DoFinal(byte[] output, int outOff)
{
// TODO Check received all 64 bytes of input?
@@ -52,7 +63,24 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus
Reset();
- return s.Length;
+ return 32;
+ }
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ public int DoFinal(Span<byte> output)
+ {
+ // TODO Check received all 64 bytes of input?
+
+ Span<byte> s = stackalloc byte[64];
+ Haraka512Perm(s);
+ Xor(s[8..], buffer.AsSpan(8), output[..8]);
+ Xor(s[24..], buffer.AsSpan(24), output[8..24]);
+ Xor(s[48..], buffer.AsSpan(48), output[24..32]);
+
+ Reset();
+
+ return 32;
}
+#endif
}
-}
\ No newline at end of file
+}
diff --git a/crypto/src/pqc/crypto/sphincsplus/HarakaSBase.cs b/crypto/src/pqc/crypto/sphincsplus/HarakaSBase.cs
index fa96512ea..5efafc1db 100644
--- a/crypto/src/pqc/crypto/sphincsplus/HarakaSBase.cs
+++ b/crypto/src/pqc/crypto/sphincsplus/HarakaSBase.cs
@@ -65,7 +65,11 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus
BrAesCtOrtho(output);
}
- protected void Haraka512Perm(byte[] output)
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ internal void Haraka512Perm(Span<byte> output)
+#else
+ internal void Haraka512Perm(byte[] output)
+#endif
{
uint[] w = new uint[16];
ulong[] q = new ulong[8];
@@ -116,7 +120,11 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus
}
}
- protected void Haraka256Perm(byte[] output)
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ internal void Haraka256Perm(Span<byte> output)
+#else
+ internal void Haraka256Perm(byte[] output)
+#endif
{
uint[] q = new uint[8];
InterleaveConstant32(q, buffer, 0);
@@ -138,8 +146,13 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus
BrAesCtOrtho(q);
for (int i = 0; i < 4; i++)
{
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ Pack.UInt32_To_LE(q[i << 1], output[(i << 2)..]);
+ Pack.UInt32_To_LE(q[(i << 1) + 1], output[((i << 2) + 16)..]);
+#else
Pack.UInt32_To_LE(q[i << 1], output, i << 2);
Pack.UInt32_To_LE(q[(i << 1) + 1], output, (i << 2) + 16);
+#endif
}
}
@@ -678,5 +691,15 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus
z[zOff + i] = (byte)(x[xOff + i] ^ y[yOff + i]);
}
}
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ protected static void Xor(ReadOnlySpan<byte> x, ReadOnlySpan<byte> y, Span<byte> z)
+ {
+ for (int i = 0; i < z.Length; i++)
+ {
+ z[i] = (byte)(x[i] ^ y[i]);
+ }
+ }
+#endif
}
}
|