1 // Copyright (c) 2017 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 // Based on the public domain implementation 'merged' by D. J. Bernstein
6 // See https://cr.yp.to/chacha.html.
8 #include <crypto/common.h>
9 #include <crypto/chacha20.h>
13 constexpr static inline uint32_t rotl32(uint32_t v
, int c
) { return (v
<< c
) | (v
>> (32 - c
)); }
15 #define QUARTERROUND(a,b,c,d) \
16 a += b; d = rotl32(d ^ a, 16); \
17 c += d; b = rotl32(b ^ c, 12); \
18 a += b; d = rotl32(d ^ a, 8); \
19 c += d; b = rotl32(b ^ c, 7);
21 static const unsigned char sigma
[] = "expand 32-byte k";
22 static const unsigned char tau
[] = "expand 16-byte k";
24 void ChaCha20::SetKey(const unsigned char* k
, size_t keylen
)
26 const unsigned char *constants
;
28 input
[4] = ReadLE32(k
+ 0);
29 input
[5] = ReadLE32(k
+ 4);
30 input
[6] = ReadLE32(k
+ 8);
31 input
[7] = ReadLE32(k
+ 12);
32 if (keylen
== 32) { /* recommended */
35 } else { /* keylen == 16 */
38 input
[8] = ReadLE32(k
+ 0);
39 input
[9] = ReadLE32(k
+ 4);
40 input
[10] = ReadLE32(k
+ 8);
41 input
[11] = ReadLE32(k
+ 12);
42 input
[0] = ReadLE32(constants
+ 0);
43 input
[1] = ReadLE32(constants
+ 4);
44 input
[2] = ReadLE32(constants
+ 8);
45 input
[3] = ReadLE32(constants
+ 12);
54 memset(input
, 0, sizeof(input
));
57 ChaCha20::ChaCha20(const unsigned char* k
, size_t keylen
)
62 void ChaCha20::SetIV(uint64_t iv
)
68 void ChaCha20::Seek(uint64_t pos
)
71 input
[13] = pos
>> 32;
74 void ChaCha20::Output(unsigned char* c
, size_t bytes
)
76 uint32_t x0
, x1
, x2
, x3
, x4
, x5
, x6
, x7
, x8
, x9
, x10
, x11
, x12
, x13
, x14
, x15
;
77 uint32_t j0
, j1
, j2
, j3
, j4
, j5
, j6
, j7
, j8
, j9
, j10
, j11
, j12
, j13
, j14
, j15
;
78 unsigned char *ctarget
= nullptr;
79 unsigned char tmp
[64];
122 for (i
= 20;i
> 0;i
-= 2) {
123 QUARTERROUND( x0
, x4
, x8
,x12
)
124 QUARTERROUND( x1
, x5
, x9
,x13
)
125 QUARTERROUND( x2
, x6
,x10
,x14
)
126 QUARTERROUND( x3
, x7
,x11
,x15
)
127 QUARTERROUND( x0
, x5
,x10
,x15
)
128 QUARTERROUND( x1
, x6
,x11
,x12
)
129 QUARTERROUND( x2
, x7
, x8
,x13
)
130 QUARTERROUND( x3
, x4
, x9
,x14
)
152 WriteLE32(c
+ 0, x0
);
153 WriteLE32(c
+ 4, x1
);
154 WriteLE32(c
+ 8, x2
);
155 WriteLE32(c
+ 12, x3
);
156 WriteLE32(c
+ 16, x4
);
157 WriteLE32(c
+ 20, x5
);
158 WriteLE32(c
+ 24, x6
);
159 WriteLE32(c
+ 28, x7
);
160 WriteLE32(c
+ 32, x8
);
161 WriteLE32(c
+ 36, x9
);
162 WriteLE32(c
+ 40, x10
);
163 WriteLE32(c
+ 44, x11
);
164 WriteLE32(c
+ 48, x12
);
165 WriteLE32(c
+ 52, x13
);
166 WriteLE32(c
+ 56, x14
);
167 WriteLE32(c
+ 60, x15
);
171 for (i
= 0;i
< bytes
;++i
) ctarget
[i
] = c
[i
];