os

An operating system
git clone https://erai.gay/code/os/
Log | Files | Refs | README | LICENSE

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 }