From 90cbc8847f7ec95646041b9b8ffad4d9bfd911d2 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Wed, 3 May 2023 16:39:09 +0700 Subject: Refactoring in Sparkle --- crypto/src/crypto/digests/SparkleDigest.cs | 45 +++++++++++++--------------- crypto/src/crypto/engines/SparkleEngine.cs | 47 ++++++++++++++++++------------ 2 files changed, 48 insertions(+), 44 deletions(-) diff --git a/crypto/src/crypto/digests/SparkleDigest.cs b/crypto/src/crypto/digests/SparkleDigest.cs index df51c9935..f818f0257 100644 --- a/crypto/src/crypto/digests/SparkleDigest.cs +++ b/crypto/src/crypto/digests/SparkleDigest.cs @@ -24,12 +24,8 @@ namespace Org.BouncyCastle.Crypto.Digests ESCH384 } - private const int RATE_BITS = 128; private const int RATE_BYTES = 16; - private const int RATE_UINTS = 4; - - private static readonly uint[] RCON = { 0xB7E15162U, 0xBF715880U, 0x38B4DA56U, 0x324E7738U, 0xBB1185EBU, - 0x4F7C7B57U, 0xCFBFA1C8U, 0xC2B3293DU }; + private const int RATE_WORDS = 4; private string algorithmName; private readonly uint[] state; @@ -37,7 +33,7 @@ namespace Org.BouncyCastle.Crypto.Digests private readonly int DIGEST_BYTES; private readonly int SPARKLE_STEPS_SLIM; private readonly int SPARKLE_STEPS_BIG; - private readonly int STATE_UINTS; + private readonly int STATE_WORDS; private int m_bufPos = 0; @@ -50,20 +46,20 @@ namespace Org.BouncyCastle.Crypto.Digests DIGEST_BYTES = 32; SPARKLE_STEPS_SLIM = 7; SPARKLE_STEPS_BIG = 11; - STATE_UINTS = 12; + STATE_WORDS = 12; break; case SparkleParameters.ESCH384: algorithmName = "ESCH-384"; DIGEST_BYTES = 48; SPARKLE_STEPS_SLIM = 8; SPARKLE_STEPS_BIG = 12; - STATE_UINTS = 16; + STATE_WORDS = 16; break; default: throw new ArgumentException("Invalid definition of ESCH instance"); } - state = new uint[STATE_UINTS]; + state = new uint[STATE_WORDS]; } public string AlgorithmName => algorithmName; @@ -165,7 +161,7 @@ namespace Org.BouncyCastle.Crypto.Digests // addition of constant M1 or M2 to the state if (m_bufPos < RATE_BYTES) { - state[(STATE_UINTS >> 1) - 1] ^= 1U << 24; + state[(STATE_WORDS >> 1) - 1] ^= 1U << 24; // padding m_buf[m_bufPos] = 0x80; @@ -176,25 +172,24 @@ namespace Org.BouncyCastle.Crypto.Digests } else { - state[(STATE_UINTS >> 1) - 1] ^= 1U << 25; + state[(STATE_WORDS >> 1) - 1] ^= 1U << 25; } - // addition of last msg block (incl. padding) ProcessBlock(m_buf, 0, SPARKLE_STEPS_BIG); - Pack.UInt32_To_LE(state, 0, RATE_UINTS, output, outOff); + Pack.UInt32_To_LE(state, 0, RATE_WORDS, output, outOff); - if (STATE_UINTS == 16) + if (STATE_WORDS == 16) { SparkleEngine.SparkleOpt16(state, SPARKLE_STEPS_SLIM); - Pack.UInt32_To_LE(state, 0, RATE_UINTS, output, outOff + 16); + Pack.UInt32_To_LE(state, 0, RATE_WORDS, output, outOff + 16); SparkleEngine.SparkleOpt16(state, SPARKLE_STEPS_SLIM); - Pack.UInt32_To_LE(state, 0, RATE_UINTS, output, outOff + 32); + Pack.UInt32_To_LE(state, 0, RATE_WORDS, output, outOff + 32); } else { SparkleEngine.SparkleOpt12(state, SPARKLE_STEPS_SLIM); - Pack.UInt32_To_LE(state, 0, RATE_UINTS, output, outOff + 16); + Pack.UInt32_To_LE(state, 0, RATE_WORDS, output, outOff + 16); } Reset(); @@ -208,7 +203,7 @@ namespace Org.BouncyCastle.Crypto.Digests // addition of constant M1 or M2 to the state if (m_bufPos < RATE_BYTES) { - state[(STATE_UINTS >> 1) - 1] ^= 1U << 24; + state[(STATE_WORDS >> 1) - 1] ^= 1U << 24; // padding m_buf[m_bufPos] = 0x80; @@ -219,25 +214,25 @@ namespace Org.BouncyCastle.Crypto.Digests } else { - state[(STATE_UINTS >> 1) - 1] ^= 1U << 25; + state[(STATE_WORDS >> 1) - 1] ^= 1U << 25; } // addition of last msg block (incl. padding) ProcessBlock(m_buf, SPARKLE_STEPS_BIG); - Pack.UInt32_To_LE(state[..RATE_UINTS], output); + Pack.UInt32_To_LE(state[..RATE_WORDS], output); - if (STATE_UINTS == 16) + if (STATE_WORDS == 16) { SparkleEngine.SparkleOpt16(state, SPARKLE_STEPS_SLIM); - Pack.UInt32_To_LE(state[..RATE_UINTS], output[16..]); + Pack.UInt32_To_LE(state[..RATE_WORDS], output[16..]); SparkleEngine.SparkleOpt16(state, SPARKLE_STEPS_SLIM); - Pack.UInt32_To_LE(state[..RATE_UINTS], output[32..]); + Pack.UInt32_To_LE(state[..RATE_WORDS], output[32..]); } else { SparkleEngine.SparkleOpt12(state, SPARKLE_STEPS_SLIM); - Pack.UInt32_To_LE(state[..RATE_UINTS], output[16..]); + Pack.UInt32_To_LE(state[..RATE_WORDS], output[16..]); } Reset(); @@ -280,7 +275,7 @@ namespace Org.BouncyCastle.Crypto.Digests state[3] ^= t3 ^ tx; state[4] ^= ty; state[5] ^= tx; - if (STATE_UINTS == 16) + if (STATE_WORDS == 16) { state[6] ^= ty; state[7] ^= tx; diff --git a/crypto/src/crypto/engines/SparkleEngine.cs b/crypto/src/crypto/engines/SparkleEngine.cs index cd6586623..13aaf1edf 100644 --- a/crypto/src/crypto/engines/SparkleEngine.cs +++ b/crypto/src/crypto/engines/SparkleEngine.cs @@ -563,7 +563,7 @@ namespace Org.BouncyCastle.Crypto.Engines uint s_j = state[j]; if (forEncryption) { - state[i] = s_j ^ buffer[i] ^ state[RATE_WORDS + i]; + state[i] = s_j ^ buffer[i] ^ state[RATE_WORDS + i]; state[j] = s_i ^ s_j ^ buffer[j] ^ state[RATE_WORDS + (j & CAP_MASK)]; } else @@ -817,7 +817,7 @@ namespace Org.BouncyCastle.Crypto.Engines uint d_i = Pack.LE_To_UInt32(buffer, bufOff + (i * 4)); uint d_j = Pack.LE_To_UInt32(buffer, bufOff + (j * 4)); - state[i] = s_j ^ d_i ^ state[RATE_WORDS + i]; + state[i] = s_j ^ d_i ^ state[RATE_WORDS + i]; state[j] = s_i ^ s_j ^ d_j ^ state[RATE_WORDS + (j & CAP_MASK)]; } @@ -868,7 +868,7 @@ namespace Org.BouncyCastle.Crypto.Engines uint d_i = Pack.LE_To_UInt32(buffer, bufOff + (i * 4)); uint d_j = Pack.LE_To_UInt32(buffer, bufOff + (j * 4)); - state[i] = s_j ^ d_i ^ state[RATE_WORDS + i]; + state[i] = s_j ^ d_i ^ state[RATE_WORDS + i]; state[j] = s_i ^ s_j ^ d_j ^ state[RATE_WORDS + (j & CAP_MASK)]; Pack.UInt32_To_LE(d_i ^ s_i, output, outOff + (i * 4)); @@ -883,26 +883,35 @@ namespace Org.BouncyCastle.Crypto.Engines private void ProcessFinalAad() { - // Authentication of Last Block - - // addition of ant A0 or A1 to the state - state[STATE_WORDS - 1] ^= (m_bufPos < RATE_BYTES) ? _A0 : _A1; - - // Rho and rate-whitening for the authentication of the last associated-data block. - uint[] buffer = new uint[RATE_WORDS]; - for (int i = 0; i < m_bufPos; ++i) + // addition of constant A0 or A1 to the state + if (m_bufPos < RATE_BYTES) { - buffer[i >> 2] |= (uint)m_buf[i] << ((i & 3) << 3); + state[STATE_WORDS - 1] ^= _A0; + + // padding + m_buf[m_bufPos] = 0x80; + while (++m_bufPos < RATE_BYTES) + { + m_buf[m_bufPos] = 0x00; + } } - if (m_bufPos < RATE_BYTES) - { // padding - buffer[m_bufPos >> 2] |= 0x80U << ((m_bufPos & 3) << 3); + else + { + state[STATE_WORDS - 1] ^= _A1; } - for (int i = 0, j = RATE_WORDS / 2; i < RATE_WORDS / 2; i++, j++) + + for (int i = 0; i < RATE_WORDS / 2; ++i) { - uint tmp = state[i]; - state[i] = state[j] ^ buffer[i] ^ state[RATE_WORDS + i]; - state[j] ^= tmp ^ buffer[j] ^ state[RATE_WORDS + (j & CAP_MASK)]; + int j = i + (RATE_WORDS / 2); + + uint s_i = state[i]; + uint s_j = state[j]; + + uint d_i = Pack.LE_To_UInt32(m_buf, i * 4); + uint d_j = Pack.LE_To_UInt32(m_buf, j * 4); + + state[i] = s_j ^ d_i ^ state[RATE_WORDS + i]; + state[j] = s_i ^ s_j ^ d_j ^ state[RATE_WORDS + (j & CAP_MASK)]; } SparkleOpt(state, SPARKLE_STEPS_BIG); -- cgit 1.4.1