diff --git a/crypto/src/crypto/engines/ISAPEngine.cs b/crypto/src/crypto/engines/ISAPEngine.cs
index 0280b1ce1..8be5a79b2 100644
--- a/crypto/src/crypto/engines/ISAPEngine.cs
+++ b/crypto/src/crypto/engines/ISAPEngine.cs
@@ -1,9 +1,14 @@
using System;
+using System.Drawing;
using System.IO;
+#if NETSTANDARD1_0_OR_GREATER || NETCOREAPP1_0_OR_GREATER
+using System.Runtime.CompilerServices;
+#endif
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Utilities;
+using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Engines
{
@@ -14,8 +19,8 @@ namespace Org.BouncyCastle.Crypto.Engines
* ISAP AEAD v2 with reference to C Reference Impl from: https://github.com/isap-lwc/isap-code-package
* </p>
*/
- public class ISAPEngine
- : IAeadBlockCipher
+ public sealed class IsapEngine
+ : IAeadCipher
{
public enum IsapType
{
@@ -25,42 +30,13 @@ namespace Org.BouncyCastle.Crypto.Engines
ISAP_K_128
}
- public ISAPEngine(IsapType isapType)
- {
- switch (isapType)
- {
- case IsapType.ISAP_A_128A:
- ISAPAEAD = new ISAPAEAD_A_128A();
- ISAP_rH = 64;
- algorithmName = "ISAP-A-128A AEAD";
- break;
- case IsapType.ISAP_K_128A:
- ISAPAEAD = new ISAPAEAD_K_128A();
- ISAP_rH = 144;
- algorithmName = "ISAP-K-128A AEAD";
- break;
- case IsapType.ISAP_A_128:
- ISAPAEAD = new ISAPAEAD_A_128();
- ISAP_rH = 64;
- algorithmName = "ISAP-A-128 AEAD";
- break;
- case IsapType.ISAP_K_128:
- ISAPAEAD = new ISAPAEAD_K_128();
- ISAP_rH = 144;
- algorithmName = "ISAP-K-128 AEAD";
- break;
- }
- ISAP_rH_SZ = (ISAP_rH + 7) >> 3;
- }
+ private const int CRYPTO_KEYBYTES = 16;
+ private const int CRYPTO_NPUBBYTES = 16;
+ private const int ISAP_STATE_SZ = 40;
private string algorithmName;
private bool forEncryption;
private bool initialised;
- const int CRYPTO_KEYBYTES = 16;
- const int CRYPTO_NPUBBYTES = 16;
- const int ISAP_STATE_SZ = 40;
- private byte[] c;
- private byte[] ad;
private byte[] mac;
private MemoryStream aadData = new MemoryStream();
private MemoryStream message = new MemoryStream();
@@ -69,18 +45,58 @@ namespace Org.BouncyCastle.Crypto.Engines
private int ISAP_rH;
private int ISAP_rH_SZ;
- public IBlockCipher UnderlyingCipher => throw new NotImplementedException();
+ public IsapEngine(IsapType isapType)
+ {
+ switch (isapType)
+ {
+ case IsapType.ISAP_A_128A:
+ ISAPAEAD = new ISAPAEAD_A_128A();
+ ISAP_rH = 64;
+ algorithmName = "ISAP-A-128A AEAD";
+ break;
+ case IsapType.ISAP_K_128A:
+ ISAPAEAD = new ISAPAEAD_K_128A();
+ ISAP_rH = 144;
+ algorithmName = "ISAP-K-128A AEAD";
+ break;
+ case IsapType.ISAP_A_128:
+ ISAPAEAD = new ISAPAEAD_A_128();
+ ISAP_rH = 64;
+ algorithmName = "ISAP-A-128 AEAD";
+ break;
+ case IsapType.ISAP_K_128:
+ ISAPAEAD = new ISAPAEAD_K_128();
+ ISAP_rH = 144;
+ algorithmName = "ISAP-K-128 AEAD";
+ break;
+ }
+ ISAP_rH_SZ = (ISAP_rH + 7) >> 3;
+ }
+
+ public int GetKeyBytesSize()
+ {
+ return CRYPTO_KEYBYTES;
+ }
+
+ public int GetIVBytesSize()
+ {
+ return CRYPTO_NPUBBYTES;
+ }
public string AlgorithmName => algorithmName;
- protected abstract class ISAP_AEAD
+ private abstract class ISAP_AEAD
{
protected byte[] k;
protected byte[] npub;
protected int ISAP_rH;
protected int ISAP_rH_SZ;
- public abstract void isap_enc(byte[] m, int mOff, int mlen, byte[] c, int cOff, int clen);
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ public abstract void isap_enc(ReadOnlySpan<byte> m, Span<byte> c);
+#else
+ public abstract void isap_enc(byte[] m, int mOff, int mlen, byte[] c, int cOff);
+#endif
public abstract void init(byte[] k, byte[] npub, int ISAP_rH, int ISAP_rH_SZ);
@@ -89,7 +105,7 @@ namespace Org.BouncyCastle.Crypto.Engines
public abstract void reset();
}
- protected abstract class ISAPAEAD_A : ISAP_AEAD
+ private abstract class ISAPAEAD_A : ISAP_AEAD
{
protected ulong[] k64;
protected ulong[] npub64;
@@ -104,14 +120,10 @@ namespace Org.BouncyCastle.Crypto.Engines
this.npub = npub;
this.ISAP_rH = ISAP_rH;
this.ISAP_rH_SZ = ISAP_rH_SZ;
- npub64 = new ulong[getulongSize(npub.Length)];
- Pack.LE_To_UInt64(npub, 0, npub64, 0, npub64.Length);
- npub64[0] = U64BIG(npub64[0]);
- npub64[1] = U64BIG(npub64[1]);
- k64 = new ulong[getulongSize(k.Length)];
- Pack.LE_To_UInt64(k, 0, k64, 0, k64.Length);
- k64[0] = U64BIG(k64[0]);
- k64[1] = U64BIG(k64[1]);
+ npub64 = new ulong[(npub.Length + 7) / 8];
+ Pack.BE_To_UInt64(npub, 0, npub64, 0, npub64.Length);
+ k64 = new ulong[(k.Length + 7) / 8];
+ Pack.BE_To_UInt64(k, 0, k64, 0, k64.Length);
reset();
}
@@ -121,21 +133,19 @@ namespace Org.BouncyCastle.Crypto.Engines
protected void ABSORB_MAC(byte[] src, int len)
{
- ulong[] src64 = new ulong[src.Length >> 3];
- Pack.LE_To_UInt64(src, 0, src64, 0, src64.Length);
- int idx = 0;
- while (len >= ISAP_rH_SZ)
+ int off = 0;
+ while (len >= 8)
{
- x0 ^= U64BIG(src64[idx++]);
+ x0 ^= Pack.BE_To_UInt64(src, off);
+ off += 8;
+ len -= 8;
P12();
- len -= ISAP_rH_SZ;
}
- /* Absorb const ad block */
- for (int i = 0; i < len; ++i)
+ if (len > 0)
{
- x0 ^= (src[(idx << 3) + i] & 0xFFUL) << ((7 - i) << 3);
+ x0 ^= Pack.BE_To_UInt64_High(src, off, len);
}
- x0 ^= 0x80UL << ((7 - len) << 3);
+ x0 ^= 0x8000000000000000UL >> (len << 3);
P12();
}
@@ -152,8 +162,8 @@ namespace Org.BouncyCastle.Crypto.Engines
x4 ^= 1L;
ABSORB_MAC(c, clen);
// Derive K*
- Pack.UInt64_To_LE(U64BIG(x0), tag, 0);
- Pack.UInt64_To_LE(U64BIG(x1), tag, 8);
+ Pack.UInt64_To_BE(x0, tag, 0);
+ Pack.UInt64_To_BE(x1, tag, 8);
ulong tmp_x2 = x2, tmp_x3 = x3, tmp_x4 = x4;
isap_rk(ISAP_IV2_64, tag, CRYPTO_KEYBYTES);
x2 = tmp_x2;
@@ -161,8 +171,8 @@ namespace Org.BouncyCastle.Crypto.Engines
x4 = tmp_x4;
// Squeeze tag
P12();
- Pack.UInt64_To_LE(U64BIG(x0), tag, tagOff);
- Pack.UInt64_To_LE(U64BIG(x1), tag, tagOff + 8);
+ Pack.UInt64_To_BE(x0, tag, tagOff);
+ Pack.UInt64_To_BE(x1, tag, tagOff + 8);
}
public void isap_rk(ulong iv64, byte[] y, int ylen)
@@ -183,28 +193,46 @@ namespace Org.BouncyCastle.Crypto.Engines
P12();
}
- public override void isap_enc(byte[] m, int mOff, int mlen, byte[] c, int cOff, int clen)
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ public override void isap_enc(ReadOnlySpan<byte> m, Span<byte> c)
{
- /* Encrypt m */
- ulong[] m64 = new ulong[mlen >> 3];
- Pack.LE_To_UInt64(m, mOff, m64, 0, m64.Length);
- ulong[] c64 = new ulong[m64.Length];
- int idx = 0;
- while (mlen >= ISAP_rH_SZ)
+ while (m.Length >= 8)
{
- c64[idx] = U64BIG(x0) ^ m64[idx];
+ ulong t = Pack.BE_To_UInt64(m);
+ t ^= x0;
+ Pack.UInt64_To_BE(t, c);
+ m = m[8..];
+ c = c[8..];
+ PX1();
+ }
+ if (!m.IsEmpty)
+ {
+ ulong t = Pack.BE_To_UInt64_High(m);
+ t ^= x0;
+ Pack.UInt64_To_BE_High(t, c[..m.Length]);
+ }
+ }
+#else
+ public override void isap_enc(byte[] m, int mOff, int mlen, byte[] c, int cOff)
+ {
+ while (mlen >= 8)
+ {
+ ulong t = Pack.BE_To_UInt64(m, mOff);
+ t ^= x0;
+ Pack.UInt64_To_BE(t, c, cOff);
+ mOff += 8;
+ mlen -= 8;
+ cOff += 8;
PX1();
- idx++;
- mlen -= ISAP_rH_SZ;
}
- Pack.UInt64_To_LE(c64, 0, c64.Length, c, cOff);
- /* Encrypt const m block */
- byte[] xo = Pack.UInt64_To_LE(x0);
- while (mlen > 0)
+ if (mlen > 0)
{
- c[(idx << 3) + cOff + mlen - 1] = (byte)(xo[ISAP_rH_SZ - mlen] ^ m[(idx << 3) + mOff + --mlen]);
+ ulong t = Pack.BE_To_UInt64_High(m, mOff, mlen);
+ t ^= x0;
+ Pack.UInt64_To_BE_High(t, c, cOff, mlen);
}
}
+#endif
public override void reset()
{
@@ -215,22 +243,9 @@ namespace Org.BouncyCastle.Crypto.Engines
PX1();
}
- private int getulongSize(int x)
- {
- return (x >> 3) + ((x & 7) != 0 ? 1 : 0);
- }
-
- private ulong ROTR(ulong x, int n)
- {
- return (x >> n) | (x << (64 - n));
- }
-
- protected ulong U64BIG(ulong x)
- {
- return ((ROTR(x, 8) & (0xFF000000FF000000UL)) | (ROTR(x, 24) & (0x00FF000000FF0000UL)) |
- (ROTR(x, 40) & (0x0000FF000000FF00UL)) | (ROTR(x, 56) & (0x000000FF000000FFUL)));
- }
-
+#if NETSTANDARD1_0_OR_GREATER || NETCOREAPP1_0_OR_GREATER
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
protected void ROUND(ulong C)
{
t0 = x0 ^ x1 ^ x2 ^ x3 ^ C ^ (x1 & (x0 ^ x2 ^ x4 ^ C));
@@ -238,11 +253,11 @@ namespace Org.BouncyCastle.Crypto.Engines
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);
+ 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);
}
public void P12()
@@ -315,8 +330,9 @@ namespace Org.BouncyCastle.Crypto.Engines
protected ushort[] ISAP_IV3_16;
protected ushort[] k16;
protected ushort[] iv16;
- private readonly int[] KeccakF400RoundConstants = {0x0001, 0x8082, 0x808a, 0x8000, 0x808b, 0x0001, 0x8081, 0x8009,
- 0x008a, 0x0088, 0x8009, 0x000a, 0x808b, 0x008b, 0x8089, 0x8003, 0x8002, 0x0080, 0x800a, 0x000a};
+ private readonly int[] KeccakF400RoundConstants = {
+ 0x0001, 0x8082, 0x808a, 0x8000, 0x808b, 0x0001, 0x8081, 0x8009, 0x008a, 0x0088, 0x8009, 0x000a, 0x808b,
+ 0x008b, 0x8089, 0x8003, 0x8002, 0x0080, 0x800a, 0x000a };
protected ushort[] SX = new ushort[25];
protected ushort[] E = new ushort[25];
protected ushort[] C = new ushort[5];
@@ -328,9 +344,9 @@ namespace Org.BouncyCastle.Crypto.Engines
this.ISAP_rH = ISAP_rH;
this.ISAP_rH_SZ = ISAP_rH_SZ;
k16 = new ushort[k.Length >> 1];
- byteToushort(k, k16, k16.Length);
+ Pack.LE_To_UInt16(k, 0, k16);
iv16 = new ushort[npub.Length >> 1];
- byteToushort(npub, iv16, iv16.Length);
+ Pack.LE_To_UInt16(npub, 0, iv16);
reset();
}
@@ -355,33 +371,28 @@ namespace Org.BouncyCastle.Crypto.Engines
{
int rem_bytes = len;
int idx = 0;
- while (true)
+ while (rem_bytes > ISAP_rH_SZ)
{
- if (rem_bytes > ISAP_rH_SZ)
- {
- byteToushortXor(src, SX, ISAP_rH_SZ >> 1);
- idx += ISAP_rH_SZ;
- rem_bytes -= ISAP_rH_SZ;
- PermuteRoundsHX(SX, E, C);
- }
- else if (rem_bytes == ISAP_rH_SZ)
- {
- byteToushortXor(src, SX, ISAP_rH_SZ >> 1);
- PermuteRoundsHX(SX, E, C);
- SX[0] ^= 0x80;
- PermuteRoundsHX(SX, E, C);
- break;
- }
- else
+ byteToushortXor(src, SX, ISAP_rH_SZ >> 1);
+ idx += ISAP_rH_SZ;
+ rem_bytes -= ISAP_rH_SZ;
+ PermuteRoundsHX(SX, E, C);
+ }
+ if (rem_bytes == ISAP_rH_SZ)
+ {
+ byteToushortXor(src, SX, ISAP_rH_SZ >> 1);
+ PermuteRoundsHX(SX, E, C);
+ SX[0] ^= 0x80;
+ PermuteRoundsHX(SX, E, C);
+ }
+ else
+ {
+ for (int i = 0; i < rem_bytes; i++)
{
- for (int i = 0; i < rem_bytes; i++)
- {
- SX[i >> 1] ^= (ushort)((src[idx++] & 0xFFU) << ((i & 1) << 3));
- }
- SX[rem_bytes >> 1] ^= (ushort)(0x80U << ((rem_bytes & 1) << 3));
- PermuteRoundsHX(SX, E, C);
- break;
+ SX[i >> 1] ^= (ushort)((src[idx++] & 0xFFU) << ((i & 1) << 3));
}
+ SX[rem_bytes >> 1] ^= (ushort)(0x80U << ((rem_bytes & 1) << 3));
+ PermuteRoundsHX(SX, E, C);
}
}
@@ -419,61 +430,64 @@ namespace Org.BouncyCastle.Crypto.Engines
// Absorb C
ABSORB_MAC(SX, c, clen, E, C);
// Derive K*
- ushortToByte(SX, tag, tagOff);
+ Pack.UInt16_To_LE(SX, 0, 8, tag, tagOff);
isap_rk(ISAP_IV2_16, tag, CRYPTO_KEYBYTES, SX, CRYPTO_KEYBYTES, C);
// Squeeze tag
PermuteRoundsHX(SX, E, C);
- ushortToByte(SX, tag, tagOff);
+ Pack.UInt16_To_LE(SX, 0, 8, tag, tagOff);
}
- public override void isap_enc(byte[] m, int mOff, int mlen, byte[] c, int cOff, int clen)
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ public override void isap_enc(ReadOnlySpan<byte> m, Span<byte> c)
{
+ int off = 0, len = m.Length;
+
// Squeeze key stream
- while (true)
+ while (len >= ISAP_rH_SZ)
{
- if (mlen >= ISAP_rH_SZ)
- {
- // Squeeze full lane and continue
- for (int i = 0; i < ISAP_rH_SZ; ++i)
- {
- c[cOff++] = (byte)((SX[i >> 1] >> ((i & 1) << 3)) ^ m[mOff++]);
- }
- mlen -= ISAP_rH_SZ;
- PermuteRoundsKX(SX, E, C);
- }
- else
+ // Squeeze full lane and continue
+ for (int i = 0; i < ISAP_rH_SZ; ++i)
{
- // Squeeze full or partial lane and stop
- for (int i = 0; i < mlen; ++i)
- {
- c[cOff++] = (byte)((SX[i >> 1] >> ((i & 1) << 3)) ^ m[mOff++]);
- }
- break;
+ c[off] = (byte)((SX[i >> 1] >> ((i & 1) << 3)) ^ m[off]);
+ ++off;
}
+ len -= ISAP_rH_SZ;
+ PermuteRoundsKX(SX, E, C);
}
- }
-
- private void byteToushortXor(byte[] input, ushort[] output, int outLen)
- {
- for (int i = 0; i < outLen; ++i)
+ // Squeeze partial lane and stop
+ for (int i = 0; i < len; ++i)
{
- output[i] ^= Pack.LE_To_UInt16(input, (i << 1));
+ c[off] = (byte)((SX[i >> 1] >> ((i & 1) << 3)) ^ m[off]);
+ ++off;
}
}
-
- private void byteToushort(byte[] input, ushort[] output, int outLen)
+#else
+ public override void isap_enc(byte[] m, int mOff, int mlen, byte[] c, int cOff)
{
- for (int i = 0; i < outLen; ++i)
+ // Squeeze key stream
+ while (mlen >= ISAP_rH_SZ)
+ {
+ // Squeeze full lane and continue
+ for (int i = 0; i < ISAP_rH_SZ; ++i)
+ {
+ c[cOff++] = (byte)((SX[i >> 1] >> ((i & 1) << 3)) ^ m[mOff++]);
+ }
+ mlen -= ISAP_rH_SZ;
+ PermuteRoundsKX(SX, E, C);
+ }
+ // Squeeze partial lane and stop
+ for (int i = 0; i < mlen; ++i)
{
- output[i] = Pack.LE_To_UInt16(input, (i << 1));
+ c[cOff++] = (byte)((SX[i >> 1] >> ((i & 1) << 3)) ^ m[mOff++]);
}
}
+#endif
- private void ushortToByte(ushort[] input, byte[] output, int outOff)
+ private void byteToushortXor(byte[] input, ushort[] output, int outLen)
{
- for (int i = 0; i < 8; ++i)
+ for (int i = 0; i < outLen; ++i)
{
- shortToLittleEndian(input[i], output, outOff + (i << 1));
+ output[i] ^= Pack.LE_To_UInt16(input, (i << 1));
}
}
@@ -522,28 +536,23 @@ namespace Org.BouncyCastle.Crypto.Engines
C[4] = (ushort)(SX[4] ^ SX[9] ^ SX[14] ^ SX[19] ^ SX[24]);
}
- private ushort ROL16(ushort a, int offset)
- {
- return (ushort)(((a & 0xFFFF) << offset) ^ ((a & 0xFFFF) >> (16 - offset)));
- }
-
protected void thetaRhoPiChiIotaPrepareTheta(int i, ushort[] A, ushort[] E, ushort[] C)
{
- ushort Da = (ushort)(C[4] ^ ROL16(C[1], 1));
- ushort De = (ushort)(C[0] ^ ROL16(C[2], 1));
- ushort Di = (ushort)(C[1] ^ ROL16(C[3], 1));
- ushort Do = (ushort)(C[2] ^ ROL16(C[4], 1));
- ushort Du = (ushort)(C[3] ^ ROL16(C[0], 1));
+ ushort Da = (ushort)(C[4] ^ Shorts.RotateLeft(C[1], 1));
+ ushort De = (ushort)(C[0] ^ Shorts.RotateLeft(C[2], 1));
+ ushort Di = (ushort)(C[1] ^ Shorts.RotateLeft(C[3], 1));
+ ushort Do = (ushort)(C[2] ^ Shorts.RotateLeft(C[4], 1));
+ ushort Du = (ushort)(C[3] ^ Shorts.RotateLeft(C[0], 1));
ushort Ba = A[0] ^= Da;
A[6] ^= De;
- ushort Be = ROL16(A[6], 12);
+ ushort Be = Shorts.RotateLeft(A[6], 12);
A[12] ^= Di;
- ushort Bi = ROL16(A[12], 11);
+ ushort Bi = Shorts.RotateLeft(A[12], 11);
A[18] ^= Do;
- ushort Bo = ROL16(A[18], 5);
+ ushort Bo = Shorts.RotateLeft(A[18], 5);
A[24] ^= Du;
- ushort Bu = ROL16(A[24], 14);
+ ushort Bu = Shorts.RotateLeft(A[24], 14);
C[0] = E[0] = (ushort)(Ba ^ ((~Be) & Bi) ^ KeccakF400RoundConstants[i]);
C[1] = E[1] = (ushort)(Be ^ ((~Bi) & Bo));
C[2] = E[2] = (ushort)(Bi ^ ((~Bo) & Bu));
@@ -551,15 +560,15 @@ namespace Org.BouncyCastle.Crypto.Engines
C[4] = E[4] = (ushort)(Bu ^ ((~Ba) & Be));
A[3] ^= Do;
- Ba = ROL16(A[3], 12);
+ Ba = Shorts.RotateLeft(A[3], 12);
A[9] ^= Du;
- Be = ROL16(A[9], 4);
+ Be = Shorts.RotateLeft(A[9], 4);
A[10] ^= Da;
- Bi = ROL16(A[10], 3);
+ Bi = Shorts.RotateLeft(A[10], 3);
A[16] ^= De;
- Bo = ROL16(A[16], 13);
+ Bo = Shorts.RotateLeft(A[16], 13);
A[22] ^= Di;
- Bu = ROL16(A[22], 13);
+ Bu = Shorts.RotateLeft(A[22], 13);
E[5] = (ushort)(Ba ^ ((~Be) & Bi));
C[0] ^= E[5];
E[6] = (ushort)(Be ^ ((~Bi) & Bo));
@@ -572,15 +581,15 @@ namespace Org.BouncyCastle.Crypto.Engines
C[4] ^= E[9];
A[1] ^= De;
- Ba = ROL16(A[1], 1);
+ Ba = Shorts.RotateLeft(A[1], 1);
A[7] ^= Di;
- Be = ROL16(A[7], 6);
+ Be = Shorts.RotateLeft(A[7], 6);
A[13] ^= Do;
- Bi = ROL16(A[13], 9);
+ Bi = Shorts.RotateLeft(A[13], 9);
A[19] ^= Du;
- Bo = ROL16(A[19], 8);
+ Bo = Shorts.RotateLeft(A[19], 8);
A[20] ^= Da;
- Bu = ROL16(A[20], 2);
+ Bu = Shorts.RotateLeft(A[20], 2);
E[10] = (ushort)(Ba ^ ((~Be) & Bi));
C[0] ^= E[10];
E[11] = (ushort)(Be ^ ((~Bi) & Bo));
@@ -593,15 +602,15 @@ namespace Org.BouncyCastle.Crypto.Engines
C[4] ^= E[14];
A[4] ^= Du;
- Ba = ROL16(A[4], 11);
+ Ba = Shorts.RotateLeft(A[4], 11);
A[5] ^= Da;
- Be = ROL16(A[5], 4);
+ Be = Shorts.RotateLeft(A[5], 4);
A[11] ^= De;
- Bi = ROL16(A[11], 10);
+ Bi = Shorts.RotateLeft(A[11], 10);
A[17] ^= Di;
- Bo = ROL16(A[17], 15);
+ Bo = Shorts.RotateLeft(A[17], 15);
A[23] ^= Do;
- Bu = ROL16(A[23], 8);
+ Bu = Shorts.RotateLeft(A[23], 8);
E[15] = (ushort)(Ba ^ ((~Be) & Bi));
C[0] ^= E[15];
E[16] = (ushort)(Be ^ ((~Bi) & Bo));
@@ -614,15 +623,15 @@ namespace Org.BouncyCastle.Crypto.Engines
C[4] ^= E[19];
A[2] ^= Di;
- Ba = ROL16(A[2], 14);
+ Ba = Shorts.RotateLeft(A[2], 14);
A[8] ^= Do;
- Be = ROL16(A[8], 7);
+ Be = Shorts.RotateLeft(A[8], 7);
A[14] ^= Du;
- Bi = ROL16(A[14], 7);
+ Bi = Shorts.RotateLeft(A[14], 7);
A[15] ^= Da;
- Bo = ROL16(A[15], 9);
+ Bo = Shorts.RotateLeft(A[15], 9);
A[21] ^= De;
- Bu = ROL16(A[21], 2);
+ Bu = Shorts.RotateLeft(A[21], 2);
E[20] = (ushort)(Ba ^ ((~Be) & Bi));
C[0] ^= E[20];
E[21] = (ushort)(Be ^ ((~Bi) & Bo));
@@ -637,21 +646,21 @@ namespace Org.BouncyCastle.Crypto.Engines
protected void thetaRhoPiChiIota(ushort[] A, ushort[] E, ushort[] C)
{
- ushort Da = (ushort)(C[4] ^ ROL16(C[1], 1));
- ushort De = (ushort)(C[0] ^ ROL16(C[2], 1));
- ushort Di = (ushort)(C[1] ^ ROL16(C[3], 1));
- ushort Do = (ushort)(C[2] ^ ROL16(C[4], 1));
- ushort Du = (ushort)(C[3] ^ ROL16(C[0], 1));
+ ushort Da = (ushort)(C[4] ^ Shorts.RotateLeft(C[1], 1));
+ ushort De = (ushort)(C[0] ^ Shorts.RotateLeft(C[2], 1));
+ ushort Di = (ushort)(C[1] ^ Shorts.RotateLeft(C[3], 1));
+ ushort Do = (ushort)(C[2] ^ Shorts.RotateLeft(C[4], 1));
+ ushort Du = (ushort)(C[3] ^ Shorts.RotateLeft(C[0], 1));
ushort Ba = A[0] ^= Da;
A[6] ^= De;
- ushort Be = ROL16(A[6], 12);
+ ushort Be = Shorts.RotateLeft(A[6], 12);
A[12] ^= Di;
- ushort Bi = ROL16(A[12], 11);
+ ushort Bi = Shorts.RotateLeft(A[12], 11);
A[18] ^= Do;
- ushort Bo = ROL16(A[18], 5);
+ ushort Bo = Shorts.RotateLeft(A[18], 5);
A[24] ^= Du;
- ushort Bu = ROL16(A[24], 14);
+ ushort Bu = Shorts.RotateLeft(A[24], 14);
E[0] = (ushort)(Ba ^ ((~Be) & Bi) ^ KeccakF400RoundConstants[19]);
E[1] = (ushort)(Be ^ ((~Bi) & Bo));
E[2] = (ushort)(Bi ^ ((~Bo) & Bu));
@@ -659,15 +668,15 @@ namespace Org.BouncyCastle.Crypto.Engines
E[4] = (ushort)(Bu ^ ((~Ba) & Be));
A[3] ^= Do;
- Ba = ROL16(A[3], 12);
+ Ba = Shorts.RotateLeft(A[3], 12);
A[9] ^= Du;
- Be = ROL16(A[9], 4);
+ Be = Shorts.RotateLeft(A[9], 4);
A[10] ^= Da;
- Bi = ROL16(A[10], 3);
+ Bi = Shorts.RotateLeft(A[10], 3);
A[16] ^= De;
- Bo = ROL16(A[16], 13);
+ Bo = Shorts.RotateLeft(A[16], 13);
A[22] ^= Di;
- Bu = ROL16(A[22], 13);
+ Bu = Shorts.RotateLeft(A[22], 13);
E[5] = (ushort)(Ba ^ ((~Be) & Bi));
E[6] = (ushort)(Be ^ ((~Bi) & Bo));
E[7] = (ushort)(Bi ^ ((~Bo) & Bu));
@@ -675,15 +684,15 @@ namespace Org.BouncyCastle.Crypto.Engines
E[9] = (ushort)(Bu ^ ((~Ba) & Be));
A[1] ^= De;
- Ba = ROL16(A[1], 1);
+ Ba = Shorts.RotateLeft(A[1], 1);
A[7] ^= Di;
- Be = ROL16(A[7], 6);
+ Be = Shorts.RotateLeft(A[7], 6);
A[13] ^= Do;
- Bi = ROL16(A[13], 9);
+ Bi = Shorts.RotateLeft(A[13], 9);
A[19] ^= Du;
- Bo = ROL16(A[19], 8);
+ Bo = Shorts.RotateLeft(A[19], 8);
A[20] ^= Da;
- Bu = ROL16(A[20], 2);
+ Bu = Shorts.RotateLeft(A[20], 2);
E[10] = (ushort)(Ba ^ ((~Be) & Bi));
E[11] = (ushort)(Be ^ ((~Bi) & Bo));
E[12] = (ushort)(Bi ^ ((~Bo) & Bu));
@@ -691,15 +700,15 @@ namespace Org.BouncyCastle.Crypto.Engines
E[14] = (ushort)(Bu ^ ((~Ba) & Be));
A[4] ^= Du;
- Ba = ROL16(A[4], 11);
+ Ba = Shorts.RotateLeft(A[4], 11);
A[5] ^= Da;
- Be = ROL16(A[5], 4);
+ Be = Shorts.RotateLeft(A[5], 4);
A[11] ^= De;
- Bi = ROL16(A[11], 10);
+ Bi = Shorts.RotateLeft(A[11], 10);
A[17] ^= Di;
- Bo = ROL16(A[17], 15);
+ Bo = Shorts.RotateLeft(A[17], 15);
A[23] ^= Do;
- Bu = ROL16(A[23], 8);
+ Bu = Shorts.RotateLeft(A[23], 8);
E[15] = (ushort)(Ba ^ ((~Be) & Bi));
E[16] = (ushort)(Be ^ ((~Bi) & Bo));
E[17] = (ushort)(Bi ^ ((~Bo) & Bu));
@@ -707,15 +716,15 @@ namespace Org.BouncyCastle.Crypto.Engines
E[19] = (ushort)(Bu ^ ((~Ba) & Be));
A[2] ^= Di;
- Ba = ROL16(A[2], 14);
+ Ba = Shorts.RotateLeft(A[2], 14);
A[8] ^= Do;
- Be = ROL16(A[8], 7);
+ Be = Shorts.RotateLeft(A[8], 7);
A[14] ^= Du;
- Bi = ROL16(A[14], 7);
+ Bi = Shorts.RotateLeft(A[14], 7);
A[15] ^= Da;
- Bo = ROL16(A[15], 9);
+ Bo = Shorts.RotateLeft(A[15], 9);
A[21] ^= De;
- Bu = ROL16(A[21], 2);
+ Bu = Shorts.RotateLeft(A[21], 2);
E[20] = (ushort)(Ba ^ ((~Be) & Bi));
E[21] = (ushort)(Be ^ ((~Bi) & Bo));
E[22] = (ushort)(Bi ^ ((~Bo) & Bu));
@@ -728,9 +737,9 @@ namespace Org.BouncyCastle.Crypto.Engines
{
public ISAPAEAD_K_128A()
{
- ISAP_IV1_16 = new ushort[] { 32769, 400, 272, 2056 };
- ISAP_IV2_16 = new ushort[] { 32770, 400, 272, 2056 };
- ISAP_IV3_16 = new ushort[] { 32771, 400, 272, 2056 };
+ ISAP_IV1_16 = new ushort[]{ 32769, 400, 272, 2056 };
+ ISAP_IV2_16 = new ushort[]{ 32770, 400, 272, 2056 };
+ ISAP_IV3_16 = new ushort[]{ 32771, 400, 272, 2056 };
}
protected override void PermuteRoundsHX(ushort[] SX, ushort[] E, ushort[] C)
@@ -758,9 +767,9 @@ namespace Org.BouncyCastle.Crypto.Engines
{
public ISAPAEAD_K_128()
{
- ISAP_IV1_16 = new ushort[] { 32769, 400, 3092, 3084 };
- ISAP_IV2_16 = new ushort[] { 32770, 400, 3092, 3084 };
- ISAP_IV3_16 = new ushort[] { 32771, 400, 3092, 3084 };
+ ISAP_IV1_16 = new ushort[]{ 32769, 400, 3092, 3084 };
+ ISAP_IV2_16 = new ushort[]{ 32770, 400, 3092, 3084 };
+ ISAP_IV3_16 = new ushort[]{ 32771, 400, 3092, 3084 };
}
protected override void PermuteRoundsHX(ushort[] SX, ushort[] E, ushort[] C)
@@ -784,251 +793,241 @@ namespace Org.BouncyCastle.Crypto.Engines
}
}
-
-
public void Init(bool forEncryption, ICipherParameters param)
{
this.forEncryption = forEncryption;
- if (!(param is ParametersWithIV))
- {
- throw new ArgumentException(
- "ISAP AEAD init parameters must include an IV");
- }
-
- ParametersWithIV ivParams = (ParametersWithIV)param;
-
- byte[] iv = ivParams.GetIV();
+ if (!(param is ParametersWithIV withIV))
+ throw new ArgumentException("ISAP AEAD init parameters must include an IV");
+ byte[] iv = withIV.GetIV();
if (iv == null || iv.Length != 16)
- {
- throw new ArgumentException(
- "ISAP AEAD requires exactly 12 bytes of IV");
- }
+ throw new ArgumentException("ISAP AEAD requires exactly 12 bytes of IV");
- if (!(ivParams.Parameters is KeyParameter))
- {
- throw new ArgumentException(
- "ISAP AEAD init parameters must include a key");
- }
+ if (!(withIV.Parameters is KeyParameter key))
+ throw new ArgumentException("ISAP AEAD init parameters must include a key");
- KeyParameter key = (KeyParameter)ivParams.Parameters;
byte[] keyBytes = key.GetKey();
if (keyBytes.Length != 16)
- {
- throw new ArgumentException(
- "ISAP AEAD key must be 128 bits ulong");
- }
+ throw new ArgumentException("ISAP AEAD key must be 128 bits ulong");
/*
* Initialize variables.
*/
- byte[] npub = new byte[iv.Length];
- byte[] k = new byte[keyBytes.Length];
- Array.Copy(iv, 0, npub, 0, iv.Length);
- Array.Copy(keyBytes, 0, k, 0, keyBytes.Length);
initialised = true;
- ISAPAEAD.init(k, npub, ISAP_rH, ISAP_rH_SZ);
+ ISAPAEAD.init(keyBytes, iv, ISAP_rH, ISAP_rH_SZ);
Reset();
}
public void ProcessAadByte(byte input)
{
- aadData.Write(new byte[] { input }, 0, 1);
+ aadData.WriteByte(input);
}
+ public void ProcessAadBytes(byte[] inBytes, int inOff, int len)
+ {
+ Check.DataLength(inBytes, inOff, len, "input buffer too short");
+
+ aadData.Write(inBytes, inOff, len);
+ }
- public void ProcessAadBytes(byte[] input, int inOff, int len)
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ public void ProcessAadBytes(ReadOnlySpan<byte> input)
{
- if ((inOff + len) > input.Length)
- {
- throw new DataLengthException("input buffer too short" + (forEncryption ? "encryption" : "decryption"));
- }
- aadData.Write(input, inOff, len);
+ aadData.Write(input);
}
+#endif
+ public int ProcessByte(byte input, byte[] outBytes, int outOff)
+ {
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ return ProcessByte(input, Spans.FromNullable(outBytes, outOff));
+#else
+ return ProcessBytes(new byte[]{ input }, 0, 1, outBytes, outOff);
+#endif
+ }
- public int ProcessByte(byte input, byte[] output, int outOff)
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ public int ProcessByte(byte input, Span<byte> output)
{
+ Span<byte> singleByte = stackalloc byte[1]{ input };
- return ProcessBytes(new byte[] { input }, 0, 1, output, outOff);
+ return ProcessBytes(singleByte, output);
}
+#endif
-
- 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)
{
+ Check.DataLength(inBytes, inOff, len, "input buffer too short");
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ return ProcessBytes(inBytes.AsSpan(inOff, len), Spans.FromNullable(outBytes, outOff));
+#else
if (!initialised)
+ throw new ArgumentException("Need to call Init function before encryption/decryption");
+
+ message.Write(inBytes, inOff, len);
+
+ if (forEncryption)
{
- throw new ArgumentException("Need call init function before encryption/decryption");
- }
- if ((inOff + len) > input.Length)
- {
- throw new DataLengthException("input buffer too short");
+ int msgLen = Convert.ToInt32(message.Length);
+ if (msgLen >= ISAP_rH_SZ)
+ {
+ int outLen = msgLen / ISAP_rH_SZ * ISAP_rH_SZ;
+ Check.OutputLength(outBytes, outOff, outLen, "output buffer is too short");
+ byte[] enc_input = message.GetBuffer();
+ ISAPAEAD.isap_enc(enc_input, 0, outLen, outBytes, outOff);
+ outputStream.Write(outBytes, outOff, outLen);
+ int enc_input_len = msgLen;
+ message.SetLength(0);
+ message.Write(enc_input, outLen, enc_input_len - outLen);
+ return outLen;
+ }
}
- message.Write(input, inOff, len);
+ return 0;
+#endif
+ }
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ public int ProcessBytes(ReadOnlySpan<byte> input, Span<byte> output)
+ {
+ if (!initialised)
+ throw new ArgumentException("Need to call Init function before encryption/decryption");
+
+ message.Write(input);
+
if (forEncryption)
{
- if (message.Length >= ISAP_rH_SZ)
+ int msgLen = Convert.ToInt32(message.Length);
+ if (msgLen >= ISAP_rH_SZ)
{
- len = (int)message.Length / ISAP_rH_SZ * ISAP_rH_SZ;
- if (outOff + len > output.Length)
- {
- throw new OutputLengthException("output buffer is too short");
- }
+ int outLen = msgLen / ISAP_rH_SZ * ISAP_rH_SZ;
+ Check.OutputLength(output, outLen, "output buffer is too short");
byte[] enc_input = message.GetBuffer();
- ISAPAEAD.isap_enc(enc_input, 0, len, output, outOff, output.Length);
- outputStream.Write(output, outOff, len);
- int enc_input_len = (int)message.Length;
+ ISAPAEAD.isap_enc(enc_input.AsSpan(0, outLen), output);
+ outputStream.Write(output[..outLen]);
+ int enc_input_len = msgLen;
message.SetLength(0);
- message.Write(enc_input, len, enc_input_len - len);
- return len;
+ message.Write(enc_input, outLen, enc_input_len - outLen);
+ return outLen;
}
}
return 0;
}
+#endif
-
- public int DoFinal(byte[] output, int outOff)
+ public int DoFinal(byte[] outBytes, int outOff)
{
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ return DoFinal(outBytes.AsSpan(outOff));
+#else
if (!initialised)
- {
throw new ArgumentException("Need call init function before encryption/decryption");
- }
- int len;
+
+ byte[] aad = aadData.GetBuffer();
+ byte[] msg = message.GetBuffer();
+
+ int aadLen = Convert.ToInt32(aadData.Length);
+ int msgLen = Convert.ToInt32(message.Length);
+ int outLen;
if (forEncryption)
{
- byte[] enc_input = message.GetBuffer();
- len = (int)message.Length;
- if (outOff + len + 16 > output.Length)
- {
- throw new OutputLengthException("output buffer is too short");
- }
- ISAPAEAD.isap_enc(enc_input, 0, len, output, outOff, output.Length);
- outputStream.Write(output, outOff, len);
- outOff += len;
- ad = aadData.GetBuffer();
- c = outputStream.GetBuffer();
+ outLen = msgLen + 16;
+ Check.OutputLength(outBytes, outOff, outLen, "output buffer is too short");
+ ISAPAEAD.isap_enc(msg, 0, msgLen, outBytes, outOff);
+ outputStream.Write(outBytes, outOff, msgLen);
+ outOff += msgLen;
+ byte[] c = outputStream.GetBuffer();
mac = new byte[16];
- ISAPAEAD.isap_mac(ad, (int)aadData.Length, c, (int)outputStream.Length, mac, 0);
- Array.Copy(mac, 0, output, outOff, 16);
- len += 16;
+ ISAPAEAD.isap_mac(aad, aadLen, c, Convert.ToInt32(outputStream.Length), mac, 0);
+ Array.Copy(mac, 0, outBytes, outOff, 16);
}
else
{
- ad = aadData.GetBuffer();
- int adlen = (int)aadData.Length;
- c = message.GetBuffer();
- int clen = (int)message.Length;
+ outLen = msgLen - 16;
+ Check.OutputLength(outBytes, outOff, outLen, "output buffer is too short");
mac = new byte[16];
- len = clen - mac.Length;
- if (len + outOff > output.Length)
- {
- throw new OutputLengthException("output buffer is too short");
- }
- ISAPAEAD.isap_mac(ad, adlen, c, len, mac, 0);
+ ISAPAEAD.isap_mac(aad, aadLen, msg, outLen, mac, 0);
ISAPAEAD.reset();
- for (int i = 0; i < 16; ++i)
- {
- if (mac[i] != c[len + i])
- {
- throw new ArgumentException("Mac does not match");
- }
- }
- ISAPAEAD.isap_enc(c, 0, len, output, outOff, output.Length);
+ if (!Arrays.FixedTimeEquals(16, mac, 0, msg, outLen))
+ throw new ArgumentException("Mac does not match");
+ ISAPAEAD.isap_enc(msg, 0, outLen, outBytes, outOff);
}
- return len;
+ return outLen;
+#endif
}
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ public int DoFinal(Span<byte> output)
+ {
+ if (!initialised)
+ throw new ArgumentException("Need call init function before encryption/decryption");
+
+ byte[] aad = aadData.GetBuffer();
+ byte[] msg = message.GetBuffer();
+
+ int aadLen = Convert.ToInt32(aadData.Length);
+ int msgLen = Convert.ToInt32(message.Length);
+ int outLen;
+ if (forEncryption)
+ {
+ outLen = msgLen + 16;
+ Check.OutputLength(output, outLen, "output buffer is too short");
+ ISAPAEAD.isap_enc(msg.AsSpan(0, msgLen), output);
+ outputStream.Write(output[..msgLen]);
+ output = output[msgLen..];
+ byte[] c = outputStream.GetBuffer();
+ mac = new byte[16];
+ ISAPAEAD.isap_mac(aad, aadLen, c, Convert.ToInt32(outputStream.Length), mac, 0);
+ mac.CopyTo(output);
+ }
+ else
+ {
+ outLen = msgLen - 16;
+ Check.OutputLength(output, outLen, "output buffer is too short");
+ mac = new byte[16];
+ 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");
+ ISAPAEAD.isap_enc(msg.AsSpan(0, outLen), output);
+ }
+ return outLen;
+ }
+#endif
public byte[] GetMac()
{
return mac;
}
-
public int GetUpdateOutputSize(int len)
{
- return len;
- }
+ if (!forEncryption)
+ return 0;
+ int totalData = Convert.ToInt32(message.Length + len);
+ return totalData - totalData % ISAP_rH_SZ;
+ }
public int GetOutputSize(int len)
{
- return len + 16;
- }
+ int totalData = Convert.ToInt32(message.Length + len);
+ if (forEncryption)
+ return totalData + 16;
+
+ return System.Math.Max(0, totalData - 16);
+ }
public void Reset()
{
if (!initialised)
- {
throw new ArgumentException("Need call init function before encryption/decryption");
- }
+
aadData.SetLength(0);
ISAPAEAD.reset();
message.SetLength(0);
outputStream.SetLength(0);
}
-
- private static void shortToLittleEndian(ushort n, byte[] bs, int off)
- {
- bs[off] = (byte)(n);
- bs[++off] = (byte)(n >> 8);
- }
-
- public int GetBlockSize()
- {
- return ISAP_rH_SZ;
- }
-
-#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
- public void ProcessAadBytes(ReadOnlySpan<byte> input)
- {
- aadData.Write(input);
- }
-
- public int ProcessByte(byte input, Span<byte> output)
- {
- byte[] rv = new byte[1];
- int len = ProcessBytes(new byte[] { input }, 0, 1, rv, 0);
- rv.AsSpan(0, len).CopyTo(output);
- return len;
- }
-
- public int ProcessBytes(ReadOnlySpan<byte> input, Span<byte> output)
- {
- byte[] rv = new byte[input.Length];
- int len = ProcessBytes(input.ToArray(), 0, rv.Length, rv, 0);
- rv.AsSpan(0, len).CopyTo(output);
- return len;
- }
-
- public int DoFinal(Span<byte> output)
- {
- byte[] rv;
- if (forEncryption)
- {
- rv = new byte[message.Length + 16];
- }
- else
- {
- rv = new byte[message.Length];
- }
- int len = DoFinal(rv, 0);
- rv.AsSpan(0, len).CopyTo(output);
- return rv.Length;
- }
-#endif
-
- public int GetKeyBytesSize()
- {
- return CRYPTO_KEYBYTES;
- }
-
- public int GetIVBytesSize()
- {
- return CRYPTO_NPUBBYTES;
- }
}
}
-
-
diff --git a/crypto/test/src/crypto/test/ISAPTest.cs b/crypto/test/src/crypto/test/ISAPTest.cs
index f38722e4a..ce19b38d5 100644
--- a/crypto/test/src/crypto/test/ISAPTest.cs
+++ b/crypto/test/src/crypto/test/ISAPTest.cs
@@ -6,63 +6,55 @@ 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;
using Org.BouncyCastle.Utilities.Test;
-using static Org.BouncyCastle.Crypto.Engines.ISAPEngine;
-
namespace Org.BouncyCastle.Crypto.Tests
{
[TestFixture]
- public class ISAPTest : SimpleTest
+ public class IsapTest
+ : SimpleTest
{
- public override string Name
- {
- get { return "ISAP"; }
- }
+ public override string Name => "ISAP";
[Test]
public override void PerformTest()
{
- ISAPEngine ISAP = new ISAPEngine(IsapType.ISAP_K_128A);
- testExceptions(ISAP, ISAP.GetKeyBytesSize(), ISAP.GetIVBytesSize(), ISAP.GetBlockSize());
- testParameters(ISAP, 16, 16, 16, 18);
- ISAP = new ISAPEngine(IsapType.ISAP_K_128);
- testExceptions(ISAP, ISAP.GetKeyBytesSize(), ISAP.GetIVBytesSize(), ISAP.GetBlockSize());
- testParameters(ISAP, 16, 16, 16, 18);
- ISAP = new ISAPEngine(IsapType.ISAP_A_128A);
- testExceptions(ISAP, ISAP.GetKeyBytesSize(), ISAP.GetIVBytesSize(), ISAP.GetBlockSize());
- testParameters(ISAP, 16, 16, 16, 8);
- ISAP = new ISAPEngine(IsapType.ISAP_A_128);
- testExceptions(ISAP, ISAP.GetKeyBytesSize(), ISAP.GetIVBytesSize(), ISAP.GetBlockSize());
- testParameters(ISAP, 16, 16, 16, 8);
- testExceptions(new ISAPDigest(), 32);
- testVectors("isapa128av20", IsapType.ISAP_A_128A);
- testVectors("isapa128v20", IsapType.ISAP_A_128);
- testVectors("isapk128av20", IsapType.ISAP_K_128A);
- testVectors("isapk128v20", IsapType.ISAP_K_128);
- testVectors();
+ IsapEngine isapEngine = new IsapEngine(IsapEngine.IsapType.ISAP_K_128A);
+ ImplTestExceptions(isapEngine);
+ ImplTestParameters(isapEngine, 16, 16, 16);
+ isapEngine = new IsapEngine(IsapEngine.IsapType.ISAP_K_128);
+ ImplTestExceptions(isapEngine);
+ ImplTestParameters(isapEngine, 16, 16, 16);
+ isapEngine = new IsapEngine(IsapEngine.IsapType.ISAP_A_128A);
+ ImplTestExceptions(isapEngine);
+ ImplTestParameters(isapEngine, 16, 16, 16);
+ isapEngine = new IsapEngine(IsapEngine.IsapType.ISAP_A_128);
+ ImplTestExceptions(isapEngine);
+ ImplTestParameters(isapEngine, 16, 16, 16);
+ 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);
+ ImplTestVectors("isapk128v20", IsapEngine.IsapType.ISAP_K_128);
+ ImplTestVectors();
}
-
- private void testVectors(string filename, IsapType isapType)
+ private void ImplTestVectors(string filename, IsapEngine.IsapType isapType)
{
- ISAPEngine isap = new ISAPEngine(isapType);
- ICipherParameters param;
+ Random random = new Random();
+ IsapEngine isapEngine = new IsapEngine(isapType);
var buf = new Dictionary<string, string>();
//TestSampler sampler = new TestSampler();
using (var src = new StreamReader(SimpleTest.GetTestDataAsStream("crypto.isap." + 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)
{
byte[] key = Hex.Decode(map["Key"]);
@@ -70,37 +62,37 @@ 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);
- isap.Init(true, param);
- isap.ProcessAadBytes(ad, 0, ad.Length);
- rv = new byte[isap.GetOutputSize(pt.Length)];
- int len = isap.ProcessBytes(pt, 0, pt.Length, rv, 0);
- //byte[] mac = new byte[16];
- isap.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));
- isap.Reset();
- isap.Init(false, param);
- //Decrypt
- isap.ProcessAadBytes(ad, 0, ad.Length);
- rv = new byte[pt.Length + 16];
- len = isap.ProcessBytes(ct, 0, ct.Length, rv, 0);
- isap.DoFinal(rv, len);
- 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();
- isap.Reset();
+
+ var parameters = new ParametersWithIV(new KeyParameter(key), nonce);
+
+ // Encrypt
+ {
+ isapEngine.Init(true, parameters);
+
+ var rv = new byte[isapEngine.GetOutputSize(pt.Length)];
+ random.NextBytes(rv); // should overwrite any existing data
+
+ isapEngine.ProcessAadBytes(ad, 0, ad.Length);
+ int len = isapEngine.ProcessBytes(pt, 0, pt.Length, rv, 0);
+ len += isapEngine.DoFinal(rv, len);
+
+ Assert.True(Arrays.AreEqual(rv, 0, len, ct, 0, ct.Length));
+ }
+
+ // Decrypt
+ {
+ isapEngine.Init(false, parameters);
+
+ var rv = new byte[isapEngine.GetOutputSize(ct.Length)];
+ random.NextBytes(rv); // should overwrite any existing data
+
+ isapEngine.ProcessAadBytes(ad, 0, ad.Length);
+ int len = isapEngine.ProcessBytes(ct, 0, ct.Length, rv, 0);
+ len += isapEngine.DoFinal(rv, len);
+
+ Assert.True(Arrays.AreEqual(rv, 0, len, pt, 0, pt.Length));
+ }
}
else
{
@@ -112,12 +104,12 @@ namespace Org.BouncyCastle.Crypto.Tests
{
map[data[0].Trim()] = "";
}
-
}
}
}
}
- private void testVectors()
+
+ private void ImplTestVectors()
{
ISAPDigest isap = new ISAPDigest();
var buf = new Dictionary<string, string>();
@@ -138,7 +130,6 @@ namespace Org.BouncyCastle.Crypto.Tests
byte[] hash = new byte[32];
isap.DoFinal(hash, 0);
Assert.True(Arrays.AreEqual(hash, Hex.Decode(map["MD"])));
- //Console.WriteLine(map["Count"] + " pass");
map.Clear();
isap.Reset();
}
@@ -158,18 +149,18 @@ namespace Org.BouncyCastle.Crypto.Tests
}
}
- private void testExceptions(IAeadBlockCipher aeadBlockCipher, int keysize, int ivsize, int blocksize)
+ private void ImplTestExceptions(IsapEngine isapEngine)
{
- ICipherParameters param;
+ int keysize = isapEngine.GetKeyBytesSize(), ivsize = isapEngine.GetIVBytesSize();
+ int offset;
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[] m = Array.Empty<byte>();
+ ICipherParameters param = new ParametersWithIV(new KeyParameter(k), iv);
try
{
- aeadBlockCipher.ProcessBytes(m, 0, m.Length, c1, 0);
- Assert.Fail(aeadBlockCipher.AlgorithmName + " need to be initialized before ProcessBytes");
+ isapEngine.ProcessBytes(m, 0, m.Length, null, 0);
+ Assert.Fail(isapEngine.AlgorithmName + " need to be initialized before ProcessBytes");
}
catch (ArgumentException)
{
@@ -178,8 +169,8 @@ namespace Org.BouncyCastle.Crypto.Tests
try
{
- aeadBlockCipher.ProcessByte((byte)0, c1, 0);
- Assert.Fail(aeadBlockCipher.AlgorithmName + " need to be initialized before ProcessByte");
+ isapEngine.ProcessByte((byte)0, null, 0);
+ Assert.Fail(isapEngine.AlgorithmName + " need to be initialized before ProcessByte");
}
catch (ArgumentException)
{
@@ -188,8 +179,8 @@ namespace Org.BouncyCastle.Crypto.Tests
try
{
- aeadBlockCipher.Reset();
- Assert.Fail(aeadBlockCipher.AlgorithmName + " need to be initialized before Reset");
+ isapEngine.Reset();
+ Assert.Fail(isapEngine.AlgorithmName + " need to be initialized before Reset");
}
catch (ArgumentException)
{
@@ -198,8 +189,8 @@ namespace Org.BouncyCastle.Crypto.Tests
try
{
- aeadBlockCipher.DoFinal(c1, m.Length);
- Assert.Fail(aeadBlockCipher.AlgorithmName + " need to be initialized before Dofinal");
+ isapEngine.DoFinal(null, m.Length);
+ Assert.Fail(isapEngine.AlgorithmName + " need to be initialized before Dofinal");
}
catch (ArgumentException)
{
@@ -208,13 +199,13 @@ namespace Org.BouncyCastle.Crypto.Tests
try
{
- aeadBlockCipher.GetMac();
- aeadBlockCipher.GetOutputSize(0);
- aeadBlockCipher.GetUpdateOutputSize(0);
+ isapEngine.GetMac();
+ isapEngine.GetOutputSize(0);
+ isapEngine.GetUpdateOutputSize(0);
}
catch (ArgumentException)
{
- Assert.Fail(aeadBlockCipher.AlgorithmName + " functions can be called before initialization");
+ Assert.Fail(isapEngine.AlgorithmName + " functions can be called before initialization");
}
Random rand = new Random();
int randomNum;
@@ -224,8 +215,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");
+ isapEngine.Init(true, new ParametersWithIV(new KeyParameter(k1), iv));
+ Assert.Fail(isapEngine.AlgorithmName + " k size does not match");
}
catch (ArgumentException)
{
@@ -233,25 +224,25 @@ namespace Org.BouncyCastle.Crypto.Tests
}
try
{
- aeadBlockCipher.Init(true, new ParametersWithIV(new KeyParameter(k), iv1));
- Assert.Fail(aeadBlockCipher.AlgorithmName + "iv size does not match");
+ isapEngine.Init(true, new ParametersWithIV(new KeyParameter(k), iv1));
+ Assert.Fail(isapEngine.AlgorithmName + "iv size does not match");
}
catch (ArgumentException)
{
//expected
}
-
- aeadBlockCipher.Init(true, param);
+ isapEngine.Init(true, param);
+ byte[] c1 = new byte[isapEngine.GetOutputSize(m.Length)];
try
{
- aeadBlockCipher.DoFinal(c1, m.Length);
+ isapEngine.DoFinal(c1, m.Length);
}
catch (Exception)
{
- Assert.Fail(aeadBlockCipher.AlgorithmName + " allows no input for AAD and plaintext");
+ Assert.Fail(isapEngine.AlgorithmName + " allows no input for AAD and plaintext");
}
- byte[] mac2 = aeadBlockCipher.GetMac();
+ byte[] mac2 = isapEngine.GetMac();
if (mac2 == null)
{
Assert.Fail("mac should not be empty after Dofinal");
@@ -260,15 +251,15 @@ 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);
+ isapEngine.ProcessAadByte(0x00);
+ byte[] mac1 = new byte[isapEngine.GetOutputSize(0)];
+ isapEngine.DoFinal(mac1, 0);
if (Arrays.AreEqual(mac1, mac2))
{
Assert.Fail("mac should not match");
}
- aeadBlockCipher.Reset();
- aeadBlockCipher.ProcessBytes(new byte[16], 0, 16, new byte[16], 0);
+ isapEngine.Reset();
+ isapEngine.ProcessBytes(new byte[16], 0, 16, new byte[16], 0);
//try
//{
// aeadBlockCipher.ProcessAadByte((byte)0);
@@ -288,10 +279,10 @@ namespace Org.BouncyCastle.Crypto.Tests
// //expected
//}
- aeadBlockCipher.Reset();
+ isapEngine.Reset();
try
{
- aeadBlockCipher.ProcessAadBytes(new byte[] { 0 }, 1, 1);
+ isapEngine.ProcessAadBytes(new byte[] { 0 }, 1, 1);
Assert.Fail("input for ProcessAadBytes is too short");
}
catch (DataLengthException)
@@ -300,7 +291,7 @@ namespace Org.BouncyCastle.Crypto.Tests
}
try
{
- aeadBlockCipher.ProcessBytes(new byte[] { 0 }, 1, 1, c1, 0);
+ isapEngine.ProcessBytes(new byte[] { 0 }, 1, 1, c1, 0);
Assert.Fail("input for ProcessBytes is too short");
}
catch (DataLengthException)
@@ -309,7 +300,9 @@ namespace Org.BouncyCastle.Crypto.Tests
}
try
{
- aeadBlockCipher.ProcessBytes(new byte[blocksize], 0, blocksize, new byte[blocksize], blocksize >> 1);
+ int inputSize = rand.Next(32, 64);
+ int outputSize = isapEngine.GetUpdateOutputSize(inputSize);
+ isapEngine.ProcessBytes(new byte[inputSize], 0, inputSize, new byte[outputSize], 1);
Assert.Fail("output for ProcessBytes is too short");
}
catch (OutputLengthException)
@@ -318,7 +311,7 @@ namespace Org.BouncyCastle.Crypto.Tests
}
try
{
- aeadBlockCipher.DoFinal(new byte[2], 2);
+ isapEngine.DoFinal(new byte[2], 2);
Assert.Fail("output for dofinal is too short");
}
catch (DataLengthException)
@@ -326,59 +319,58 @@ namespace Org.BouncyCastle.Crypto.Tests
//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[isapEngine.GetOutputSize(0)];
+ mac2 = new byte[isapEngine.GetOutputSize(0)];
+ isapEngine.Reset();
+ isapEngine.ProcessAadBytes(new byte[] { 0, 0 }, 0, 2);
+ isapEngine.DoFinal(mac1, 0);
+ isapEngine.Reset();
+ isapEngine.ProcessAadByte((byte)0);
+ isapEngine.ProcessAadByte((byte)0);
+ isapEngine.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[isapEngine.GetOutputSize(10)];
+ byte[] c3 = new byte[isapEngine.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);
+ isapEngine.Reset();
+ isapEngine.ProcessAadBytes(aad2, 0, aad2.Length);
+ offset = isapEngine.ProcessBytes(m2, 0, m2.Length, c2, 0);
+ isapEngine.DoFinal(c2, offset);
+ isapEngine.Reset();
+ isapEngine.ProcessAadBytes(aad3, 1, aad2.Length);
+ offset = isapEngine.ProcessBytes(m3, 1, m2.Length, c3, 1);
+ isapEngine.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);
+ isapEngine.Reset();
+ isapEngine.Init(false, param);
+ isapEngine.ProcessAadBytes(aad2, 0, aad2.Length);
+ offset = isapEngine.ProcessBytes(c2, 0, c2.Length, m4, 0);
+ offset += isapEngine.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);
+ isapEngine.Reset();
+ isapEngine.Init(false, param);
+ isapEngine.ProcessAadBytes(aad2, 0, aad2.Length);
+ offset = isapEngine.ProcessBytes(c2, 0, c2.Length, m4, 0);
try
{
- aeadBlockCipher.DoFinal(m4, offset);
+ offset += isapEngine.DoFinal(m4, offset);
Assert.Fail("The decryption should fail");
}
catch (ArgumentException)
@@ -387,26 +379,27 @@ namespace Org.BouncyCastle.Crypto.Tests
}
c2[c2.Length - 1] ^= 1;
- byte[] m7 = new byte[blocksize * 2];
+ byte[] m7 = new byte[32 + rand.Next(32)];
rand.NextBytes(m7);
- byte[] c7 = new byte[aeadBlockCipher.GetOutputSize(m7.Length)];
+
+ isapEngine.Init(true, param);
+ byte[] c7 = new byte[isapEngine.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();
- 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);
+ isapEngine.ProcessAadBytes(aad2, 0, aad2.Length);
+ offset = isapEngine.ProcessBytes(m7, 0, m7.Length, c7, 0);
+ offset += isapEngine.DoFinal(c7, offset);
+ isapEngine.Reset();
+ isapEngine.ProcessAadBytes(aad2, 0, aad2.Length);
+ offset = isapEngine.ProcessBytes(m7, 0, m7.Length / 2, c8, 0);
+ offset += isapEngine.ProcessBytes(m7, m7.Length / 2, m7.Length - m7.Length / 2, c8, offset);
+ offset += isapEngine.DoFinal(c8, offset);
+ isapEngine.Reset();
+ int split = rand.Next(1, m7.Length);
+ isapEngine.ProcessAadBytes(aad2, 0, aad2.Length);
+ offset = isapEngine.ProcessBytes(m7, 0, split, c9, 0);
+ offset += isapEngine.ProcessBytes(m7, split, m7.Length - split, c9, offset);
+ isapEngine.DoFinal(c9, offset);
if (!Arrays.AreEqual(c7, c8) || !Arrays.AreEqual(c7, c9))
{
Assert.Fail("Splitting input of plaintext should output the same ciphertext");
@@ -418,10 +411,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);
+ isapEngine.Init(true, param);
+ isapEngine.ProcessAadBytes(aad4);
+ 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);
@@ -429,14 +422,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);
+ isapEngine.Reset();
+ isapEngine.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);
+ isapEngine.ProcessAadBytes(aad4);
+ 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);
@@ -447,28 +440,25 @@ namespace Org.BouncyCastle.Crypto.Tests
#endif
}
- private void testParameters(ISAPEngine ascon, int keySize, int ivSize, int macSize, int blockSize)
+ private void ImplTestParameters(IsapEngine isapEngine, int keySize, int ivSize, int macSize)
{
- if (ascon.GetKeyBytesSize() != keySize)
- {
- Assert.Fail("key bytes of " + ascon.AlgorithmName + " is not correct");
- }
- if (ascon.GetIVBytesSize() != ivSize)
- {
- Assert.Fail("iv bytes of " + ascon.AlgorithmName + " is not correct");
- }
- if (ascon.GetOutputSize(0) != macSize)
- {
- Assert.Fail("mac bytes of " + ascon.AlgorithmName + " is not correct");
- }
- if (ascon.GetBlockSize() != blockSize)
- {
- Assert.Fail("block size of " + ascon.AlgorithmName + " is not correct");
- }
- //Console.WriteLine(ascon.AlgorithmName + " test Parameters pass");
+ Assert.AreEqual(keySize, isapEngine.GetKeyBytesSize(),
+ "key bytes of " + isapEngine.AlgorithmName + " is not correct");
+ Assert.AreEqual(ivSize, isapEngine.GetIVBytesSize(),
+ "iv bytes of " + isapEngine.AlgorithmName + " is not correct");
+
+ var parameters = new ParametersWithIV(new KeyParameter(new byte[keySize]), new byte[ivSize]);
+
+ isapEngine.Init(true, parameters);
+ Assert.AreEqual(macSize, isapEngine.GetOutputSize(0),
+ "GetOutputSize of " + isapEngine.AlgorithmName + " is incorrect for encryption");
+
+ isapEngine.Init(false, parameters);
+ Assert.AreEqual(0, isapEngine.GetOutputSize(macSize),
+ "GetOutputSize of " + isapEngine.AlgorithmName + " is incorrect for decryption");
}
- private void testExceptions(IDigest digest, int digestsize)
+ private void ImplTestExceptions(IDigest digest, int digestsize)
{
if (digest.GetDigestSize() != digestsize)
{
@@ -493,7 +483,6 @@ namespace Org.BouncyCastle.Crypto.Tests
{
//expected
}
- //Console.WriteLine(digest.AlgorithmName + " test Exceptions pass");
}
}
}
\ No newline at end of file
|