Bitcoin ABC  0.24.7
P2P Digital Currency
poly1305.cpp
Go to the documentation of this file.
1 // Copyright (c) 2019 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.
4 
5 // Based on the public domain implementation by Andrew Moon
6 // poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna
7 
8 #include <crypto/common.h>
9 #include <crypto/poly1305.h>
10 
11 #include <cstring>
12 
13 #define mul32x32_64(a, b) ((uint64_t)(a) * (b))
14 
15 void poly1305_auth(uint8_t out[POLY1305_TAGLEN], const uint8_t *m, size_t inlen,
16  const uint8_t key[POLY1305_KEYLEN]) {
17  uint32_t t0, t1, t2, t3;
18  uint32_t h0, h1, h2, h3, h4;
19  uint32_t r0, r1, r2, r3, r4;
20  uint32_t s1, s2, s3, s4;
21  uint32_t b, nb;
22  size_t j;
23  uint64_t t[5];
24  uint64_t f0, f1, f2, f3;
25  uint64_t g0, g1, g2, g3, g4;
26  uint64_t c;
27  uint8_t mp[16];
28 
29  /* clamp key */
30  t0 = ReadLE32(key + 0);
31  t1 = ReadLE32(key + 4);
32  t2 = ReadLE32(key + 8);
33  t3 = ReadLE32(key + 12);
34 
35  /* precompute multipliers */
36  r0 = t0 & 0x3ffffff;
37  t0 >>= 26;
38  t0 |= t1 << 6;
39  r1 = t0 & 0x3ffff03;
40  t1 >>= 20;
41  t1 |= t2 << 12;
42  r2 = t1 & 0x3ffc0ff;
43  t2 >>= 14;
44  t2 |= t3 << 18;
45  r3 = t2 & 0x3f03fff;
46  t3 >>= 8;
47  r4 = t3 & 0x00fffff;
48 
49  s1 = r1 * 5;
50  s2 = r2 * 5;
51  s3 = r3 * 5;
52  s4 = r4 * 5;
53 
54  /* init state */
55  h0 = 0;
56  h1 = 0;
57  h2 = 0;
58  h3 = 0;
59  h4 = 0;
60 
61  /* full blocks */
62  if (inlen < 16) {
63  goto poly1305_donna_atmost15bytes;
64  }
65 
66 poly1305_donna_16bytes:
67  m += 16;
68  inlen -= 16;
69 
70  t0 = ReadLE32(m - 16);
71  t1 = ReadLE32(m - 12);
72  t2 = ReadLE32(m - 8);
73  t3 = ReadLE32(m - 4);
74 
75  h0 += t0 & 0x3ffffff;
76  h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff;
77  h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff;
78  h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff;
79  h4 += (t3 >> 8) | (1 << 24);
80 
81 poly1305_donna_mul:
82  t[0] = mul32x32_64(h0, r0) + mul32x32_64(h1, s4) + mul32x32_64(h2, s3) +
83  mul32x32_64(h3, s2) + mul32x32_64(h4, s1);
84  t[1] = mul32x32_64(h0, r1) + mul32x32_64(h1, r0) + mul32x32_64(h2, s4) +
85  mul32x32_64(h3, s3) + mul32x32_64(h4, s2);
86  t[2] = mul32x32_64(h0, r2) + mul32x32_64(h1, r1) + mul32x32_64(h2, r0) +
87  mul32x32_64(h3, s4) + mul32x32_64(h4, s3);
88  t[3] = mul32x32_64(h0, r3) + mul32x32_64(h1, r2) + mul32x32_64(h2, r1) +
89  mul32x32_64(h3, r0) + mul32x32_64(h4, s4);
90  t[4] = mul32x32_64(h0, r4) + mul32x32_64(h1, r3) + mul32x32_64(h2, r2) +
91  mul32x32_64(h3, r1) + mul32x32_64(h4, r0);
92 
93  h0 = (uint32_t)t[0] & 0x3ffffff;
94  c = (t[0] >> 26);
95  t[1] += c;
96  h1 = (uint32_t)t[1] & 0x3ffffff;
97  b = (uint32_t)(t[1] >> 26);
98  t[2] += b;
99  h2 = (uint32_t)t[2] & 0x3ffffff;
100  b = (uint32_t)(t[2] >> 26);
101  t[3] += b;
102  h3 = (uint32_t)t[3] & 0x3ffffff;
103  b = (uint32_t)(t[3] >> 26);
104  t[4] += b;
105  h4 = (uint32_t)t[4] & 0x3ffffff;
106  b = (uint32_t)(t[4] >> 26);
107  h0 += b * 5;
108 
109  if (inlen >= 16) {
110  goto poly1305_donna_16bytes;
111  }
112 
113  /* final bytes */
114 poly1305_donna_atmost15bytes:
115  if (!inlen) {
116  goto poly1305_donna_finish;
117  }
118 
119  for (j = 0; j < inlen; j++) {
120  mp[j] = m[j];
121  }
122  mp[j++] = 1;
123  for (; j < 16; j++) {
124  mp[j] = 0;
125  }
126  inlen = 0;
127 
128  t0 = ReadLE32(mp + 0);
129  t1 = ReadLE32(mp + 4);
130  t2 = ReadLE32(mp + 8);
131  t3 = ReadLE32(mp + 12);
132 
133  h0 += t0 & 0x3ffffff;
134  h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff;
135  h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff;
136  h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff;
137  h4 += (t3 >> 8);
138 
139  goto poly1305_donna_mul;
140 
141 poly1305_donna_finish:
142  b = h0 >> 26;
143  h0 = h0 & 0x3ffffff;
144  h1 += b;
145  b = h1 >> 26;
146  h1 = h1 & 0x3ffffff;
147  h2 += b;
148  b = h2 >> 26;
149  h2 = h2 & 0x3ffffff;
150  h3 += b;
151  b = h3 >> 26;
152  h3 = h3 & 0x3ffffff;
153  h4 += b;
154  b = h4 >> 26;
155  h4 = h4 & 0x3ffffff;
156  h0 += b * 5;
157  b = h0 >> 26;
158  h0 = h0 & 0x3ffffff;
159  h1 += b;
160 
161  g0 = h0 + 5;
162  b = g0 >> 26;
163  g0 &= 0x3ffffff;
164  g1 = h1 + b;
165  b = g1 >> 26;
166  g1 &= 0x3ffffff;
167  g2 = h2 + b;
168  b = g2 >> 26;
169  g2 &= 0x3ffffff;
170  g3 = h3 + b;
171  b = g3 >> 26;
172  g3 &= 0x3ffffff;
173  g4 = h4 + b - (1 << 26);
174 
175  b = (g4 >> 31) - 1;
176  nb = ~b;
177  h0 = (h0 & nb) | (g0 & b);
178  h1 = (h1 & nb) | (g1 & b);
179  h2 = (h2 & nb) | (g2 & b);
180  h3 = (h3 & nb) | (g3 & b);
181  h4 = (h4 & nb) | (g4 & b);
182 
183  f0 = ((h0) | (h1 << 26)) + (uint64_t)ReadLE32(&key[16]);
184  f1 = ((h1 >> 6) | (h2 << 20)) + (uint64_t)ReadLE32(&key[20]);
185  f2 = ((h2 >> 12) | (h3 << 14)) + (uint64_t)ReadLE32(&key[24]);
186  f3 = ((h3 >> 18) | (h4 << 8)) + (uint64_t)ReadLE32(&key[28]);
187 
188  WriteLE32(&out[0], f0);
189  f1 += (f0 >> 32);
190  WriteLE32(&out[4], f1);
191  f2 += (f1 >> 32);
192  WriteLE32(&out[8], f2);
193  f3 += (f2 >> 32);
194  WriteLE32(&out[12], f3);
195 }
WriteLE32
static void WriteLE32(uint8_t *ptr, uint32_t x)
Definition: common.h:40
ReadLE32
static uint32_t ReadLE32(const uint8_t *ptr)
Definition: common.h:23
mul32x32_64
#define mul32x32_64(a, b)
Definition: poly1305.cpp:13
poly1305.h
POLY1305_TAGLEN
#define POLY1305_TAGLEN
Definition: poly1305.h:12
common.h
POLY1305_KEYLEN
#define POLY1305_KEYLEN
Definition: poly1305.h:11
poly1305_auth
void poly1305_auth(uint8_t out[POLY1305_TAGLEN], const uint8_t *m, size_t inlen, const uint8_t key[POLY1305_KEYLEN])
Definition: poly1305.cpp:15