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 hidden or 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 hidden or 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