Merge #11726: Cleanups + nit fixes for walletdir PR
[bitcoinplatinum.git] / src / crypto / chacha20.cpp
blobac4470f04f73e1b7baaac2f16da9af92993922a8
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>
11 #include <string.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 */
33 k += 16;
34 constants = sigma;
35 } else { /* keylen == 16 */
36 constants = tau;
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);
46 input[12] = 0;
47 input[13] = 0;
48 input[14] = 0;
49 input[15] = 0;
52 ChaCha20::ChaCha20()
54 memset(input, 0, sizeof(input));
57 ChaCha20::ChaCha20(const unsigned char* k, size_t keylen)
59 SetKey(k, keylen);
62 void ChaCha20::SetIV(uint64_t iv)
64 input[14] = iv;
65 input[15] = iv >> 32;
68 void ChaCha20::Seek(uint64_t pos)
70 input[12] = 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];
80 unsigned int i;
82 if (!bytes) return;
84 j0 = input[0];
85 j1 = input[1];
86 j2 = input[2];
87 j3 = input[3];
88 j4 = input[4];
89 j5 = input[5];
90 j6 = input[6];
91 j7 = input[7];
92 j8 = input[8];
93 j9 = input[9];
94 j10 = input[10];
95 j11 = input[11];
96 j12 = input[12];
97 j13 = input[13];
98 j14 = input[14];
99 j15 = input[15];
101 for (;;) {
102 if (bytes < 64) {
103 ctarget = c;
104 c = tmp;
106 x0 = j0;
107 x1 = j1;
108 x2 = j2;
109 x3 = j3;
110 x4 = j4;
111 x5 = j5;
112 x6 = j6;
113 x7 = j7;
114 x8 = j8;
115 x9 = j9;
116 x10 = j10;
117 x11 = j11;
118 x12 = j12;
119 x13 = j13;
120 x14 = j14;
121 x15 = j15;
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)
132 x0 += j0;
133 x1 += j1;
134 x2 += j2;
135 x3 += j3;
136 x4 += j4;
137 x5 += j5;
138 x6 += j6;
139 x7 += j7;
140 x8 += j8;
141 x9 += j9;
142 x10 += j10;
143 x11 += j11;
144 x12 += j12;
145 x13 += j13;
146 x14 += j14;
147 x15 += j15;
149 ++j12;
150 if (!j12) ++j13;
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);
169 if (bytes <= 64) {
170 if (bytes < 64) {
171 for (i = 0;i < bytes;++i) ctarget[i] = c[i];
173 input[12] = j12;
174 input[13] = j13;
175 return;
177 bytes -= 64;
178 c += 64;