summary refs log tree commit diff
path: root/crypto
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2022-10-11 20:07:15 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2022-10-11 20:07:15 +0700
commit38976b06878cd797c252c99bd9bd9259fa7057a8 (patch)
tree97127d6495e85d3673ec0363af08aee0819e0963 /crypto
parentStores don't need ref (diff)
downloadBouncyCastle.NET-ed25519-38976b06878cd797c252c99bd9bd9259fa7057a8.tar.xz
Support custom round constants
Diffstat (limited to 'crypto')
-rw-r--r--crypto/src/crypto/digests/Haraka256_X86.cs39
-rw-r--r--crypto/src/crypto/digests/Haraka512_X86.cs49
2 files changed, 82 insertions, 6 deletions
diff --git a/crypto/src/crypto/digests/Haraka256_X86.cs b/crypto/src/crypto/digests/Haraka256_X86.cs
index aaab2017b..ab64f91ae 100644
--- a/crypto/src/crypto/digests/Haraka256_X86.cs
+++ b/crypto/src/crypto/digests/Haraka256_X86.cs
@@ -29,6 +29,24 @@ namespace Org.BouncyCastle.Crypto.Digests
             Store128(s1, output[16..32]);
         }
 
+        public static void Hash(ReadOnlySpan<byte> input, Span<byte> output,
+            ReadOnlySpan<Vector128<byte>> roundConstants)
+        {
+            if (!IsSupported)
+                throw new PlatformNotSupportedException(nameof(Haraka256_X86));
+
+            var s0 = Load128(input[  ..16]);
+            var s1 = Load128(input[16..32]);
+
+            ImplRounds(ref s0, ref s1, roundConstants[..20]);
+
+            s0 = Sse2.Xor(s0, Load128(input[  ..16]));
+            s1 = Sse2.Xor(s1, Load128(input[16..32]));
+
+            Store128(s0, output[  ..16]);
+            Store128(s1, output[16..32]);
+        }
+
         public static void Permute(ReadOnlySpan<byte> input, Span<byte> output)
         {
             if (!IsSupported)
@@ -43,8 +61,23 @@ namespace Org.BouncyCastle.Crypto.Digests
             Store128(s1, output[16..32]);
         }
 
+        public static void Permute(ReadOnlySpan<byte> input, Span<byte> output,
+            ReadOnlySpan<Vector128<byte>> roundConstants)
+        {
+            if (!IsSupported)
+                throw new PlatformNotSupportedException(nameof(Haraka256_X86));
+
+            var s0 = Load128(input[  ..16]);
+            var s1 = Load128(input[16..32]);
+
+            ImplRounds(ref s0, ref s1, roundConstants[..20]);
+
+            Store128(s0, output[  ..16]);
+            Store128(s1, output[16..32]);
+        }
+
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        private static void ImplRounds(ref Vector128<byte> s0, ref Vector128<byte> s1, Span<Vector128<byte>> rc)
+        private static void ImplRounds(ref Vector128<byte> s0, ref Vector128<byte> s1, ReadOnlySpan<Vector128<byte>> rc)
         {
             ImplRound(ref s0, ref s1, rc[  .. 4]);
             ImplRound(ref s0, ref s1, rc[ 4.. 8]);
@@ -54,14 +87,14 @@ namespace Org.BouncyCastle.Crypto.Digests
         }
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        private static void ImplRound(ref Vector128<byte> s0, ref Vector128<byte> s1, Span<Vector128<byte>> rc)
+        private static void ImplRound(ref Vector128<byte> s0, ref Vector128<byte> s1, ReadOnlySpan<Vector128<byte>> rc)
         {
             ImplAes(ref s0, ref s1, rc[..4]);
             ImplMix(ref s0, ref s1);
         }
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        private static void ImplAes(ref Vector128<byte> s0, ref Vector128<byte> s1, Span<Vector128<byte>> rc)
+        private static void ImplAes(ref Vector128<byte> s0, ref Vector128<byte> s1, ReadOnlySpan<Vector128<byte>> rc)
         {
             s0 = Aes.Encrypt(s0, rc[0]);
             s1 = Aes.Encrypt(s1, rc[1]);
diff --git a/crypto/src/crypto/digests/Haraka512_X86.cs b/crypto/src/crypto/digests/Haraka512_X86.cs
index 4a6626714..e781a6e5a 100644
--- a/crypto/src/crypto/digests/Haraka512_X86.cs
+++ b/crypto/src/crypto/digests/Haraka512_X86.cs
@@ -80,6 +80,30 @@ namespace Org.BouncyCastle.Crypto.Digests
             Store64(s3.GetLower(), output[24..32]);
         }
 
