aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPieter Wuille <pieter@wuille.net>2022-09-21 18:01:57 -0400
committerPieter Wuille <pieter@wuille.net>2023-01-30 18:12:21 -0500
commit93aee8bbdad808b7009279b67470d496cc26b936 (patch)
tree4b700ff0ad65750aa7b151c52ca72a0e11d8db39 /src
parent62ec713961ade7b58e90c905395558a41e8a59f0 (diff)
Inline ChaCha20 32-byte specific constants
Diffstat (limited to 'src')
-rw-r--r--src/crypto/chacha20.cpp138
-rw-r--r--src/crypto/chacha20.h2
-rw-r--r--src/test/fuzz/crypto_diff_fuzz_chacha20.cpp15
3 files changed, 71 insertions, 84 deletions
diff --git a/src/crypto/chacha20.cpp b/src/crypto/chacha20.cpp
index c5eee5ccfd..6934cef163 100644
--- a/src/crypto/chacha20.cpp
+++ b/src/crypto/chacha20.cpp
@@ -21,26 +21,20 @@ constexpr static inline uint32_t rotl32(uint32_t v, int c) { return (v << c) | (
#define REPEAT10(a) do { {a}; {a}; {a}; {a}; {a}; {a}; {a}; {a}; {a}; {a}; } while(0)
-static const unsigned char sigma[] = "expand 32-byte k";
-
void ChaCha20Aligned::SetKey32(const unsigned char* k)
{
- input[0] = ReadLE32(sigma + 0);
- input[1] = ReadLE32(sigma + 4);
- input[2] = ReadLE32(sigma + 8);
- input[3] = ReadLE32(sigma + 12);
- input[4] = ReadLE32(k + 0);
- input[5] = ReadLE32(k + 4);
- input[6] = ReadLE32(k + 8);
- input[7] = ReadLE32(k + 12);
- input[8] = ReadLE32(k + 16);
- input[9] = ReadLE32(k + 20);
- input[10] = ReadLE32(k + 24);
- input[11] = ReadLE32(k + 28);
- input[12] = 0;
- input[13] = 0;
- input[14] = 0;
- input[15] = 0;
+ input[0] = ReadLE32(k + 0);
+ input[1] = ReadLE32(k + 4);
+ input[2] = ReadLE32(k + 8);
+ input[3] = ReadLE32(k + 12);
+ input[4] = ReadLE32(k + 16);
+ input[5] = ReadLE32(k + 20);
+ input[6] = ReadLE32(k + 24);
+ input[7] = ReadLE32(k + 28);
+ input[8] = 0;
+ input[9] = 0;
+ input[10] = 0;
+ input[11] = 0;
}
ChaCha20Aligned::ChaCha20Aligned()
@@ -55,45 +49,41 @@ ChaCha20Aligned::ChaCha20Aligned(const unsigned char* key32)
void ChaCha20Aligned::SetIV(uint64_t iv)
{
- input[14] = iv;
- input[15] = iv >> 32;
+ input[10] = iv;
+ input[11] = iv >> 32;
}
void ChaCha20Aligned::Seek64(uint64_t pos)
{
- input[12] = pos;
- input[13] = pos >> 32;
+ input[8] = pos;
+ input[9] = pos >> 32;
}
inline void ChaCha20Aligned::Keystream64(unsigned char* c, size_t blocks)
{
uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
- uint32_t j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
+ uint32_t j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
if (!blocks) return;
- j0 = input[0];
- j1 = input[1];
- j2 = input[2];
- j3 = input[3];
- j4 = input[4];
- j5 = input[5];
- j6 = input[6];
- j7 = input[7];
- j8 = input[8];
- j9 = input[9];
- j10 = input[10];
- j11 = input[11];
- j12 = input[12];
- j13 = input[13];
- j14 = input[14];
- j15 = input[15];
+ j4 = input[0];
+ j5 = input[1];
+ j6 = input[2];
+ j7 = input[3];
+ j8 = input[4];
+ j9 = input[5];
+ j10 = input[6];
+ j11 = input[7];
+ j12 = input[8];
+ j13 = input[9];
+ j14 = input[10];
+ j15 = input[11];
for (;;) {
- x0 = j0;
- x1 = j1;
- x2 = j2;
- x3 = j3;
+ x0 = 0x61707865;
+ x1 = 0x3320646e;
+ x2 = 0x79622d32;
+ x3 = 0x6b206574;
x4 = j4;
x5 = j5;
x6 = j6;
@@ -119,10 +109,10 @@ inline void ChaCha20Aligned::Keystream64(unsigned char* c, size_t blocks)
QUARTERROUND( x3, x4, x9,x14);
);
- x0 += j0;
- x1 += j1;
- x2 += j2;
- x3 += j3;
+ x0 += 0x61707865;
+ x1 += 0x3320646e;
+ x2 += 0x79622d32;
+ x3 += 0x6b206574;
x4 += j4;
x5 += j5;
x6 += j6;
@@ -157,8 +147,8 @@ inline void ChaCha20Aligned::Keystream64(unsigned char* c, size_t blocks)
WriteLE32(c + 60, x15);
if (blocks == 1) {
- input[12] = j12;
- input[13] = j13;
+ input[8] = j12;
+ input[9] = j13;
return;
}
blocks -= 1;
@@ -169,32 +159,28 @@ inline void ChaCha20Aligned::Keystream64(unsigned char* c, size_t blocks)
inline void ChaCha20Aligned::Crypt64(const unsigned char* m, unsigned char* c, size_t blocks)
{
uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
- uint32_t j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
+ uint32_t j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
if (!blocks) return;
- j0 = input[0];
- j1 = input[1];
- j2 = input[2];
- j3 = input[3];
- j4 = input[4];
- j5 = input[5];
- j6 = input[6];
- j7 = input[7];
- j8 = input[8];
- j9 = input[9];
- j10 = input[10];
- j11 = input[11];
- j12 = input[12];
- j13 = input[13];
- j14 = input[14];
- j15 = input[15];
+ j4 = input[0];
+ j5 = input[1];
+ j6 = input[2];
+ j7 = input[3];
+ j8 = input[4];
+ j9 = input[5];
+ j10 = input[6];
+ j11 = input[7];
+ j12 = input[8];
+ j13 = input[9];
+ j14 = input[10];
+ j15 = input[11];
for (;;) {
- x0 = j0;
- x1 = j1;
- x2 = j2;
- x3 = j3;
+ x0 = 0x61707865;
+ x1 = 0x3320646e;
+ x2 = 0x79622d32;
+ x3 = 0x6b206574;
x4 = j4;
x5 = j5;
x6 = j6;
@@ -220,10 +206,10 @@ inline void ChaCha20Aligned::Crypt64(const unsigned char* m, unsigned char* c, s
QUARTERROUND( x3, x4, x9,x14);
);
- x0 += j0;
- x1 += j1;
- x2 += j2;
- x3 += j3;
+ x0 += 0x61707865;
+ x1 += 0x3320646e;
+ x2 += 0x79622d32;
+ x3 += 0x6b206574;
x4 += j4;
x5 += j5;
x6 += j6;
@@ -275,8 +261,8 @@ inline void ChaCha20Aligned::Crypt64(const unsigned char* m, unsigned char* c, s
WriteLE32(c + 60, x15);
if (blocks == 1) {
- input[12] = j12;
- input[13] = j13;
+ input[8] = j12;
+ input[9] = j13;
return;
}
blocks -= 1;
diff --git a/src/crypto/chacha20.h b/src/crypto/chacha20.h
index 1119bf6323..b286ef59fe 100644
--- a/src/crypto/chacha20.h
+++ b/src/crypto/chacha20.h
@@ -15,7 +15,7 @@
class ChaCha20Aligned
{
private:
- uint32_t input[16];
+ uint32_t input[12];
public:
ChaCha20Aligned();
diff --git a/src/test/fuzz/crypto_diff_fuzz_chacha20.cpp b/src/test/fuzz/crypto_diff_fuzz_chacha20.cpp
index 9d650fc492..78fee48de6 100644
--- a/src/test/fuzz/crypto_diff_fuzz_chacha20.cpp
+++ b/src/test/fuzz/crypto_diff_fuzz_chacha20.cpp
@@ -267,24 +267,25 @@ void ECRYPT_keystream_bytes(ECRYPT_ctx* x, u8* stream, u32 bytes)
FUZZ_TARGET(crypto_diff_fuzz_chacha20)
{
+ static const unsigned char ZEROKEY[32] = {0};
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
ChaCha20 chacha20;
ECRYPT_ctx ctx;
- // D. J. Bernstein doesn't initialise ctx to 0 while Bitcoin Core initialises chacha20 to 0 in the constructor
- for (int i = 0; i < 16; i++) {
- ctx.input[i] = 0;
- }
if (fuzzed_data_provider.ConsumeBool()) {
const std::vector<unsigned char> key = ConsumeFixedLengthByteVector(fuzzed_data_provider, 32);
chacha20 = ChaCha20{key.data()};
ECRYPT_keysetup(&ctx, key.data(), key.size() * 8, 0);
- // ECRYPT_keysetup() doesn't set the counter and nonce to 0 while SetKey32() does
- uint8_t iv[8] = {0, 0, 0, 0, 0, 0, 0, 0};
- ECRYPT_ivsetup(&ctx, iv);
+ } else {
+ // The default ChaCha20 constructor is equivalent to using the all-0 key.
+ ECRYPT_keysetup(&ctx, ZEROKEY, 256, 0);
}
+ // ECRYPT_keysetup() doesn't set the counter and nonce to 0 while SetKey32() does
+ static const uint8_t iv[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+ ECRYPT_ivsetup(&ctx, iv);
+
LIMITED_WHILE (fuzzed_data_provider.ConsumeBool(), 3000) {
CallOneOf(
fuzzed_data_provider,