39void poly_block(uint32_t h[5],
const uint32_t r[5],
const uint32_t sr[5],
const uint8_t blk[16], uint32_t hibit)
42 h[0] += t0 & 0x3ffffff;
43 h[1] += ((t0 >> 26) | (t1 << 6)) & 0x3ffffff;
44 h[2] += ((t1 >> 20) | (t2 << 12)) & 0x3ffffff;
45 h[3] += ((t2 >> 14) | (t3 << 18)) & 0x3ffffff;
46 h[4] += (t3 >> 8) | hibit;
48 uint64_t d0 = (uint64_t)h[0] * r[0] + (uint64_t)h[1] * sr[4] + (uint64_t)h[2] * sr[3] + (uint64_t)h[3] * sr[2] +
49 (uint64_t)h[4] * sr[1];
50 uint64_t d1 = (uint64_t)h[0] * r[1] + (uint64_t)h[1] * r[0] + (uint64_t)h[2] * sr[4] + (uint64_t)h[3] * sr[3] +
51 (uint64_t)h[4] * sr[2];
52 uint64_t d2 = (uint64_t)h[0] * r[2] + (uint64_t)h[1] * r[1] + (uint64_t)h[2] * r[0] + (uint64_t)h[3] * sr[4] +
53 (uint64_t)h[4] * sr[3];
54 uint64_t d3 = (uint64_t)h[0] * r[3] + (uint64_t)h[1] * r[2] + (uint64_t)h[2] * r[1] + (uint64_t)h[3] * r[0] +
55 (uint64_t)h[4] * sr[4];
56 uint64_t d4 = (uint64_t)h[0] * r[4] + (uint64_t)h[1] * r[3] + (uint64_t)h[2] * r[2] + (uint64_t)h[3] * r[1] +
57 (uint64_t)h[4] * r[0];
60 c = (uint32_t)(d0 >> 26);
61 h[0] = (uint32_t)d0 & 0x3ffffff;
63 c = (uint32_t)(d1 >> 26);
64 h[1] = (uint32_t)d1 & 0x3ffffff;
66 c = (uint32_t)(d2 >> 26);
67 h[2] = (uint32_t)d2 & 0x3ffffff;
69 c = (uint32_t)(d3 >> 26);
70 h[3] = (uint32_t)d3 & 0x3ffffff;
72 c = (uint32_t)(d4 >> 26);
73 h[4] = (uint32_t)d4 & 0x3ffffff;
84 uint32_t t0 = rd_le32(key + 0), t1 = rd_le32(key + 4), t2 = rd_le32(key + 8), t3 = rd_le32(key + 12);
87 r[0] = t0 & 0x3ffffff;
88 r[1] = ((t0 >> 26) | (t1 << 6)) & 0x3ffff03;
89 r[2] = ((t1 >> 20) | (t2 << 12)) & 0x3ffc0ff;
90 r[3] = ((t2 >> 14) | (t3 << 18)) & 0x3f03fff;
91 r[4] = (t3 >> 8) & 0x00fffff;
92 uint32_t sr[5] = {0, r[1] * 5, r[2] * 5, r[3] * 5, r[4] * 5};
93 uint32_t h[5] = {0, 0, 0, 0, 0};
97 poly_block(h, r, sr, msg, 1u << 24);
103 uint8_t buf[16] = {0};
104 for (
size_t i = 0; i < len; i++)
107 poly_block(h, r, sr, buf, 0);
129 uint32_t g0 = h[0] + 5;
132 uint32_t g1 = h[1] + c;
135 uint32_t g2 = h[2] + c;
138 uint32_t g3 = h[3] + c;
141 uint32_t g4 = h[4] + c - (1u << 26);
144 uint32_t mask = (g4 >> 31) - 1;
151 h[0] = (h[0] & mask) | g0;
152 h[1] = (h[1] & mask) | g1;
153 h[2] = (h[2] & mask) | g2;
154 h[3] = (h[3] & mask) | g3;
155 h[4] = (h[4] & mask) | g4;
158 uint32_t f0 = (h[0]) | (h[1] << 26);
159 uint32_t f1 = (h[1] >> 6) | (h[2] << 20);
160 uint32_t f2 = (h[2] >> 12) | (h[3] << 14);
161 uint32_t f3 = (h[3] >> 18) | (h[4] << 8);
164 uint64_t f = (uint64_t)f0 + rd_le32(key + 16);
166 f = (uint64_t)f1 + rd_le32(key + 20) + (f >> 32);
168 f = (uint64_t)f2 + rd_le32(key + 24) + (f >> 32);
170 f = (uint64_t)f3 + rd_le32(key + 28) + (f >> 32);
173 wr_le32(tag + 0, f0);
174 wr_le32(tag + 4, f1);
175 wr_le32(tag + 8, f2);
176 wr_le32(tag + 12, f3);
void ssh_poly1305(uint8_t tag[SSH_POLY1305_TAG_LEN], const uint8_t *msg, size_t len, const uint8_t key[SSH_POLY1305_KEY_LEN])
Compute the 16-byte Poly1305 tag over msg under the 32-byte one-time key.