commit 83d9fd50f6f583181c0b413d6fbf4b85060cd063
parent c3925a275220036818d7ccf58c3e054473445a06
Author: erai <erai@omiltem.net>
Date: Wed, 8 May 2024 21:59:35 -0400
Add poly1305
Diffstat:
A | poly1305.c | | | 236 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | poly1305_test.c | | | 55 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
2 files changed, 291 insertions(+), 0 deletions(-)
diff --git a/poly1305.c b/poly1305.c
@@ -0,0 +1,236 @@
+// https://www.rfc-editor.org/rfc/rfc7539
+
+struct _poly1305_ctx {
+ a0: int;
+ a1: int;
+ a2: int;
+ a3: int;
+ a4: int;
+ a5: int;
+ a6: int;
+ a7: int;
+ a8: int;
+ a9: int;
+}
+
+poly1305_reduce(a: *int) {
+ var c: int;
+ var k: int;
+
+ c = (a[0] + 5) >> 32;
+ c = (c + a[1]) >> 32;
+ c = (c + a[2]) >> 32;
+ c = (c + a[3]) >> 32;
+ c = (c + a[4] + (~3 & (-1 >> 32))) >> 32;
+
+ k = -c >> 32;
+
+ c = c + a[0] + (4 & k); a[0] = c & (-1 >> 32); c = c >> 32;
+ c = c + a[1]; a[1] = c & (-1 >> 32); c = c >> 32;
+ c = c + a[2]; a[2] = c & (-1 >> 32); c = c >> 32;
+ c = c + a[3]; a[3] = c & (-1 >> 32); c = c >> 32;
+ c = c + a[4] + (~3 & k); a[4] = c & (-1 >> 32); c = c >> 32;
+}
+
+poly1305_load(dest: *int, src: *byte, n: int) {
+ var i: int;
+ i = 0;
+ loop {
+ if i == n {
+ break;
+ }
+ dest[i] = src[i * 4]:int
+ | (src[i * 4 + 1]:int << 8)
+ | (src[i * 4 + 2]:int << 16)
+ | (src[i * 4 + 3]:int << 24);
+ i = i + 1;
+ }
+}
+
+poly1305_digest(dest: *byte, src: *int) {
+ poly1305_reduce(src);
+ dest[0] = src[0]:byte;
+ dest[1] = (src[0] >> 8):byte;
+ dest[2] = (src[0] >> 16):byte;
+ dest[3] = (src[0] >> 24):byte;
+ dest[4] = src[1]:byte;
+ dest[5] = (src[1] >> 8):byte;
+ dest[6] = (src[1] >> 16):byte;
+ dest[7] = (src[1] >> 24):byte;
+ dest[8] = src[2]:byte;
+ dest[9] = (src[2] >> 8):byte;
+ dest[10] = (src[2] >> 16):byte;
+ dest[11] = (src[2] >> 24):byte;
+ dest[12] = src[3]:byte;
+ dest[13] = (src[3] >> 8):byte;
+ dest[14] = (src[3] >> 16):byte;
+ dest[15] = (src[3] >> 24):byte;
+}
+
+poly1305_add(a: *int, x: *int) {
+ var c: int;
+ c = x[0] + a[0]; a[0] = c & (-1 >> 32); c = c >> 32;
+ c = c + x[1] + a[1]; a[1] = c & (-1 >> 32); c = c >> 32;
+ c = c + x[2] + a[2]; a[2] = c & (-1 >> 32); c = c >> 32;
+ c = c + x[3] + a[3]; a[3] = c & (-1 >> 32); c = c >> 32;
+ c = c + x[4] + a[4]; a[4] = c & (-1 >> 32);
+}
+
+poly1305_mul(a: *int, r: *int) {
+ var _x: _poly1305_ctx;
+ var x: *int;
+ var i: int;
+ var c: int;
+
+ x = (&_x):*int;
+
+ x[0] = 0;
+ x[1] = 0;
+ x[2] = 0;
+ x[3] = 0;
+ x[4] = 0;
+ x[5] = 0;
+ x[6] = 0;
+ x[7] = 0;
+ x[8] = 0;
+ x[9] = 0;
+
+ // Schoolbook Multiplication
+ c = a[0] * r[0] + x[0]; x[0] = c & (-1 >> 32); c = c >> 32;
+ c = c + a[0] * r[1] + x[1]; x[1] = c & (-1 >> 32); c = c >> 32;
+ c = c + a[0] * r[2] + x[2]; x[2] = c & (-1 >> 32); c = c >> 32;
+ c = c + a[0] * r[3] + x[3]; x[3] = c & (-1 >> 32); c = c >> 32;
+ c = c + a[0] * r[4] + x[4]; x[4] = c & (-1 >> 32); c = c >> 32;
+ x[5] = (c + x[5]) & (-1 >> 32);
+
+ c = a[1] * r[0] + x[1]; x[1] = c & (-1 >> 32); c = c >> 32;
+ c = c + a[1] * r[1] + x[2]; x[2] = c & (-1 >> 32); c = c >> 32;
+ c = c + a[1] * r[2] + x[3]; x[3] = c & (-1 >> 32); c = c >> 32;
+ c = c + a[1] * r[3] + x[4]; x[4] = c & (-1 >> 32); c = c >> 32;
+ c = c + a[1] * r[4] + x[5]; x[5] = c & (-1 >> 32); c = c >> 32;
+ x[6] = (c + x[6]) & (-1 >> 32);
+
+ c = a[2] * r[0] + x[2]; x[2] = c & (-1 >> 32); c = c >> 32;
+ c = c + a[2] * r[1] + x[3]; x[3] = c & (-1 >> 32); c = c >> 32;
+ c = c + a[2] * r[2] + x[4]; x[4] = c & (-1 >> 32); c = c >> 32;
+ c = c + a[2] * r[3] + x[5]; x[5] = c & (-1 >> 32); c = c >> 32;
+ c = c + a[2] * r[4] + x[6]; x[6] = c & (-1 >> 32); c = c >> 32;
+ x[7] = (c + x[7]) & (-1 >> 32);
+
+ c = a[3] * r[0] + x[3]; x[3] = c & (-1 >> 32); c = c >> 32;
+ c = c + a[3] * r[1] + x[4]; x[4] = c & (-1 >> 32); c = c >> 32;
+ c = c + a[3] * r[2] + x[5]; x[5] = c & (-1 >> 32); c = c >> 32;
+ c = c + a[3] * r[3] + x[6]; x[6] = c & (-1 >> 32); c = c >> 32;
+ c = c + a[3] * r[4] + x[7]; x[7] = c & (-1 >> 32); c = c >> 32;
+ x[8] = (c + x[8]) & (-1 >> 32);
+
+ c = a[4] * r[0] + x[4]; x[4] = c & (-1 >> 32); c = c >> 32;
+ c = c + a[4] * r[1] + x[5]; x[5] = c & (-1 >> 32); c = c >> 32;
+ c = c + a[4] * r[2] + x[6]; x[6] = c & (-1 >> 32); c = c >> 32;
+ c = c + a[4] * r[3] + x[7]; x[7] = c & (-1 >> 32); c = c >> 32;
+ c = c + a[4] * r[4] + x[8]; x[8] = c & (-1 >> 32); c = c >> 32;
+ x[9] = (c + x[9]) & (-1 >> 32);
+
+ a[0] = x[0];
+ a[1] = x[1];
+ a[2] = x[2];
+ a[3] = x[3];
+ a[4] = x[4] & 3;
+
+ // Modular reduction
+ c = (x[4] >> 2) * 5 + ((x[5] & 3) << 30) * 5 + a[0]; a[0] = c & (-1 >> 32); c = c >> 32;
+ c = c + (x[5] >> 2) * 5 + ((x[6] & 3) << 30) * 5 + a[1]; a[1] = c & (-1 >> 32); c = c >> 32;
+ c = c + (x[6] >> 2) * 5 + ((x[7] & 3) << 30) * 5 + a[2]; a[2] = c & (-1 >> 32); c = c >> 32;
+ c = c + (x[7] >> 2) * 5 + ((x[8] & 3) << 30) * 5 + a[3]; a[3] = c & (-1 >> 32); c = c >> 32;
+ c = c + (x[8] >> 2) * 5 + ((x[9] & 3) << 30) * 5 + a[4]; a[4] = c & (-1 >> 32); c = c >> 32;
+}
+
+poly1305_truncate(dest: *int, key: *byte) {
+ poly1305_load(dest, key, 4);
+
+ dest[0] = dest[0] & ((0x0fff << 16) | 0xffff);
+ dest[1] = dest[1] & ((0x0fff << 16) | 0xfffc);
+ dest[2] = dest[2] & ((0x0fff << 16) | 0xfffc);
+ dest[3] = dest[3] & ((0x0fff << 16) | 0xfffc);
+ dest[4] = 0;
+}
+
+poly1305_pad(dest: *int, msg: *byte, n: int) {
+ var _pad: _poly1305_ctx;
+ var pad: *byte;
+ var i: int;
+
+ pad = (&_pad):*byte;
+
+ i = 0;
+ loop {
+ if i == n {
+ break;
+ }
+
+ pad[i] = msg[i];
+
+ i = i + 1;
+ }
+
+ pad[i] = 1:byte;
+ i = i + 1;
+
+ loop {
+ if i == 20 {
+ break;
+ }
+
+ pad[i] = 0:byte;
+
+ i = i + 1;
+ }
+
+ poly1305_load(dest, pad, 5);
+}
+
+poly1305(mac: *byte, key: *byte, msg: *byte, len: int) {
+ var _a: _poly1305_ctx;
+ var a: *int;
+ var _r: _poly1305_ctx;
+ var r: *int;
+ var _s: _poly1305_ctx;
+ var s: *int;
+ var i: int;
+
+ a = (&_a):*int;
+ r = (&_r):*int;
+ s = (&_s):*int;
+
+ a[0] = 0;
+ a[1] = 0;
+ a[2] = 0;
+ a[3] = 0;
+ a[4] = 0;
+
+ poly1305_truncate(r, key);
+
+ i = 0;
+ loop {
+ if i >= len {
+ break;
+ }
+
+ if (len - i >= 16) {
+ poly1305_pad(s, &msg[i], 16);
+ } else {
+ poly1305_pad(s, &msg[i], len - i);
+ }
+
+ poly1305_add(a, s);
+
+ poly1305_mul(a, r);
+
+ i = i + 16;
+ }
+
+ poly1305_load(s, &key[16], 4);
+ poly1305_add(a, s);
+
+ poly1305_digest(mac, a);
+}
diff --git a/poly1305_test.c b/poly1305_test.c
@@ -0,0 +1,55 @@
+main(c: int, v: **byte, e: **byte) {
+ var _key: _poly1305_ctx;
+ var _text: _poly1305_ctx;
+ var _mac: _poly1305_ctx;
+ var key: *byte;
+ var text: *byte;
+ var mac: *byte;
+
+ key = (&_key):*byte;
+ text = (&_text):*byte;
+ mac = (&_mac):*byte;
+
+ bzero(key, 32);
+ bzero(text, 64);
+ bzero(mac, 32);
+
+ poly1305(mac, key, text, 64);
+ fdxxd(1, mac, 16);
+
+ key[0] = 0x85:byte;
+ key[1] = 0xd6:byte;
+ key[2] = 0xbe:byte;
+ key[3] = 0x78:byte;
+ key[4] = 0x57:byte;
+ key[5] = 0x55:byte;
+ key[6] = 0x6d:byte;
+ key[7] = 0x33:byte;
+ key[8] = 0x7f:byte;
+ key[9] = 0x44:byte;
+ key[10] = 0x52:byte;
+ key[11] = 0xfe:byte;
+ key[12] = 0x42:byte;
+ key[13] = 0xd5:byte;
+ key[14] = 0x06:byte;
+ key[15] = 0xa8:byte;
+ key[16] = 0x01:byte;
+ key[17] = 0x03:byte;
+ key[18] = 0x80:byte;
+ key[19] = 0x8a:byte;
+ key[20] = 0xfb:byte;
+ key[21] = 0x0d:byte;
+ key[22] = 0xb2:byte;
+ key[23] = 0xfd:byte;
+ key[24] = 0x4a:byte;
+ key[25] = 0xbf:byte;
+ key[26] = 0xf6:byte;
+ key[27] = 0xaf:byte;
+ key[28] = 0x41:byte;
+ key[29] = 0x49:byte;
+ key[30] = 0xf5:byte;
+ key[31] = 0x1b:byte;
+
+ poly1305(mac, key, "Cryptographic Forum Research Group", 34);
+ fdxxd(1, mac, 16);
+}