poly1305.om (5735B)
1 // https://www.rfc-editor.org/rfc/rfc7539 2 3 struct _poly1305_ctx { 4 a0: int; 5 a1: int; 6 a2: int; 7 a3: int; 8 a4: int; 9 a5: int; 10 a6: int; 11 a7: int; 12 a8: int; 13 a9: int; 14 } 15 16 func poly1305_reduce(a: *int) { 17 var c: int; 18 var k: int; 19 20 c = (a[0] + 5) >> 32; 21 c = (c + a[1]) >> 32; 22 c = (c + a[2]) >> 32; 23 c = (c + a[3]) >> 32; 24 c = (c + a[4] + (-4 & (-1 >> 32))) >> 32; 25 26 k = -c >> 32; 27 28 c = c + a[0] + (4 & k); a[0] = c & (-1 >> 32); c = c >> 32; 29 c = c + a[1]; a[1] = c & (-1 >> 32); c = c >> 32; 30 c = c + a[2]; a[2] = c & (-1 >> 32); c = c >> 32; 31 c = c + a[3]; a[3] = c & (-1 >> 32); c = c >> 32; 32 c = c + a[4] + (-4 & (-1 >> 32) & k); a[4] = c & (-1 >> 32); c = c >> 32; 33 } 34 35 func poly1305_load(dest: *int, src: *byte, n: int) { 36 var i: int; 37 i = 0; 38 loop { 39 if i == n { 40 break; 41 } 42 dest[i] = src[i * 4] as int 43 | (src[i * 4 + 1] as int << 8) 44 | (src[i * 4 + 2] as int << 16) 45 | (src[i * 4 + 3] as int << 24); 46 i = i + 1; 47 } 48 } 49 50 func poly1305_digest(dest: *byte, src: *int) { 51 dest[0] = src[0] as byte; 52 dest[1] = (src[0] >> 8) as byte; 53 dest[2] = (src[0] >> 16) as byte; 54 dest[3] = (src[0] >> 24) as byte; 55 dest[4] = src[1] as byte; 56 dest[5] = (src[1] >> 8) as byte; 57 dest[6] = (src[1] >> 16) as byte; 58 dest[7] = (src[1] >> 24) as byte; 59 dest[8] = src[2] as byte; 60 dest[9] = (src[2] >> 8) as byte; 61 dest[10] = (src[2] >> 16) as byte; 62 dest[11] = (src[2] >> 24) as byte; 63 dest[12] = src[3] as byte; 64 dest[13] = (src[3] >> 8) as byte; 65 dest[14] = (src[3] >> 16) as byte; 66 dest[15] = (src[3] >> 24) as byte; 67 } 68 69 func poly1305_add(a: *int, x: *int) { 70 var c: int; 71 c = x[0] + a[0]; a[0] = c & (-1 >> 32); c = c >> 32; 72 c = c + x[1] + a[1]; a[1] = c & (-1 >> 32); c = c >> 32; 73 c = c + x[2] + a[2]; a[2] = c & (-1 >> 32); c = c >> 32; 74 c = c + x[3] + a[3]; a[3] = c & (-1 >> 32); c = c >> 32; 75 c = c + x[4] + a[4]; a[4] = c & (-1 >> 32); 76 } 77 78 func poly1305_mul(a: *int, r: *int) { 79 var _x: _poly1305_ctx; 80 var x: *int; 81 var i: int; 82 var c: int; 83 84 x = (&_x) as *int; 85 86 x[0] = 0; 87 x[1] = 0; 88 x[2] = 0; 89 x[3] = 0; 90 x[4] = 0; 91 x[5] = 0; 92 x[6] = 0; 93 x[7] = 0; 94 x[8] = 0; 95 x[9] = 0; 96 97 // Schoolbook Multiplication 98 c = a[0] * r[0] + x[0]; x[0] = c & (-1 >> 32); c = c >> 32; 99 c = c + a[0] * r[1] + x[1]; x[1] = c & (-1 >> 32); c = c >> 32; 100 c = c + a[0] * r[2] + x[2]; x[2] = c & (-1 >> 32); c = c >> 32; 101 c = c + a[0] * r[3] + x[3]; x[3] = c & (-1 >> 32); c = c >> 32; 102 c = c + a[0] * r[4] + x[4]; x[4] = c & (-1 >> 32); c = c >> 32; 103 x[5] = (c + x[5]) & (-1 >> 32); 104 105 c = a[1] * r[0] + x[1]; x[1] = c & (-1 >> 32); c = c >> 32; 106 c = c + a[1] * r[1] + x[2]; x[2] = c & (-1 >> 32); c = c >> 32; 107 c = c + a[1] * r[2] + x[3]; x[3] = c & (-1 >> 32); c = c >> 32; 108 c = c + a[1] * r[3] + x[4]; x[4] = c & (-1 >> 32); c = c >> 32; 109 c = c + a[1] * r[4] + x[5]; x[5] = c & (-1 >> 32); c = c >> 32; 110 x[6] = (c + x[6]) & (-1 >> 32); 111 112 c = a[2] * r[0] + x[2]; x[2] = c & (-1 >> 32); c = c >> 32; 113 c = c + a[2] * r[1] + x[3]; x[3] = c & (-1 >> 32); c = c >> 32; 114 c = c + a[2] * r[2] + x[4]; x[4] = c & (-1 >> 32); c = c >> 32; 115 c = c + a[2] * r[3] + x[5]; x[5] = c & (-1 >> 32); c = c >> 32; 116 c = c + a[2] * r[4] + x[6]; x[6] = c & (-1 >> 32); c = c >> 32; 117 x[7] = (c + x[7]) & (-1 >> 32); 118 119 c = a[3] * r[0] + x[3]; x[3] = c & (-1 >> 32); c = c >> 32; 120 c = c + a[3] * r[1] + x[4]; x[4] = c & (-1 >> 32); c = c >> 32; 121 c = c + a[3] * r[2] + x[5]; x[5] = c & (-1 >> 32); c = c >> 32; 122 c = c + a[3] * r[3] + x[6]; x[6] = c & (-1 >> 32); c = c >> 32; 123 c = c + a[3] * r[4] + x[7]; x[7] = c & (-1 >> 32); c = c >> 32; 124 x[8] = (c + x[8]) & (-1 >> 32); 125 126 c = a[4] * r[0] + x[4]; x[4] = c & (-1 >> 32); c = c >> 32; 127 c = c + a[4] * r[1] + x[5]; x[5] = c & (-1 >> 32); c = c >> 32; 128 c = c + a[4] * r[2] + x[6]; x[6] = c & (-1 >> 32); c = c >> 32; 129 c = c + a[4] * r[3] + x[7]; x[7] = c & (-1 >> 32); c = c >> 32; 130 c = c + a[4] * r[4] + x[8]; x[8] = c & (-1 >> 32); c = c >> 32; 131 x[9] = (c + x[9]) & (-1 >> 32); 132 133 a[0] = x[0]; 134 a[1] = x[1]; 135 a[2] = x[2]; 136 a[3] = x[3]; 137 a[4] = x[4] & 3; 138 139 // Modular reduction 140 c = (x[4] >> 2) * 5 + ((x[5] & 3) << 30) * 5 + a[0]; a[0] = c & (-1 >> 32); c = c >> 32; 141 c = c + (x[5] >> 2) * 5 + ((x[6] & 3) << 30) * 5 + a[1]; a[1] = c & (-1 >> 32); c = c >> 32; 142 c = c + (x[6] >> 2) * 5 + ((x[7] & 3) << 30) * 5 + a[2]; a[2] = c & (-1 >> 32); c = c >> 32; 143 c = c + (x[7] >> 2) * 5 + ((x[8] & 3) << 30) * 5 + a[3]; a[3] = c & (-1 >> 32); c = c >> 32; 144 c = c + (x[8] >> 2) * 5 + ((x[9] & 3) << 30) * 5 + a[4]; a[4] = c & (-1 >> 32); c = c >> 32; 145 } 146 147 func poly1305_truncate(dest: *int, key: *byte) { 148 poly1305_load(dest, key, 4); 149 150 dest[0] = dest[0] & 0x0fffffff; 151 dest[1] = dest[1] & 0x0ffffffc; 152 dest[2] = dest[2] & 0x0ffffffc; 153 dest[3] = dest[3] & 0x0ffffffc; 154 dest[4] = 0; 155 } 156 157 func poly1305_pad(dest: *int, msg: *byte, n: int) { 158 var _pad: _poly1305_ctx; 159 var pad: *byte; 160 var i: int; 161 162 pad = (&_pad) as *byte; 163 164 i = 0; 165 loop { 166 if i == n { 167 break; 168 } 169 170 pad[i] = msg[i]; 171 172 i = i + 1; 173 } 174 175 pad[i] = 1 as byte; 176 i = i + 1; 177 178 loop { 179 if i == 20 { 180 break; 181 } 182 183 pad[i] = 0 as byte; 184 185 i = i + 1; 186 } 187 188 poly1305_load(dest, pad, 5); 189 } 190 191 func poly1305(mac: *byte, key: *byte, msg: *byte, len: int) { 192 var _a: _poly1305_ctx; 193 var a: *int; 194 var _r: _poly1305_ctx; 195 var r: *int; 196 var _s: _poly1305_ctx; 197 var s: *int; 198 var i: int; 199 200 a = (&_a) as *int; 201 r = (&_r) as *int; 202 s = (&_s) as *int; 203 204 a[0] = 0; 205 a[1] = 0; 206 a[2] = 0; 207 a[3] = 0; 208 a[4] = 0; 209 210 poly1305_truncate(r, key); 211 212 i = 0; 213 loop { 214 if i >= len { 215 break; 216 } 217 218 if (len - i >= 16) { 219 poly1305_pad(s, &msg[i], 16); 220 } else { 221 poly1305_pad(s, &msg[i], len - i); 222 } 223 224 poly1305_add(a, s); 225 poly1305_reduce(a); 226 227 poly1305_mul(a, r); 228 poly1305_reduce(a); 229 230 i = i + 16; 231 } 232 233 poly1305_load(s, &key[16], 4); 234 s[4] = 0; 235 236 poly1305_add(a, s); 237 238 poly1305_digest(mac, a); 239 }