From 38976b06878cd797c252c99bd9bd9259fa7057a8 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Tue, 11 Oct 2022 20:07:15 +0700 Subject: Support custom round constants --- crypto/src/crypto/digests/Haraka256_X86.cs | 39 ++++++++++++++++++++++-- crypto/src/crypto/digests/Haraka512_X86.cs | 49 ++++++++++++++++++++++++++++-- 2 files changed, 82 insertions(+), 6 deletions(-) (limited to 'crypto/src') 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 input, Span output, + ReadOnlySpan> 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 input, Span output) { if (!IsSupported) @@ -43,8 +61,23 @@ namespace Org.BouncyCastle.Crypto.Digests Store128(s1, output[16..32]); } + public static void Permute(ReadOnlySpan input, Span output, + ReadOnlySpan> 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 s0, ref Vector128 s1, Span> rc) + private static void ImplRounds(ref Vector128 s0, ref Vector128 s1, ReadOnlySpan> 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 s0, ref Vector128 s1, Span> rc) + private static void ImplRound(ref Vector128 s0, ref Vector128 s1, ReadOnlySpan> rc) { ImplAes(ref s0, ref s1, rc[..4]); ImplMix(ref s0, ref s1); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void ImplAes(ref Vector128 s0, ref Vector128 s1, Span> rc) + private static void ImplAes(ref Vector128 s0, ref Vector128 s1, ReadOnlySpan> 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 input, Span output, + ReadOnlySpan> 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 input, Span output) { if (!IsSupported) @@ -98,9 +122,28 @@ namespace Org.BouncyCastle.Crypto.Digests Store128(s3, output[48..64]); } + public static void Permute(ReadOnlySpan input, Span output, + ReadOnlySpan> 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 s0, ref Vector128 s1, ref Vector128 s2, - ref Vector128 s3, Span> rc) + ref Vector128 s3, ReadOnlySpan> 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 s0, ref Vector128 s1, ref Vector128 s2, - ref Vector128 s3, Span> rc) + ref Vector128 s3, ReadOnlySpan> 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 s0, ref Vector128 s1, ref Vector128 s2, - ref Vector128 s3, Span> rc) + ref Vector128 s3, ReadOnlySpan> rc) { s0 = Aes.Encrypt(s0, rc[0]); s1 = Aes.Encrypt(s1, rc[1]); -- cgit 1.5.1