diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2023-02-13 00:34:55 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2023-02-13 00:34:55 +0700 |
commit | f52b9a1ea4b3b1aea3615636d282b119a2e7a05e (patch) | |
tree | 7b41c49bc5cdd3af6f12e8fd33896c5d831601e6 /crypto | |
parent | Support explicit blockSize (diff) | |
download | BouncyCastle.NET-ed25519-f52b9a1ea4b3b1aea3615636d282b119a2e7a05e.tar.xz |
Fix/refactor LWC algorithms
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/src/crypto/digests/AsconDigest.cs | 385 | ||||
-rw-r--r-- | crypto/src/crypto/digests/ISAPDigest.cs | 184 | ||||
-rw-r--r-- | crypto/src/crypto/digests/PhotonBeetleDigest.cs | 14 | ||||
-rw-r--r-- | crypto/src/crypto/digests/SparkleDigest.cs | 75 | ||||
-rw-r--r-- | crypto/src/crypto/engines/AsconEngine.cs | 10 | ||||
-rw-r--r-- | crypto/src/crypto/engines/ElephantEngine.cs | 131 | ||||
-rw-r--r-- | crypto/src/crypto/engines/ISAPEngine.cs | 12 | ||||
-rw-r--r-- | crypto/src/crypto/engines/PhotonBeetleEngine.cs | 44 | ||||
-rw-r--r-- | crypto/src/crypto/engines/SparkleEngine.cs | 25 | ||||
-rw-r--r-- | crypto/src/crypto/engines/XoodyakEngine.cs | 42 | ||||
-rw-r--r-- | crypto/test/src/crypto/test/AsconTest.cs | 65 | ||||
-rw-r--r-- | crypto/test/src/crypto/test/ElephantTest.cs | 244 | ||||
-rw-r--r-- | crypto/test/src/crypto/test/ISAPTest.cs | 48 | ||||
-rw-r--r-- | crypto/test/src/crypto/test/PhotonBeetleTest.cs | 126 | ||||
-rw-r--r-- | crypto/test/src/crypto/test/SparkleTest.cs | 342 | ||||
-rw-r--r-- | crypto/test/src/crypto/test/XoodyakTest.cs | 278 |
16 files changed, 949 insertions, 1076 deletions
diff --git a/crypto/src/crypto/digests/AsconDigest.cs b/crypto/src/crypto/digests/AsconDigest.cs index 2607cddde..343036b99 100644 --- a/crypto/src/crypto/digests/AsconDigest.cs +++ b/crypto/src/crypto/digests/AsconDigest.cs @@ -1,10 +1,15 @@ using System; -using System.IO; +#if NETSTANDARD1_0_OR_GREATER || NETCOREAPP1_0_OR_GREATER +using System.Runtime.CompilerServices; +#endif + using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Crypto.Digests { - public class AsconDigest : IDigest + public sealed class AsconDigest + : IDigest { public enum AsconParameters { @@ -14,236 +19,266 @@ namespace Org.BouncyCastle.Crypto.Digests AsconXofA, } - public AsconDigest(AsconParameters parameters) - { - asconParameters = parameters; - switch (parameters) - { - case AsconParameters.AsconHash: - ASCON_PB_ROUNDS = 12; - algorithmName = "Ascon-Hash"; - break; - case AsconParameters.AsconHashA: - ASCON_PB_ROUNDS = 8; - algorithmName = "Ascon-HashA"; - break; - case AsconParameters.AsconXof: - ASCON_PB_ROUNDS = 12; - algorithmName = "Ascon-Xof"; - break; - case AsconParameters.AsconXofA: - ASCON_PB_ROUNDS = 8; - algorithmName = "Ascon-XofA"; - break; - default: - throw new ArgumentException("Invalid parameter settings for Ascon Hash"); - } - Reset(); - } - - private AsconParameters asconParameters; + private readonly AsconParameters m_asconParameters; + private readonly int ASCON_PB_ROUNDS; - private string algorithmName; - - private readonly MemoryStream buffer = new MemoryStream(); private ulong x0; private ulong x1; private ulong x2; private ulong x3; private ulong x4; - private readonly int CRYPTO_BYTES = 32; - private int ASCON_PB_ROUNDS; - - public string AlgorithmName => algorithmName; - private ulong ROR(ulong x, int n) - { - return x >> n | x << (64 - n); - } + private readonly byte[] m_buf = new byte[8]; + private int m_bufPos = 0; - private void ROUND(ulong C) + public AsconDigest(AsconParameters parameters) { - ulong t0 = x0 ^ x1 ^ x2 ^ x3 ^ C ^ (x1 & (x0 ^ x2 ^ x4 ^ C)); - ulong t1 = x0 ^ x2 ^ x3 ^ x4 ^ C ^ ((x1 ^ x2 ^ C) & (x1 ^ x3)); - ulong t2 = x1 ^ x2 ^ x4 ^ C ^ (x3 & x4); - ulong t3 = x0 ^ x1 ^ x2 ^ C ^ ((~x0) & (x3 ^ x4)); - ulong t4 = x1 ^ x3 ^ x4 ^ ((x0 ^ x4) & x1); - x0 = t0 ^ ROR(t0, 19) ^ ROR(t0, 28); - x1 = t1 ^ ROR(t1, 39) ^ ROR(t1, 61); - x2 = ~(t2 ^ ROR(t2, 1) ^ ROR(t2, 6)); - x3 = t3 ^ ROR(t3, 10) ^ ROR(t3, 17); - x4 = t4 ^ ROR(t4, 7) ^ ROR(t4, 41); + m_asconParameters = parameters; + switch (parameters) + { + case AsconParameters.AsconHash: + ASCON_PB_ROUNDS = 12; + break; + case AsconParameters.AsconHashA: + ASCON_PB_ROUNDS = 8; + break; + case AsconParameters.AsconXof: + ASCON_PB_ROUNDS = 12; + break; + case AsconParameters.AsconXofA: + ASCON_PB_ROUNDS = 8; + break; + default: + throw new ArgumentException("Invalid parameter settings for Ascon Hash"); + } + Reset(); } - private void P(int nr) + public string AlgorithmName { - if (nr == 12) + get { - ROUND(0xf0UL); - ROUND(0xe1UL); - ROUND(0xd2UL); - ROUND(0xc3UL); + switch (m_asconParameters) + { + case AsconParameters.AsconHash: return "Ascon-Hash"; + case AsconParameters.AsconHashA: return "Ascon-HashA"; + case AsconParameters.AsconXof: return "Ascon-Xof"; + case AsconParameters.AsconXofA: return "Ascon-XofA"; + default: throw new InvalidOperationException(); + } } - if (nr >= 8) - { - ROUND(0xb4UL); - ROUND(0xa5UL); - } - ROUND(0x96UL); - ROUND(0x87UL); - ROUND(0x78UL); - ROUND(0x69UL); - ROUND(0x5aUL); - ROUND(0x4bUL); } - private ulong PAD(int i) - { - return 0x80UL << (56 - (i << 3)); - } + public int GetDigestSize() => 32; + + public int GetByteLength() => 8; - private ulong LOADBYTES(byte[] bytes, int inOff, int n) + public void Update(byte input) { - ulong x = 0; - for (int i = 0; i < n; ++i) + m_buf[m_bufPos] = input; + if (++m_bufPos == 8) { - x |= (bytes[i + inOff] & 0xFFUL) << ((7 - i) << 3); + x0 ^= Pack.BE_To_UInt64(m_buf, 0); + P(ASCON_PB_ROUNDS); + m_bufPos = 0; } - return x; } - private void STOREBYTES(byte[] bytes, int inOff, ulong w, int n) + public void BlockUpdate(byte[] input, int inOff, int inLen) { - for (int i = 0; i < n; ++i) + Check.DataLength(input, inOff, inLen, "input buffer too short"); + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + BlockUpdate(input.AsSpan(inOff, inLen)); +#else + if (inLen < 1) + return; + + int available = 8 - m_bufPos; + if (inLen < available) { - bytes[i + inOff] = (byte)(w >> ((7 - i) << 3)); + Array.Copy(input, inOff, m_buf, m_bufPos, inLen); + m_bufPos += inLen; + return; } - } - public int GetDigestSize() - { - return CRYPTO_BYTES; - } + int inPos = 0; + if (m_bufPos > 0) + { + Array.Copy(input, inOff, m_buf, m_bufPos, available); + inPos += available; + x0 ^= Pack.BE_To_UInt64(m_buf, 0); + P(ASCON_PB_ROUNDS); + } + int remaining; + while ((remaining = inLen - inPos) >= 8) + { + x0 ^= Pack.BE_To_UInt64(input, inOff + inPos); + P(ASCON_PB_ROUNDS); + inPos += 8; + } - public void Update(byte input) - { - buffer.Write(new byte[] { input }, 0, 1); + Array.Copy(input, inOff + inPos, m_buf, 0, remaining); + m_bufPos = remaining; +#endif } - - public void BlockUpdate(byte[] input, int inOff, int len) +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public void BlockUpdate(ReadOnlySpan<byte> input) { - if ((inOff + len) > input.Length) + int available = 8 - m_bufPos; + if (input.Length < available) { - throw new DataLengthException("input buffer too ushort"); + input.CopyTo(m_buf.AsSpan(m_bufPos)); + m_bufPos += input.Length; + return; } - buffer.Write(input, inOff, len); - } - - public int DoFinal(byte[] output, int outOff) - { - if (CRYPTO_BYTES + outOff > output.Length) + if (m_bufPos > 0) { - throw new OutputLengthException("output buffer is too ushort"); + input[..available].CopyTo(m_buf.AsSpan(m_bufPos)); + x0 ^= Pack.BE_To_UInt64(m_buf); + P(ASCON_PB_ROUNDS); + input = input[available..]; } - byte[] input = buffer.GetBuffer(); - int len = (int)buffer.Length; - int inOff = 0; - ///* initialize */ - //x0 = ASCON_IV; - //x1 = 0; - //x2 = 0; - //x3 = 0; - //x4 = 0; - //P(ASCON_PA_ROUNDS); - /* absorb full plaintext blocks */ - int ASCON_HASH_RATE = 8; - while (len >= ASCON_HASH_RATE) + + while (input.Length >= 8) { - x0 ^= LOADBYTES(input, inOff, 8); + x0 ^= Pack.BE_To_UInt64(input); P(ASCON_PB_ROUNDS); - inOff += ASCON_HASH_RATE; - len -= ASCON_HASH_RATE; + input = input[8..]; } - /* absorb readonly plaintext block */ - x0 ^= LOADBYTES(input, inOff, len); - x0 ^= PAD(len); - int ASCON_PA_ROUNDS = 12; - P(ASCON_PA_ROUNDS); - /* squeeze full output blocks */ - len = CRYPTO_BYTES; - while (len > ASCON_HASH_RATE) + + input.CopyTo(m_buf); + m_bufPos = input.Length; + } +#endif + + public int DoFinal(byte[] output, int outOff) + { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + return DoFinal(output.AsSpan(outOff)); +#else + Check.OutputLength(output, outOff, 32, "output buffer is too short"); + + m_buf[m_bufPos] = 0x80; + x0 ^= Pack.BE_To_UInt64(m_buf, 0) & (ulong.MaxValue << (56 - (m_bufPos << 3))); + + P(12); + Pack.UInt64_To_BE(x0, output, outOff); + + for (int i = 0; i < 3; ++i) { - STOREBYTES(output, outOff, x0, 8); + outOff += 8; + P(ASCON_PB_ROUNDS); - outOff += ASCON_HASH_RATE; - len -= ASCON_HASH_RATE; + Pack.UInt64_To_BE(x0, output, outOff); } - /* squeeze readonly output block */ - STOREBYTES(output, outOff, x0, len); + Reset(); - return CRYPTO_BYTES; + return 32; +#endif } - - public void Reset() +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public int DoFinal(Span<byte> output) { - buffer.SetLength(0); - /* initialize */ - switch (asconParameters) + Check.OutputLength(output, 32, "output buffer is too short"); + + m_buf[m_bufPos] = 0x80; + x0 ^= Pack.BE_To_UInt64(m_buf) & (ulong.MaxValue << (56 - (m_bufPos << 3))); + + P(12); + Pack.UInt64_To_BE(x0, output); + + for (int i = 0; i < 3; ++i) { - case AsconParameters.AsconHashA: - x0 = 92044056785660070UL; - x1 = 8326807761760157607UL; - x2 = 3371194088139667532UL; - x3 = 15489749720654559101UL; - x4 = 11618234402860862855UL; - break; - case AsconParameters.AsconHash: - x0 = 17191252062196199485UL; - x1 = 10066134719181819906UL; - x2 = 13009371945472744034UL; - x3 = 4834782570098516968UL; - x4 = 3787428097924915520UL; - break; - case AsconParameters.AsconXof: - x0 = 13077933504456348694UL; - x1 = 3121280575360345120UL; - x2 = 7395939140700676632UL; - x3 = 6533890155656471820UL; - x4 = 5710016986865767350UL; - break; - case AsconParameters.AsconXofA: - x0 = 4940560291654768690UL; - x1 = 14811614245468591410UL; - x2 = 17849209150987444521UL; - x3 = 2623493988082852443UL; - x4 = 12162917349548726079UL; - break; + output = output[8..]; + + P(ASCON_PB_ROUNDS); + Pack.UInt64_To_BE(x0, output); } + + Reset(); + return 32; } +#endif - public int GetByteLength() + public void Reset() { - throw new NotImplementedException(); + Array.Clear(m_buf, 0, m_buf.Length); + m_bufPos = 0; + + switch (m_asconParameters) + { + case AsconParameters.AsconHashA: + x0 = 92044056785660070UL; + x1 = 8326807761760157607UL; + x2 = 3371194088139667532UL; + x3 = 15489749720654559101UL; + x4 = 11618234402860862855UL; + break; + case AsconParameters.AsconHash: + x0 = 17191252062196199485UL; + x1 = 10066134719181819906UL; + x2 = 13009371945472744034UL; + x3 = 4834782570098516968UL; + x4 = 3787428097924915520UL; + break; + case AsconParameters.AsconXof: + x0 = 13077933504456348694UL; + x1 = 3121280575360345120UL; + x2 = 7395939140700676632UL; + x3 = 6533890155656471820UL; + x4 = 5710016986865767350UL; + break; + case AsconParameters.AsconXofA: + x0 = 4940560291654768690UL; + x1 = 14811614245468591410UL; + x2 = 17849209150987444521UL; + x3 = 2623493988082852443UL; + x4 = 12162917349548726079UL; + break; + default: + throw new InvalidOperationException(); + } } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - public int DoFinal(Span<byte> output) + private void P(int nr) { - byte[] rv = new byte[32]; - int rlt = DoFinal(rv, 0); - rv.AsSpan(0, 32).CopyTo(output); - return rlt; + if (nr == 12) + { + ROUND(0xf0UL); + ROUND(0xe1UL); + ROUND(0xd2UL); + ROUND(0xc3UL); + } + ROUND(0xb4UL); + ROUND(0xa5UL); + ROUND(0x96UL); + ROUND(0x87UL); + ROUND(0x78UL); + ROUND(0x69UL); + ROUND(0x5aUL); + ROUND(0x4bUL); } - public void BlockUpdate(ReadOnlySpan<byte> input) +#if NETSTANDARD1_0_OR_GREATER || NETCOREAPP1_0_OR_GREATER + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#endif + private void ROUND(ulong C) { - buffer.Write(input.ToArray(), 0, input.Length); + ulong t0 = x0 ^ x1 ^ x2 ^ x3 ^ C ^ (x1 & (x0 ^ x2 ^ x4 ^ C)); + ulong t1 = x0 ^ x2 ^ x3 ^ x4 ^ C ^ ((x1 ^ x2 ^ C) & (x1 ^ x3)); + ulong t2 = x1 ^ x2 ^ x4 ^ C ^ (x3 & x4); + ulong t3 = x0 ^ x1 ^ x2 ^ C ^ (~x0 & (x3 ^ x4)); + ulong t4 = x1 ^ x3 ^ x4 ^ ((x0 ^ x4) & x1); + x0 = t0 ^ Longs.RotateRight(t0, 19) ^ Longs.RotateRight(t0, 28); + x1 = t1 ^ Longs.RotateRight(t1, 39) ^ Longs.RotateRight(t1, 61); + x2 = ~(t2 ^ Longs.RotateRight(t2, 1) ^ Longs.RotateRight(t2, 6)); + x3 = t3 ^ Longs.RotateRight(t3, 10) ^ Longs.RotateRight(t3, 17); + x4 = t4 ^ Longs.RotateRight(t4, 7) ^ Longs.RotateRight(t4, 41); } -#endif } } - diff --git a/crypto/src/crypto/digests/ISAPDigest.cs b/crypto/src/crypto/digests/ISAPDigest.cs index 3be28e4e2..348242e6e 100644 --- a/crypto/src/crypto/digests/ISAPDigest.cs +++ b/crypto/src/crypto/digests/ISAPDigest.cs @@ -1,149 +1,165 @@ using System; using System.IO; +#if NETSTANDARD1_0_OR_GREATER || NETCOREAPP1_0_OR_GREATER +using System.Runtime.CompilerServices; +#endif + using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Crypto.Digests { - public class ISAPDigest : IDigest + public sealed class IsapDigest + : IDigest { private ulong x0, x1, x2, x3, x4; private ulong t0, t1, t2, t3, t4; private MemoryStream buffer = new MemoryStream(); - private void ROUND(ulong C) - { - t0 = x0 ^ x1 ^ x2 ^ x3 ^ C ^ (x1 & (x0 ^ x2 ^ x4 ^ C)); - t1 = x0 ^ x2 ^ x3 ^ x4 ^ C ^ ((x1 ^ x2 ^ C) & (x1 ^ x3)); - t2 = x1 ^ x2 ^ x4 ^ C ^ (x3 & x4); - t3 = x0 ^ x1 ^ x2 ^ C ^ ((~x0) & (x3 ^ x4)); - t4 = x1 ^ x3 ^ x4 ^ ((x0 ^ x4) & x1); - x0 = t0 ^ ROTR(t0, 19) ^ ROTR(t0, 28); - x1 = t1 ^ ROTR(t1, 39) ^ ROTR(t1, 61); - x2 = ~(t2 ^ ROTR(t2, 1) ^ ROTR(t2, 6)); - x3 = t3 ^ ROTR(t3, 10) ^ ROTR(t3, 17); - x4 = t4 ^ ROTR(t4, 7) ^ ROTR(t4, 41); - } - - private void P12() - { - ROUND(0xf0); - ROUND(0xe1); - ROUND(0xd2); - ROUND(0xc3); - ROUND(0xb4); - ROUND(0xa5); - ROUND(0x96); - ROUND(0x87); - ROUND(0x78); - ROUND(0x69); - ROUND(0x5a); - ROUND(0x4b); - } + public string AlgorithmName => "ISAP Hash"; - private ulong ROTR(ulong x, int n) - { - return (x >> n) | (x << (64 - n)); - } + public int GetDigestSize() => 32; - protected ulong U64BIG(ulong x) - { - return ((ROTR(x, 8) & (0xFF000000FF000000UL)) | (ROTR(x, 24) & (0x00FF000000FF0000UL)) | - (ROTR(x, 40) & (0x0000FF000000FF00UL)) | (ROTR(x, 56) & (0x000000FF000000FFUL))); - } + public int GetByteLength() => 8; - public string AlgorithmName + public void Update(byte input) { - get { return "ISAP Hash"; } + buffer.WriteByte(input); } public void BlockUpdate(byte[] input, int inOff, int inLen) { - if (inOff + inLen > input.Length) - { - throw new DataLengthException("input buffer too short"); - } + Check.DataLength(input, inOff, inLen, "input buffer too short"); + buffer.Write(input, inOff, inLen); } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public void BlockUpdate(ReadOnlySpan<byte> input) { - buffer.Write(input.ToArray(), 0, input.Length); - } - - public int DoFinal(Span<byte> output) - { - byte[] rv = new byte[32]; - int rlt = DoFinal(rv, 0); - rv.AsSpan(0, 32).CopyTo(output); - return rlt; + buffer.Write(input); } - #endif public int DoFinal(byte[] output, int outOff) { - if (32 + outOff > output.Length) - { - throw new OutputLengthException("output buffer is too short"); - } +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + return DoFinal(output.AsSpan(outOff)); +#else + Check.OutputLength(output, outOff, 32, "output buffer is too short"); + t0 = t1 = t2 = t3 = t4 = 0; + /* init state */ x0 = 17191252062196199485UL; x1 = 10066134719181819906UL; x2 = 13009371945472744034UL; x3 = 4834782570098516968UL; x4 = 3787428097924915520UL; - /* absorb */ + byte[] input = buffer.GetBuffer(); - int len = (int)buffer.Length; - ulong[] in64 = new ulong[len >> 3]; - Pack.LE_To_UInt64(input, 0, in64, 0, in64.Length); - int idx = 0; + int len = Convert.ToInt32(buffer.Length); + + int pos = 0; while (len >= 8) { - x0 ^= U64BIG(in64[idx++]); - P12(); + x0 ^= Pack.BE_To_UInt64(input, pos); + pos += 8; len -= 8; + P12(); } - /* absorb final input block */ x0 ^= 0x80UL << ((7 - len) << 3); - while (len > 0) + if (len > 0) { - x0 ^= (input[(idx << 3) + --len] & 0xFFUL) << ((7 - len) << 3); + x0 ^= Pack.BE_To_UInt64_High(input, pos, len); } - P12(); - // squeeze - ulong[] out64 = new ulong[4]; - for (idx = 0; idx < 3; ++idx) + + for (int i = 0; i < 4; ++i) { - out64[idx] = U64BIG(x0); P12(); + Pack.UInt64_To_BE(x0, output, outOff + (i << 3)); } - /* squeeze final output block */ - out64[idx] = U64BIG(x0); - Pack.UInt64_To_LE(out64, output, outOff); + return 32; +#endif } - public int GetByteLength() +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public int DoFinal(Span<byte> output) { - throw new NotImplementedException(); - } + Check.OutputLength(output, 32, "output buffer is too short"); + + t0 = t1 = t2 = t3 = t4 = 0; + + /* init state */ + x0 = 17191252062196199485UL; + x1 = 10066134719181819906UL; + x2 = 13009371945472744034UL; + x3 = 4834782570098516968UL; + x4 = 3787428097924915520UL; + + if (!buffer.TryGetBuffer(out var bufferContents)) + throw new UnauthorizedAccessException(); + + var input = bufferContents.AsSpan(); + while (input.Length >= 8) + { + x0 ^= Pack.BE_To_UInt64(input); + input = input[8..]; + P12(); + } + x0 ^= 0x80UL << ((7 - input.Length) << 3); + if (!input.IsEmpty) + { + x0 ^= Pack.BE_To_UInt64_High(input); + } + + for (int i = 0; i < 4; ++i) + { + P12(); + Pack.UInt64_To_BE(x0, output[(i << 3)..]); + } - public int GetDigestSize() - { return 32; } +#endif public void Reset() { buffer.SetLength(0); } - public void Update(byte input) + private void P12() { - buffer.Write(new byte[] { input }, 0, 1); + ROUND(0xf0); + ROUND(0xe1); + ROUND(0xd2); + ROUND(0xc3); + ROUND(0xb4); + ROUND(0xa5); + ROUND(0x96); + ROUND(0x87); + ROUND(0x78); + ROUND(0x69); + ROUND(0x5a); + ROUND(0x4b); + } + +#if NETSTANDARD1_0_OR_GREATER || NETCOREAPP1_0_OR_GREATER + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#endif + private void ROUND(ulong C) + { + t0 = x0 ^ x1 ^ x2 ^ x3 ^ C ^ (x1 & (x0 ^ x2 ^ x4 ^ C)); + t1 = x0 ^ x2 ^ x3 ^ x4 ^ C ^ ((x1 ^ x2 ^ C) & (x1 ^ x3)); + t2 = x1 ^ x2 ^ x4 ^ C ^ (x3 & x4); + t3 = x0 ^ x1 ^ x2 ^ C ^ ((~x0) & (x3 ^ x4)); + t4 = x1 ^ x3 ^ x4 ^ ((x0 ^ x4) & x1); + x0 = t0 ^ Longs.RotateRight(t0, 19) ^ Longs.RotateRight(t0, 28); + x1 = t1 ^ Longs.RotateRight(t1, 39) ^ Longs.RotateRight(t1, 61); + x2 = ~(t2 ^ Longs.RotateRight(t2, 1) ^ Longs.RotateRight(t2, 6)); + x3 = t3 ^ Longs.RotateRight(t3, 10) ^ Longs.RotateRight(t3, 17); + x4 = t4 ^ Longs.RotateRight(t4, 7) ^ Longs.RotateRight(t4, 41); } } } diff --git a/crypto/src/crypto/digests/PhotonBeetleDigest.cs b/crypto/src/crypto/digests/PhotonBeetleDigest.cs index 13b30e025..1af8aee2c 100644 --- a/crypto/src/crypto/digests/PhotonBeetleDigest.cs +++ b/crypto/src/crypto/digests/PhotonBeetleDigest.cs @@ -67,19 +67,19 @@ namespace Org.BouncyCastle.Crypto.Digests public String AlgorithmName => "Photon-Beetle Hash"; + public int GetDigestSize() => TAG_INBYTES; - public int GetDigestSize() + public int GetByteLength() { - return TAG_INBYTES; + // TODO + throw new NotImplementedException(); } - public void Update(byte input) { - buffer.Write(new byte[] { input }, 0, 1); + buffer.WriteByte(input); } - public void BlockUpdate(byte[] input, int inOff, int len) { if ((inOff + len) > input.Length) @@ -223,10 +223,6 @@ namespace Org.BouncyCastle.Crypto.Digests } } - public int GetByteLength() - { - throw new NotImplementedException(); - } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public int DoFinal(Span<byte> output) diff --git a/crypto/src/crypto/digests/SparkleDigest.cs b/crypto/src/crypto/digests/SparkleDigest.cs index b8134dd91..ad558effc 100644 --- a/crypto/src/crypto/digests/SparkleDigest.cs +++ b/crypto/src/crypto/digests/SparkleDigest.cs @@ -1,23 +1,26 @@ using System; using System.IO; + using Org.BouncyCastle.Crypto.Utilities; using Org.BouncyCastle.Utilities; -/** - * Sparkle v1.2, based on the current round 3 submission, https://sparkle-lwc.github.io/ - * Reference C implementation: https://github.com/cryptolu/sparkle - * Specification: https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-spec-doc/sparkle-spec-final.pdf - */ - namespace Org.BouncyCastle.Crypto.Digests { - public class SparkleDigest : IDigest + /// <summary>Sparkle v1.2, based on the current round 3 submission, https://sparkle-lwc.github.io/ .</summary> + /// <remarks> + /// Reference C implementation: https://github.com/cryptolu/sparkle.<br/> + /// Specification: + /// https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-spec-doc/sparkle-spec-final.pdf . + /// </remarks> + public class SparkleDigest + : IDigest { public enum SparkleParameters { ESCH256, ESCH384 } + private string algorithmName; private readonly uint[] state; private MemoryStream message = new MemoryStream(); @@ -36,22 +39,22 @@ namespace Org.BouncyCastle.Crypto.Digests int SPARKLE_RATE = 128; switch (sparkleParameters) { - case SparkleParameters.ESCH256: - ESCH_DIGEST_LEN = 256; - SPARKLE_STATE = 384; - SPARKLE_STEPS_SLIM = 7; - SPARKLE_STEPS_BIG = 11; - algorithmName = "ESCH-256"; - break; - case SparkleParameters.ESCH384: - ESCH_DIGEST_LEN = 384; - SPARKLE_STATE = 512; - SPARKLE_STEPS_SLIM = 8; - SPARKLE_STEPS_BIG = 12; - algorithmName = "ESCH-384"; - break; - default: - throw new ArgumentException("Invalid definition of SCHWAEMM instance"); + case SparkleParameters.ESCH256: + ESCH_DIGEST_LEN = 256; + SPARKLE_STATE = 384; + SPARKLE_STEPS_SLIM = 7; + SPARKLE_STEPS_BIG = 11; + algorithmName = "ESCH-256"; + break; + case SparkleParameters.ESCH384: + ESCH_DIGEST_LEN = 384; + SPARKLE_STATE = 512; + SPARKLE_STEPS_SLIM = 8; + SPARKLE_STEPS_BIG = 12; + algorithmName = "ESCH-384"; + break; + default: + throw new ArgumentException("Invalid definition of SCHWAEMM instance"); } STATE_BRANS = SPARKLE_STATE >> 6; STATE_WORDS = SPARKLE_STATE >> 5; @@ -61,14 +64,9 @@ namespace Org.BouncyCastle.Crypto.Digests state = new uint[STATE_WORDS]; } - private uint ROT(uint x, int n) - { - return (((x) >> n) | ((x) << (32 - n))); - } - private uint ELL(uint x) { - return ROT(((x) ^ ((x) << 16)), 16); + return Integers.RotateRight(x ^ (x << 16), 16); } private static readonly uint[] RCON = {0xB7E15162, 0xBF715880, 0x38B4DA56, 0x324E7738, 0xBB1185EB, 0x4F7C7B57, @@ -86,17 +84,17 @@ namespace Org.BouncyCastle.Crypto.Digests for (j = 0; j < 2 * brans; j += 2) { rc = RCON[j >> 1]; - state[j] += ROT(state[j + 1], 31); - state[j + 1] ^= ROT(state[j], 24); + state[j] += Integers.RotateRight(state[j + 1], 31); + state[j + 1] ^= Integers.RotateRight(state[j], 24); state[j] ^= rc; - state[j] += ROT(state[j + 1], 17); - state[j + 1] ^= ROT(state[j], 17); + state[j] += Integers.RotateRight(state[j + 1], 17); + state[j + 1] ^= Integers.RotateRight(state[j], 17); state[j] ^= rc; state[j] += state[j + 1]; - state[j + 1] ^= ROT(state[j], 31); + state[j + 1] ^= Integers.RotateRight(state[j], 31); state[j] ^= rc; - state[j] += ROT(state[j + 1], 24); - state[j + 1] ^= ROT(state[j], 16); + state[j] += Integers.RotateRight(state[j + 1], 24); + state[j + 1] ^= Integers.RotateRight(state[j], 16); state[j] ^= rc; } // Linear layer @@ -226,7 +224,6 @@ namespace Org.BouncyCastle.Crypto.Digests public string AlgorithmName => algorithmName; - public void Update(byte input) { message.Write(new byte[] { input }, 0, 1); @@ -240,7 +237,7 @@ namespace Org.BouncyCastle.Crypto.Digests public int GetByteLength() { - return STATE_WORDS; + return RATE_BYTES; } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER @@ -258,7 +255,5 @@ namespace Org.BouncyCastle.Crypto.Digests return DIGEST_BYTES; } #endif - } } - diff --git a/crypto/src/crypto/engines/AsconEngine.cs b/crypto/src/crypto/engines/AsconEngine.cs index 21607483d..e8848c3d8 100644 --- a/crypto/src/crypto/engines/AsconEngine.cs +++ b/crypto/src/crypto/engines/AsconEngine.cs @@ -224,7 +224,7 @@ namespace Org.BouncyCastle.Crypto.Engines return DoFinal(outBytes.AsSpan(outOff)); #else if (!initialised) - throw new ArgumentException("Need call init function before encryption/decryption"); + throw new ArgumentException("Need to call Init before encryption/decryption"); if (!aadFinished) { @@ -265,7 +265,7 @@ namespace Org.BouncyCastle.Crypto.Engines Reset(true); if (result != 0UL) - throw new ArgumentException("Mac does not match"); + throw new InvalidCipherTextException("mac check in " + AlgorithmName + " failed"); return len; } @@ -276,7 +276,7 @@ namespace Org.BouncyCastle.Crypto.Engines public int DoFinal(Span<byte> output) { if (!initialised) - throw new ArgumentException("Need call init function before encryption/decryption"); + throw new ArgumentException("Need to call Init before encryption/decryption"); if (!aadFinished) { @@ -317,7 +317,7 @@ namespace Org.BouncyCastle.Crypto.Engines Reset(true); if (result != 0UL) - throw new ArgumentException("Mac does not match"); + throw new InvalidCipherTextException("mac check in " + AlgorithmName + " failed"); return len; } @@ -838,7 +838,7 @@ namespace Org.BouncyCastle.Crypto.Engines private void Reset(bool clearMac) { if (!initialised) - throw new ArgumentException("Need call init function before encryption/decryption"); + throw new ArgumentException("Need to call Init function before encryption/decryption"); x0 = x1 = x2 = x3 = x4 = 0; ascon_aeadinit(); diff --git a/crypto/src/crypto/engines/ElephantEngine.cs b/crypto/src/crypto/engines/ElephantEngine.cs index d5f05f658..4e0e3216d 100644 --- a/crypto/src/crypto/engines/ElephantEngine.cs +++ b/crypto/src/crypto/engines/ElephantEngine.cs @@ -70,32 +70,32 @@ namespace Org.BouncyCastle.Crypto.Engines { switch (parameters) { - case ElephantParameters.elephant160: - BLOCK_SIZE = 20; - nBits = 160; - nSBox = 20; - nRounds = 80; - lfsrIV = 0x75; - CRYPTO_ABYTES = 8; - algorithmName = "Elephant 160 AEAD"; - break; - case ElephantParameters.elephant176: - BLOCK_SIZE = 22; - nBits = 176; - nSBox = 22; - nRounds = 90; - lfsrIV = 0x45; - CRYPTO_ABYTES = 8; - algorithmName = "Elephant 176 AEAD"; - break; - case ElephantParameters.elephant200: - BLOCK_SIZE = 25; - nRounds = 18; - CRYPTO_ABYTES = 16; - algorithmName = "Elephant 200 AEAD"; - break; - default: - throw new ArgumentException("Invalid parameter settings for Elephant"); + case ElephantParameters.elephant160: + BLOCK_SIZE = 20; + nBits = 160; + nSBox = 20; + nRounds = 80; + lfsrIV = 0x75; + CRYPTO_ABYTES = 8; + algorithmName = "Elephant 160 AEAD"; + break; + case ElephantParameters.elephant176: + BLOCK_SIZE = 22; + nBits = 176; + nSBox = 22; + nRounds = 90; + lfsrIV = 0x45; + CRYPTO_ABYTES = 8; + algorithmName = "Elephant 176 AEAD"; + break; + case ElephantParameters.elephant200: + BLOCK_SIZE = 25; + nRounds = 18; + CRYPTO_ABYTES = 16; + algorithmName = "Elephant 200 AEAD"; + break; + default: + throw new ArgumentException("Invalid parameter settings for Elephant"); } this.parameters = parameters; initialised = false; @@ -316,40 +316,25 @@ namespace Org.BouncyCastle.Crypto.Engines } } - - public void Init(bool forEncryption, ICipherParameters param) { this.forEncryption = forEncryption; - if (!(param is ParametersWithIV)) - { - throw new ArgumentException( - "Elephant init parameters must include an IV"); - } - ParametersWithIV ivParams = (ParametersWithIV)param; + if (!(param is ParametersWithIV ivParams)) + throw new ArgumentException("Elephant init parameters must include an IV"); npub = ivParams.GetIV(); if (npub == null || npub.Length != 12) - { - throw new ArgumentException( - "Elephant requires exactly 12 bytes of IV"); - } + throw new ArgumentException("Elephant requires exactly 12 bytes of IV"); - if (!(ivParams.Parameters is KeyParameter)) - { - throw new ArgumentException( - "Elephant init parameters must include a key"); - } + if (!(ivParams.Parameters is KeyParameter key)) + throw new ArgumentException("Elephant init parameters must include a key"); - KeyParameter key = (KeyParameter)ivParams.Parameters; byte[] k = key.GetKey(); if (k.Length != 16) - { - throw new ArgumentException( - "Elephant key must be 128 bits long"); - } + throw new ArgumentException("Elephant key must be 128 bits long"); + // Storage for the expanded key L expanded_key = new byte[BLOCK_SIZE]; Array.Copy(k, 0, expanded_key, 0, CRYPTO_KEYBYTES); @@ -365,44 +350,35 @@ namespace Org.BouncyCastle.Crypto.Engines public void ProcessAadByte(byte input) { - aadData.Write(new byte[] { input }, 0, 1); + aadData.WriteByte(input); } - - public void ProcessAadBytes(byte[] input, int inOff, int len) + public void ProcessAadBytes(byte[] inBytes, int inOff, int len) { - if (inOff + len > input.Length) - { - throw new DataLengthException("input buffer too short"); - } - aadData.Write(input, inOff, len); - } + Check.DataLength(inBytes, inOff, len, "input buffer too short"); + aadData.Write(inBytes, inOff, len); + } - public int ProcessByte(byte input, byte[] output, int outOff) + public int ProcessByte(byte input, byte[] outBytes, int outOff) { - message.Write(new byte[] { input }, 0, 1); + message.Write(new byte[]{ input }, 0, 1); return 0; } - - public int ProcessBytes(byte[] input, int inOff, int len, byte[] output, int outOff) + public int ProcessBytes(byte[] inBytes, int inOff, int len, byte[] outBytes, int outOff) { - if (inOff + len > input.Length) - { - throw new DataLengthException("input buffer too short"); - } - message.Write(input, inOff, len); + Check.DataLength(inBytes, inOff, len, "input buffer too short"); + + message.Write(inBytes, inOff, len); return 0; } - public int DoFinal(byte[] output, int outOff) { if (!initialised) - { - throw new ArgumentException("Need call init function before encryption/decryption"); - } + throw new ArgumentException("Need to call Init function before encryption/decryption"); + int mlen = (int)message.Length - (forEncryption ? 0 : CRYPTO_ABYTES); if ((forEncryption && mlen + outOff + CRYPTO_ABYTES > output.Length) || (!forEncryption && mlen + outOff - CRYPTO_ABYTES > output.Length)) @@ -493,37 +469,28 @@ namespace Org.BouncyCastle.Crypto.Engines } else { - for (int i = 0; i < CRYPTO_ABYTES; ++i) - { - if (tag_buffer[i] != m[mlen + i]) - { - throw new ArgumentException("Mac does not match"); - } - } + if (!Arrays.FixedTimeEquals(CRYPTO_ABYTES, tag_buffer, 0, m, mlen)) + throw new InvalidCipherTextException("mac check in " + AlgorithmName + " failed"); } reset(false); return mlen; } - public byte[] GetMac() { return tag; } - public int GetUpdateOutputSize(int len) { return len; } - public int GetOutputSize(int len) { return len + CRYPTO_ABYTES; } - public void Reset() { reset(true); @@ -547,7 +514,7 @@ namespace Org.BouncyCastle.Crypto.Engines public int ProcessByte(byte input, Span<byte> output) { - message.Write(new byte[] { input }); + message.Write(new byte[]{ input }); return 0; } diff --git a/crypto/src/crypto/engines/ISAPEngine.cs b/crypto/src/crypto/engines/ISAPEngine.cs index 8be5a79b2..7ef629d1b 100644 --- a/crypto/src/crypto/engines/ISAPEngine.cs +++ b/crypto/src/crypto/engines/ISAPEngine.cs @@ -921,7 +921,7 @@ namespace Org.BouncyCastle.Crypto.Engines return DoFinal(outBytes.AsSpan(outOff)); #else if (!initialised) - throw new ArgumentException("Need call init function before encryption/decryption"); + throw new ArgumentException("Need to call Init before encryption/decryption"); byte[] aad = aadData.GetBuffer(); byte[] msg = message.GetBuffer(); @@ -949,7 +949,8 @@ namespace Org.BouncyCastle.Crypto.Engines ISAPAEAD.isap_mac(aad, aadLen, msg, outLen, mac, 0); ISAPAEAD.reset(); if (!Arrays.FixedTimeEquals(16, mac, 0, msg, outLen)) - throw new ArgumentException("Mac does not match"); + throw new InvalidCipherTextException("mac check in " + AlgorithmName + " failed"); + ISAPAEAD.isap_enc(msg, 0, outLen, outBytes, outOff); } return outLen; @@ -960,7 +961,7 @@ namespace Org.BouncyCastle.Crypto.Engines public int DoFinal(Span<byte> output) { if (!initialised) - throw new ArgumentException("Need call init function before encryption/decryption"); + throw new ArgumentException("Need to call Init before encryption/decryption"); byte[] aad = aadData.GetBuffer(); byte[] msg = message.GetBuffer(); @@ -988,7 +989,8 @@ namespace Org.BouncyCastle.Crypto.Engines ISAPAEAD.isap_mac(aad, aadLen, msg, outLen, mac, 0); ISAPAEAD.reset(); if (!Arrays.FixedTimeEquals(16, mac, 0, msg, outLen)) - throw new ArgumentException("Mac does not match"); + throw new InvalidCipherTextException("mac check in " + AlgorithmName + " failed"); + ISAPAEAD.isap_enc(msg.AsSpan(0, outLen), output); } return outLen; @@ -1022,7 +1024,7 @@ namespace Org.BouncyCastle.Crypto.Engines public void Reset() { if (!initialised) - throw new ArgumentException("Need call init function before encryption/decryption"); + throw new ArgumentException("Need to call Init before encryption/decryption"); aadData.SetLength(0); ISAPAEAD.reset(); diff --git a/crypto/src/crypto/engines/PhotonBeetleEngine.cs b/crypto/src/crypto/engines/PhotonBeetleEngine.cs index 0d5728a76..e593bb6f5 100644 --- a/crypto/src/crypto/engines/PhotonBeetleEngine.cs +++ b/crypto/src/crypto/engines/PhotonBeetleEngine.cs @@ -3,6 +3,7 @@ using System.IO; using Org.BouncyCastle.Crypto.Modes; using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Crypto.Engines { @@ -150,37 +151,32 @@ namespace Org.BouncyCastle.Crypto.Engines aadData.Write(new byte[] { input }, 0, 1); } - public void ProcessAadBytes(byte[] input, int inOff, int len) + public void ProcessAadBytes(byte[] inBytes, int inOff, int len) { - if (inOff + len > input.Length) - { - throw new DataLengthException("input buffer too short"); - } - aadData.Write(input, inOff, len); + Check.DataLength(inBytes, inOff, len, "input buffer too short"); + + aadData.Write(inBytes, inOff, len); } - public int ProcessByte(byte input, byte[] output, int outOff) + public int ProcessByte(byte input, byte[] outBytes, int outOff) { - message.Write(new byte[] { input }, 0, 1); + message.WriteByte(input); return 0; } - public int ProcessBytes(byte[] input, int inOff, int len, byte[] output, int outOff) + public int ProcessBytes(byte[] inBytes, int inOff, int len, byte[] outBytes, int outOff) { - if (inOff + len > input.Length) - { - throw new DataLengthException("input buffer too short"); - } - message.Write(input, inOff, len); + Check.DataLength(inBytes, inOff, len, "input buffer too short"); + + message.Write(inBytes, inOff, len); return 0; } public void Reset() { if (!initialised) - { - throw new ArgumentException("Need call init function before encryption/decryption"); - } + throw new ArgumentException("Need to call Init before encryption/decryption"); + reset(true); } @@ -323,9 +319,8 @@ namespace Org.BouncyCastle.Crypto.Engines public int DoFinal(byte[] output, int outOff) { if (!initialised) - { - throw new ArgumentException("Need call init function before encryption/decryption"); - } + throw new ArgumentException("Need to call Init before encryption/decryption"); + int len = (int)message.Length - (forEncryption ? 0 : TAG_INBYTES); if ((forEncryption && len + TAG_INBYTES + outOff > output.Length) || (!forEncryption && len + outOff > output.Length)) @@ -392,13 +387,8 @@ namespace Org.BouncyCastle.Crypto.Engines } else { - for (i = 0; i < TAG_INBYTES; ++i) - { - if (T[i] != input[len + i]) - { - throw new ArgumentException("Mac does not match"); - } - } + if (!Arrays.FixedTimeEquals(TAG_INBYTES, T, 0, input, len)) + throw new InvalidCipherTextException("mac check in " + AlgorithmName + " failed"); } reset(false); return len; diff --git a/crypto/src/crypto/engines/SparkleEngine.cs b/crypto/src/crypto/engines/SparkleEngine.cs index bbdce7ef8..63e400d4c 100644 --- a/crypto/src/crypto/engines/SparkleEngine.cs +++ b/crypto/src/crypto/engines/SparkleEngine.cs @@ -1,19 +1,21 @@ using System; using System.IO; + using Org.BouncyCastle.Crypto.Modes; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Crypto.Utilities; using Org.BouncyCastle.Utilities; -/** - * Sparkle v1.2, based on the current round 3 submission, https://sparkle-lwc.github.io/ - * Reference C implementation: https://github.com/cryptolu/sparkle - * Specification: https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-spec-doc/sparkle-spec-final.pdf - */ - namespace Org.BouncyCastle.Crypto.Engines { - public class SparkleEngine : IAeadBlockCipher + /// <summary>Sparkle v1.2, based on the current round 3 submission, https://sparkle-lwc.github.io/ .</summary> + /// <remarks> + /// Reference C implementation: https://github.com/cryptolu/sparkle.<br/> + /// Specification: + /// https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-spec-doc/sparkle-spec-final.pdf . + /// </remarks> + public class SparkleEngine + : IAeadBlockCipher { public enum SparkleParameters { @@ -481,13 +483,8 @@ namespace Org.BouncyCastle.Crypto.Engines } else { - for (i = 0; i < TAG_BYTES; ++i) - { - if (tag[i] != input[inlen + i]) - { - throw new ArgumentException(algorithmName + " mac does not match"); - } - } + if (!Arrays.FixedTimeEquals(TAG_BYTES, tag, 0, input, inlen)) + throw new InvalidCipherTextException("mac check in " + AlgorithmName + " failed"); } reset(false); return inlen; diff --git a/crypto/src/crypto/engines/XoodyakEngine.cs b/crypto/src/crypto/engines/XoodyakEngine.cs index caf49e53c..e0263272e 100644 --- a/crypto/src/crypto/engines/XoodyakEngine.cs +++ b/crypto/src/crypto/engines/XoodyakEngine.cs @@ -126,27 +126,20 @@ namespace Org.BouncyCastle.Crypto.Engines public int ProcessBytes(byte[] input, int inOff, int len, byte[] output, int outOff) { if (!initialised) - { - throw new ArgumentException("Need call init function before encryption/decryption"); - } + throw new ArgumentException("Need to call Init before encryption/decryption"); + if (mode != MODE.ModeKeyed) - { throw new ArgumentException("Xoodyak has not been initialised"); - } - if (inOff + len > input.Length) - { - throw new DataLengthException("input buffer too short"); - } + + Check.DataLength(input, inOff, len, "input buffer too short"); + message.Write(input, inOff, len); int blockLen = (int)message.Length - (forEncryption ? 0 : TAGLEN); if (blockLen >= GetBlockSize()) { byte[] blocks = message.GetBuffer(); len = blockLen / GetBlockSize() * GetBlockSize(); - if (len + outOff > output.Length) - { - throw new OutputLengthException("output buffer is too short"); - } + Check.OutputLength(output, outOff, len, "output buffer is too short"); processAAD(); encrypt(blocks, 0, len, output, outOff); int messageLen = (int)message.Length; @@ -196,9 +189,7 @@ namespace Org.BouncyCastle.Crypto.Engines public int DoFinal(byte[] output, int outOff) { if (!initialised) - { - throw new ArgumentException("Need call init function before encryption/decryption"); - } + throw new ArgumentException("Need to call Init before encryption/decryption"); byte[] blocks = message.GetBuffer(); int len = (int)message.Length; @@ -225,43 +216,34 @@ namespace Org.BouncyCastle.Crypto.Engines encrypt(blocks, 0, inOff, output, outOff); tag = new byte[TAGLEN]; Up(tag, TAGLEN, 0x40); - for (int i = 0; i < TAGLEN; ++i) - { - if (tag[i] != blocks[inOff++]) - { - throw new ArgumentException("Mac does not match"); - } - } + + if (!Arrays.FixedTimeEquals(TAGLEN, tag, 0, blocks, inOff)) + throw new InvalidCipherTextException("mac check in " + AlgorithmName + " failed"); } reset(false); return rv; } - public byte[] GetMac() { return tag; } - public int GetUpdateOutputSize(int len) { return len; } - public int GetOutputSize(int len) { return len + TAGLEN; } - public void Reset() { if (!initialised) - { - throw new ArgumentException("Need call init function before encryption/decryption"); - } + throw new ArgumentException("Need to call Init before encryption/decryption"); + reset(true); } diff --git a/crypto/test/src/crypto/test/AsconTest.cs b/crypto/test/src/crypto/test/AsconTest.cs index 9adff8c49..665673a55 100644 --- a/crypto/test/src/crypto/test/AsconTest.cs +++ b/crypto/test/src/crypto/test/AsconTest.cs @@ -127,7 +127,7 @@ namespace Org.BouncyCastle.Crypto.Tests try { asconEngine.ProcessBytes(m, 0, m.Length, null, 0); - Assert.Fail(asconEngine.AlgorithmName + " need to be initialized before ProcessBytes"); + Assert.Fail(asconEngine.AlgorithmName + " needs to be initialized before ProcessBytes"); } catch (ArgumentException) { @@ -137,7 +137,7 @@ namespace Org.BouncyCastle.Crypto.Tests try { asconEngine.ProcessByte((byte)0, null, 0); - Assert.Fail(asconEngine.AlgorithmName + " need to be initialized before ProcessByte"); + Assert.Fail(asconEngine.AlgorithmName + " needs to be initialized before ProcessByte"); } catch (ArgumentException) { @@ -147,7 +147,7 @@ namespace Org.BouncyCastle.Crypto.Tests try { asconEngine.Reset(); - Assert.Fail(asconEngine.AlgorithmName + " need to be initialized before reset"); + Assert.Fail(asconEngine.AlgorithmName + " needs to be initialized before Reset"); } catch (ArgumentException) { @@ -157,7 +157,7 @@ namespace Org.BouncyCastle.Crypto.Tests try { asconEngine.DoFinal(null, m.Length); - Assert.Fail(asconEngine.AlgorithmName + " need to be initialized before Dofinal"); + Assert.Fail(asconEngine.AlgorithmName + " needs to be initialized before DoFinal"); } catch (ArgumentException) { @@ -173,7 +173,7 @@ namespace Org.BouncyCastle.Crypto.Tests catch (ArgumentException) { //expected - Assert.Fail(asconEngine.AlgorithmName + " functions can be called before initialisation"); + Assert.Fail(asconEngine.AlgorithmName + " functions can be called before initialization"); } Random rand = new Random(); @@ -214,11 +214,11 @@ namespace Org.BouncyCastle.Crypto.Tests byte[] mac2 = asconEngine.GetMac(); if (mac2 == null) { - Assert.Fail("mac should not be empty after dofinal"); + Assert.Fail("mac should not be empty after DoFinal"); } if (!Arrays.AreEqual(mac2, c1)) { - Assert.Fail("mac should be equal when calling dofinal and getMac"); + Assert.Fail("mac should be equal when calling DoFinal and GetMac"); } asconEngine.ProcessAadByte((byte)0); byte[] mac1 = new byte[asconEngine.GetOutputSize(0)]; @@ -281,9 +281,9 @@ namespace Org.BouncyCastle.Crypto.Tests try { asconEngine.DoFinal(new byte[2], 2); - Assert.Fail("output for dofinal is too short"); + Assert.Fail("output for DoFinal is too short"); } - catch (DataLengthException) + catch (OutputLengthException) { //expected } @@ -342,7 +342,7 @@ namespace Org.BouncyCastle.Crypto.Tests asconEngine.DoFinal(m4, offset); Assert.Fail("The decryption should fail"); } - catch (ArgumentException) + catch (InvalidCipherTextException) { //expected; } @@ -357,7 +357,7 @@ namespace Org.BouncyCastle.Crypto.Tests byte[] c9 = new byte[c7.Length]; asconEngine.ProcessAadBytes(aad2, 0, aad2.Length); offset = asconEngine.ProcessBytes(m7, 0, m7.Length, c7, 0); - asconEngine.DoFinal(c7, offset); + offset += asconEngine.DoFinal(c7, offset); asconEngine.Reset(); asconEngine.ProcessAadBytes(aad2, 0, aad2.Length); offset = asconEngine.ProcessBytes(m7, 0, m7.Length / 2, c8, 0); @@ -385,8 +385,8 @@ namespace Org.BouncyCastle.Crypto.Tests offset = asconEngine.ProcessBytes(m5, c4_1); asconEngine.DoFinal(c4_2); byte[] c5 = new byte[c2.Length]; - Array.Copy(c4_1.ToArray(), 0, c5, 0, offset); - Array.Copy(c4_2.ToArray(), 0, c5, offset, c5.Length - offset); + c4_1[..offset].CopyTo(c5); + c4_2[..(c5.Length - offset)].CopyTo(c5.AsSpan(offset)); if (!Arrays.AreEqual(c2, c5)) { Assert.Fail("mac should match for the same AAD and message with different offset for both input and output"); @@ -400,8 +400,8 @@ namespace Org.BouncyCastle.Crypto.Tests offset = asconEngine.ProcessBytes(c6, m6_1); asconEngine.DoFinal(m6_2); byte[] m6 = new byte[m2.Length]; - Array.Copy(m6_1.ToArray(), 0, m6, 0, offset); - Array.Copy(m6_2.ToArray(), 0, m6, offset, m6.Length - offset); + m6_1[..offset].CopyTo(m6); + m6_2[..(m6.Length - offset)].CopyTo(m6.AsSpan(offset)); if (!Arrays.AreEqual(m2, m6)) { Assert.Fail("mac should match for the same AAD and message with different offset for both input and output"); @@ -427,29 +427,27 @@ namespace Org.BouncyCastle.Crypto.Tests "GetOutputSize of " + asconEngine.AlgorithmName + " is incorrect for decryption"); } - private void ImplTestVectorsHash(AsconDigest.AsconParameters AsconParameters, String filename) + private void ImplTestVectorsHash(AsconDigest.AsconParameters AsconParameters, string filename) { AsconDigest Ascon = new AsconDigest(AsconParameters); var buf = new Dictionary<string, string>(); - //TestSampler sampler = new TestSampler(); using (var src = new StreamReader(SimpleTest.GetTestDataAsStream("crypto.ascon."+filename+"_LWC_HASH_KAT_256.txt"))) { - string line; - string[] data; - byte[] ptByte; Dictionary<string, string> map = new Dictionary<string, string>(); + string line; while ((line = src.ReadLine()) != null) { - data = line.Split(' '); + var data = line.Split(' '); if (data.Length == 1) { - ptByte = Hex.Decode(map["Msg"]); + byte[] ptByte = Hex.Decode(map["Msg"]); + byte[] expected = Hex.Decode(map["MD"]); + map.Clear(); + Ascon.BlockUpdate(ptByte, 0, ptByte.Length); byte[] hash = new byte[Ascon.GetDigestSize()]; Ascon.DoFinal(hash, 0); - Assert.True(Arrays.AreEqual(hash, Hex.Decode(map["MD"]))); - //Console.WriteLine(map["Count"] + " pass"); - map.Clear(); + Assert.True(Arrays.AreEqual(expected, hash)); Ascon.Reset(); } else @@ -468,17 +466,17 @@ namespace Org.BouncyCastle.Crypto.Tests } } - private void ImplTestExceptions(IDigest digest, int digestsize) + private void ImplTestExceptions(AsconDigest asconDigest, int digestSize) { - if (digest.GetDigestSize() != digestsize) + if (asconDigest.GetDigestSize() != digestSize) { - Assert.Fail(digest.AlgorithmName + ": digest size is not correct"); + Assert.Fail(asconDigest.AlgorithmName + ": digest size is not correct"); } try { - digest.BlockUpdate(new byte[1], 1, 1); - Assert.Fail(digest.AlgorithmName + ": input for update is too short"); + asconDigest.BlockUpdate(new byte[1], 1, 1); + Assert.Fail(asconDigest.AlgorithmName + ": input for BlockUpdate is too short"); } catch (DataLengthException) { @@ -486,14 +484,13 @@ namespace Org.BouncyCastle.Crypto.Tests } try { - digest.DoFinal(new byte[digest.GetDigestSize() - 1], 2); - Assert.Fail(digest.AlgorithmName + ": output for dofinal is too short"); + asconDigest.DoFinal(new byte[digestSize - 1], 2); + Assert.Fail(asconDigest.AlgorithmName + ": output for DoFinal is too short"); } - catch (DataLengthException) + catch (OutputLengthException) { //expected } - //Console.WriteLine(digest.AlgorithmName + " test Exceptions pass"); } } } diff --git a/crypto/test/src/crypto/test/ElephantTest.cs b/crypto/test/src/crypto/test/ElephantTest.cs index 6adc2a2aa..406be7c6f 100644 --- a/crypto/test/src/crypto/test/ElephantTest.cs +++ b/crypto/test/src/crypto/test/ElephantTest.cs @@ -13,73 +13,55 @@ using Org.BouncyCastle.Utilities.Test; namespace Org.BouncyCastle.Crypto.Tests { - public class ElephantTest : SimpleTest + public class ElephantTest + : SimpleTest { - public override string Name - { - get { return "Photon-Beetle"; } - } + public override string Name => "Elephant"; [Test] public override void PerformTest() { - testVectors(ElephantEngine.ElephantParameters.elephant160, "v160"); - testVectors(ElephantEngine.ElephantParameters.elephant176, "v176"); - testVectors(ElephantEngine.ElephantParameters.elephant200, "v200"); - ElephantEngine elephant = new ElephantEngine(ElephantEngine.ElephantParameters.elephant160); - testExceptions(elephant, elephant.GetKeyBytesSize(), elephant.GetIVBytesSize(), elephant.GetBlockSize()); - testParameters(elephant, 16, 12, 8, 20); - elephant = new ElephantEngine(ElephantEngine.ElephantParameters.elephant176); - testExceptions(elephant, elephant.GetKeyBytesSize(), elephant.GetIVBytesSize(), elephant.GetBlockSize()); - testParameters(elephant, 16, 12, 8, 22); - elephant = new ElephantEngine(ElephantEngine.ElephantParameters.elephant200); - testExceptions(elephant, elephant.GetKeyBytesSize(), elephant.GetIVBytesSize(), elephant.GetBlockSize()); - testParameters(elephant, 16, 12, 16, 25); + ImplTestVectors(ElephantEngine.ElephantParameters.elephant160, "v160"); + ImplTestVectors(ElephantEngine.ElephantParameters.elephant176, "v176"); + ImplTestVectors(ElephantEngine.ElephantParameters.elephant200, "v200"); + ElephantEngine elephantEngine = new ElephantEngine(ElephantEngine.ElephantParameters.elephant160); + ImplTestExceptions(elephantEngine, elephantEngine.GetKeyBytesSize(), elephantEngine.GetIVBytesSize(), elephantEngine.GetBlockSize()); + ImplTestParameters(elephantEngine, 16, 12, 8, 20); + elephantEngine = new ElephantEngine(ElephantEngine.ElephantParameters.elephant176); + ImplTestExceptions(elephantEngine, elephantEngine.GetKeyBytesSize(), elephantEngine.GetIVBytesSize(), elephantEngine.GetBlockSize()); + ImplTestParameters(elephantEngine, 16, 12, 8, 22); + elephantEngine = new ElephantEngine(ElephantEngine.ElephantParameters.elephant200); + ImplTestExceptions(elephantEngine, elephantEngine.GetKeyBytesSize(), elephantEngine.GetIVBytesSize(), elephantEngine.GetBlockSize()); + ImplTestParameters(elephantEngine, 16, 12, 16, 25); } - private void testVectors(ElephantEngine.ElephantParameters pbp, String filename) + private void ImplTestVectors(ElephantEngine.ElephantParameters pbp, String filename) { ElephantEngine Elephant = new ElephantEngine(pbp); ICipherParameters param; var buf = new Dictionary<string, string>(); - //TestSampler sampler = new TestSampler(); using (var src = new StreamReader(SimpleTest.GetTestDataAsStream("crypto.elephant." + filename + "_LWC_AEAD_KAT_128_96.txt"))) { - string line; - string[] data; - byte[] rv; Dictionary<string, string> map = new Dictionary<string, string>(); + string line; while ((line = src.ReadLine()) != null) { - data = line.Split(' '); + var data = line.Split(' '); if (data.Length == 1) { - //if (!map["Count"].Equals("2")) - //{ - // continue; - //} byte[] key = Hex.Decode(map["Key"]); byte[] nonce = Hex.Decode(map["Nonce"]); byte[] ad = Hex.Decode(map["AD"]); byte[] pt = Hex.Decode(map["PT"]); byte[] ct = Hex.Decode(map["CT"]); + map.Clear(); + param = new ParametersWithIV(new KeyParameter(key), nonce); Elephant.Init(true, param); Elephant.ProcessAadBytes(ad, 0, ad.Length); - rv = new byte[Elephant.GetOutputSize(pt.Length)]; + byte[] rv = new byte[Elephant.GetOutputSize(pt.Length)]; int len = Elephant.ProcessBytes(pt, 0, pt.Length, rv, 0); - //byte[] mac = new byte[16]; Elephant.DoFinal(rv, len); - //foreach(byte b in Hex.Decode(map["CT"])) - //{ - // Console.Write(b.ToString("X2")); - //} - //Console.WriteLine(); - //foreach (byte b in Arrays.Concatenate(rv, mac)) - //{ - // Console.Write(b.ToString("X2")); - //} - //Console.WriteLine(); Assert.True(Arrays.AreEqual(rv, ct)); Elephant.Reset(); Elephant.Init(false, param); @@ -91,10 +73,7 @@ namespace Org.BouncyCastle.Crypto.Tests byte[] pt_recovered = new byte[pt.Length]; Array.Copy(rv, 0, pt_recovered, 0, pt.Length); Assert.True(Arrays.AreEqual(pt, pt_recovered)); - //Console.WriteLine(map["Count"] + " pass"); - map.Clear(); Elephant.Reset(); - } else { @@ -112,18 +91,17 @@ namespace Org.BouncyCastle.Crypto.Tests } } - private void testExceptions(IAeadBlockCipher aeadBlockCipher, int keysize, int ivsize, int blocksize) + private void ImplTestExceptions(ElephantEngine elephantEngine, int keysize, int ivsize, int blocksize) { - ICipherParameters param; byte[] k = new byte[keysize]; byte[] iv = new byte[ivsize]; byte[] m = new byte[0]; - byte[] c1 = new byte[aeadBlockCipher.GetOutputSize(m.Length)]; - param = new ParametersWithIV(new KeyParameter(k), iv); + byte[] c1 = new byte[elephantEngine.GetOutputSize(m.Length)]; + var param = new ParametersWithIV(new KeyParameter(k), iv); //try //{ // aeadBlockCipher.ProcessBytes(m, 0, m.Length, c1, 0); - // Assert.Fail(aeadBlockCipher.AlgorithmName + " need to be initialed before ProcessBytes"); + // Assert.Fail(aeadBlockCipher.AlgorithmName + " needs to be initialized before ProcessBytes"); //} //catch (ArgumentException e) //{ @@ -133,7 +111,7 @@ namespace Org.BouncyCastle.Crypto.Tests //try //{ // aeadBlockCipher.ProcessByte((byte)0, c1, 0); - // Assert.Fail(aeadBlockCipher.AlgorithmName + " need to be initialed before ProcessByte"); + // Assert.Fail(aeadBlockCipher.AlgorithmName + " needs to be initialized before ProcessByte"); //} //catch (ArgumentException e) //{ @@ -143,7 +121,7 @@ namespace Org.BouncyCastle.Crypto.Tests //try //{ // aeadBlockCipher.Reset(); - // Assert.Fail(aeadBlockCipher.AlgorithmName + " need to be initialed before reset"); + // Assert.Fail(aeadBlockCipher.AlgorithmName + " needs to be initialized before Reset"); //} //catch (ArgumentException e) //{ @@ -152,8 +130,8 @@ namespace Org.BouncyCastle.Crypto.Tests try { - aeadBlockCipher.DoFinal(c1, m.Length); - Assert.Fail(aeadBlockCipher.AlgorithmName + " need to be initialed before dofinal"); + elephantEngine.DoFinal(c1, m.Length); + Assert.Fail(elephantEngine.AlgorithmName + " needs to be initialized before DoFinal"); } catch (ArgumentException) { @@ -162,14 +140,14 @@ namespace Org.BouncyCastle.Crypto.Tests try { - aeadBlockCipher.GetMac(); - aeadBlockCipher.GetOutputSize(0); - aeadBlockCipher.GetUpdateOutputSize(0); + elephantEngine.GetMac(); + elephantEngine.GetOutputSize(0); + elephantEngine.GetUpdateOutputSize(0); } catch (ArgumentException) { //expected - Assert.Fail(aeadBlockCipher.AlgorithmName + " functions can be called before initialisation"); + Assert.Fail(elephantEngine.AlgorithmName + " functions can be called before initialization"); } Random rand = new Random(); int randomNum; @@ -179,8 +157,8 @@ namespace Org.BouncyCastle.Crypto.Tests byte[] iv1 = new byte[randomNum]; try { - aeadBlockCipher.Init(true, new ParametersWithIV(new KeyParameter(k1), iv)); - Assert.Fail(aeadBlockCipher.AlgorithmName + " k size does not match"); + elephantEngine.Init(true, new ParametersWithIV(new KeyParameter(k1), iv)); + Assert.Fail(elephantEngine.AlgorithmName + " k size does not match"); } catch (ArgumentException) { @@ -188,8 +166,8 @@ namespace Org.BouncyCastle.Crypto.Tests } try { - aeadBlockCipher.Init(true, new ParametersWithIV(new KeyParameter(k), iv1)); - Assert.Fail(aeadBlockCipher.AlgorithmName + "iv size does not match"); + elephantEngine.Init(true, new ParametersWithIV(new KeyParameter(k), iv1)); + Assert.Fail(elephantEngine.AlgorithmName + "iv size does not match"); } catch (ArgumentException) { @@ -197,16 +175,16 @@ namespace Org.BouncyCastle.Crypto.Tests } - aeadBlockCipher.Init(true, param); + elephantEngine.Init(true, param); try { - aeadBlockCipher.DoFinal(c1, m.Length); + elephantEngine.DoFinal(c1, m.Length); } catch (Exception) { - Assert.Fail(aeadBlockCipher.AlgorithmName + " allows no input for AAD and plaintext"); + Assert.Fail(elephantEngine.AlgorithmName + " allows no input for AAD and plaintext"); } - byte[] mac2 = aeadBlockCipher.GetMac(); + byte[] mac2 = elephantEngine.GetMac(); if (mac2 == null) { Assert.Fail("mac should not be empty after dofinal"); @@ -215,9 +193,9 @@ namespace Org.BouncyCastle.Crypto.Tests { Assert.Fail("mac should be equal when calling dofinal and getMac"); } - aeadBlockCipher.ProcessAadByte((byte)0); - byte[] mac1 = new byte[aeadBlockCipher.GetOutputSize(0)]; - aeadBlockCipher.DoFinal(mac1, 0); + elephantEngine.ProcessAadByte((byte)0); + byte[] mac1 = new byte[elephantEngine.GetOutputSize(0)]; + elephantEngine.DoFinal(mac1, 0); if (Arrays.AreEqual(mac1, mac2)) { Assert.Fail("mac should not match"); @@ -243,10 +221,10 @@ namespace Org.BouncyCastle.Crypto.Tests // //expected //} - aeadBlockCipher.Reset(); + elephantEngine.Reset(); try { - aeadBlockCipher.ProcessAadBytes(new byte[] { 0 }, 1, 1); + elephantEngine.ProcessAadBytes(new byte[] { 0 }, 1, 1); Assert.Fail("input for ProcessAadBytes is too short"); } catch (DataLengthException) @@ -255,7 +233,7 @@ namespace Org.BouncyCastle.Crypto.Tests } try { - aeadBlockCipher.ProcessBytes(new byte[] { 0 }, 1, 1, c1, 0); + elephantEngine.ProcessBytes(new byte[] { 0 }, 1, 1, c1, 0); Assert.Fail("input for ProcessBytes is too short"); } catch (DataLengthException) @@ -267,76 +245,76 @@ namespace Org.BouncyCastle.Crypto.Tests // aeadBlockCipher.ProcessBytes(new byte[blocksize], 0, blocksize, new byte[blocksize], blocksize >> 1); // Assert.Fail("output for ProcessBytes is too short"); //} - //catch (OutputLengthException e) + //catch (OutputLengthException) //{ // //expected //} try { - aeadBlockCipher.DoFinal(new byte[2], 2); - Assert.Fail("output for dofinal is too short"); + elephantEngine.DoFinal(new byte[2], 2); + Assert.Fail("output for DoFinal is too short"); } - catch (DataLengthException) + catch (OutputLengthException) { //expected } - mac1 = new byte[aeadBlockCipher.GetOutputSize(0)]; - mac2 = new byte[aeadBlockCipher.GetOutputSize(0)]; - aeadBlockCipher.Reset(); - aeadBlockCipher.ProcessAadBytes(new byte[] { 0, 0 }, 0, 2); - aeadBlockCipher.DoFinal(mac1, 0); - aeadBlockCipher.Reset(); - aeadBlockCipher.ProcessAadByte((byte)0); - aeadBlockCipher.ProcessAadByte((byte)0); - aeadBlockCipher.DoFinal(mac2, 0); + mac1 = new byte[elephantEngine.GetOutputSize(0)]; + mac2 = new byte[elephantEngine.GetOutputSize(0)]; + elephantEngine.Reset(); + elephantEngine.ProcessAadBytes(new byte[] { 0, 0 }, 0, 2); + elephantEngine.DoFinal(mac1, 0); + elephantEngine.Reset(); + elephantEngine.ProcessAadByte((byte)0); + elephantEngine.ProcessAadByte((byte)0); + elephantEngine.DoFinal(mac2, 0); if (!Arrays.AreEqual(mac1, mac2)) { Assert.Fail("mac should match for the same AAD with different ways of inputing"); } - byte[] c2 = new byte[aeadBlockCipher.GetOutputSize(10)]; - byte[] c3 = new byte[aeadBlockCipher.GetOutputSize(10) + 2]; + byte[] c2 = new byte[elephantEngine.GetOutputSize(10)]; + byte[] c3 = new byte[elephantEngine.GetOutputSize(10) + 2]; byte[] aad2 = { 0, 1, 2, 3, 4 }; byte[] aad3 = { 0, 0, 1, 2, 3, 4, 5 }; byte[] m2 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; byte[] m3 = { 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; byte[] m4 = new byte[m2.Length]; - aeadBlockCipher.Reset(); - aeadBlockCipher.ProcessAadBytes(aad2, 0, aad2.Length); - int offset = aeadBlockCipher.ProcessBytes(m2, 0, m2.Length, c2, 0); - aeadBlockCipher.DoFinal(c2, offset); - aeadBlockCipher.Reset(); - aeadBlockCipher.ProcessAadBytes(aad3, 1, aad2.Length); - offset = aeadBlockCipher.ProcessBytes(m3, 1, m2.Length, c3, 1); - aeadBlockCipher.DoFinal(c3, offset + 1); + elephantEngine.Reset(); + elephantEngine.ProcessAadBytes(aad2, 0, aad2.Length); + int offset = elephantEngine.ProcessBytes(m2, 0, m2.Length, c2, 0); + elephantEngine.DoFinal(c2, offset); + elephantEngine.Reset(); + elephantEngine.ProcessAadBytes(aad3, 1, aad2.Length); + offset = elephantEngine.ProcessBytes(m3, 1, m2.Length, c3, 1); + elephantEngine.DoFinal(c3, offset + 1); byte[] c3_partial = new byte[c2.Length]; Array.Copy(c3, 1, c3_partial, 0, c2.Length); if (!Arrays.AreEqual(c2, c3_partial)) { Assert.Fail("mac should match for the same AAD and message with different offset for both input and output"); } - aeadBlockCipher.Reset(); - aeadBlockCipher.Init(false, param); - aeadBlockCipher.ProcessAadBytes(aad2, 0, aad2.Length); - offset = aeadBlockCipher.ProcessBytes(c2, 0, c2.Length, m4, 0); - aeadBlockCipher.DoFinal(m4, offset); + elephantEngine.Reset(); + elephantEngine.Init(false, param); + elephantEngine.ProcessAadBytes(aad2, 0, aad2.Length); + offset = elephantEngine.ProcessBytes(c2, 0, c2.Length, m4, 0); + elephantEngine.DoFinal(m4, offset); if (!Arrays.AreEqual(m2, m4)) { Assert.Fail("The encryption and decryption does not recover the plaintext"); } - Console.WriteLine(aeadBlockCipher.AlgorithmName + " test Exceptions pass"); + Console.WriteLine(elephantEngine.AlgorithmName + " test Exceptions pass"); c2[c2.Length - 1] ^= 1; - aeadBlockCipher.Reset(); - aeadBlockCipher.Init(false, param); - aeadBlockCipher.ProcessAadBytes(aad2, 0, aad2.Length); - offset = aeadBlockCipher.ProcessBytes(c2, 0, c2.Length, m4, 0); + elephantEngine.Reset(); + elephantEngine.Init(false, param); + elephantEngine.ProcessAadBytes(aad2, 0, aad2.Length); + offset = elephantEngine.ProcessBytes(c2, 0, c2.Length, m4, 0); try { - aeadBlockCipher.DoFinal(m4, offset); + elephantEngine.DoFinal(m4, offset); Assert.Fail("The decryption should fail"); } - catch (ArgumentException) + catch (InvalidCipherTextException) { //expected; } @@ -347,24 +325,24 @@ namespace Org.BouncyCastle.Crypto.Tests { m7[i] = (byte)rand.Next(); } - byte[] c7 = new byte[aeadBlockCipher.GetOutputSize(m7.Length)]; + byte[] c7 = new byte[elephantEngine.GetOutputSize(m7.Length)]; byte[] c8 = new byte[c7.Length]; byte[] c9 = new byte[c7.Length]; - aeadBlockCipher.Init(true, param); - aeadBlockCipher.ProcessAadBytes(aad2, 0, aad2.Length); - offset = aeadBlockCipher.ProcessBytes(m7, 0, m7.Length, c7, 0); - aeadBlockCipher.DoFinal(c7, offset); - aeadBlockCipher.Reset(); - aeadBlockCipher.ProcessAadBytes(aad2, 0, aad2.Length); - offset = aeadBlockCipher.ProcessBytes(m7, 0, blocksize, c8, 0); - offset += aeadBlockCipher.ProcessBytes(m7, blocksize, m7.Length - blocksize, c8, offset); - aeadBlockCipher.DoFinal(c8, offset); - aeadBlockCipher.Reset(); + elephantEngine.Init(true, param); + elephantEngine.ProcessAadBytes(aad2, 0, aad2.Length); + offset = elephantEngine.ProcessBytes(m7, 0, m7.Length, c7, 0); + elephantEngine.DoFinal(c7, offset); + elephantEngine.Reset(); + elephantEngine.ProcessAadBytes(aad2, 0, aad2.Length); + offset = elephantEngine.ProcessBytes(m7, 0, blocksize, c8, 0); + offset += elephantEngine.ProcessBytes(m7, blocksize, m7.Length - blocksize, c8, offset); + elephantEngine.DoFinal(c8, offset); + elephantEngine.Reset(); int split = rand.Next(blocksize * 2); - aeadBlockCipher.ProcessAadBytes(aad2, 0, aad2.Length); - offset = aeadBlockCipher.ProcessBytes(m7, 0, split, c9, 0); - offset += aeadBlockCipher.ProcessBytes(m7, split, m7.Length - split, c9, offset); - aeadBlockCipher.DoFinal(c9, offset); + elephantEngine.ProcessAadBytes(aad2, 0, aad2.Length); + offset = elephantEngine.ProcessBytes(m7, 0, split, c9, 0); + offset += elephantEngine.ProcessBytes(m7, split, m7.Length - split, c9, offset); + elephantEngine.DoFinal(c9, offset); if (!Arrays.AreEqual(c7, c8) || !Arrays.AreEqual(c7, c9)) { Assert.Fail("Splitting input of plaintext should output the same ciphertext"); @@ -374,28 +352,28 @@ namespace Org.BouncyCastle.Crypto.Tests Span<byte> c4_2 = new byte[c2.Length]; ReadOnlySpan<byte> m5 = new ReadOnlySpan<byte>(m2); ReadOnlySpan<byte> aad4 = new ReadOnlySpan<byte>(aad2); - aeadBlockCipher.Init(true, param); - aeadBlockCipher.ProcessAadBytes(aad4); - offset = aeadBlockCipher.ProcessBytes(m5, c4_1); - aeadBlockCipher.DoFinal(c4_2); + elephantEngine.Init(true, param); + elephantEngine.ProcessAadBytes(aad4); + offset = elephantEngine.ProcessBytes(m5, c4_1); + elephantEngine.DoFinal(c4_2); byte[] c5 = new byte[c2.Length]; - Array.Copy(c4_1.ToArray(), 0, c5, 0, offset); - Array.Copy(c4_2.ToArray(), 0, c5, offset, c5.Length - offset); + c4_1[..offset].CopyTo(c5); + c4_2[..(c5.Length - offset)].CopyTo(c5.AsSpan(offset)); if (!Arrays.AreEqual(c2, c5)) { Assert.Fail("mac should match for the same AAD and message with different offset for both input and output"); } - aeadBlockCipher.Reset(); - aeadBlockCipher.Init(false, param); + elephantEngine.Reset(); + elephantEngine.Init(false, param); Span<byte> m6_1 = new byte[m2.Length]; Span<byte> m6_2 = new byte[m2.Length]; ReadOnlySpan<byte> c6 = new ReadOnlySpan<byte>(c2); - aeadBlockCipher.ProcessAadBytes(aad4); - offset = aeadBlockCipher.ProcessBytes(c6, m6_1); - aeadBlockCipher.DoFinal(m6_2); + elephantEngine.ProcessAadBytes(aad4); + offset = elephantEngine.ProcessBytes(c6, m6_1); + elephantEngine.DoFinal(m6_2); byte[] m6 = new byte[m2.Length]; - Array.Copy(m6_1.ToArray(), 0, m6, 0, offset); - Array.Copy(m6_2.ToArray(), 0, m6, offset, m6.Length - offset); + m6_1[..offset].CopyTo(m6); + m6_2[..(m6.Length - offset)].CopyTo(m6.AsSpan(offset)); if (!Arrays.AreEqual(m2, m6)) { Assert.Fail("mac should match for the same AAD and message with different offset for both input and output"); @@ -404,7 +382,7 @@ namespace Org.BouncyCastle.Crypto.Tests } - private void testParameters(ElephantEngine Elephant, int keySize, int ivSize, int macSize, int blockSize) + private void ImplTestParameters(ElephantEngine Elephant, int keySize, int ivSize, int macSize, int blockSize) { if (Elephant.GetKeyBytesSize() != keySize) { diff --git a/crypto/test/src/crypto/test/ISAPTest.cs b/crypto/test/src/crypto/test/ISAPTest.cs index ce19b38d5..e7b0bd25c 100644 --- a/crypto/test/src/crypto/test/ISAPTest.cs +++ b/crypto/test/src/crypto/test/ISAPTest.cs @@ -34,7 +34,7 @@ namespace Org.BouncyCastle.Crypto.Tests isapEngine = new IsapEngine(IsapEngine.IsapType.ISAP_A_128); ImplTestExceptions(isapEngine); ImplTestParameters(isapEngine, 16, 16, 16); - ImplTestExceptions(new ISAPDigest(), 32); + ImplTestExceptions(new IsapDigest(), 32); ImplTestVectors("isapa128av20", IsapEngine.IsapType.ISAP_A_128A); ImplTestVectors("isapa128v20", IsapEngine.IsapType.ISAP_A_128); ImplTestVectors("isapk128av20", IsapEngine.IsapType.ISAP_K_128A); @@ -111,7 +111,7 @@ namespace Org.BouncyCastle.Crypto.Tests private void ImplTestVectors() { - ISAPDigest isap = new ISAPDigest(); + IsapDigest isap = new IsapDigest(); var buf = new Dictionary<string, string>(); //TestSampler sampler = new TestSampler(); using (var src = new StreamReader(SimpleTest.GetTestDataAsStream("crypto.isap.LWC_HASH_KAT_256.txt"))) @@ -151,10 +151,10 @@ namespace Org.BouncyCastle.Crypto.Tests private void ImplTestExceptions(IsapEngine isapEngine) { - int keysize = isapEngine.GetKeyBytesSize(), ivsize = isapEngine.GetIVBytesSize(); + int keySize = isapEngine.GetKeyBytesSize(), ivSize = isapEngine.GetIVBytesSize(); int offset; - byte[] k = new byte[keysize]; - byte[] iv = new byte[ivsize]; + byte[] k = new byte[keySize]; + byte[] iv = new byte[ivSize]; byte[] m = Array.Empty<byte>(); ICipherParameters param = new ParametersWithIV(new KeyParameter(k), iv); try @@ -190,7 +190,7 @@ namespace Org.BouncyCastle.Crypto.Tests try { isapEngine.DoFinal(null, m.Length); - Assert.Fail(isapEngine.AlgorithmName + " need to be initialized before Dofinal"); + Assert.Fail(isapEngine.AlgorithmName + " need to be initialized before DoFinal"); } catch (ArgumentException) { @@ -209,9 +209,9 @@ namespace Org.BouncyCastle.Crypto.Tests } Random rand = new Random(); int randomNum; - while ((randomNum = rand.Next(100)) == keysize) ; + while ((randomNum = rand.Next(100)) == keySize) ; byte[] k1 = new byte[randomNum]; - while ((randomNum = rand.Next(100)) == ivsize) ; + while ((randomNum = rand.Next(100)) == ivSize) ; byte[] iv1 = new byte[randomNum]; try { @@ -312,9 +312,9 @@ namespace Org.BouncyCastle.Crypto.Tests try { isapEngine.DoFinal(new byte[2], 2); - Assert.Fail("output for dofinal is too short"); + Assert.Fail("output for DoFinal is too short"); } - catch (DataLengthException) + catch (OutputLengthException) { //expected } @@ -373,7 +373,7 @@ namespace Org.BouncyCastle.Crypto.Tests offset += isapEngine.DoFinal(m4, offset); Assert.Fail("The decryption should fail"); } - catch (ArgumentException) + catch (InvalidCipherTextException) { //expected; } @@ -416,8 +416,8 @@ namespace Org.BouncyCastle.Crypto.Tests offset = isapEngine.ProcessBytes(m5, c4_1); isapEngine.DoFinal(c4_2); byte[] c5 = new byte[c2.Length]; - Array.Copy(c4_1.ToArray(), 0, c5, 0, offset); - Array.Copy(c4_2.ToArray(), 0, c5, offset, c5.Length - offset); + c4_1[..offset].CopyTo(c5); + c4_2[..(c5.Length - offset)].CopyTo(c5.AsSpan(offset)); if (!Arrays.AreEqual(c2, c5)) { Assert.Fail("mac should match for the same AAD and message with different offset for both input and output"); @@ -431,8 +431,8 @@ namespace Org.BouncyCastle.Crypto.Tests offset = isapEngine.ProcessBytes(c6, m6_1); isapEngine.DoFinal(m6_2); byte[] m6 = new byte[m2.Length]; - Array.Copy(m6_1.ToArray(), 0, m6, 0, offset); - Array.Copy(m6_2.ToArray(), 0, m6, offset, m6.Length - offset); + m6_1[..offset].CopyTo(m6); + m6_2[..(m6.Length - offset)].CopyTo(m6.AsSpan(offset)); if (!Arrays.AreEqual(m2, m6)) { Assert.Fail("mac should match for the same AAD and message with different offset for both input and output"); @@ -458,17 +458,17 @@ namespace Org.BouncyCastle.Crypto.Tests "GetOutputSize of " + isapEngine.AlgorithmName + " is incorrect for decryption"); } - private void ImplTestExceptions(IDigest digest, int digestsize) + private void ImplTestExceptions(IsapDigest isapDigest, int digestsize) { - if (digest.GetDigestSize() != digestsize) + if (isapDigest.GetDigestSize() != digestsize) { - Assert.Fail(digest.AlgorithmName + ": digest size is not correct"); + Assert.Fail(isapDigest.AlgorithmName + ": digest size is not correct"); } try { - digest.BlockUpdate(new byte[1], 1, 1); - Assert.Fail(digest.AlgorithmName + ": input for BlockUpdate is too short"); + isapDigest.BlockUpdate(new byte[1], 1, 1); + Assert.Fail(isapDigest.AlgorithmName + ": input for BlockUpdate is too short"); } catch (DataLengthException) { @@ -476,13 +476,13 @@ namespace Org.BouncyCastle.Crypto.Tests } try { - digest.DoFinal(new byte[digest.GetDigestSize() - 1], 2); - Assert.Fail(digest.AlgorithmName + ": output for Dofinal is too short"); + isapDigest.DoFinal(new byte[isapDigest.GetDigestSize() - 1], 2); + Assert.Fail(isapDigest.AlgorithmName + ": output for DoFinal is too short"); } - catch (DataLengthException) + catch (OutputLengthException) { //expected } } } -} \ No newline at end of file +} diff --git a/crypto/test/src/crypto/test/PhotonBeetleTest.cs b/crypto/test/src/crypto/test/PhotonBeetleTest.cs index 9d400848d..80e34ad4b 100644 --- a/crypto/test/src/crypto/test/PhotonBeetleTest.cs +++ b/crypto/test/src/crypto/test/PhotonBeetleTest.cs @@ -15,71 +15,52 @@ using Org.BouncyCastle.Utilities.Test; namespace Org.BouncyCastle.Crypto.Tests { [TestFixture] - public class PhotonBeetleTest : SimpleTest + public class PhotonBeetleTest + : SimpleTest { - public override string Name - { - get { return "Photon-Beetle"; } - } + public override string Name => "Photon-Beetle"; [Test] public override void PerformTest() { - testVectors("v32", PhotonBeetleEngine.PhotonBeetleParameters.pb32); - testVectors("v128", PhotonBeetleEngine.PhotonBeetleParameters.pb128); - testVectors(); - PhotonBeetleEngine pb = new PhotonBeetleEngine(PhotonBeetleEngine.PhotonBeetleParameters.pb32); - testExceptions(pb, pb.GetKeyBytesSize(), pb.GetIVBytesSize(), pb.GetBlockSize()); - testParameters(pb, 16, 16, 16, 4); - pb = new PhotonBeetleEngine(PhotonBeetleEngine.PhotonBeetleParameters.pb128); - testExceptions(pb, pb.GetKeyBytesSize(), pb.GetIVBytesSize(), pb.GetBlockSize()); - testParameters(pb, 16, 16, 16, 16); - testExceptions(new PhotonBeetleDigest(), 32); + ImplTestVectors("v32", PhotonBeetleEngine.PhotonBeetleParameters.pb32); + ImplTestVectors("v128", PhotonBeetleEngine.PhotonBeetleParameters.pb128); + ImplTestVectors(); + PhotonBeetleEngine photonBeetleEngine = new PhotonBeetleEngine(PhotonBeetleEngine.PhotonBeetleParameters.pb32); + ImplTestExceptions(photonBeetleEngine, photonBeetleEngine.GetKeyBytesSize(), photonBeetleEngine.GetIVBytesSize(), photonBeetleEngine.GetBlockSize()); + ImplTestParameters(photonBeetleEngine, 16, 16, 16, 4); + photonBeetleEngine = new PhotonBeetleEngine(PhotonBeetleEngine.PhotonBeetleParameters.pb128); + ImplTestExceptions(photonBeetleEngine, photonBeetleEngine.GetKeyBytesSize(), photonBeetleEngine.GetIVBytesSize(), photonBeetleEngine.GetBlockSize()); + ImplTestParameters(photonBeetleEngine, 16, 16, 16, 16); + ImplTestExceptions(new PhotonBeetleDigest(), 32); } - private void testVectors(String filename, PhotonBeetleEngine.PhotonBeetleParameters PhotonBeetleType) + private void ImplTestVectors(String filename, PhotonBeetleEngine.PhotonBeetleParameters PhotonBeetleType) { PhotonBeetleEngine PhotonBeetle = new PhotonBeetleEngine(PhotonBeetleType); - ICipherParameters param; var buf = new Dictionary<string, string>(); - //TestSampler sampler = new TestSampler(); using (var src = new StreamReader(SimpleTest.GetTestDataAsStream("crypto.photonbeetle." + filename + "_LWC_AEAD_KAT_128_128.txt"))) { - string line; - string[] data; - byte[] rv; Dictionary<string, string> map = new Dictionary<string, string>(); + string line; while ((line = src.ReadLine()) != null) { - data = line.Split(' '); + var data = line.Split(' '); if (data.Length == 1) { - //if (!map["Count"].Equals("34")) - //{ - // continue; - //} byte[] key = Hex.Decode(map["Key"]); byte[] nonce = Hex.Decode(map["Nonce"]); byte[] ad = Hex.Decode(map["AD"]); byte[] pt = Hex.Decode(map["PT"]); byte[] ct = Hex.Decode(map["CT"]); - param = new ParametersWithIV(new KeyParameter(key), nonce); + map.Clear(); + + var param = new ParametersWithIV(new KeyParameter(key), nonce); PhotonBeetle.Init(true, param); PhotonBeetle.ProcessAadBytes(ad, 0, ad.Length); - rv = new byte[PhotonBeetle.GetOutputSize(pt.Length)]; + byte[] rv = new byte[PhotonBeetle.GetOutputSize(pt.Length)]; int len = PhotonBeetle.ProcessBytes(pt, 0, pt.Length, rv, 0); - //byte[] mac = new byte[16]; PhotonBeetle.DoFinal(rv, len); - //foreach(byte b in Hex.Decode(map["CT"])) - //{ - // Console.Write(b.ToString("X2")); - //} - //Console.WriteLine(); - //foreach (byte b in Arrays.Concatenate(rv, mac)) - //{ - // Console.Write(b.ToString("X2")); - //} - //Console.WriteLine(); Assert.True(Arrays.AreEqual(rv, ct)); PhotonBeetle.Reset(); PhotonBeetle.Init(false, param); @@ -91,8 +72,6 @@ namespace Org.BouncyCastle.Crypto.Tests byte[] pt_recovered = new byte[pt.Length]; Array.Copy(rv, 0, pt_recovered, 0, pt.Length); Assert.True(Arrays.AreEqual(pt, pt_recovered)); - //Console.WriteLine(map["Count"] + " pass"); - map.Clear(); PhotonBeetle.Reset(); } else @@ -109,10 +88,9 @@ namespace Org.BouncyCastle.Crypto.Tests } } } - Console.WriteLine(PhotonBeetle.AlgorithmName + " test pass"); } - private void testVectors() + private void ImplTestVectors() { PhotonBeetleDigest PhotonBeetle = new PhotonBeetleDigest(); var buf = new Dictionary<string, string>(); @@ -133,7 +111,6 @@ namespace Org.BouncyCastle.Crypto.Tests byte[] hash = new byte[32]; PhotonBeetle.DoFinal(hash, 0); Assert.True(Arrays.AreEqual(hash, Hex.Decode(map["MD"]))); - //Console.WriteLine(map["Count"] + " pass"); map.Clear(); PhotonBeetle.Reset(); } @@ -153,7 +130,7 @@ namespace Org.BouncyCastle.Crypto.Tests } } - private void testExceptions(IAeadBlockCipher aeadBlockCipher, int keysize, int ivsize, int blocksize) + private void ImplTestExceptions(IAeadBlockCipher aeadBlockCipher, int keysize, int ivsize, int blocksize) { ICipherParameters param; byte[] k = new byte[keysize]; @@ -164,7 +141,7 @@ namespace Org.BouncyCastle.Crypto.Tests //try //{ // aeadBlockCipher.ProcessBytes(m, 0, m.Length, c1, 0); - // Assert.Fail(aeadBlockCipher.AlgorithmName + " need to be initialed before ProcessBytes"); + // Assert.Fail(aeadBlockCipher.AlgorithmName + " needs to be initialized before ProcessBytes"); //} //catch (ArgumentException e) //{ @@ -174,7 +151,7 @@ namespace Org.BouncyCastle.Crypto.Tests //try //{ // aeadBlockCipher.ProcessByte((byte)0, c1, 0); - // Assert.Fail(aeadBlockCipher.AlgorithmName + " need to be initialed before ProcessByte"); + // Assert.Fail(aeadBlockCipher.AlgorithmName + " needs to be initialized before ProcessByte"); //} //catch (ArgumentException e) //{ @@ -184,7 +161,7 @@ namespace Org.BouncyCastle.Crypto.Tests try { aeadBlockCipher.Reset(); - Assert.Fail(aeadBlockCipher.AlgorithmName + " need to be initialed before reset"); + Assert.Fail(aeadBlockCipher.AlgorithmName + " needs to be initialized before Reset"); } catch (ArgumentException) { @@ -194,7 +171,7 @@ namespace Org.BouncyCastle.Crypto.Tests try { aeadBlockCipher.DoFinal(c1, m.Length); - Assert.Fail(aeadBlockCipher.AlgorithmName + " need to be initialed before dofinal"); + Assert.Fail(aeadBlockCipher.AlgorithmName + " needs to be initialized before DoFinal"); } catch (ArgumentException) { @@ -210,7 +187,7 @@ namespace Org.BouncyCastle.Crypto.Tests catch (ArgumentException) { //expected - Assert.Fail(aeadBlockCipher.AlgorithmName + " functions can be called before initialisation"); + Assert.Fail(aeadBlockCipher.AlgorithmName + " functions can be called before initialization"); } Random rand = new Random(); int randomNum; @@ -250,11 +227,11 @@ namespace Org.BouncyCastle.Crypto.Tests byte[] mac2 = aeadBlockCipher.GetMac(); if (mac2 == null) { - Assert.Fail("mac should not be empty after dofinal"); + Assert.Fail("mac should not be empty after DoFinal"); } if (!Arrays.AreEqual(mac2, c1)) { - Assert.Fail("mac should be equal when calling dofinal and getMac"); + Assert.Fail("mac should be equal when calling DoFinal and GetMac"); } aeadBlockCipher.ProcessAadByte((byte)0); byte[] mac1 = new byte[aeadBlockCipher.GetOutputSize(0)]; @@ -315,9 +292,9 @@ namespace Org.BouncyCastle.Crypto.Tests try { aeadBlockCipher.DoFinal(new byte[2], 2); - Assert.Fail("output for dofinal is too short"); + Assert.Fail("output for DoFinal is too short"); } - catch (DataLengthException) + catch (OutputLengthException) { //expected } @@ -366,7 +343,6 @@ namespace Org.BouncyCastle.Crypto.Tests { Assert.Fail("The encryption and decryption does not recover the plaintext"); } - Console.WriteLine(aeadBlockCipher.AlgorithmName + " test Exceptions pass"); c2[c2.Length - 1] ^= 1; aeadBlockCipher.Reset(); aeadBlockCipher.Init(false, param); @@ -377,7 +353,7 @@ namespace Org.BouncyCastle.Crypto.Tests aeadBlockCipher.DoFinal(m4, offset); Assert.Fail("The decryption should fail"); } - catch (ArgumentException) + catch (InvalidCipherTextException) { //expected; } @@ -420,8 +396,8 @@ namespace Org.BouncyCastle.Crypto.Tests offset = aeadBlockCipher.ProcessBytes(m5, c4_1); aeadBlockCipher.DoFinal(c4_2); byte[] c5 = new byte[c2.Length]; - Array.Copy(c4_1.ToArray(), 0, c5, 0, offset); - Array.Copy(c4_2.ToArray(), 0, c5, offset, c5.Length - offset); + c4_1[..offset].CopyTo(c5); + c4_2[..(c5.Length - offset)].CopyTo(c5.AsSpan(offset)); if (!Arrays.AreEqual(c2, c5)) { Assert.Fail("mac should match for the same AAD and message with different offset for both input and output"); @@ -435,38 +411,36 @@ namespace Org.BouncyCastle.Crypto.Tests offset = aeadBlockCipher.ProcessBytes(c6, m6_1); aeadBlockCipher.DoFinal(m6_2); byte[] m6 = new byte[m2.Length]; - Array.Copy(m6_1.ToArray(), 0, m6, 0, offset); - Array.Copy(m6_2.ToArray(), 0, m6, offset, m6.Length - offset); + m6_1[..offset].CopyTo(m6); + m6_2[..(m6.Length - offset)].CopyTo(m6.AsSpan(offset)); if (!Arrays.AreEqual(m2, m6)) { Assert.Fail("mac should match for the same AAD and message with different offset for both input and output"); } #endif - } - private void testParameters(PhotonBeetleEngine PhotonBeetle, int keySize, int ivSize, int macSize, int blockSize) + private void ImplTestParameters(PhotonBeetleEngine photonBeetleEngine, int keySize, int ivSize, int macSize, int blockSize) { - if (PhotonBeetle.GetKeyBytesSize() != keySize) + if (photonBeetleEngine.GetKeyBytesSize() != keySize) { - Assert.Fail("key bytes of " + PhotonBeetle.AlgorithmName + " is not correct"); + Assert.Fail("key bytes of " + photonBeetleEngine.AlgorithmName + " is not correct"); } - if (PhotonBeetle.GetIVBytesSize() != ivSize) + if (photonBeetleEngine.GetIVBytesSize() != ivSize) { - Assert.Fail("iv bytes of " + PhotonBeetle.AlgorithmName + " is not correct"); + Assert.Fail("iv bytes of " + photonBeetleEngine.AlgorithmName + " is not correct"); } - if (PhotonBeetle.GetOutputSize(0) != macSize) + if (photonBeetleEngine.GetOutputSize(0) != macSize) { - Assert.Fail("mac bytes of " + PhotonBeetle.AlgorithmName + " is not correct"); + Assert.Fail("mac bytes of " + photonBeetleEngine.AlgorithmName + " is not correct"); } - if (PhotonBeetle.GetBlockSize() != blockSize) + if (photonBeetleEngine.GetBlockSize() != blockSize) { - Assert.Fail("block size of " + PhotonBeetle.AlgorithmName + " is not correct"); + Assert.Fail("block size of " + photonBeetleEngine.AlgorithmName + " is not correct"); } - Console.WriteLine(PhotonBeetle.AlgorithmName + " test Parameters pass"); } - private void testExceptions(IDigest digest, int digestsize) + private void ImplTestExceptions(IDigest digest, int digestsize) { if (digest.GetDigestSize() != digestsize) { @@ -476,7 +450,7 @@ namespace Org.BouncyCastle.Crypto.Tests try { digest.BlockUpdate(new byte[1], 1, 1); - Assert.Fail(digest.AlgorithmName + ": input for update is too short"); + Assert.Fail(digest.AlgorithmName + ": input for BlockUpdate is too short"); } catch (DataLengthException) { @@ -485,14 +459,12 @@ namespace Org.BouncyCastle.Crypto.Tests try { digest.DoFinal(new byte[digest.GetDigestSize() - 1], 2); - Assert.Fail(digest.AlgorithmName + ": output for dofinal is too short"); + Assert.Fail(digest.AlgorithmName + ": output for DoFinal is too short"); } - catch (DataLengthException) + catch (OutputLengthException) { //expected } - Console.WriteLine(digest.AlgorithmName + " test Exceptions pass"); } - } } diff --git a/crypto/test/src/crypto/test/SparkleTest.cs b/crypto/test/src/crypto/test/SparkleTest.cs index 73aaefec5..245a1831c 100644 --- a/crypto/test/src/crypto/test/SparkleTest.cs +++ b/crypto/test/src/crypto/test/SparkleTest.cs @@ -15,54 +15,48 @@ using Org.BouncyCastle.Utilities.Test; namespace Org.BouncyCastle.Crypto.Tests { [TestFixture] - public class SparkleTest : SimpleTest + public class SparkleTest + : SimpleTest { - public override string Name - { - get { return "Sparkle"; } - } + public override string Name => "Sparkle"; [Test] public override void PerformTest() { - SparkleEngine sparkle = new SparkleEngine(SparkleEngine.SparkleParameters.SCHWAEMM128_128); - testExceptions(sparkle, sparkle.GetKeyBytesSize(), sparkle.GetIVBytesSize(), sparkle.GetBlockSize()); - testParameters(sparkle, 16, 16, 16, 16); - sparkle = new SparkleEngine(SparkleEngine.SparkleParameters.SCHWAEMM192_192); - testExceptions(sparkle, sparkle.GetKeyBytesSize(), sparkle.GetIVBytesSize(), sparkle.GetBlockSize()); - testParameters(sparkle, 24, 24, 24, 24); - sparkle = new SparkleEngine(SparkleEngine.SparkleParameters.SCHWAEMM256_128); - testExceptions(sparkle, sparkle.GetKeyBytesSize(), sparkle.GetIVBytesSize(), sparkle.GetBlockSize()); - testParameters(sparkle, 16, 32, 16, 32); - sparkle = new SparkleEngine(SparkleEngine.SparkleParameters.SCHWAEMM256_256); - testExceptions(sparkle, sparkle.GetKeyBytesSize(), sparkle.GetIVBytesSize(), sparkle.GetBlockSize()); - testParameters(sparkle, 32, 32, 32, 32); - testExceptions(new SparkleDigest(SparkleDigest.SparkleParameters.ESCH256), 32); - testExceptions(new SparkleDigest(SparkleDigest.SparkleParameters.ESCH384), 48); - testVectors("128_128", SparkleEngine.SparkleParameters.SCHWAEMM128_128); - testVectors("192_192", SparkleEngine.SparkleParameters.SCHWAEMM192_192); - testVectors("128_256", SparkleEngine.SparkleParameters.SCHWAEMM256_128); - testVectors("256_256", SparkleEngine.SparkleParameters.SCHWAEMM256_256); - testVectors("256", SparkleDigest.SparkleParameters.ESCH256); - testVectors("384", SparkleDigest.SparkleParameters.ESCH384); + SparkleEngine sparkleEngine = new SparkleEngine(SparkleEngine.SparkleParameters.SCHWAEMM128_128); + ImplTestExceptions(sparkleEngine); + ImplTestParameters(sparkleEngine, 16, 16, 16, 16); + sparkleEngine = new SparkleEngine(SparkleEngine.SparkleParameters.SCHWAEMM192_192); + ImplTestExceptions(sparkleEngine); + ImplTestParameters(sparkleEngine, 24, 24, 24, 24); + sparkleEngine = new SparkleEngine(SparkleEngine.SparkleParameters.SCHWAEMM256_128); + ImplTestExceptions(sparkleEngine); + ImplTestParameters(sparkleEngine, 16, 32, 16, 32); + sparkleEngine = new SparkleEngine(SparkleEngine.SparkleParameters.SCHWAEMM256_256); + ImplTestExceptions(sparkleEngine); + ImplTestParameters(sparkleEngine, 32, 32, 32, 32); + ImplTestExceptions(new SparkleDigest(SparkleDigest.SparkleParameters.ESCH256), 32); + ImplTestExceptions(new SparkleDigest(SparkleDigest.SparkleParameters.ESCH384), 48); + ImplTestVectors("128_128", SparkleEngine.SparkleParameters.SCHWAEMM128_128); + ImplTestVectors("192_192", SparkleEngine.SparkleParameters.SCHWAEMM192_192); + ImplTestVectors("128_256", SparkleEngine.SparkleParameters.SCHWAEMM256_128); + ImplTestVectors("256_256", SparkleEngine.SparkleParameters.SCHWAEMM256_256); + ImplTestVectors("256", SparkleDigest.SparkleParameters.ESCH256); + ImplTestVectors("384", SparkleDigest.SparkleParameters.ESCH384); } - private void testVectors(string filename, SparkleEngine.SparkleParameters SparkleType) + private void ImplTestVectors(string filename, SparkleEngine.SparkleParameters SparkleType) { SparkleEngine Sparkle = new SparkleEngine(SparkleType); ICipherParameters param; var buf = new Dictionary<string, string>(); - //TestSampler sampler = new TestSampler(); using (var src = new StreamReader(SimpleTest.GetTestDataAsStream("crypto.sparkle.LWC_AEAD_KAT_" + filename + ".txt"))) { - string line; - string[] data; - byte[] ptByte, adByte; - byte[] rv; Dictionary<string, string> map = new Dictionary<string, string>(); + string line; while ((line = src.ReadLine()) != null) { - data = line.Split(' '); + var data = line.Split(' '); if (data.Length == 1) { //if (!map["Count"].Equals("562")) @@ -77,20 +71,9 @@ namespace Org.BouncyCastle.Crypto.Tests param = new ParametersWithIV(new KeyParameter(key), nonce); Sparkle.Init(true, param); Sparkle.ProcessAadBytes(ad, 0, ad.Length); - rv = new byte[Sparkle.GetOutputSize(pt.Length)]; + byte[] rv = new byte[Sparkle.GetOutputSize(pt.Length)]; int len = Sparkle.ProcessBytes(pt, 0, pt.Length, rv, 0); - //byte[] mac = new byte[16]; Sparkle.DoFinal(rv, len); - //foreach(byte b in Hex.Decode(map["CT"])) - //{ - // Console.Write(b.ToString("X2")); - //} - //Console.WriteLine(); - //foreach (byte b in Arrays.Concatenate(rv, mac)) - //{ - // Console.Write(b.ToString("X2")); - //} - //Console.WriteLine(); Assert.True(Arrays.AreEqual(rv, ct)); Sparkle.Reset(); Sparkle.Init(false, param); @@ -102,7 +85,6 @@ namespace Org.BouncyCastle.Crypto.Tests byte[] pt_recovered = new byte[pt.Length]; Array.Copy(rv, 0, pt_recovered, 0, pt.Length); Assert.True(Arrays.AreEqual(pt, pt_recovered)); - //Console.WriteLine(map["Count"] + " pass"); map.Clear(); Sparkle.Reset(); @@ -121,32 +103,27 @@ namespace Org.BouncyCastle.Crypto.Tests } } } - Console.WriteLine("Sparkle AEAD pass"); } - private void testVectors(String filename, SparkleDigest.SparkleParameters SparkleType) + private void ImplTestVectors(String filename, SparkleDigest.SparkleParameters SparkleType) { SparkleDigest Sparkle = new SparkleDigest(SparkleType); var buf = new Dictionary<string, string>(); //TestSampler sampler = new TestSampler(); using (var src = new StreamReader(SimpleTest.GetTestDataAsStream("crypto.sparkle.LWC_HASH_KAT_" + filename + ".txt"))) { - string line; - string[] data; - byte[] ptByte, adByte; - byte[] rv; Dictionary<string, string> map = new Dictionary<string, string>(); + string line; while ((line = src.ReadLine()) != null) { - data = line.Split(' '); + var data = line.Split(' '); if (data.Length == 1) { - ptByte = Hex.Decode(map["Msg"]); + var ptByte = Hex.Decode(map["Msg"]); Sparkle.BlockUpdate(ptByte, 0, ptByte.Length); byte[] hash = new byte[Sparkle.GetDigestSize()]; Sparkle.DoFinal(hash, 0); Assert.True(Arrays.AreEqual(hash, Hex.Decode(map["MD"]))); - //Console.WriteLine(map["Count"] + " pass"); map.Clear(); Sparkle.Reset(); } @@ -164,67 +141,67 @@ namespace Org.BouncyCastle.Crypto.Tests } } } - Console.WriteLine("Sparkle Hash pass"); } - private void testExceptions(IAeadBlockCipher aeadBlockCipher, int keysize, int ivsize, int blocksize) + private void ImplTestExceptions(SparkleEngine sparkleEngine) { - ICipherParameters param; + int blocksize = sparkleEngine.GetBlockSize(); + int keysize = sparkleEngine.GetKeyBytesSize(), ivsize = sparkleEngine.GetIVBytesSize(); byte[] k = new byte[keysize]; byte[] iv = new byte[ivsize]; byte[] m = new byte[0]; - byte[] c1 = new byte[aeadBlockCipher.GetOutputSize(m.Length)]; - param = new ParametersWithIV(new KeyParameter(k), iv); + byte[] c1 = new byte[sparkleEngine.GetOutputSize(m.Length)]; + var param = new ParametersWithIV(new KeyParameter(k), iv); try { - aeadBlockCipher.ProcessBytes(m, 0, m.Length, c1, 0); - Assert.Fail(aeadBlockCipher.AlgorithmName + " need to be initialed before ProcessBytes"); + sparkleEngine.ProcessBytes(m, 0, m.Length, c1, 0); + Assert.Fail(sparkleEngine.AlgorithmName + " needs to be initialized before ProcessBytes"); } - catch (ArgumentException e) + catch (ArgumentException) { //expected } try { - aeadBlockCipher.ProcessByte((byte)0, c1, 0); - Assert.Fail(aeadBlockCipher.AlgorithmName + " need to be initialed before ProcessByte"); + sparkleEngine.ProcessByte((byte)0, c1, 0); + Assert.Fail(sparkleEngine.AlgorithmName + " needs to be initialized before ProcessByte"); } - catch (ArgumentException e) + catch (ArgumentException) { //expected } try { - aeadBlockCipher.Reset(); - Assert.Fail(aeadBlockCipher.AlgorithmName + " need to be initialed before reset"); + sparkleEngine.Reset(); + Assert.Fail(sparkleEngine.AlgorithmName + " needs to be initialized before Reset"); } - catch (ArgumentException e) + catch (ArgumentException) { //expected } try { - aeadBlockCipher.DoFinal(c1, m.Length); - Assert.Fail(aeadBlockCipher.AlgorithmName + " need to be initialed before dofinal"); + sparkleEngine.DoFinal(c1, m.Length); + Assert.Fail(sparkleEngine.AlgorithmName + " needs to be initialized before DoFinal"); } - catch (ArgumentException e) + catch (ArgumentException) { //expected } try { - aeadBlockCipher.GetMac(); - aeadBlockCipher.GetOutputSize(0); - aeadBlockCipher.GetUpdateOutputSize(0); + sparkleEngine.GetMac(); + sparkleEngine.GetOutputSize(0); + sparkleEngine.GetUpdateOutputSize(0); } - catch (ArgumentException e) + catch (ArgumentException) { //expected - Assert.Fail(aeadBlockCipher.AlgorithmName + " functions can be called before initialisation"); + Assert.Fail(sparkleEngine.AlgorithmName + " functions can be called before initialization"); } Random rand = new Random(); int randomNum; @@ -234,164 +211,163 @@ namespace Org.BouncyCastle.Crypto.Tests byte[] iv1 = new byte[randomNum]; try { - aeadBlockCipher.Init(true, new ParametersWithIV(new KeyParameter(k1), iv)); - Assert.Fail(aeadBlockCipher.AlgorithmName + " k size does not match"); + sparkleEngine.Init(true, new ParametersWithIV(new KeyParameter(k1), iv)); + Assert.Fail(sparkleEngine.AlgorithmName + " k size does not match"); } - catch (ArgumentException e) + catch (ArgumentException) { //expected } try { - aeadBlockCipher.Init(true, new ParametersWithIV(new KeyParameter(k), iv1)); - Assert.Fail(aeadBlockCipher.AlgorithmName + "iv size does not match"); + sparkleEngine.Init(true, new ParametersWithIV(new KeyParameter(k), iv1)); + Assert.Fail(sparkleEngine.AlgorithmName + "iv size does not match"); } - catch (ArgumentException e) + catch (ArgumentException) { //expected } - aeadBlockCipher.Init(true, param); + sparkleEngine.Init(true, param); try { - aeadBlockCipher.DoFinal(c1, m.Length); + sparkleEngine.DoFinal(c1, m.Length); } - catch (Exception e) + catch (Exception) { - Assert.Fail(aeadBlockCipher.AlgorithmName + " allows no input for AAD and plaintext"); + Assert.Fail(sparkleEngine.AlgorithmName + " allows no input for AAD and plaintext"); } - byte[] mac2 = aeadBlockCipher.GetMac(); + byte[] mac2 = sparkleEngine.GetMac(); if (mac2 == null) { - Assert.Fail("mac should not be empty after dofinal"); + Assert.Fail("mac should not be empty after DoFinal"); } if (!Arrays.AreEqual(mac2, c1)) { - Assert.Fail("mac should be equal when calling dofinal and getMac"); + Assert.Fail("mac should be equal when calling DoFinal and GetMac"); } - aeadBlockCipher.ProcessAadByte((byte)0); - byte[] mac1 = new byte[aeadBlockCipher.GetOutputSize(0)]; - aeadBlockCipher.DoFinal(mac1, 0); + sparkleEngine.ProcessAadByte((byte)0); + byte[] mac1 = new byte[sparkleEngine.GetOutputSize(0)]; + sparkleEngine.DoFinal(mac1, 0); if (Arrays.AreEqual(mac1, mac2)) { Assert.Fail("mac should not match"); } - aeadBlockCipher.Reset(); - aeadBlockCipher.ProcessBytes(new byte[blocksize+1], 0, blocksize+1, new byte[blocksize+1], 0); + sparkleEngine.Reset(); + sparkleEngine.ProcessBytes(new byte[blocksize+1], 0, blocksize+1, new byte[blocksize+1], 0); try { - aeadBlockCipher.ProcessAadByte((byte)0); + sparkleEngine.ProcessAadByte((byte)0); Assert.Fail("ProcessAadByte(s) cannot be called after encryption/decryption"); } - catch (ArgumentException e) + catch (ArgumentException) { //expected } try { - aeadBlockCipher.ProcessAadBytes(new byte[] { 0 }, 0, 1); + sparkleEngine.ProcessAadBytes(new byte[] { 0 }, 0, 1); Assert.Fail("ProcessAadByte(s) cannot be called once only"); } - catch (ArgumentException e) + catch (ArgumentException) { //expected } - aeadBlockCipher.Reset(); + sparkleEngine.Reset(); try { - aeadBlockCipher.ProcessAadBytes(new byte[] { 0 }, 1, 1); + sparkleEngine.ProcessAadBytes(new byte[] { 0 }, 1, 1); Assert.Fail("input for ProcessAadBytes is too short"); } - catch (DataLengthException e) + catch (DataLengthException) { //expected } try { - aeadBlockCipher.ProcessBytes(new byte[] { 0 }, 1, 1, c1, 0); + sparkleEngine.ProcessBytes(new byte[] { 0 }, 1, 1, c1, 0); Assert.Fail("input for ProcessBytes is too short"); } - catch (DataLengthException e) + catch (DataLengthException) { //expected } try { - aeadBlockCipher.ProcessBytes(new byte[blocksize+1], 0, blocksize+1, new byte[blocksize+1], blocksize >> 1); + sparkleEngine.ProcessBytes(new byte[blocksize+1], 0, blocksize+1, new byte[blocksize+1], blocksize >> 1); Assert.Fail("output for ProcessBytes is too short"); } - catch (OutputLengthException e) + catch (OutputLengthException) { //expected } try { - aeadBlockCipher.DoFinal(new byte[2], 2); - Assert.Fail("output for dofinal is too short"); + sparkleEngine.DoFinal(new byte[2], 2); + Assert.Fail("output for DoFinal is too short"); } - catch (DataLengthException e) + catch (OutputLengthException) { //expected } - mac1 = new byte[aeadBlockCipher.GetOutputSize(0)]; - mac2 = new byte[aeadBlockCipher.GetOutputSize(0)]; - aeadBlockCipher.Reset(); - aeadBlockCipher.ProcessAadBytes(new byte[] { 0, 0 }, 0, 2); - aeadBlockCipher.DoFinal(mac1, 0); - aeadBlockCipher.Reset(); - aeadBlockCipher.ProcessAadByte((byte)0); - aeadBlockCipher.ProcessAadByte((byte)0); - aeadBlockCipher.DoFinal(mac2, 0); + mac1 = new byte[sparkleEngine.GetOutputSize(0)]; + mac2 = new byte[sparkleEngine.GetOutputSize(0)]; + sparkleEngine.Reset(); + sparkleEngine.ProcessAadBytes(new byte[] { 0, 0 }, 0, 2); + sparkleEngine.DoFinal(mac1, 0); + sparkleEngine.Reset(); + sparkleEngine.ProcessAadByte((byte)0); + sparkleEngine.ProcessAadByte((byte)0); + sparkleEngine.DoFinal(mac2, 0); if (!Arrays.AreEqual(mac1, mac2)) { Assert.Fail("mac should match for the same AAD with different ways of inputing"); } - byte[] c2 = new byte[aeadBlockCipher.GetOutputSize(10)]; - byte[] c3 = new byte[aeadBlockCipher.GetOutputSize(10) + 2]; + byte[] c2 = new byte[sparkleEngine.GetOutputSize(10)]; + byte[] c3 = new byte[sparkleEngine.GetOutputSize(10) + 2]; byte[] aad2 = { 0, 1, 2, 3, 4 }; byte[] aad3 = { 0, 0, 1, 2, 3, 4, 5 }; byte[] m2 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; byte[] m3 = { 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; byte[] m4 = new byte[m2.Length]; - aeadBlockCipher.Reset(); - aeadBlockCipher.ProcessAadBytes(aad2, 0, aad2.Length); - int offset = aeadBlockCipher.ProcessBytes(m2, 0, m2.Length, c2, 0); - aeadBlockCipher.DoFinal(c2, offset); - aeadBlockCipher.Reset(); - aeadBlockCipher.ProcessAadBytes(aad3, 1, aad2.Length); - offset = aeadBlockCipher.ProcessBytes(m3, 1, m2.Length, c3, 1); - aeadBlockCipher.DoFinal(c3, offset + 1); + sparkleEngine.Reset(); + sparkleEngine.ProcessAadBytes(aad2, 0, aad2.Length); + int offset = sparkleEngine.ProcessBytes(m2, 0, m2.Length, c2, 0); + sparkleEngine.DoFinal(c2, offset); + sparkleEngine.Reset(); + sparkleEngine.ProcessAadBytes(aad3, 1, aad2.Length); + offset = sparkleEngine.ProcessBytes(m3, 1, m2.Length, c3, 1); + sparkleEngine.DoFinal(c3, offset + 1); byte[] c3_partial = new byte[c2.Length]; Array.Copy(c3, 1, c3_partial, 0, c2.Length); if (!Arrays.AreEqual(c2, c3_partial)) { Assert.Fail("mac should match for the same AAD and message with different offset for both input and output"); } - aeadBlockCipher.Reset(); - aeadBlockCipher.Init(false, param); - aeadBlockCipher.ProcessAadBytes(aad2, 0, aad2.Length); - offset = aeadBlockCipher.ProcessBytes(c2, 0, c2.Length, m4, 0); - aeadBlockCipher.DoFinal(m4, offset); + sparkleEngine.Reset(); + sparkleEngine.Init(false, param); + sparkleEngine.ProcessAadBytes(aad2, 0, aad2.Length); + offset = sparkleEngine.ProcessBytes(c2, 0, c2.Length, m4, 0); + sparkleEngine.DoFinal(m4, offset); if (!Arrays.AreEqual(m2, m4)) { Assert.Fail("The encryption and decryption does not recover the plaintext"); } - Console.WriteLine(aeadBlockCipher.AlgorithmName + " test Exceptions pass"); c2[c2.Length - 1] ^= 1; - aeadBlockCipher.Reset(); - aeadBlockCipher.Init(false, param); - aeadBlockCipher.ProcessAadBytes(aad2, 0, aad2.Length); - offset = aeadBlockCipher.ProcessBytes(c2, 0, c2.Length, m4, 0); + sparkleEngine.Reset(); + sparkleEngine.Init(false, param); + sparkleEngine.ProcessAadBytes(aad2, 0, aad2.Length); + offset = sparkleEngine.ProcessBytes(c2, 0, c2.Length, m4, 0); try { - aeadBlockCipher.DoFinal(m4, offset); + sparkleEngine.DoFinal(m4, offset); Assert.Fail("The decryption should fail"); } - catch (ArgumentException e) + catch (InvalidCipherTextException) { //expected; } @@ -402,24 +378,24 @@ namespace Org.BouncyCastle.Crypto.Tests { m7[i] = (byte)rand.Next(); } - byte[] c7 = new byte[aeadBlockCipher.GetOutputSize(m7.Length)]; + byte[] c7 = new byte[sparkleEngine.GetOutputSize(m7.Length)]; byte[] c8 = new byte[c7.Length]; byte[] c9 = new byte[c7.Length]; - aeadBlockCipher.Init(true, param); - aeadBlockCipher.ProcessAadBytes(aad2, 0, aad2.Length); - offset = aeadBlockCipher.ProcessBytes(m7, 0, m7.Length, c7, 0); - aeadBlockCipher.DoFinal(c7, offset); - aeadBlockCipher.Reset(); - aeadBlockCipher.ProcessAadBytes(aad2, 0, aad2.Length); - offset = aeadBlockCipher.ProcessBytes(m7, 0, blocksize, c8, 0); - offset += aeadBlockCipher.ProcessBytes(m7, blocksize, m7.Length - blocksize, c8, offset); - aeadBlockCipher.DoFinal(c8, offset); - aeadBlockCipher.Reset(); + sparkleEngine.Init(true, param); + sparkleEngine.ProcessAadBytes(aad2, 0, aad2.Length); + offset = sparkleEngine.ProcessBytes(m7, 0, m7.Length, c7, 0); + sparkleEngine.DoFinal(c7, offset); + sparkleEngine.Reset(); + sparkleEngine.ProcessAadBytes(aad2, 0, aad2.Length); + offset = sparkleEngine.ProcessBytes(m7, 0, blocksize, c8, 0); + offset += sparkleEngine.ProcessBytes(m7, blocksize, m7.Length - blocksize, c8, offset); + sparkleEngine.DoFinal(c8, offset); + sparkleEngine.Reset(); int split = rand.Next(blocksize * 2); - aeadBlockCipher.ProcessAadBytes(aad2, 0, aad2.Length); - offset = aeadBlockCipher.ProcessBytes(m7, 0, split, c9, 0); - offset += aeadBlockCipher.ProcessBytes(m7, split, m7.Length - split, c9, offset); - aeadBlockCipher.DoFinal(c9, offset); + sparkleEngine.ProcessAadBytes(aad2, 0, aad2.Length); + offset = sparkleEngine.ProcessBytes(m7, 0, split, c9, 0); + offset += sparkleEngine.ProcessBytes(m7, split, m7.Length - split, c9, offset); + sparkleEngine.DoFinal(c9, offset); if (!Arrays.AreEqual(c7, c8) || !Arrays.AreEqual(c7, c9)) { Assert.Fail("Splitting input of plaintext should output the same ciphertext"); @@ -429,10 +405,10 @@ namespace Org.BouncyCastle.Crypto.Tests Span<byte> c4_2 = new byte[c2.Length]; ReadOnlySpan<byte> m5 = new ReadOnlySpan<byte>(m2); ReadOnlySpan<byte> aad4 = new ReadOnlySpan<byte>(aad2); - aeadBlockCipher.Init(true, param); - aeadBlockCipher.ProcessAadBytes(aad4); - offset = aeadBlockCipher.ProcessBytes(m5, c4_1); - aeadBlockCipher.DoFinal(c4_2); + sparkleEngine.Init(true, param); + sparkleEngine.ProcessAadBytes(aad4); + offset = sparkleEngine.ProcessBytes(m5, c4_1); + sparkleEngine.DoFinal(c4_2); byte[] c5 = new byte[c2.Length]; Array.Copy(c4_1.ToArray(), 0, c5, 0, offset); Array.Copy(c4_2.ToArray(), 0, c5, offset, c5.Length - offset); @@ -440,14 +416,14 @@ namespace Org.BouncyCastle.Crypto.Tests { Assert.Fail("mac should match for the same AAD and message with different offset for both input and output"); } - aeadBlockCipher.Reset(); - aeadBlockCipher.Init(false, param); + sparkleEngine.Reset(); + sparkleEngine.Init(false, param); Span<byte> m6_1 = new byte[m2.Length]; Span<byte> m6_2 = new byte[m2.Length]; ReadOnlySpan<byte> c6 = new ReadOnlySpan<byte>(c2); - aeadBlockCipher.ProcessAadBytes(aad4); - offset = aeadBlockCipher.ProcessBytes(c6, m6_1); - aeadBlockCipher.DoFinal(m6_2); + sparkleEngine.ProcessAadBytes(aad4); + offset = sparkleEngine.ProcessBytes(c6, m6_1); + sparkleEngine.DoFinal(m6_2); byte[] m6 = new byte[m2.Length]; Array.Copy(m6_1.ToArray(), 0, m6, 0, offset); Array.Copy(m6_2.ToArray(), 0, m6, offset, m6.Length - offset); @@ -456,57 +432,53 @@ namespace Org.BouncyCastle.Crypto.Tests Assert.Fail("mac should match for the same AAD and message with different offset for both input and output"); } #endif - } - private void testParameters(SparkleEngine Sparkle, int keySize, int ivSize, int macSize, int blockSize) + private void ImplTestParameters(SparkleEngine sparkleEngine, int keySize, int ivSize, int macSize, int blockSize) { - if (Sparkle.GetKeyBytesSize() != keySize) + if (sparkleEngine.GetKeyBytesSize() != keySize) { - Assert.Fail("key bytes of " + Sparkle.AlgorithmName + " is not correct"); + Assert.Fail("key bytes of " + sparkleEngine.AlgorithmName + " is not correct"); } - if (Sparkle.GetIVBytesSize() != ivSize) + if (sparkleEngine.GetIVBytesSize() != ivSize) { - Assert.Fail("iv bytes of " + Sparkle.AlgorithmName + " is not correct"); + Assert.Fail("iv bytes of " + sparkleEngine.AlgorithmName + " is not correct"); } - if (Sparkle.GetOutputSize(0) != macSize) + if (sparkleEngine.GetOutputSize(0) != macSize) { - Assert.Fail("mac bytes of " + Sparkle.AlgorithmName + " is not correct"); + Assert.Fail("mac bytes of " + sparkleEngine.AlgorithmName + " is not correct"); } - if (Sparkle.GetBlockSize() != blockSize) + if (sparkleEngine.GetBlockSize() != blockSize) { - Assert.Fail("block size of " + Sparkle.AlgorithmName + " is not correct"); + Assert.Fail("block size of " + sparkleEngine.AlgorithmName + " is not correct"); } - Console.WriteLine(Sparkle.AlgorithmName + " test Parameters pass"); } - private void testExceptions(IDigest digest, int digestsize) + private void ImplTestExceptions(SparkleDigest sparkleDigest, int digestsize) { - if (digest.GetDigestSize() != digestsize) + if (sparkleDigest.GetDigestSize() != digestsize) { - Assert.Fail(digest.AlgorithmName + ": digest size is not correct"); + Assert.Fail(sparkleDigest.AlgorithmName + ": digest size is not correct"); } try { - digest.BlockUpdate(new byte[1], 1, 1); - Assert.Fail(digest.AlgorithmName + ": input for update is too short"); + sparkleDigest.BlockUpdate(new byte[1], 1, 1); + Assert.Fail(sparkleDigest.AlgorithmName + ": input for BlockUpdate is too short"); } - catch (DataLengthException e) + catch (DataLengthException) { //expected } try { - digest.DoFinal(new byte[digest.GetDigestSize() - 1], 2); - Assert.Fail(digest.AlgorithmName + ": output for dofinal is too short"); + sparkleDigest.DoFinal(new byte[sparkleDigest.GetDigestSize() - 1], 2); + Assert.Fail(sparkleDigest.AlgorithmName + ": output for DoFinal is too short"); } - catch (DataLengthException e) + catch (OutputLengthException) { //expected } - Console.WriteLine(digest.AlgorithmName + " test Exceptions pass"); } - } } diff --git a/crypto/test/src/crypto/test/XoodyakTest.cs b/crypto/test/src/crypto/test/XoodyakTest.cs index 5c6d3893e..d8664e82f 100644 --- a/crypto/test/src/crypto/test/XoodyakTest.cs +++ b/crypto/test/src/crypto/test/XoodyakTest.cs @@ -6,7 +6,6 @@ using NUnit.Framework; using Org.BouncyCastle.Crypto.Digests; using Org.BouncyCastle.Crypto.Engines; -using Org.BouncyCastle.Crypto.Modes; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.Encoders; @@ -15,39 +14,33 @@ using Org.BouncyCastle.Utilities.Test; namespace Org.BouncyCastle.Crypto.Tests { [TestFixture] - public class XoodyakTest : SimpleTest + public class XoodyakTest + : SimpleTest { - public override string Name - { - get { return "Xoodyak"; } - } + public override string Name => "Xoodyak"; [Test] public override void PerformTest() { - testVectorsHash(); - testVectors(); - XoodyakEngine xoodyak = new XoodyakEngine(); - testExceptions(xoodyak, xoodyak.GetKeyBytesSize(), xoodyak.GetIVBytesSize(), xoodyak.GetBlockSize()); - testParameters(xoodyak, 16, 16, 16, 24); - testExceptions(new XoodyakDigest(), 32); + ImplTestVectorsHash(); + ImplTestVectors(); + XoodyakEngine xoodyakEngine = new XoodyakEngine(); + ImplTestExceptions(xoodyakEngine, xoodyakEngine.GetKeyBytesSize(), xoodyakEngine.GetIVBytesSize(), xoodyakEngine.GetBlockSize()); + ImplTestParameters(xoodyakEngine, 16, 16, 16, 24); + ImplTestExceptions(new XoodyakDigest(), 32); } - private void testVectors() + private void ImplTestVectors() { XoodyakEngine xoodyak = new XoodyakEngine(); - ICipherParameters param; var buf = new Dictionary<string, string>(); - //TestSampler sampler = new TestSampler(); using (var src = new StreamReader(SimpleTest.GetTestDataAsStream("crypto.xoodyak.LWC_AEAD_KAT_128_128.txt"))) { - string line; - string[] data; - byte[] rv; Dictionary<string, string> map = new Dictionary<string, string>(); + string line; while ((line = src.ReadLine()) != null) { - data = line.Split(' '); + var data = line.Split(' '); if (data.Length == 1) { byte[] key = Hex.Decode(map["Key"]); @@ -55,23 +48,14 @@ namespace Org.BouncyCastle.Crypto.Tests byte[] ad = Hex.Decode(map["AD"]); byte[] pt = Hex.Decode(map["PT"]); byte[] ct = Hex.Decode(map["CT"]); - param = new ParametersWithIV(new KeyParameter(key), nonce); + map.Clear(); + + var param = new ParametersWithIV(new KeyParameter(key), nonce); xoodyak.Init(true, param); xoodyak.ProcessAadBytes(ad, 0, ad.Length); - rv = new byte[xoodyak.GetOutputSize(pt.Length)]; + byte[] rv = new byte[xoodyak.GetOutputSize(pt.Length)]; int len = xoodyak.ProcessBytes(pt, 0, pt.Length, rv, 0); - //byte[] mac = new byte[16]; xoodyak.DoFinal(rv, len); - //foreach(byte b in Hex.Decode(map["CT"])) - //{ - // Console.Write(b.ToString("X2")); - //} - //Console.WriteLine(); - //foreach (byte b in Arrays.Concatenate(rv, mac)) - //{ - // Console.Write(b.ToString("X2")); - //} - //Console.WriteLine(); Assert.True(Arrays.AreEqual(rv, ct)); xoodyak.Reset(); xoodyak.Init(false, param); @@ -83,8 +67,6 @@ namespace Org.BouncyCastle.Crypto.Tests byte[] pt_recovered = new byte[pt.Length]; Array.Copy(rv, 0, pt_recovered, 0, pt.Length); Assert.True(Arrays.AreEqual(pt, pt_recovered)); - //Console.WriteLine(map["Count"] + " pass"); - map.Clear(); xoodyak.Reset(); } else @@ -101,28 +83,25 @@ namespace Org.BouncyCastle.Crypto.Tests } } } - private void testVectorsHash() + private void ImplTestVectorsHash() { XoodyakDigest xoodyak = new XoodyakDigest(); var buf = new Dictionary<string, string>(); //TestSampler sampler = new TestSampler(); using (var src = new StreamReader(SimpleTest.GetTestDataAsStream("crypto.xoodyak.LWC_HASH_KAT_256.txt"))) { - string line; - string[] data; - byte[] ptByte; Dictionary<string, string> map = new Dictionary<string, string>(); + string line; while ((line = src.ReadLine()) != null) { - data = line.Split(' '); + var data = line.Split(' '); if (data.Length == 1) { - ptByte = Hex.Decode(map["Msg"]); + var ptByte = Hex.Decode(map["Msg"]); xoodyak.BlockUpdate(ptByte, 0, ptByte.Length); byte[] hash = new byte[32]; xoodyak.DoFinal(hash, 0); Assert.True(Arrays.AreEqual(hash, Hex.Decode(map["MD"]))); - //Console.WriteLine(map["Count"] + " pass"); map.Clear(); xoodyak.Reset(); } @@ -142,18 +121,17 @@ namespace Org.BouncyCastle.Crypto.Tests } } - private void testExceptions(IAeadBlockCipher aeadBlockCipher, int keysize, int ivsize, int blocksize) + private void ImplTestExceptions(XoodyakEngine xoodyakEngine, int keysize, int ivsize, int blocksize) { - ICipherParameters param; byte[] k = new byte[keysize]; byte[] iv = new byte[ivsize]; byte[] m = new byte[0]; - byte[] c1 = new byte[aeadBlockCipher.GetOutputSize(m.Length)]; - param = new ParametersWithIV(new KeyParameter(k), iv); + byte[] c1 = new byte[xoodyakEngine.GetOutputSize(m.Length)]; + var param = new ParametersWithIV(new KeyParameter(k), iv); try { - aeadBlockCipher.ProcessBytes(m, 0, m.Length, c1, 0); - Assert.Fail(aeadBlockCipher.AlgorithmName + " need to be initialed before ProcessBytes"); + xoodyakEngine.ProcessBytes(m, 0, m.Length, c1, 0); + Assert.Fail(xoodyakEngine.AlgorithmName + " needs to be initialized before ProcessBytes"); } catch (ArgumentException) { @@ -162,8 +140,8 @@ namespace Org.BouncyCastle.Crypto.Tests try { - aeadBlockCipher.ProcessByte((byte)0, c1, 0); - Assert.Fail(aeadBlockCipher.AlgorithmName + " need to be initialed before ProcessByte"); + xoodyakEngine.ProcessByte((byte)0, c1, 0); + Assert.Fail(xoodyakEngine.AlgorithmName + " needs to be initialized before ProcessByte"); } catch (ArgumentException) { @@ -172,8 +150,8 @@ namespace Org.BouncyCastle.Crypto.Tests try { - aeadBlockCipher.Reset(); - Assert.Fail(aeadBlockCipher.AlgorithmName + " need to be initialed before reset"); + xoodyakEngine.Reset(); + Assert.Fail(xoodyakEngine.AlgorithmName + " needs to be initialized before Reset"); } catch (ArgumentException) { @@ -182,8 +160,8 @@ namespace Org.BouncyCastle.Crypto.Tests try { - aeadBlockCipher.DoFinal(c1, m.Length); - Assert.Fail(aeadBlockCipher.AlgorithmName + " need to be initialed before dofinal"); + xoodyakEngine.DoFinal(c1, m.Length); + Assert.Fail(xoodyakEngine.AlgorithmName + " needs to be initialized before DoFinal"); } catch (ArgumentException) { @@ -192,14 +170,14 @@ namespace Org.BouncyCastle.Crypto.Tests try { - aeadBlockCipher.GetMac(); - aeadBlockCipher.GetOutputSize(0); - aeadBlockCipher.GetUpdateOutputSize(0); + xoodyakEngine.GetMac(); + xoodyakEngine.GetOutputSize(0); + xoodyakEngine.GetUpdateOutputSize(0); } catch (ArgumentException) { //expected - Assert.Fail(aeadBlockCipher.AlgorithmName + " functions can be called before initialisation"); + Assert.Fail(xoodyakEngine.AlgorithmName + " functions can be called before initialization"); } Random rand = new Random(); int randomNum; @@ -209,8 +187,8 @@ namespace Org.BouncyCastle.Crypto.Tests byte[] iv1 = new byte[randomNum]; try { - aeadBlockCipher.Init(true, new ParametersWithIV(new KeyParameter(k1), iv)); - Assert.Fail(aeadBlockCipher.AlgorithmName + " k size does not match"); + xoodyakEngine.Init(true, new ParametersWithIV(new KeyParameter(k1), iv)); + Assert.Fail(xoodyakEngine.AlgorithmName + " k size does not match"); } catch (ArgumentException) { @@ -218,8 +196,8 @@ namespace Org.BouncyCastle.Crypto.Tests } try { - aeadBlockCipher.Init(true, new ParametersWithIV(new KeyParameter(k), iv1)); - Assert.Fail(aeadBlockCipher.AlgorithmName + "iv size does not match"); + xoodyakEngine.Init(true, new ParametersWithIV(new KeyParameter(k), iv1)); + Assert.Fail(xoodyakEngine.AlgorithmName + "iv size does not match"); } catch (ArgumentException) { @@ -227,36 +205,36 @@ namespace Org.BouncyCastle.Crypto.Tests } - aeadBlockCipher.Init(true, param); + xoodyakEngine.Init(true, param); try { - aeadBlockCipher.DoFinal(c1, m.Length); + xoodyakEngine.DoFinal(c1, m.Length); } catch (Exception) { - Assert.Fail(aeadBlockCipher.AlgorithmName + " allows no input for AAD and plaintext"); + Assert.Fail(xoodyakEngine.AlgorithmName + " allows no input for AAD and plaintext"); } - byte[] mac2 = aeadBlockCipher.GetMac(); + byte[] mac2 = xoodyakEngine.GetMac(); if (mac2 == null) { - Assert.Fail("mac should not be empty after dofinal"); + Assert.Fail("mac should not be empty after DoFinal"); } if (!Arrays.AreEqual(mac2, c1)) { - Assert.Fail("mac should be equal when calling dofinal and getMac"); + Assert.Fail("mac should be equal when calling DoFinal and GetMac"); } - aeadBlockCipher.ProcessAadByte((byte)0); - byte[] mac1 = new byte[aeadBlockCipher.GetOutputSize(0)]; - aeadBlockCipher.DoFinal(mac1, 0); + xoodyakEngine.ProcessAadByte((byte)0); + byte[] mac1 = new byte[xoodyakEngine.GetOutputSize(0)]; + xoodyakEngine.DoFinal(mac1, 0); if (Arrays.AreEqual(mac1, mac2)) { Assert.Fail("mac should not match"); } - aeadBlockCipher.Reset(); - aeadBlockCipher.ProcessBytes(new byte[blocksize], 0, blocksize, new byte[blocksize], 0); + xoodyakEngine.Reset(); + xoodyakEngine.ProcessBytes(new byte[blocksize], 0, blocksize, new byte[blocksize], 0); try { - aeadBlockCipher.ProcessAadByte((byte)0); + xoodyakEngine.ProcessAadByte((byte)0); Assert.Fail("ProcessAadByte(s) cannot be called after encryption/decryption"); } catch (ArgumentException) @@ -265,7 +243,7 @@ namespace Org.BouncyCastle.Crypto.Tests } try { - aeadBlockCipher.ProcessAadBytes(new byte[] { 0 }, 0, 1); + xoodyakEngine.ProcessAadBytes(new byte[] { 0 }, 0, 1); Assert.Fail("ProcessAadByte(s) cannot be called once only"); } catch (ArgumentException) @@ -273,10 +251,10 @@ namespace Org.BouncyCastle.Crypto.Tests //expected } - aeadBlockCipher.Reset(); + xoodyakEngine.Reset(); try { - aeadBlockCipher.ProcessAadBytes(new byte[] { 0 }, 1, 1); + xoodyakEngine.ProcessAadBytes(new byte[] { 0 }, 1, 1); Assert.Fail("input for ProcessAadBytes is too short"); } catch (DataLengthException) @@ -285,7 +263,7 @@ namespace Org.BouncyCastle.Crypto.Tests } try { - aeadBlockCipher.ProcessBytes(new byte[] { 0 }, 1, 1, c1, 0); + xoodyakEngine.ProcessBytes(new byte[] { 0 }, 1, 1, c1, 0); Assert.Fail("input for ProcessBytes is too short"); } catch (DataLengthException) @@ -294,7 +272,7 @@ namespace Org.BouncyCastle.Crypto.Tests } try { - aeadBlockCipher.ProcessBytes(new byte[blocksize], 0, blocksize, new byte[blocksize], blocksize >> 1); + xoodyakEngine.ProcessBytes(new byte[blocksize], 0, blocksize, new byte[blocksize], blocksize >> 1); Assert.Fail("output for ProcessBytes is too short"); } catch (OutputLengthException) @@ -303,70 +281,69 @@ namespace Org.BouncyCastle.Crypto.Tests } try { - aeadBlockCipher.DoFinal(new byte[2], 2); - Assert.Fail("output for dofinal is too short"); + xoodyakEngine.DoFinal(new byte[2], 2); + Assert.Fail("output for DoFinal is too short"); } - catch (DataLengthException) + catch (OutputLengthException) { //expected } - mac1 = new byte[aeadBlockCipher.GetOutputSize(0)]; - mac2 = new byte[aeadBlockCipher.GetOutputSize(0)]; - aeadBlockCipher.Reset(); - aeadBlockCipher.ProcessAadBytes(new byte[] { 0, 0 }, 0, 2); - aeadBlockCipher.DoFinal(mac1, 0); - aeadBlockCipher.Reset(); - aeadBlockCipher.ProcessAadByte((byte)0); - aeadBlockCipher.ProcessAadByte((byte)0); - aeadBlockCipher.DoFinal(mac2, 0); + mac1 = new byte[xoodyakEngine.GetOutputSize(0)]; + mac2 = new byte[xoodyakEngine.GetOutputSize(0)]; + xoodyakEngine.Reset(); + xoodyakEngine.ProcessAadBytes(new byte[] { 0, 0 }, 0, 2); + xoodyakEngine.DoFinal(mac1, 0); + xoodyakEngine.Reset(); + xoodyakEngine.ProcessAadByte((byte)0); + xoodyakEngine.ProcessAadByte((byte)0); + xoodyakEngine.DoFinal(mac2, 0); if (!Arrays.AreEqual(mac1, mac2)) { Assert.Fail("mac should match for the same AAD with different ways of inputing"); } - byte[] c2 = new byte[aeadBlockCipher.GetOutputSize(10)]; - byte[] c3 = new byte[aeadBlockCipher.GetOutputSize(10) + 2]; + byte[] c2 = new byte[xoodyakEngine.GetOutputSize(10)]; + byte[] c3 = new byte[xoodyakEngine.GetOutputSize(10) + 2]; byte[] aad2 = { 0, 1, 2, 3, 4 }; byte[] aad3 = { 0, 0, 1, 2, 3, 4, 5 }; byte[] m2 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; byte[] m3 = { 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; byte[] m4 = new byte[m2.Length]; - aeadBlockCipher.Reset(); - aeadBlockCipher.ProcessAadBytes(aad2, 0, aad2.Length); - int offset = aeadBlockCipher.ProcessBytes(m2, 0, m2.Length, c2, 0); - aeadBlockCipher.DoFinal(c2, offset); - aeadBlockCipher.Reset(); - aeadBlockCipher.ProcessAadBytes(aad3, 1, aad2.Length); - offset = aeadBlockCipher.ProcessBytes(m3, 1, m2.Length, c3, 1); - aeadBlockCipher.DoFinal(c3, offset + 1); + xoodyakEngine.Reset(); + xoodyakEngine.ProcessAadBytes(aad2, 0, aad2.Length); + int offset = xoodyakEngine.ProcessBytes(m2, 0, m2.Length, c2, 0); + xoodyakEngine.DoFinal(c2, offset); + xoodyakEngine.Reset(); + xoodyakEngine.ProcessAadBytes(aad3, 1, aad2.Length); + offset = xoodyakEngine.ProcessBytes(m3, 1, m2.Length, c3, 1); + xoodyakEngine.DoFinal(c3, offset + 1); byte[] c3_partial = new byte[c2.Length]; Array.Copy(c3, 1, c3_partial, 0, c2.Length); if (!Arrays.AreEqual(c2, c3_partial)) { Assert.Fail("mac should match for the same AAD and message with different offset for both input and output"); } - aeadBlockCipher.Reset(); - aeadBlockCipher.Init(false, param); - aeadBlockCipher.ProcessAadBytes(aad2, 0, aad2.Length); - offset = aeadBlockCipher.ProcessBytes(c2, 0, c2.Length, m4, 0); - aeadBlockCipher.DoFinal(m4, offset); + xoodyakEngine.Reset(); + xoodyakEngine.Init(false, param); + xoodyakEngine.ProcessAadBytes(aad2, 0, aad2.Length); + offset = xoodyakEngine.ProcessBytes(c2, 0, c2.Length, m4, 0); + xoodyakEngine.DoFinal(m4, offset); if (!Arrays.AreEqual(m2, m4)) { Assert.Fail("The encryption and decryption does not recover the plaintext"); } - Console.WriteLine(aeadBlockCipher.AlgorithmName + " test Exceptions pass"); c2[c2.Length - 1] ^= 1; - aeadBlockCipher.Reset(); - aeadBlockCipher.Init(false, param); - aeadBlockCipher.ProcessAadBytes(aad2, 0, aad2.Length); - offset = aeadBlockCipher.ProcessBytes(c2, 0, c2.Length, m4, 0); + xoodyakEngine.Reset(); + xoodyakEngine.Init(false, param); + xoodyakEngine.ProcessAadBytes(aad2, 0, aad2.Length); + offset = xoodyakEngine.ProcessBytes(c2, 0, c2.Length, m4, 0); try { - aeadBlockCipher.DoFinal(m4, offset); + xoodyakEngine.DoFinal(m4, offset); Assert.Fail("The decryption should fail"); } - catch (ArgumentException) + catch (InvalidCipherTextException) { //expected; } @@ -377,24 +354,24 @@ namespace Org.BouncyCastle.Crypto.Tests { m7[i] = (byte)rand.Next(); } - byte[] c7 = new byte[aeadBlockCipher.GetOutputSize(m7.Length)]; + byte[] c7 = new byte[xoodyakEngine.GetOutputSize(m7.Length)]; byte[] c8 = new byte[c7.Length]; byte[] c9 = new byte[c7.Length]; - aeadBlockCipher.Init(true, param); - aeadBlockCipher.ProcessAadBytes(aad2, 0, aad2.Length); - offset = aeadBlockCipher.ProcessBytes(m7, 0, m7.Length, c7, 0); - aeadBlockCipher.DoFinal(c7, offset); - aeadBlockCipher.Reset(); - aeadBlockCipher.ProcessAadBytes(aad2, 0, aad2.Length); - offset = aeadBlockCipher.ProcessBytes(m7, 0, blocksize, c8, 0); - offset += aeadBlockCipher.ProcessBytes(m7, blocksize, m7.Length - blocksize, c8, offset); - aeadBlockCipher.DoFinal(c8, offset); - aeadBlockCipher.Reset(); + xoodyakEngine.Init(true, param); + xoodyakEngine.ProcessAadBytes(aad2, 0, aad2.Length); + offset = xoodyakEngine.ProcessBytes(m7, 0, m7.Length, c7, 0); + xoodyakEngine.DoFinal(c7, offset); + xoodyakEngine.Reset(); + xoodyakEngine.ProcessAadBytes(aad2, 0, aad2.Length); + offset = xoodyakEngine.ProcessBytes(m7, 0, blocksize, c8, 0); + offset += xoodyakEngine.ProcessBytes(m7, blocksize, m7.Length - blocksize, c8, offset); + xoodyakEngine.DoFinal(c8, offset); + xoodyakEngine.Reset(); int split = rand.Next(blocksize * 2); - aeadBlockCipher.ProcessAadBytes(aad2, 0, aad2.Length); - offset = aeadBlockCipher.ProcessBytes(m7, 0, split, c9, 0); - offset += aeadBlockCipher.ProcessBytes(m7, split, m7.Length - split, c9, offset); - aeadBlockCipher.DoFinal(c9, offset); + xoodyakEngine.ProcessAadBytes(aad2, 0, aad2.Length); + offset = xoodyakEngine.ProcessBytes(m7, 0, split, c9, 0); + offset += xoodyakEngine.ProcessBytes(m7, split, m7.Length - split, c9, offset); + xoodyakEngine.DoFinal(c9, offset); if (!Arrays.AreEqual(c7, c8) || !Arrays.AreEqual(c7, c9)) { Assert.Fail("Splitting input of plaintext should output the same ciphertext"); @@ -404,28 +381,28 @@ namespace Org.BouncyCastle.Crypto.Tests Span<byte> c4_2 = new byte[c2.Length]; ReadOnlySpan<byte> m5 = new ReadOnlySpan<byte>(m2); ReadOnlySpan<byte> aad4 = new ReadOnlySpan<byte>(aad2); - aeadBlockCipher.Init(true, param); - aeadBlockCipher.ProcessAadBytes(aad4); - offset = aeadBlockCipher.ProcessBytes(m5, c4_1); - aeadBlockCipher.DoFinal(c4_2); + xoodyakEngine.Init(true, param); + xoodyakEngine.ProcessAadBytes(aad4); + offset = xoodyakEngine.ProcessBytes(m5, c4_1); + xoodyakEngine.DoFinal(c4_2); byte[] c5 = new byte[c2.Length]; - Array.Copy(c4_1.ToArray(), 0, c5, 0, offset); - Array.Copy(c4_2.ToArray(), 0, c5, offset, c5.Length - offset); + c4_1[..offset].CopyTo(c5); + c4_2[..(c5.Length - offset)].CopyTo(c5.AsSpan(offset)); if (!Arrays.AreEqual(c2, c5)) { Assert.Fail("mac should match for the same AAD and message with different offset for both input and output"); } - aeadBlockCipher.Reset(); - aeadBlockCipher.Init(false, param); + xoodyakEngine.Reset(); + xoodyakEngine.Init(false, param); Span<byte> m6_1 = new byte[m2.Length]; Span<byte> m6_2 = new byte[m2.Length]; ReadOnlySpan<byte> c6 = new ReadOnlySpan<byte>(c2); - aeadBlockCipher.ProcessAadBytes(aad4); - offset = aeadBlockCipher.ProcessBytes(c6, m6_1); - aeadBlockCipher.DoFinal(m6_2); + xoodyakEngine.ProcessAadBytes(aad4); + offset = xoodyakEngine.ProcessBytes(c6, m6_1); + xoodyakEngine.DoFinal(m6_2); byte[] m6 = new byte[m2.Length]; - Array.Copy(m6_1.ToArray(), 0, m6, 0, offset); - Array.Copy(m6_2.ToArray(), 0, m6, offset, m6.Length - offset); + m6_1[..offset].CopyTo(m6); + m6_2[..(m6.Length - offset)].CopyTo(m6.AsSpan(offset)); if (!Arrays.AreEqual(m2, m6)) { Assert.Fail("mac should match for the same AAD and message with different offset for both input and output"); @@ -434,7 +411,7 @@ namespace Org.BouncyCastle.Crypto.Tests } - private void testParameters(XoodyakEngine xoodyak, int keySize, int ivSize, int macSize, int blockSize) + private void ImplTestParameters(XoodyakEngine xoodyak, int keySize, int ivSize, int macSize, int blockSize) { if (xoodyak.GetKeyBytesSize() != keySize) { @@ -452,20 +429,19 @@ namespace Org.BouncyCastle.Crypto.Tests { Assert.Fail("block size of " + xoodyak.AlgorithmName + " is not correct"); } - Console.WriteLine(xoodyak.AlgorithmName + " test Parameters pass"); } - private void testExceptions(IDigest digest, int digestsize) + private void ImplTestExceptions(XoodyakDigest xoodyakDigest, int digestsize) { - if (digest.GetDigestSize() != digestsize) + if (xoodyakDigest.GetDigestSize() != digestsize) { - Assert.Fail(digest.AlgorithmName + ": digest size is not correct"); + Assert.Fail(xoodyakDigest.AlgorithmName + ": digest size is not correct"); } try { - digest.BlockUpdate(new byte[1], 1, 1); - Assert.Fail(digest.AlgorithmName + ": input for update is too short"); + xoodyakDigest.BlockUpdate(new byte[1], 1, 1); + Assert.Fail(xoodyakDigest.AlgorithmName + ": input for BlockUpdate is too short"); } catch (DataLengthException) { @@ -473,15 +449,13 @@ namespace Org.BouncyCastle.Crypto.Tests } try { - digest.DoFinal(new byte[digest.GetDigestSize() - 1], 2); - Assert.Fail(digest.AlgorithmName + ": output for dofinal is too short"); + xoodyakDigest.DoFinal(new byte[xoodyakDigest.GetDigestSize() - 1], 2); + Assert.Fail(xoodyakDigest.AlgorithmName + ": output for DoFinal is too short"); } - catch (DataLengthException) + catch (OutputLengthException) { //expected } - Console.WriteLine(digest.AlgorithmName + " test Exceptions pass"); } - } } |