+        public static void Hash(ReadOnlySpan<byte> input, Span<byte> output,
+            ReadOnlySpan<Vector128<byte>> roundConstants)
+        {
+            if (!IsSupported)
+                throw new PlatformNotSupportedException(nameof(Haraka512_X86));
+
+            var s0 = Load128(input[  ..16]);
+            var s1 = Load128(input[16..32]);
+            var s2 = Load128(input[32..48]);
+            var s3 = Load128(input[48..64]);
+
+            ImplRounds(ref s0, ref s1, ref s2, ref s3, roundConstants[..40]);
+
+            s0 = Sse2.Xor(s0, Load128(input[  ..16]));
+            s1 = Sse2.Xor(s1, Load128(input[16..32]));
+            s2 = Sse2.Xor(s2, Load128(input[32..48]));
+            s3 = Sse2.Xor(s3, Load128(input[48..64]));
+
+            Store64(s0.GetUpper(), output[..8]);
+            Store64(s1.GetUpper(), output[8..16]);
+            Store64(s2.GetLower(), output[16..24]);
+            Store64(s3.GetLower(), output[24..32]);
+        }
+
         public static void Permute(ReadOnlySpan<byte> input, Span<byte> output)
         {
             if (!IsSupported)
@@ -98,9 +122,28 @@ namespace Org.BouncyCastle.Crypto.Digests
             Store128(s3, output[48..64]);
         }
 
+        public static void Permute(ReadOnlySpan<byte> input, Span<byte> output,
+            ReadOnlySpan<Vector128<byte>> roundConstants)
+        {
+            if (!IsSupported)
+                throw new PlatformNotSupportedException(nameof(Haraka512_X86));
+
+            var s0 = Load128(input[  ..16]);
+            var s1 = Load128(input[16..32]);
+            var s2 = Load128(input[32..48]);
+            var s3 = Load128(input[48..64]);
+
+            ImplRounds(ref s0, ref s1, ref s2, ref s3, roundConstants[..40]);
+
+            Store128(s0, output[  ..16]);
+            Store128(s1, output[16..32]);
+            Store128(s2, output[32..48]);
+            Store128(s3, output[48..64]);
+        }
+
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         private static void ImplRounds(ref Vector128<byte> s0, ref Vector128<byte> s1, ref Vector128<byte> s2,
-            ref Vector128<byte> s3, Span<Vector128<byte>> rc)
+            ref Vector128<byte> s3, ReadOnlySpan<Vector128<byte>> rc)
         {
             ImplRound(ref s0, ref s1, ref s2, ref s3, rc[  .. 8]);
             ImplRound(ref s0, ref s1, ref s2, ref s3, rc[ 8..16]);
@@ -111,7 +154,7 @@ namespace Org.BouncyCastle.Crypto.Digests
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         private static void ImplRound(ref Vector128<byte> s0, ref Vector128<byte> s1, ref Vector128<byte> s2,
-            ref Vector128<byte> s3, Span<Vector128<byte>> rc)
+            ref Vector128<byte> s3, ReadOnlySpan<Vector128<byte>> rc)
         {
             ImplAes(ref s0, ref s1, ref s2, ref s3, rc[..8]);
             ImplMix(ref s0, ref s1, ref s2, ref s3);
@@ -119,7 +162,7 @@ namespace Org.BouncyCastle.Crypto.Digests
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         private static void ImplAes(ref Vector128<byte> s0, ref Vector128<byte> s1, ref Vector128<byte> s2,
-            ref Vector128<byte> s3, Span<Vector128<byte>> rc)
+            ref Vector128<byte> s3, ReadOnlySpan<Vector128<byte>> rc)
         {
             s0 = Aes.Encrypt(s0, rc[0]);
             s1 = Aes.Encrypt(s1, rc[1]);