Last active
May 6, 2023 04:34
-
-
Save resilar/6eaeb71fcf0bb3c3e4b55c8fb9bcc1b2 to your computer and use it in GitHub Desktop.
poly1305 implementation in C
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stddef.h> | |
#include <stdint.h> | |
#define LOAD32_LE(p) \ | |
( ((uint32_t)((p)[0]) << 0) \ | |
| ((uint32_t)((p)[1]) << 8) \ | |
| ((uint32_t)((p)[2]) << 16) \ | |
| ((uint32_t)((p)[3]) << 24) \ | |
) | |
#define STORE32_LE(p, v) \ | |
(p)[0] = ((v) >> 0) & 0xFF; \ | |
(p)[1] = ((v) >> 8) & 0xFF; \ | |
(p)[2] = ((v) >> 16) & 0xFF; \ | |
(p)[3] = ((v) >> 24) & 0xFF; | |
void poly1305(const uint8_t *msg, size_t n, | |
const uint8_t key[32], uint8_t tag[16]) | |
{ | |
uint64_t d0, d1, d2, d3, d4; | |
uint32_t h0, h1, h2, h3, h4; | |
uint32_t r0, r1, r2, r3, r4; | |
uint32_t s1, s2, s3, s4; | |
h0 = h1 = h2 = h3 = h4 = 0; | |
r0 = (LOAD32_LE(key + 0) >> 0) & 0x03FFFFFF; | |
r1 = (LOAD32_LE(key + 3) >> 2) & 0x03FFFF03; s1 = r1 * 5; | |
r2 = (LOAD32_LE(key + 6) >> 4) & 0x03FFC0FF; s2 = r2 * 5; | |
r3 = (LOAD32_LE(key + 9) >> 6) & 0x03F03FFF; s3 = r3 * 5; | |
r4 = (LOAD32_LE(key + 12) >> 8) & 0x000FFFFF; s4 = r4 * 5; | |
while (n >= 16) { | |
h4 += 0x01000000; | |
process_block: | |
h0 += (LOAD32_LE(msg + 0) >> 0) & 0x03FFFFFF; | |
h1 += (LOAD32_LE(msg + 3) >> 2) & 0x03FFFFFF; | |
h2 += (LOAD32_LE(msg + 6) >> 4) & 0x03FFFFFF; | |
h3 += (LOAD32_LE(msg + 9) >> 6) & 0x03FFFFFF; | |
h4 += (LOAD32_LE(msg + 12) >> 8); | |
#define MUL(a,b) ((uint64_t)(a) * (b)) | |
d0 = MUL(h0,r0) + MUL(h1,s4) + MUL(h2,s3) + MUL(h3,s2) + MUL(h4,s1); | |
d1 = MUL(h0,r1) + MUL(h1,r0) + MUL(h2,s4) + MUL(h3,s3) + MUL(h4,s2); | |
d2 = MUL(h0,r2) + MUL(h1,r1) + MUL(h2,r0) + MUL(h3,s4) + MUL(h4,s3); | |
d3 = MUL(h0,r3) + MUL(h1,r2) + MUL(h2,r1) + MUL(h3,r0) + MUL(h4,s4); | |
d4 = MUL(h0,r4) + MUL(h1,r3) + MUL(h2,r2) + MUL(h3,r1) + MUL(h4,r0); | |
#undef MUL | |
h0 = d0 & 0x03FFFFFF; d1 += (d0 >> 26); | |
h1 = d1 & 0x03FFFFFF; d2 += (d1 >> 26); | |
h2 = d2 & 0x03FFFFFF; d3 += (d2 >> 26); | |
h3 = d3 & 0x03FFFFFF; d4 += (d3 >> 26); | |
h4 = d4 & 0x03FFFFFF; h0 += (uint32_t)(d4 >> 26) * 5; | |
msg += 16; | |
n -= 16; | |
} | |
if (n) { | |
size_t i; | |
for (i = 0; i < n; tag[i] = msg[i], i++); | |
for (tag[i++] = 1; i < 16; tag[i++] = 0); | |
msg = tag; | |
n = 16; | |
goto process_block; | |
} | |
r0 = (h0 + 5) >> 26; | |
r1 = (h1 + r0) >> 26; | |
r2 = (h2 + r1) >> 26; | |
r3 = (h3 + r2) >> 26; | |
r4 = (h4 + r3) >> 26; | |
h0 += r4 * 5; | |
d1 = (uint64_t)LOAD32_LE(key + 16) + (h0 >> 0) + (h1 << 26); | |
d2 = (uint64_t)LOAD32_LE(key + 20) + (h1 >> 6) + (h2 << 20) + (d1 >> 32); | |
d3 = (uint64_t)LOAD32_LE(key + 24) + (h2 >> 12) + (h3 << 14) + (d2 >> 32); | |
d4 = (uint64_t)LOAD32_LE(key + 28) + (h3 >> 18) + (h4 << 8) + (d3 >> 32); | |
s1 = d1; STORE32_LE(tag + 0, s1); | |
s2 = d2; STORE32_LE(tag + 4, s2); | |
s3 = d3; STORE32_LE(tag + 8, s3); | |
s4 = d4; STORE32_LE(tag + 12, s4); | |
} | |
int poly1305_tagcmp(const uint8_t tag1[16], const uint8_t tag2[16]) | |
{ | |
uint8_t d = 0; | |
d |= tag1[ 0] ^ tag2[ 0]; | |
d |= tag1[ 1] ^ tag2[ 1]; | |
d |= tag1[ 2] ^ tag2[ 2]; | |
d |= tag1[ 3] ^ tag2[ 3]; | |
d |= tag1[ 4] ^ tag2[ 4]; | |
d |= tag1[ 5] ^ tag2[ 5]; | |
d |= tag1[ 6] ^ tag2[ 6]; | |
d |= tag1[ 7] ^ tag2[ 7]; | |
d |= tag1[ 8] ^ tag2[ 8]; | |
d |= tag1[ 9] ^ tag2[ 9]; | |
d |= tag1[10] ^ tag2[10]; | |
d |= tag1[11] ^ tag2[11]; | |
d |= tag1[12] ^ tag2[12]; | |
d |= tag1[13] ^ tag2[13]; | |
d |= tag1[14] ^ tag2[14]; | |
d |= tag1[15] ^ tag2[15]; | |
return (int)d; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* poly1305 unit test harness */ | |
#include <stdint.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
extern void poly1305(const uint8_t *msg, size_t n, | |
const uint8_t key[32], uint8_t tag[16]); | |
struct { const char *key; const char *msg; const char *tag; } tests[] = { | |
{ | |
"0000000000000000000000000000000000000000000000000000000000000000", | |
"", | |
"00000000000000000000000000000000" | |
}, | |
{ | |
"36e5f6b5c5e06070f0efca96227a863e00000000000000000000000000000000", | |
"", | |
"00000000000000000000000000000000" | |
}, | |
{ | |
"0000000000000000000000000000000036e5f6b5c5e06070f0efca96227a863e", | |
"", | |
"36e5f6b5c5e06070f0efca96227a863e" | |
}, | |
{ | |
"79207375626d697373696f6e20746f2036e5f6b5c5e06070f0efca96227a863e", | |
"", | |
"36e5f6b5c5e06070f0efca96227a863e" | |
}, | |
{ | |
"0000000000000000000000000000000000000000000000000000000000000000", | |
"0000000000000000000000000000000000000000000000000000000000000000" | |
"0000000000000000000000000000000000000000000000000000000000000000", | |
"00000000000000000000000000000000" | |
}, | |
{ | |
"0000000000000000000000000000000036e5f6b5c5e06070f0efca96227a863e", | |
"416e79207375626d697373696f6e20746f20746865204945544620696e74656e" | |
"6465642062792074686520436f6e7472696275746f7220666f72207075626c69" | |
"636174696f6e20617320616c6c206f722070617274206f6620616e2049455446" | |
"20496e7465726e65742d4472616674206f722052464320616e6420616e792073" | |
"746174656d656e74206d6164652077697468696e2074686520636f6e74657874" | |
"206f6620616e204945544620616374697669747920697320636f6e7369646572" | |
"656420616e20224945544620436f6e747269627574696f6e222e205375636820" | |
"73746174656d656e747320696e636c756465206f72616c2073746174656d656e" | |
"747320696e20494554462073657373696f6e732c2061732077656c6c20617320" | |
"7772697474656e20616e6420656c656374726f6e696320636f6d6d756e696361" | |
"74696f6e73206d61646520617420616e792074696d65206f7220706c6163652c" | |
"207768696368206172652061646472657373656420746f", | |
"36e5f6b5c5e06070f0efca96227a863e" | |
}, | |
{ | |
"36e5f6b5c5e06070f0efca96227a863e00000000000000000000000000000000", | |
"416e79207375626d697373696f6e20746f20746865204945544620696e74656e" | |
"6465642062792074686520436f6e7472696275746f7220666f72207075626c69" | |
"636174696f6e20617320616c6c206f722070617274206f6620616e2049455446" | |
"20496e7465726e65742d4472616674206f722052464320616e6420616e792073" | |
"746174656d656e74206d6164652077697468696e2074686520636f6e74657874" | |
"206f6620616e204945544620616374697669747920697320636f6e7369646572" | |
"656420616e20224945544620436f6e747269627574696f6e222e205375636820" | |
"73746174656d656e747320696e636c756465206f72616c2073746174656d656e" | |
"747320696e20494554462073657373696f6e732c2061732077656c6c20617320" | |
"7772697474656e20616e6420656c656374726f6e696320636f6d6d756e696361" | |
"74696f6e73206d61646520617420616e792074696d65206f7220706c6163652c" | |
"207768696368206172652061646472657373656420746f", | |
"f3477e7cd95417af89a6b8794c310cf0" | |
}, | |
{ | |
"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0", | |
"2754776173206272696c6c69672c20616e642074686520736c6974687920746f" | |
"7665730a446964206779726520616e642067696d626c6520696e207468652077" | |
"6162653a0a416c6c206d696d737920776572652074686520626f726f676f7665" | |
"732c0a416e6420746865206d6f6d65207261746873206f757467726162652e", | |
"4541669a7eaaee61e708dc7cbcc5eb62" | |
}, | |
{ | |
"0200000000000000000000000000000000000000000000000000000000000000", | |
"ffffffffffffffffffffffffffffffff", | |
"03000000000000000000000000000000" | |
}, | |
{ | |
"0100000000000000000000000000000000000000000000000000000000000000", | |
"fffffffffffffffffffffffffffffffff0ffffffffffffffffffffffffffffff" | |
"11000000000000000000000000000000", | |
"05000000000000000000000000000000" | |
}, | |
{ | |
"0100000000000000000000000000000000000000000000000000000000000000", | |
"fffffffffffffffffffffffffffffffffbfefefefefefefefefefefefefefefe" | |
"01010101010101010101010101010101", | |
"00000000000000000000000000000000" | |
}, | |
{ | |
"0200000000000000000000000000000000000000000000000000000000000000", | |
"fdffffffffffffffffffffffffffffff", | |
"faffffffffffffffffffffffffffffff" | |
}, | |
{ | |
"0100000000000000040000000000000000000000000000000000000000000000", | |
"e33594d7505e43b900000000000000003394d7505e4379cd0100000000000000" | |
"0000000000000000000000000000000001000000000000000000000000000000", | |
"14000000000000005500000000000000" | |
}, | |
{ | |
"0100000000000000040000000000000000000000000000000000000000000000", | |
"e33594d7505e43b900000000000000003394d7505e4379cd0100000000000000" | |
"00000000000000000000000000000000", | |
"13000000000000000000000000000000" | |
}, | |
{ | |
"85d6be7857556d337f4452fe42d506a80103808afb0db2fd4abff6af4149f51b", | |
"43727970746f6772617068696320466f72756d2052657365617263682047726f" | |
"7570", | |
"a8061dc1305136c6c22b8baf0c0127a9" | |
}, | |
{ | |
"48443d0bb0d21109c89a100b5ce2c20883149c69b561dd88298a1798b10716ef", | |
"663cea190ffb83d89593f3f476b6bc24d7e679107ea26adb8caf6652d0656136", | |
"0ee1c16bb73f0f4fd19881753c01cdbe" | |
}, | |
{ | |
"12976a08c4426d0ce8a82407c4f4820780f8c20aa71202d1e29179cbcb555a57", | |
"ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0" | |
"990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9", | |
"5154ad0d2cb26e01274fc51148491f1b" | |
}, | |
{ | |
"12976a08c4426d0ce8a82407c4f4820780f8c20aa71202d1e29179cbcb555a57", | |
"ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0" | |
"990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9af", | |
"812059a5da198637cac7c4a631bee466" | |
}, | |
{ | |
"12976a08c4426d0ce8a82407c4f4820780f8c20aa71202d1e29179cbcb555a57", | |
"ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0" | |
"990c62e48b8018b2c3e4a0fa3134cb67", | |
"5b88d7f6228b11e2e28579a5c0c1f761" | |
}, | |
{ | |
"12976a08c4426d0ce8a82407c4f4820780f8c20aa71202d1e29179cbcb555a57", | |
"ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0" | |
"990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9af" | |
"663cea190ffb83d89593f3f476b6bc24d7e679107ea26adb8caf6652d0656136", | |
"bbb613b2b6d753ba07395b916aaece15" | |
}, | |
{ | |
"12976a08c4426d0ce8a82407c4f4820780f8c20aa71202d1e29179cbcb555a57", | |
"ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0" | |
"990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9af" | |
"48443d0bb0d21109c89a100b5ce2c20883149c69b561dd88298a1798b10716ef" | |
"663cea190ffb83d89593f3f476b6bc24", | |
"c794d7057d1778c4bbee0a39b3d97342" | |
}, | |
{ | |
"12976a08c4426d0ce8a82407c4f4820780f8c20aa71202d1e29179cbcb555a57", | |
"ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0" | |
"990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9af" | |
"48443d0bb0d21109c89a100b5ce2c20883149c69b561dd88298a1798b10716ef" | |
"663cea190ffb83d89593f3f476b6bc24d7e679107ea26adb8caf6652d0656136", | |
"ffbcb9b371423152d7fca5ad042fbaa9" | |
}, | |
{ | |
"12976a08c4426d0ce8a82407c4f4820780f8c20aa71202d1e29179cbcb555a57", | |
"ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0" | |
"990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9af" | |
"48443d0bb0d21109c89a100b5ce2c20883149c69b561dd88298a1798b10716ef" | |
"663cea190ffb83d89593f3f476b6bc24d7e679107ea26adb8caf6652d0656136" | |
"812059a5da198637cac7c4a631bee466", | |
"069ed6b8ef0f207b3e243bb1019fe632" | |
}, | |
{ | |
"12976a08c4426d0ce8a82407c4f4820780f8c20aa71202d1e29179cbcb555a57", | |
"ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0" | |
"990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9af" | |
"48443d0bb0d21109c89a100b5ce2c20883149c69b561dd88298a1798b10716ef" | |
"663cea190ffb83d89593f3f476b6bc24d7e679107ea26adb8caf6652d0656136" | |
"812059a5da198637cac7c4a631bee4665b88d7f6228b11e2e28579a5c0c1f761", | |
"cca339d9a45fa2368c2c68b3a4179133" | |
}, | |
{ | |
"12976a08c4426d0ce8a82407c4f4820780f8c20aa71202d1e29179cbcb555a57", | |
"ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0" | |
"990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9af" | |
"48443d0bb0d21109c89a100b5ce2c20883149c69b561dd88298a1798b10716ef" | |
"663cea190ffb83d89593f3f476b6bc24d7e679107ea26adb8caf6652d0656136" | |
"812059a5da198637cac7c4a631bee4665b88d7f6228b11e2e28579a5c0c1f761" | |
"ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0" | |
"990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9af" | |
"48443d0bb0d21109c89a100b5ce2c20883149c69b561dd88298a1798b10716ef" | |
"663cea190ffb83d89593f3f476b6bc24d7e679107ea26adb8caf6652d0656136", | |
"53f6e828a2f0fe0ee815bf0bd5841a34" | |
}, | |
{ | |
"12976a08c4426d0ce8a82407c4f4820780f8c20aa71202d1e29179cbcb555a57", | |
"ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0" | |
"990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9af" | |
"48443d0bb0d21109c89a100b5ce2c20883149c69b561dd88298a1798b10716ef" | |
"663cea190ffb83d89593f3f476b6bc24d7e679107ea26adb8caf6652d0656136" | |
"812059a5da198637cac7c4a631bee4665b88d7f6228b11e2e28579a5c0c1f761" | |
"ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0" | |
"990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9af" | |
"48443d0bb0d21109c89a100b5ce2c20883149c69b561dd88298a1798b10716ef" | |
"663cea190ffb83d89593f3f476b6bc24d7e679107ea26adb8caf6652d0656136" | |
"812059a5da198637cac7c4a631bee4665b88d7f6228b11e2e28579a5c0c1f761", | |
"b846d44e9bbd53cedffbfbb6b7fa4933" | |
}, | |
{ | |
"ad628107e8351d0f2c231a05dc4a410600000000000000000000000000000000", | |
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" | |
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" | |
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" | |
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" | |
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" | |
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" | |
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" | |
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", | |
"07145a4c02fe5fa32036de68fabe9066" | |
}, | |
{ | |
"95d5c005503e510d8cd0aa072c4a4d066eabc52d11653df47fbf63ab198bcc26", | |
"842364e156336c0998b933a6237726180d9e3fdcbde4cd5d17080fc3beb49614" | |
"d7122c037463ff104d73f19c12704628d417c4c54a3fe30d3c3d7714382d43b0" | |
"382a50a5dee54be844b076e8df88201a1cd43b90eb21643fa96f39b518aa8340" | |
"c942ff3c31baf7c9bdbf0f31ae3fa096bf8c63030609829fe72e179824890bc8" | |
"e08c315c1cce2a83144dbbff09f74e3efc770b54d0984a8f19b14719e6363564" | |
"1d6b1eedf63efbf080e1783d32445412114c20de0b837a0dfa33d6b82825fff4" | |
"4c9a70ea54ce47f07df698e6b03323b53079364a5fc3e9dd034392bdde86dccd" | |
"da94321c5e44060489336cb65bf3989c36f7282c2f5d2b882c171e74", | |
"f248312e578d9d58f8b7bb4d19105431" | |
}, | |
{ | |
"000102030405060708090a0b0c0d0e0f00000000000000000000000000000000", | |
"248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd" | |
"2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e8" | |
"74cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c" | |
"8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936a" | |
"ff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a37" | |
"09894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901f" | |
"de7db79fa1818c11336dbc07244a40eb", | |
"bc939bc5281480fa99c6d68c258ec42f" | |
}, | |
{ | |
"746869732069732033322d62797465206b657920666f7220506f6c7931333035", | |
"48656c6c6f20776f726c6421", | |
"a6f745008f81c916a20dcc74eef2b2f0" | |
}, | |
{ | |
"746869732069732033322d62797465206b657920666f7220506f6c7931333035", | |
"0000000000000000000000000000000000000000000000000000000000000000", | |
"49ec78090e481ec6c26b33b91ccc0307" | |
}, | |
{ | |
"2d773be37adb1e4d683bf0075e79c4ee037918535a7f99ccb7040fb5f5f43aea", | |
"89dab80b7717c1db5db437860a3f70218e93e1b8f461fb677f16f35f6f87e2a9" | |
"1c99bc3a47ace47640cc95c345be5ecca5a3523c35cc01893af0b64a62033427" | |
"0372ec12482d1b1e363561698a578b359803495bb4e2ef1930b17a5190b580f1" | |
"41300df30adbeca28f6427a8bc1a999fd51c554a017d095d8c3e3127daf9f595", | |
"c85d15ed44c378d6b00e23064c7bcd51" | |
}, | |
{ | |
"99e5822dd4173c995e3dae0ddefb97743fde3b080134b39f76e9bf8d0e88d546", | |
"000000000000000b170303020000000006db1f1f368d696a810a349c0c714c9a" | |
"5e7850c2407d721acded95e018d7a85266a6e1289cdb4aeb18da5ac8a2b0026d" | |
"24a59ad485227f3eaedbb2e7e35e1c66cd60f9abf716dcc9ac42682dd7dab287" | |
"a7024c4eefc321cc0574e16793e37cec03c5bda42b54c114a80b57af26416c7b" | |
"e742005e20855c73e21dc8e2edc9d435cb6f6059280011c270b71570051c1c9b" | |
"3052126620bc1e2730fa066c7a509d53c60e5ae1b40aa6e39e49669228c90eec" | |
"b4a50db32a50bc49e90b4f4b359a1dfd11749cd3867fcf2fb7bb6cd4738f6a4a" | |
"d6f7ca5058f7618845af9f020f6c3b967b8f4cd4a91e2813b507ae66f2d35c18" | |
"284f7292186062e10fd5510d18775351ef334e7634ab4743f5b68f49adcab384" | |
"d3fd75f7390f4006ef2a295c8c7a076ad54546cd25d2107fbe1436c840924aae" | |
"be5b370893cd63d1325b8616fc4810886bc152c53221b6df373119393255ee72" | |
"bcaa880174f1717f9184fa91646f17a24ac55d16bfddca9581a92eda479201f0" | |
"edbf633600d6066d1ab36d5d2415d71351bbcd608a25108d25641992c1f26c53" | |
"1cf9f90203bc4cc19f5927d834b0a47116d3884bbb164b8ec883d1ac832e56b3" | |
"918a98601a08d171881541d594db399c6ae6151221745aec814c45b0b05b5654" | |
"36fd6f137aa10a0c0b643761dbd6f9a9dcb99b1a6e690854ce0769cde39761d8" | |
"2fcdec15f0d92d7d8e94ade8eb83fbe0", | |
"2637408fe13086ea73f971e3425e2820" | |
}, | |
{ | |
"7f1b02640000000000000000000000000000000000000000cccccccccccccccc", | |
"cccccccccccccccccccccccccccccccccccccccccccccccccc80cccccccccccc" | |
"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccecccccc" | |
"ccccccccccccccccccccccccccccccc5cccccccccccccccccccccccccccccccc" | |
"cccccccccce3cccccccccccccccccccccccccccccccccccccccccccccccccccc" | |
"ccccccccaccccccccccccccccccccce6cccccccccc000000afcccccccccccccc" | |
"ccccfffffff50000000000000000000000000000000000000000000000000000" | |
"00ffffffe7000000000000000000000000000000000000000000000000000000" | |
"0000000000000000000000000000000000000000000000000000719205a8521d" | |
"fc", | |
"8559b876eceed66eb37798c0457baff9" | |
}, | |
{ | |
"e00016000000000000000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaaaa", | |
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0000000000" | |
"00000000800264", | |
"00bd1258978e205444c9aaaa82006fed" | |
}, | |
{ | |
"0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c", | |
"02fc", | |
"06120c0c0c0c0c0c0c0c0c0c0c0c0c0c" | |
}, | |
{ | |
"00ff000000000000000000000000000000000000001e00000000000000007b7b", | |
"7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b" | |
"7b7b7b7b7b7b7a7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b" | |
"7b7b5c7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b" | |
"7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b6e7b007b7b7b7b7b7b7b7b7b" | |
"7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7a7b7b7b7b7b7b7b7b7b7b7b7b" | |
"7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b5c7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b" | |
"7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b" | |
"7b6e7b001300000000b300000000000000000000000000000000000000000000" | |
"f20000000000000000000000000000000000002000efff000900000000000000" | |
"0000000000100000000009000000640000000000000000000000001300000000" | |
"b300000000000000000000000000000000000000000000f20000000000000000" | |
"000000000000000000002000efff00090000000000000000007a000010000000" | |
"000900000064000000000000000000000000000000000000000000000000fc", | |
"33205bbf9e9f8f7212ab9e2ab9b7e4a5" | |
}, | |
{ | |
"0000007f0000007f01000020000000000000cf77777777777777777777777777", | |
"7777777777777777777777777777777777777777777777777777777777777777" | |
"7777777777777777777777777777777777777777777777777777777777777777" | |
"777777777777777777777777ffffffe9e9acacacacacacacacacacac0000acac" | |
"ec0100acacac2caca2acacacacacacacacacacac64f2", | |
"02ee7c8c546ddeb1a467e4c3981158b9" | |
}, | |
{ | |
"eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880", | |
"8e993b9f48681273c29650ba32fc76ce48332ea7164d96a4476fb8c531a1186a" | |
"c0dfc17c98dce87b4da7f011ec48c97271d2c20f9b928fe2270d6fb863d51738" | |
"b48eeee314a7cc8ab932164548e526ae90224368517acfeabd6bb3732bc0e9da" | |
"99832b61ca01b6de56244a9e88d5f9b37973f622a43d14a6599b1f654cb45a74" | |
"e355a5", | |
"f3ffc7703f9400e52a7dfb4b3d3305d9" | |
}, | |
/* custom tests for interesting edge cases */ | |
{ | |
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", | |
"ffffffffffffffffffffffffffffffff", | |
"fbffff17faffff17faffff17faffff17" | |
}, | |
{ | |
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", | |
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" | |
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", | |
"900fe32bc15fa8d7bca8efe4c7e37eb1" | |
}, | |
{ | |
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", | |
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" | |
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" | |
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" | |
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", | |
"f8aaa2240c6c4b3a9de57476ea806eb4" | |
}, | |
{ | |
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", | |
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" | |
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" | |
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" | |
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" | |
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" | |
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" | |
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" | |
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", | |
"c30c8c6a3af35fc6645a7e3a51df3f04" | |
}, | |
{ | |
"1111111111111111111111111111111122222222222222222222222222222222", | |
"00000000000000000000000000000000", | |
"76777723767777237677772376777723" | |
}, | |
{ | |
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", | |
"811000fcffffffffffffffffffffffffffffffffffffffffffffffffffffffff" | |
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" | |
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" | |
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", | |
"9438472b0afb6a59fff6685d07b47057" | |
} | |
}; | |
int decode_xdigit(char xdigit) | |
{ | |
if ('0' <= xdigit && xdigit <= '9') { | |
xdigit -= '0'; | |
} else if ('A' <= xdigit && xdigit <= 'F') { | |
xdigit -= 'A'; | |
xdigit += 10; | |
} else if ('a' <= xdigit && xdigit <= 'f') { | |
xdigit -= 'a'; | |
xdigit += 10; | |
} else { | |
fprintf(stderr, "bad xdigit: %c\n", xdigit); | |
abort(); | |
} | |
return xdigit; | |
} | |
size_t decode_hex(const unsigned char *in, void *out) | |
{ | |
size_t len = 0; | |
for (len = 0; in[2*len] && in[2*len+1]; len++) { | |
int hi = decode_xdigit(in[2*len]); | |
int lo = decode_xdigit(in[2*len + 1]); | |
if (out) ((unsigned char *)out)[len] = (hi << 4) + lo; | |
} | |
if (in[2*len]) { | |
fprintf(stderr, "odd length hex input string: %s\n", in); | |
abort(); | |
} | |
return len; | |
} | |
size_t encode_hex(const void *in, size_t len, unsigned char *out) | |
{ | |
static const char pool[16] = { | |
'0', '1', '2', '3', '4', '5', '6', '7', | |
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' | |
}; | |
size_t i; | |
if (!len) len = strlen((char *)in); | |
for (i = 0; i < len; i++) { | |
*out++ = pool[(((unsigned char *)in)[i] >> 4) & 0x0F]; | |
*out++ = pool[((unsigned char *)in)[i] & 0x0F]; | |
} | |
return i; | |
} | |
void self_tests() | |
{ | |
size_t i; | |
unsigned char key[32], msg[4096 * 10], tag[16]; | |
for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { | |
size_t len; | |
unsigned char out[16]; | |
unsigned char hex[32]; | |
fprintf(stdout, "TEST %02u: ", (unsigned int)i); | |
fflush(stdout); | |
len = decode_hex((unsigned char *)tests[i].msg, msg); | |
if (len > sizeof(msg)) { | |
fprintf(stderr, "message length %lu exceeds limit %lu\n", | |
(unsigned long)len, (unsigned long)sizeof(msg)); | |
abort(); | |
} | |
decode_hex((unsigned char *)tests[i].key, key); | |
decode_hex((unsigned char *)tests[i].tag, tag); | |
poly1305((uint8_t *)msg, len, (uint8_t *)key, (uint8_t *)out); | |
encode_hex(out, 16, hex); | |
fprintf(stdout, "%.32s", hex); | |
fprintf(stdout, " %s\n", !memcmp(tag, out, 16) ? "OK" : "FAIL"); | |
fflush(stdout); | |
} | |
} | |
static unsigned char *read_input_message(FILE *in, size_t *length) | |
{ | |
void *buf; | |
unsigned char *msg; | |
size_t capacity, *size, tmp; | |
/* Read using a dynamic buffer (to support non-seekable streams) */ | |
if (!(buf = malloc((capacity = 1024)))) | |
return NULL; | |
msg = (unsigned char *)buf; | |
*(size = length ? length : &tmp) = 0; | |
while (!feof(in)) { | |
if (*size == capacity) { | |
buf = realloc(buf, (capacity = capacity*2)); | |
if (!buf) goto fail; | |
msg = (unsigned char *)buf; | |
} | |
*size += fread(&msg[*size], sizeof(unsigned char), capacity-*size, in); | |
if (ferror(in)) | |
goto fail; | |
} | |
/* Truncate */ | |
if (0 < *size && *size < capacity && (buf = realloc(buf, *size))) | |
msg = (unsigned char *)buf; | |
return msg; | |
fail: | |
free((void *)msg); | |
return NULL; | |
} | |
int main(int argc, char *argv[]) | |
{ | |
char *end; | |
long reps = 1; | |
if (argc != 2 && argc != 3) { | |
self_tests(); | |
} else if (argc == 2 || ((reps = strtol(argv[2], &end, 0)) > 0 && !*end)) { | |
size_t len; | |
unsigned char *key; | |
unsigned char *msg; | |
unsigned char *input; | |
unsigned char tag[16]; | |
unsigned char hex[64]; | |
if (!strcmp(argv[1], "-")) { | |
input = read_input_message(stdin, &len); | |
} else { | |
FILE *in; | |
if (!(in = fopen(argv[1], "rb"))) { | |
fprintf(stderr, "opening '%s' for read failed\n", argv[1]); | |
return 1; | |
} | |
input = read_input_message(in, &len); | |
fclose(in); | |
} | |
if (input == NULL) { | |
fprintf(stderr, "reading file '%s' failed\n", argv[1]); | |
return 2; | |
} | |
if (len < 32) { | |
free(input); | |
fprintf(stderr, "file '%s' shorter than 32 key bytes\n", argv[1]); | |
return 2; | |
} | |
key = input; | |
msg = input + 32; | |
encode_hex(key, 32, hex); | |
fprintf(stderr, "Poly1305(%s, len=%lu, key=%.64s, reps=%ld)\n", | |
argv[1], (unsigned long)(len - 32), hex, reps); | |
fflush(stderr); | |
do { | |
poly1305((uint8_t *)msg, len - 32, (uint8_t *)key, (uint8_t *)tag); | |
} while (--reps > 0); | |
encode_hex(tag, 16, hex); | |
printf("%.32s\n", hex); | |
fflush(stdout); | |
free(input); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment