os

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

ed25519.om (30293B)


      1 // https://www.rfc-editor.org/rfc/rfc8032
      2 // p = 2**255 - 19
      3 // = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed
      4 // = 57896044618658097711785492504343953926634992332820282019728792003956564819949
      5 // order
      6 // L = 2**252 + 0x14def9dea2f79cd65812631a5cf5d3ed
      7 // = 0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed
      8 // = 7237005577332262213973186563042994240857116359379907606001950938285454250989
      9 // cofactor = 8
     10 //
     11 // cv25519: v**2 = u**3 + a*u**2 + u mod p
     12 // a = 486662
     13 // = 0x76d06
     14 // u = 9
     15 // = 0x9
     16 // v = 14781619447589544791020593568409986887264606134616475288964881837755586237401
     17 // = 0x20ae19a1b8a086b4e01edd2c7748d14c923d4d7e6d7c61b229e9c5a27eced3d9
     18 //
     19 // ed25519: -x**2 + y**2 = 1 + d*x**2*y**2 mod p
     20 // d = 37095705934669439343138083508754565189542113879843219016388785533085940283555
     21 // = 0x52036cee2b6ffe738cc740797779e89800700a4d4141d8ab75eb4dca135978a3
     22 // x = 15112221349535400772501151409588531511454012693041857206046113283949847762202
     23 // = 0x216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a
     24 // y = 46316835694926478169428394003475163141307993866256225615783033603165251855960
     25 // = 0x6666666666666666666666666666666666666666666666666666666666666658
     26 //
     27 // sqrt(-486664) = 6853475219497561581579357271197624642482790079785650197046958215289687604742
     28 // = 0xf26edf460a006bbd27b08dc03fc4f7ec5a1d3d14b7d1a82cc6e04aaff457e06
     29 //
     30 // birational map
     31 //
     32 // ed25519 -> cv25519
     33 // u = (1 + y) / (1 - y)
     34 // v = sqrt(-486664) * u / x
     35 //
     36 // cv25519 -> ed25519
     37 // x = sqrt(-486664) * u / v
     38 // y = (u - 1) / (u + 1)
     39 
     40 struct _ed25519_limb {
     41 	x0: int;
     42 	x1: int;
     43 	x2: int;
     44 	x3: int;
     45 	x4: int;
     46 	x5: int;
     47 	x6: int;
     48 	x7: int;
     49 }
     50 
     51 struct _ed25519_point {
     52 	x0: int;
     53 	x1: int;
     54 	x2: int;
     55 	x3: int;
     56 	x4: int;
     57 	x5: int;
     58 	x6: int;
     59 	x7: int;
     60 	y0: int;
     61 	y1: int;
     62 	y2: int;
     63 	y3: int;
     64 	y4: int;
     65 	y5: int;
     66 	y6: int;
     67 	y7: int;
     68 }
     69 
     70 struct _ed25519_mod {
     71 	x0: int;
     72 	x1: int;
     73 	x2: int;
     74 	x3: int;
     75 	x4: int;
     76 	x5: int;
     77 	x6: int;
     78 	x7: int;
     79 	x8: int;
     80 	x9: int;
     81 	x10: int;
     82 	x11: int;
     83 	x12: int;
     84 	x13: int;
     85 	x14: int;
     86 	x15: int;
     87 	x16: int;
     88 }
     89 
     90 struct _x25519_block {
     91 	_x0: int;
     92 	_x1: int;
     93 	_x2: int;
     94 	_x3: int;
     95 	_x4: int;
     96 }
     97 
     98 struct _ed25519_priv {
     99 	x0: int;
    100 	x1: int;
    101 	x2: int;
    102 	x3: int;
    103 }
    104 
    105 struct _ed25519_pub {
    106 	x0: int;
    107 	x1: int;
    108 	x2: int;
    109 	x3: int;
    110 }
    111 
    112 struct _ed25519_sig {
    113 	x0: int;
    114 	x1: int;
    115 	x2: int;
    116 	x3: int;
    117 	x4: int;
    118 	x5: int;
    119 	x6: int;
    120 	x7: int;
    121 }
    122 
    123 func ed25519_reduce(r: *int) {
    124 	var c: int;
    125 	var k: int;
    126 
    127 	c = (r[0] + 19) >> 32;
    128 	c = (c + r[1]) >> 32;
    129 	c = (c + r[2]) >> 32;
    130 	c = (c + r[3]) >> 32;
    131 	c = (c + r[4]) >> 32;
    132 	c = (c + r[5]) >> 32;
    133 	c = (c + r[6]) >> 32;
    134 	c = (c + r[7] + (1 << 31)) >> 32;
    135 
    136 	k = -c >> 32;
    137 
    138 	c = c + r[0] + (18 & k); r[0] = c & (-1 >> 32); c = c >> 32;
    139 	c = c + r[1]; r[1] = c & (-1 >> 32); c = c >> 32;
    140 	c = c + r[2]; r[2] = c & (-1 >> 32); c = c >> 32;
    141 	c = c + r[3]; r[3] = c & (-1 >> 32); c = c >> 32;
    142 	c = c + r[4]; r[4] = c & (-1 >> 32); c = c >> 32;
    143 	c = c + r[5]; r[5] = c & (-1 >> 32); c = c >> 32;
    144 	c = c + r[6]; r[6] = c & (-1 >> 32); c = c >> 32;
    145 	c = c + r[7] + ((1 << 31) & k); r[7] = c & (-1 >> 32); c = c >> 32;
    146 }
    147 
    148 func ed25519_add(r: *int, a: *int, b: *int) {
    149 	var c: int;
    150 
    151 	c = a[0] + b[0]; r[0] = c & (-1 >> 32); c = c >> 32;
    152 	c = c + a[1] + b[1]; r[1] = c & (-1 >> 32); c = c >> 32;
    153 	c = c + a[2] + b[2]; r[2] = c & (-1 >> 32); c = c >> 32;
    154 	c = c + a[3] + b[3]; r[3] = c & (-1 >> 32); c = c >> 32;
    155 	c = c + a[4] + b[4]; r[4] = c & (-1 >> 32); c = c >> 32;
    156 	c = c + a[5] + b[5]; r[5] = c & (-1 >> 32); c = c >> 32;
    157 	c = c + a[6] + b[6]; r[6] = c & (-1 >> 32); c = c >> 32;
    158 	c = c + a[7] + b[7]; r[7] = c & (-1 >> 32); c = c >> 32;
    159 
    160 	ed25519_reduce(r);
    161 }
    162 
    163 func ed25519_sub(r: *int, a: *int, b: *int) {
    164 	var c: int;
    165 
    166 	c = 1 + a[0] + (-19 & (-1 >> 32)) + (b[0] ^ (-1 >> 32)); r[0] = c & (-1 >> 32); c = c >> 32;
    167 	c = c + a[1] + (-1 >> 32) + (b[1] ^ (-1 >> 32)); r[1] = c & (-1 >> 32); c = c >> 32;
    168 	c = c + a[2] + (-1 >> 32) + (b[2] ^ (-1 >> 32)); r[2] = c & (-1 >> 32); c = c >> 32;
    169 	c = c + a[3] + (-1 >> 32) + (b[3] ^ (-1 >> 32)); r[3] = c & (-1 >> 32); c = c >> 32;
    170 	c = c + a[4] + (-1 >> 32) + (b[4] ^ (-1 >> 32)); r[4] = c & (-1 >> 32); c = c >> 32;
    171 	c = c + a[5] + (-1 >> 32) + (b[5] ^ (-1 >> 32)); r[5] = c & (-1 >> 32); c = c >> 32;
    172 	c = c + a[6] + (-1 >> 32) + (b[6] ^ (-1 >> 32)); r[6] = c & (-1 >> 32); c = c >> 32;
    173 	c = c + a[7] + (-1 >> 33) + (b[7] ^ (-1 >> 32)); r[7] = c & (-1 >> 32); c = c >> 32;
    174 
    175 	ed25519_reduce(r);
    176 }
    177 
    178 func ed25519_mul(r: *int, a: *int, b: *int) {
    179 	var _x: _ed25519_point;
    180 	var x: *int;
    181 	var c: int;
    182 	var i: int;
    183 
    184 	x = (&_x) as *int;
    185 
    186 	x[0] = 0;
    187 	x[1] = 0;
    188 	x[2] = 0;
    189 	x[3] = 0;
    190 	x[4] = 0;
    191 	x[5] = 0;
    192 	x[6] = 0;
    193 	x[7] = 0;
    194 	x[8] = 0;
    195 	x[9] = 0;
    196 	x[10] = 0;
    197 	x[11] = 0;
    198 	x[12] = 0;
    199 	x[13] = 0;
    200 	x[14] = 0;
    201 	x[15] = 0;
    202 
    203 	i = 0;
    204 	loop {
    205 		if i == 8 {
    206 			break;
    207 		}
    208 
    209 		c = x[i + 0] + a[i] * b[0]; x[i + 0] = c & (-1 >> 32); c = c >> 32;
    210 		c = c + x[i + 1] + a[i] * b[1]; x[i + 1] = c & (-1 >> 32); c = c >> 32;
    211 		c = c + x[i + 2] + a[i] * b[2]; x[i + 2] = c & (-1 >> 32); c = c >> 32;
    212 		c = c + x[i + 3] + a[i] * b[3]; x[i + 3] = c & (-1 >> 32); c = c >> 32;
    213 		c = c + x[i + 4] + a[i] * b[4]; x[i + 4] = c & (-1 >> 32); c = c >> 32;
    214 		c = c + x[i + 5] + a[i] * b[5]; x[i + 5] = c & (-1 >> 32); c = c >> 32;
    215 		c = c + x[i + 6] + a[i] * b[6]; x[i + 6] = c & (-1 >> 32); c = c >> 32;
    216 		c = c + x[i + 7] + a[i] * b[7]; x[i + 7] = c & (-1 >> 32); c = c >> 32;
    217 		c = c + x[i + 8]; x[i + 8] = c & (-1 >> 32);
    218 
    219 		i = i + 1;
    220 	}
    221 
    222 	c = x[0] + x[8] * 38; x[0] = c & (-1 >> 32); c = c >> 32;
    223 	c = c + x[1] + x[9] * 38; x[1] = c & (-1 >> 32); c = c >> 32;
    224 	c = c + x[2] + x[10] * 38; x[2] = c & (-1 >> 32); c = c >> 32;
    225 	c = c + x[3] + x[11] * 38; x[3] = c & (-1 >> 32); c = c >> 32;
    226 	c = c + x[4] + x[12] * 38; x[4] = c & (-1 >> 32); c = c >> 32;
    227 	c = c + x[5] + x[13] * 38; x[5] = c & (-1 >> 32); c = c >> 32;
    228 	c = c + x[6] + x[14] * 38; x[6] = c & (-1 >> 32); c = c >> 32;
    229 	c = c + x[7] + x[15] * 38; x[7] = c & (-1 >> 32); c = c >> 32;
    230 
    231 	ed25519_reduce(x);
    232 
    233 	c = c * 38 + x[0]; x[0] = c & (-1 >> 32); c = c >> 32;
    234 	c = c + x[1]; x[1] = c & (-1 >> 32); c = c >> 32;
    235 	c = c + x[2]; x[2] = c & (-1 >> 32); c = c >> 32;
    236 	c = c + x[3]; x[3] = c & (-1 >> 32); c = c >> 32;
    237 	c = c + x[4]; x[4] = c & (-1 >> 32); c = c >> 32;
    238 	c = c + x[5]; x[5] = c & (-1 >> 32); c = c >> 32;
    239 	c = c + x[6]; x[6] = c & (-1 >> 32); c = c >> 32;
    240 	c = c + x[7]; x[7] = c & (-1 >> 32);
    241 
    242 	ed25519_reduce(x);
    243 
    244 	r[0] = x[0];
    245 	r[1] = x[1];
    246 	r[2] = x[2];
    247 	r[3] = x[3];
    248 	r[4] = x[4];
    249 	r[5] = x[5];
    250 	r[6] = x[6];
    251 	r[7] = x[7];
    252 }
    253 
    254 func ed25519_inv(r: *int, a: *int) {
    255 	var _x: _ed25519_point;
    256 	var x: *int;
    257 	var i: int;
    258 
    259 	x = (&_x) as *int;
    260 
    261 	i = 0;
    262 	loop {
    263 		if i == 8 {
    264 			break;
    265 		}
    266 		x[i] = a[i]; r[i] = a[i];
    267 		i = i + 1;
    268 	}
    269 
    270 	i = 0;
    271 	loop {
    272 		if i == 254 {
    273 			break;
    274 		}
    275 		ed25519_mul(r, r, r);
    276 		if (i != 249 && i != 251) {
    277 			ed25519_mul(r, r, x);
    278 		}
    279 		i = i + 1;
    280 	}
    281 }
    282 
    283 func ed25519_selectl(r: *int, a: *int, b: *int, k: int) {
    284 	k = -(k & 1);
    285 	r[0] = (a[0] & ~k) | (b[0] & k);
    286 	r[1] = (a[1] & ~k) | (b[1] & k);
    287 	r[2] = (a[2] & ~k) | (b[2] & k);
    288 	r[3] = (a[3] & ~k) | (b[3] & k);
    289 	r[4] = (a[4] & ~k) | (b[4] & k);
    290 	r[5] = (a[5] & ~k) | (b[5] & k);
    291 	r[6] = (a[6] & ~k) | (b[6] & k);
    292 	r[7] = (a[7] & ~k) | (b[7] & k);
    293 }
    294 
    295 func ed25519_zero(r: *int) {
    296 	r[0] = 0;
    297 	r[1] = 0;
    298 	r[2] = 0;
    299 	r[3] = 0;
    300 	r[4] = 0;
    301 	r[5] = 0;
    302 	r[6] = 0;
    303 	r[7] = 0;
    304 }
    305 
    306 func ed25519_one(r: *int) {
    307 	r[0] = 1;
    308 	r[1] = 0;
    309 	r[2] = 0;
    310 	r[3] = 0;
    311 	r[4] = 0;
    312 	r[5] = 0;
    313 	r[6] = 0;
    314 	r[7] = 0;
    315 }
    316 
    317 func ed25519_d(d: *int) {
    318 	d[7] = 0x52036cee;
    319 	d[6] = 0x2b6ffe73;
    320 	d[5] = 0x8cc74079;
    321 	d[4] = 0x7779e898;
    322 	d[3] = 0x00700a4d;
    323 	d[2] = 0x4141d8ab;
    324 	d[1] = 0x75eb4dca;
    325 	d[0] = 0x135978a3;
    326 }
    327 
    328 func ed25519_a(a: *int) {
    329 	a[7] = 0;
    330 	a[6] = 0;
    331 	a[5] = 0;
    332 	a[4] = 0;
    333 	a[3] = 0;
    334 	a[2] = 0;
    335 	a[1] = 0;
    336 	a[0] = 486662;
    337 }
    338 
    339 ////           x1 * y2 + x2 * y1                y1 * y2 - a * x1 * x2
    340 //// x3 = ---------------------------,  y3 = ---------------------------
    341 ////       1 + d * x1 * x2 * y1 * y2          1 - d * x1 * x2 * y1 * y2
    342 func ed25519_pa(r: *int, a: *int, b: * int) {
    343 	var _y1y2: _ed25519_limb;
    344 	var y1y2: *int;
    345 	var _x1x2: _ed25519_limb;
    346 	var x1x2: *int;
    347 	var _x1y2: _ed25519_limb;
    348 	var x1y2: *int;
    349 	var _x2y1: _ed25519_limb;
    350 	var x2y1: *int;
    351 	var _dxy: _ed25519_limb;
    352 	var dxy: *int;
    353 	var _dxy1: _ed25519_limb;
    354 	var dxy1: *int;
    355 	var _dxy2: _ed25519_limb;
    356 	var dxy2: *int;
    357 	var _d: _ed25519_limb;
    358 	var d: *int;
    359 
    360 	y1y2 = &_y1y2.x0;
    361 	x1x2 = &_x1x2.x0;
    362 	x1y2 = &_x1y2.x0;
    363 	x2y1 = &_x2y1.x0;
    364 	dxy = &_dxy.x0;
    365 	dxy1 = &_dxy1.x0;
    366 	dxy2 = &_dxy2.x0;
    367 	d = &_d.x0;
    368 
    369 	ed25519_d(d);
    370 
    371 	ed25519_mul(y1y2, &a[8], &b[8]);
    372 	ed25519_mul(x1x2, a, b);
    373 
    374 	ed25519_mul(x1y2, a, &b[8]);
    375 	ed25519_mul(x2y1, b, &a[8]);
    376 
    377 	ed25519_mul(dxy, x1y2, x2y1);
    378 	ed25519_mul(dxy, d, dxy);
    379 
    380 	ed25519_one(dxy1);
    381 	ed25519_add(dxy1, dxy1, dxy);
    382 	ed25519_inv(dxy1, dxy1);
    383 
    384 	ed25519_add(r, x1y2, x2y1);
    385 	ed25519_mul(r, r, dxy1);
    386 
    387 	ed25519_one(dxy2);
    388 	ed25519_sub(dxy2, dxy2, dxy);
    389 	ed25519_inv(dxy2, dxy2);
    390 
    391 	ed25519_add(&r[8], y1y2, x1x2);
    392 	ed25519_mul(&r[8], &r[8], dxy2);
    393 }
    394 
    395 func ed25519_pk(r: *int, a: *int, k: *int) {
    396 	var _b: _ed25519_point;
    397 	var b: *int;
    398 	var _c: _ed25519_point;
    399 	var c: *int;
    400 	var e: int;
    401 	var i: int;
    402 	var j: int;
    403 
    404 	b = &_b.x0;
    405 	c = &_c.x0;
    406 
    407 	b[0] = a[0] & (-1 >> 32); r[0] = 0;
    408 	b[1] = a[1] & (-1 >> 32); r[1] = 0;
    409 	b[2] = a[2] & (-1 >> 32); r[2] = 0;
    410 	b[3] = a[3] & (-1 >> 32); r[3] = 0;
    411 	b[4] = a[4] & (-1 >> 32); r[4] = 0;
    412 	b[5] = a[5] & (-1 >> 32); r[5] = 0;
    413 	b[6] = a[6] & (-1 >> 32); r[6] = 0;
    414 	b[7] = a[7] & (-1 >> 32); r[7] = 0;
    415 	b[8] = a[8] & (-1 >> 32); r[8] = 1;
    416 	b[9] = a[9] & (-1 >> 32); r[9] = 0;
    417 	b[10] = a[10] & (-1 >> 32); r[10] = 0;
    418 	b[11] = a[11] & (-1 >> 32); r[11] = 0;
    419 	b[12] = a[12] & (-1 >> 32); r[12] = 0;
    420 	b[13] = a[13] & (-1 >> 32); r[13] = 0;
    421 	b[14] = a[14] & (-1 >> 32); r[14] = 0;
    422 	b[15] = a[15] & (-1 >> 32); r[15] = 0;
    423 
    424 	i = 7;
    425 	loop {
    426 		e = k[i];
    427 
    428 		j = 0;
    429 		loop {
    430 			if j == 32 {
    431 				break;
    432 			}
    433 			ed25519_pa(r, r, r);
    434 			ed25519_pa(c, r, b);
    435 			ed25519_selectl(r, r, c, -((e >> 31) & 1));
    436 			ed25519_selectl(&r[8], &r[8], &c[8], -((e >> 31) & 1));
    437 			e = e << 1;
    438 			j = j + 1;
    439 		}
    440 
    441 		if i == 0 {
    442 			break;
    443 		}
    444 
    445 		i = i - 1;
    446 	}
    447 }
    448 
    449 func ed25519_base(p: *int) {
    450 	p[7] = 0x216936d3;
    451 	p[6] = 0xcd6e53fe;
    452 	p[5] = 0xc0a4e231;
    453 	p[4] = 0xfdd6dc5c;
    454 	p[3] = 0x692cc760;
    455 	p[2] = 0x9525a7b2;
    456 	p[1] = 0xc9562d60;
    457 	p[0] = 0x8f25d51a;
    458 	p[15] = 0x66666666;
    459 	p[14] = 0x66666666;
    460 	p[13] = 0x66666666;
    461 	p[12] = 0x66666666;
    462 	p[11] = 0x66666666;
    463 	p[10] = 0x66666666;
    464 	p[9] = 0x66666666;
    465 	p[8] = 0x66666658;
    466 }
    467 
    468 // 2**((p-1)//4)
    469 func ed25519_sqrtz(z: *int) {
    470 	z[7] = 0x2b832480;
    471 	z[6] = 0x4fc1df0b;
    472 	z[5] = 0x2b4d0099;
    473 	z[4] = 0x3dfbd7a7;
    474 	z[3] = 0x2f431806;
    475 	z[2] = 0xad2fe478;
    476 	z[1] = 0xc4ee1b27;
    477 	z[0] = 0x4a0ea0b0;
    478 }
    479 
    480 // sqrt(x) = x**((p+3)/8) * [1 or 2**((p-1)/4)]
    481 func ed25519_sqrt(r: *int, x: *int): int {
    482 	var _a: _ed25519_limb;
    483 	var _z: _ed25519_limb;
    484 	var a: *int;
    485 	var z: *int;
    486 	var i: int;
    487 
    488 	a = &_a.x0;
    489 	z = &_z.x0;
    490 
    491 	ed25519_one(a);
    492 
    493 	i = 0;
    494 	loop {
    495 		if i == 252 {
    496 			break;
    497 		}
    498 
    499 		ed25519_mul(a, a, a);
    500 
    501 		if i != 251 {
    502 			ed25519_mul(a, a, x);
    503 		}
    504 
    505 		i = i + 1;
    506 	}
    507 
    508 	ed25519_mul(z, a, a);
    509 	ed25519_sub(z, z, x);
    510 	i = ed25519_zerop(z);
    511 
    512 	ed25519_sqrtz(z);
    513 	ed25519_mul(z, z, a);
    514 
    515 	ed25519_selectl(a, z, a, i);
    516 
    517 	ed25519_mul(z, a, a);
    518 	ed25519_sub(z, z, x);
    519 
    520 	i = ed25519_zerop(z);
    521 
    522 	r[0] = a[0];
    523 	r[1] = a[1];
    524 	r[2] = a[2];
    525 	r[3] = a[3];
    526 	r[4] = a[4];
    527 	r[5] = a[5];
    528 	r[6] = a[6];
    529 	r[7] = a[7];
    530 
    531 	return i;
    532 }
    533 
    534 // x**2 = (y**2 - 1) / (1 + d * y**2) mod p
    535 func ed25519_decode(p: *int, y: *byte): int {
    536 	var _xy: _ed25519_point;
    537 	var xy: *int;
    538 	var _a: _ed25519_limb;
    539 	var a: *int;
    540 	var _b: _ed25519_limb;
    541 	var b: *int;
    542 
    543 	xy = &_xy.x0;
    544 	a = &_a.x0;
    545 	b = &_b.x0;
    546 
    547 	xy[8] = y[0] as int | (y[1] as int << 8) | (y[2] as int << 16) | (y[3] as int << 24);
    548 	xy[9] = y[4] as int | (y[5] as int << 8) | (y[6] as int << 16) | (y[7] as int << 24);
    549 	xy[10] = y[8] as int | (y[9] as int << 8) | (y[10] as int << 16) | (y[11] as int << 24);
    550 	xy[11] = y[12] as int | (y[13] as int << 8) | (y[14] as int << 16) | (y[15] as int << 24);
    551 	xy[12] = y[16] as int | (y[17] as int << 8) | (y[18] as int << 16) | (y[19] as int << 24);
    552 	xy[13] = y[20] as int | (y[21] as int << 8) | (y[22] as int << 16) | (y[23] as int << 24);
    553 	xy[14] = y[24] as int | (y[25] as int << 8) | (y[26] as int << 16) | (y[27] as int << 24);
    554 	xy[15] = (y[28] as int | (y[29] as int << 8) | (y[30] as int << 16) | (y[31] as int << 24)) & (-1 >> 33);
    555 
    556 	ed25519_mul(a, &xy[8], &xy[8]);
    557 	ed25519_d(b);
    558 	ed25519_mul(b, b, a);
    559 	ed25519_one(xy);
    560 	ed25519_add(b, b, xy);
    561 	ed25519_sub(xy, a, xy);
    562 	ed25519_inv(b, b);
    563 	ed25519_mul(xy, xy, b);
    564 
    565 	if !ed25519_sqrt(xy, xy) {
    566 		return 0;
    567 	}
    568 
    569 	ed25519_set_lsb(xy, y[31] as int >> 7);
    570 
    571 	p[0] = xy[0];
    572 	p[1] = xy[1];
    573 	p[2] = xy[2];
    574 	p[3] = xy[3];
    575 	p[4] = xy[4];
    576 	p[5] = xy[5];
    577 	p[6] = xy[6];
    578 	p[7] = xy[7];
    579 	p[8] = xy[8];
    580 	p[9] = xy[9];
    581 	p[10] = xy[10];
    582 	p[11] = xy[11];
    583 	p[12] = xy[12];
    584 	p[13] = xy[13];
    585 	p[14] = xy[14];
    586 	p[15] = xy[15];
    587 
    588 	return 1;
    589 }
    590 
    591 func ed25519_encode(dest: *byte, p: *int) {
    592 	dest[0] = p[8] as byte;
    593 	dest[1] = (p[8] >> 8) as byte;
    594 	dest[2] = (p[8] >> 16) as byte;
    595 	dest[3] = (p[8] >> 24) as byte;
    596 	dest[4] = p[9] as byte;
    597 	dest[5] = (p[9] >> 8) as byte;
    598 	dest[6] = (p[9] >> 16) as byte;
    599 	dest[7] = (p[9] >> 24) as byte;
    600 	dest[8] = p[10] as byte;
    601 	dest[9] = (p[10] >> 8) as byte;
    602 	dest[10] = (p[10] >> 16) as byte;
    603 	dest[11] = (p[10] >> 24) as byte;
    604 	dest[12] = p[11] as byte;
    605 	dest[13] = (p[11] >> 8) as byte;
    606 	dest[14] = (p[11] >> 16) as byte;
    607 	dest[15] = (p[11] >> 24) as byte;
    608 	dest[16] = p[12] as byte;
    609 	dest[17] = (p[12] >> 8) as byte;
    610 	dest[18] = (p[12] >> 16) as byte;
    611 	dest[19] = (p[12] >> 24) as byte;
    612 	dest[20] = p[13] as byte;
    613 	dest[21] = (p[13] >> 8) as byte;
    614 	dest[22] = (p[13] >> 16) as byte;
    615 	dest[23] = (p[13] >> 24) as byte;
    616 	dest[24] = p[14] as byte;
    617 	dest[25] = (p[14] >> 8) as byte;
    618 	dest[26] = (p[14] >> 16) as byte;
    619 	dest[27] = (p[14] >> 24) as byte;
    620 	dest[28] = p[15] as byte;
    621 	dest[29] = (p[15] >> 8) as byte;
    622 	dest[30] = (p[15] >> 16) as byte;
    623 	dest[31] = (p[15] >> 24) as byte | ((p[0] & 1) << 7) as byte;
    624 }
    625 
    626 func ed25519_pub(pub: *byte, b: *byte) {
    627 	var _h: _sha512_digest;
    628 	var h: *byte;
    629 	var _a: _ed25519_point;
    630 	var a: *int;
    631 	var _s: _ed25519_limb;
    632 	var s: *int;
    633 
    634 	h = (&_h) as *byte;
    635 	a = &_a.x0;
    636 	s = &_s.x0;
    637 
    638 	// h || prefix = SHA-512(b)
    639 	sha512(h, b, 32);
    640 
    641 	// s = clamp(h)
    642 	ed25519_clamp(s, h);
    643 
    644 	// A = [s]B
    645 	ed25519_base(a);
    646 	ed25519_pk(a, a, s);
    647 
    648 	// public key = A
    649 	ed25519_encode(pub, a);
    650 }
    651 
    652 func ed25519_sign(sig: *byte, b: *byte, msg: *byte, len: int) {
    653 	var _h: _sha512_digest;
    654 	var h: *byte;
    655 	var _hr: _sha512_digest;
    656 	var hr: *byte;
    657 	var _hk: _sha512_digest;
    658 	var hk: *byte;
    659 	var ctx: sha512_ctx;
    660 	var _a: _ed25519_point;
    661 	var a: *int;
    662 	var _pub: _ed25519_point;
    663 	var pub: *byte;
    664 	var _rb: _ed25519_point;
    665 	var rb: *int;
    666 	var _s: _ed25519_limb;
    667 	var s: *int;
    668 	var _r: _ed25519_limb;
    669 	var r: *int;
    670 	var _k: _ed25519_limb;
    671 	var k: *int;
    672 
    673 	h = (&_h) as *byte;
    674 	hr = (&_hr) as *byte;
    675 	hk = (&_hk) as *byte;
    676 	a = &_a.x0;
    677 	pub = (&_pub) as *byte;
    678 	rb = &_rb.x0;
    679 	s = &_s.x0;
    680 	r = &_r.x0;
    681 	k = &_k.x0;
    682 
    683 	// h || prefix = SHA-512(b)
    684 	sha512(h, b, 32);
    685 
    686 	// s = clamp(h)
    687 	ed25519_clamp(s, h);
    688 
    689 	// A = [s]B
    690 	ed25519_base(a);
    691 	ed25519_pk(a, a, s);
    692 	ed25519_encode(pub, a);
    693 
    694 	// r = SHA-512(prefix || M)
    695 	sha512_init(&ctx);
    696 	sha512_update(&ctx, &h[32], 32);
    697 	sha512_update(&ctx, msg, len);
    698 	sha512_final(hr, &ctx);
    699 	ed25519_reduce_l(r, hr);
    700 
    701 	// R = [r]B
    702 	ed25519_base(rb);
    703 	ed25519_pk(rb, rb, r);
    704 	ed25519_encode(sig, rb);
    705 
    706 	// k = SHA-512(R || A || M)
    707 	sha512_init(&ctx);
    708 	sha512_update(&ctx, sig, 32);
    709 	sha512_update(&ctx, pub, 32);
    710 	sha512_update(&ctx, msg, len);
    711 	sha512_final(hk, &ctx);
    712 	ed25519_reduce_l(k, hk);
    713 
    714 	// S = k * s + r mod L
    715 	ed25519_ma_l(s, s, k, r);
    716 	ed25519_encode_l(&sig[32], s);
    717 }
    718 
    719 func ed25519_l(l: *int) {
    720 	l[7] = 0x10000000;
    721 	l[6] = 0x00000000;
    722 	l[5] = 0x00000000;
    723 	l[4] = 0x00000000;
    724 	l[3] = 0x14def9de;
    725 	l[2] = 0xa2f79cd6;
    726 	l[1] = 0x5812631a;
    727 	l[0] = 0x5cf5d3ed;
    728 }
    729 
    730 func ed25519_mod1(m: *int, l: *int, q: int) {
    731 	var c: int;
    732 	var r: int;
    733 
    734 	c = q * l[0]; r = 1 + m[0] + (~c & (-1 >> 32)); c = c >> 32; r = r >> 32;
    735 	c = c + q * l[1]; r = r + m[1] + (~c & (-1 >> 32)); c = c >> 32; r = r >> 32;
    736 	c = c + q * l[2]; r = r + m[2] + (~c & (-1 >> 32)); c = c >> 32; r = r >> 32;
    737 	c = c + q * l[3]; r = r + m[3] + (~c & (-1 >> 32)); c = c >> 32; r = r >> 32;
    738 	c = c + q * l[4]; r = r + m[4] + (~c & (-1 >> 32)); c = c >> 32; r = r >> 32;
    739 	c = c + q * l[5]; r = r + m[5] + (~c & (-1 >> 32)); c = c >> 32; r = r >> 32;
    740 	c = c + q * l[6]; r = r + m[6] + (~c & (-1 >> 32)); c = c >> 32; r = r >> 32;
    741 	c = c + q * l[7]; r = r + m[7] + (~c & (-1 >> 32)); c = c >> 32; r = r >> 32;
    742 	r = r + m[8] + (~c & (-1 >> 32)); c = c >> 32; r = r >> 32;
    743 
    744 	q = q - (r ^ 1);
    745 
    746 	c = q * l[0]; r = 1 + m[0] + (~c & (-1 >> 32)); m[0] = r & (-1 >> 32); c = c >> 32; r = r >> 32;
    747 	c = c + q * l[1]; r = r + m[1] + (~c & (-1 >> 32)); m[1] = r & (-1 >> 32); c = c >> 32; r = r >> 32;
    748 	c = c + q * l[2]; r = r + m[2] + (~c & (-1 >> 32)); m[2] = r & (-1 >> 32); c = c >> 32; r = r >> 32;
    749 	c = c + q * l[3]; r = r + m[3] + (~c & (-1 >> 32)); m[3] = r & (-1 >> 32); c = c >> 32; r = r >> 32;
    750 	c = c + q * l[4]; r = r + m[4] + (~c & (-1 >> 32)); m[4] = r & (-1 >> 32); c = c >> 32; r = r >> 32;
    751 	c = c + q * l[5]; r = r + m[5] + (~c & (-1 >> 32)); m[5] = r & (-1 >> 32); c = c >> 32; r = r >> 32;
    752 	c = c + q * l[6]; r = r + m[6] + (~c & (-1 >> 32)); m[6] = r & (-1 >> 32); c = c >> 32; r = r >> 32;
    753 	c = c + q * l[7]; r = r + m[7] + (~c & (-1 >> 32)); m[7] = r & (-1 >> 32); c = c >> 32; r = r >> 32;
    754 	r = r + m[8] + (~c & (-1 >> 32)); m[8] = r & (-1 >> 32); c = c >> 32; r = r >> 32;
    755 }
    756 
    757 // r = x mod L
    758 func ed25519_mod_l(r: *int, x: *int) {
    759 	var _l: _ed25519_limb;
    760 	var l: *int;
    761 	var _m: _ed25519_mod;
    762 	var m: *int;
    763 
    764 	l = &_l.x0;
    765 	m = &_m.x0;
    766 
    767 	ed25519_l(l);
    768 
    769 	m[0] = x[0];
    770 	m[1] = x[1];
    771 	m[2] = x[2];
    772 	m[3] = x[3];
    773 	m[4] = x[4];
    774 	m[5] = x[5];
    775 	m[6] = x[6];
    776 	m[7] = x[7];
    777 	m[8] = x[8];
    778 	m[9] = x[9];
    779 	m[10] = x[10];
    780 	m[11] = x[11];
    781 	m[12] = x[12];
    782 	m[13] = x[13];
    783 	m[14] = x[14];
    784 	m[15] = x[15];
    785 	m[16] = 0;
    786 
    787 	ed25519_mod1(&m[8], l, m[15] >> 28);
    788 	ed25519_mod1(&m[7], l, (m[15] << 4) + (m[14] >> 28));
    789 	ed25519_mod1(&m[6], l, (m[14] << 4) + (m[13] >> 28));
    790 	ed25519_mod1(&m[5], l, (m[13] << 4) + (m[12] >> 28));
    791 	ed25519_mod1(&m[4], l, (m[12] << 4) + (m[11] >> 28));
    792 	ed25519_mod1(&m[3], l, (m[11] << 4) + (m[10] >> 28));
    793 	ed25519_mod1(&m[2], l, (m[10] << 4) + (m[9] >> 28));
    794 	ed25519_mod1(&m[1], l, (m[9] << 4) + (m[8] >> 28));
    795 	ed25519_mod1(&m[0], l, (m[8] << 4) + (m[7] >> 28));
    796 
    797 	r[0] = m[0];
    798 	r[1] = m[1];
    799 	r[2] = m[2];
    800 	r[3] = m[3];
    801 	r[4] = m[4];
    802 	r[5] = m[5];
    803 	r[6] = m[6];
    804 	r[7] = m[7];
    805 }
    806 
    807 // x = a * b + y mod L
    808 func ed25519_ma_l(x: *int, a: *int, b: *int, y: *int) {
    809 	var _z: _ed25519_mod;
    810 	var z: *int;
    811 	var c: int;
    812 	var i: int;
    813 
    814 	z = (&_z) as *int;
    815 
    816 	z[0] = 0;
    817 	z[1] = 0;
    818 	z[2] = 0;
    819 	z[3] = 0;
    820 	z[4] = 0;
    821 	z[5] = 0;
    822 	z[6] = 0;
    823 	z[7] = 0;
    824 	z[8] = 0;
    825 	z[9] = 0;
    826 	z[10] = 0;
    827 	z[11] = 0;
    828 	z[12] = 0;
    829 	z[13] = 0;
    830 	z[14] = 0;
    831 	z[15] = 0;
    832 
    833 	i = 0;
    834 	loop {
    835 		if i == 8 {
    836 			break;
    837 		}
    838 
    839 		c = z[i + 0] + a[i] * b[0]; z[i + 0] = c & (-1 >> 32); c = c >> 32;
    840 		c = c + z[i + 1] + a[i] * b[1]; z[i + 1] = c & (-1 >> 32); c = c >> 32;
    841 		c = c + z[i + 2] + a[i] * b[2]; z[i + 2] = c & (-1 >> 32); c = c >> 32;
    842 		c = c + z[i + 3] + a[i] * b[3]; z[i + 3] = c & (-1 >> 32); c = c >> 32;
    843 		c = c + z[i + 4] + a[i] * b[4]; z[i + 4] = c & (-1 >> 32); c = c >> 32;
    844 		c = c + z[i + 5] + a[i] * b[5]; z[i + 5] = c & (-1 >> 32); c = c >> 32;
    845 		c = c + z[i + 6] + a[i] * b[6]; z[i + 6] = c & (-1 >> 32); c = c >> 32;
    846 		c = c + z[i + 7] + a[i] * b[7]; z[i + 7] = c & (-1 >> 32); c = c >> 32;
    847 		c = c + z[i + 8]; z[i + 8] = c & (-1 >> 32);
    848 
    849 		i = i + 1;
    850 	}
    851 
    852 	ed25519_mod_l(z, z);
    853 
    854 	c = z[0] + y[0]; z[0] = c; c = c >> 32;
    855 	c = z[1] + y[1]; z[1] = c; c = c >> 32;
    856 	c = z[2] + y[2]; z[2] = c; c = c >> 32;
    857 	c = z[3] + y[3]; z[3] = c; c = c >> 32;
    858 	c = z[4] + y[4]; z[4] = c; c = c >> 32;
    859 	c = z[5] + y[5]; z[5] = c; c = c >> 32;
    860 	c = z[6] + y[6]; z[6] = c; c = c >> 32;
    861 	c = z[7] + y[7]; z[7] = c; c = c >> 32;
    862 	z[8] = 0;
    863 	z[9] = 0;
    864 	z[10] = 0;
    865 	z[11] = 0;
    866 	z[12] = 0;
    867 	z[13] = 0;
    868 	z[14] = 0;
    869 	z[15] = 0;
    870 
    871 	ed25519_mod_l(x, z);
    872 }
    873 
    874 // x = a_512 mod L
    875 func ed25519_reduce_l(x: *int, a: *byte) {
    876 	var _z: _ed25519_point;
    877 	var z: *int;
    878 
    879 	z = (&_z) as *int;
    880 
    881 	z[0] = a[0] as int | (a[1] as int << 8) | (a[2] as int << 16) | (a[3] as int << 24);
    882 	z[1] = a[4] as int | (a[5] as int << 8) | (a[6] as int << 16) | (a[7] as int << 24);
    883 	z[2] = a[8] as int | (a[9] as int << 8) | (a[10] as int << 16) | (a[11] as int << 24);
    884 	z[3] = a[12] as int | (a[13] as int << 8) | (a[14] as int << 16) | (a[15] as int << 24);
    885 	z[4] = a[16] as int | (a[17] as int << 8) | (a[18] as int << 16) | (a[19] as int << 24);
    886 	z[5] = a[20] as int | (a[21] as int << 8) | (a[22] as int << 16) | (a[23] as int << 24);
    887 	z[6] = a[24] as int | (a[25] as int << 8) | (a[26] as int << 16) | (a[27] as int << 24);
    888 	z[7] = a[28] as int | (a[29] as int << 8) | (a[30] as int << 16) | (a[31] as int << 24);
    889 	z[8] = a[32] as int | (a[33] as int << 8) | (a[34] as int << 16) | (a[35] as int << 24);
    890 	z[9] = a[36] as int | (a[37] as int << 8) | (a[38] as int << 16) | (a[39] as int << 24);
    891 	z[10] = a[40] as int | (a[41] as int << 8) | (a[42] as int << 16) | (a[43] as int << 24);
    892 	z[11] = a[44] as int | (a[45] as int << 8) | (a[46] as int << 16) | (a[47] as int << 24);
    893 	z[12] = a[48] as int | (a[49] as int << 8) | (a[50] as int << 16) | (a[51] as int << 24);
    894 	z[13] = a[52] as int | (a[53] as int << 8) | (a[54] as int << 16) | (a[55] as int << 24);
    895 	z[14] = a[56] as int | (a[57] as int << 8) | (a[58] as int << 16) | (a[59] as int << 24);
    896 	z[15] = a[60] as int | (a[61] as int << 8) | (a[62] as int << 16) | (a[63] as int << 24);
    897 
    898 	ed25519_mod_l(x, z);
    899 }
    900 
    901 func ed25519_encode_l(dest: *byte, p: *int) {
    902 	dest[0] = p[0] as byte;
    903 	dest[1] = (p[0] >> 8) as byte;
    904 	dest[2] = (p[0] >> 16) as byte;
    905 	dest[3] = (p[0] >> 24) as byte;
    906 	dest[4] = p[1] as byte;
    907 	dest[5] = (p[1] >> 8) as byte;
    908 	dest[6] = (p[1] >> 16) as byte;
    909 	dest[7] = (p[1] >> 24) as byte;
    910 	dest[8] = p[2] as byte;
    911 	dest[9] = (p[2] >> 8) as byte;
    912 	dest[10] = (p[2] >> 16) as byte;
    913 	dest[11] = (p[2] >> 24) as byte;
    914 	dest[12] = p[3] as byte;
    915 	dest[13] = (p[3] >> 8) as byte;
    916 	dest[14] = (p[3] >> 16) as byte;
    917 	dest[15] = (p[3] >> 24) as byte;
    918 	dest[16] = p[4] as byte;
    919 	dest[17] = (p[4] >> 8) as byte;
    920 	dest[18] = (p[4] >> 16) as byte;
    921 	dest[19] = (p[4] >> 24) as byte;
    922 	dest[20] = p[5] as byte;
    923 	dest[21] = (p[5] >> 8) as byte;
    924 	dest[22] = (p[5] >> 16) as byte;
    925 	dest[23] = (p[5] >> 24) as byte;
    926 	dest[24] = p[6] as byte;
    927 	dest[25] = (p[6] >> 8) as byte;
    928 	dest[26] = (p[6] >> 16) as byte;
    929 	dest[27] = (p[6] >> 24) as byte;
    930 	dest[28] = p[7] as byte;
    931 	dest[29] = (p[7] >> 8) as byte;
    932 	dest[30] = (p[7] >> 16) as byte;
    933 	dest[31] = (p[7] >> 24) as byte;
    934 }
    935 
    936 func ed25519_eq(a: *int, b: *int): int {
    937 	var x: int;
    938 	x = a[0] ^ b[0];
    939 	x = x | (a[1] ^ b[1]);
    940 	x = x | (a[2] ^ b[2]);
    941 	x = x | (a[3] ^ b[3]);
    942 	x = x | (a[4] ^ b[4]);
    943 	x = x | (a[5] ^ b[5]);
    944 	x = x | (a[6] ^ b[6]);
    945 	x = x | (a[7] ^ b[7]);
    946 	x = x | (a[8] ^ b[8]);
    947 	x = x | (a[9] ^ b[9]);
    948 	x = x | (a[10] ^ b[10]);
    949 	x = x | (a[11] ^ b[11]);
    950 	x = x | (a[12] ^ b[12]);
    951 	x = x | (a[13] ^ b[13]);
    952 	x = x | (a[14] ^ b[14]);
    953 	x = x | (a[15] ^ b[15]);
    954 	x = (x >> 32) | x;
    955 	x = (x >> 16) | x;
    956 	x = (x >> 8) | x;
    957 	x = (x >> 4) | x;
    958 	x = (x >> 2) | x;
    959 	x = (x >> 1) | x;
    960 	return (x & 1) ^ 1;
    961 }
    962 
    963 func ed25519_verify(sig: *byte, pub: *byte, msg: *byte, len: int): int {
    964 	var ctx: sha512_ctx;
    965 	var _a: _ed25519_point;
    966 	var a: *int;
    967 	var _b: _ed25519_point;
    968 	var b: *int;
    969 	var _r: _ed25519_point;
    970 	var r: *int;
    971 	var _s: _ed25519_point;
    972 	var s: *int;
    973 	var _k: _ed25519_point;
    974 	var k: *int;
    975 	var _hk: _sha512_digest;
    976 	var hk: *byte;
    977 	var _sk: _sha512_digest;
    978 	var sk: *byte;
    979 
    980 	a = (&_a) as *int;
    981 	b = (&_b) as *int;
    982 	r = (&_r) as *int;
    983 	s = (&_s) as *int;
    984 	k = (&_k) as *int;
    985 	hk = (&_hk) as *byte;
    986 	sk = (&_sk) as *byte;
    987 
    988 	// A = public key
    989 	if !ed25519_decode(a, pub){
    990 		return 0;
    991 	}
    992 
    993 	// sig = R || S
    994 	if !ed25519_decode(r, sig) {
    995 		return 0;
    996 	}
    997 
    998 	bzero(sk, 64);
    999 	memcpy(sk, &sig[32], 32);
   1000 	ed25519_reduce_l(s, sk);
   1001 
   1002 	// k' = SHA-512(R || A || M)
   1003 	sha512_init(&ctx);
   1004 	sha512_update(&ctx, sig, 32);
   1005 	sha512_update(&ctx, pub, 32);
   1006 	sha512_update(&ctx, msg, len);
   1007 	sha512_final(hk, &ctx);
   1008 	ed25519_reduce_l(k, hk);
   1009 
   1010 	// RHS = R + [k']A
   1011 	ed25519_pk(a, a, k);
   1012 	ed25519_pa(a, a, r);
   1013 
   1014 	// LHS = [S]B
   1015 	ed25519_base(b);
   1016 	ed25519_pk(b, b, s);
   1017 
   1018 	return ed25519_eq(a, b);
   1019 }
   1020 
   1021 func ed25519_bi(d: *int) {
   1022 	d[7] = 0x0f26edf4;
   1023 	d[6] = 0x60a006bb;
   1024 	d[5] = 0xd27b08dc;
   1025 	d[4] = 0x03fc4f7e;
   1026 	d[3] = 0xc5a1d3d1;
   1027 	d[2] = 0x4b7d1a82;
   1028 	d[1] = 0xcc6e04aa;
   1029 	d[0] = 0xff457e06;
   1030 }
   1031 
   1032 // u = (1 + y) / (1 - y)
   1033 // v = sqrt(-486664) * u / x
   1034 func cv25519_of_ed25519(uv: *int, xy: *int) {
   1035 	var _a: _ed25519_limb;
   1036 	var _b: _ed25519_limb;
   1037 	var _c: _ed25519_limb;
   1038 	var _d: _ed25519_limb;
   1039 	var a: *int;
   1040 	var b: *int;
   1041 	var c: *int;
   1042 	var d: *int;
   1043 
   1044 	a = &_a.x0;
   1045 	b = &_b.x0;
   1046 	c = &_c.x0;
   1047 	d = &_d.x0;
   1048 
   1049 	ed25519_one(a);
   1050 	ed25519_add(a, a, &xy[8]);
   1051 	ed25519_one(b);
   1052 	ed25519_sub(b, b, &xy[8]);
   1053 	ed25519_inv(b, b);
   1054 
   1055 	ed25519_inv(d, xy);
   1056 
   1057 	ed25519_mul(uv, a, b);
   1058 
   1059 	ed25519_bi(c);
   1060 	ed25519_mul(c, c, uv);
   1061 	ed25519_mul(&uv[8], c, d);
   1062 }
   1063 
   1064 // x = sqrt(-486664) * u / v
   1065 // y = (u - 1) / (u + 1)
   1066 func ed25519_of_cv25519(xy: *int, uv: *int) {
   1067 	var _a: _ed25519_limb;
   1068 	var _b: _ed25519_limb;
   1069 	var _c: _ed25519_limb;
   1070 	var _d: _ed25519_limb;
   1071 	var a: *int;
   1072 	var b: *int;
   1073 	var c: *int;
   1074 	var d: *int;
   1075 
   1076 	a = &_a.x0;
   1077 	b = &_b.x0;
   1078 	c = &_c.x0;
   1079 	d = &_d.x0;
   1080 
   1081 	ed25519_bi(a);
   1082 	ed25519_mul(a, a, uv);
   1083 	ed25519_inv(b, &uv[8]);
   1084 
   1085 	ed25519_one(c);
   1086 	ed25519_sub(c, uv, c);
   1087 	ed25519_one(d);
   1088 	ed25519_add(d, uv, d);
   1089 	ed25519_inv(d, d);
   1090 
   1091 	ed25519_mul(xy, a, b);
   1092 	ed25519_mul(&xy[8], c, d);
   1093 }
   1094 
   1095 // cv25519: v**2 = u**3 + a*u**2 + u mod p
   1096 func x25519_decode(uv: *int, u: *byte): int {
   1097 	var _v: _ed25519_limb;
   1098 	var v: *int;
   1099 
   1100 	v = &_v.x0;
   1101 
   1102 	uv[0] = u[0] as int | (u[1] as int << 8) | (u[2] as int << 16) | (u[3] as int << 24);
   1103 	uv[1] = u[4] as int | (u[5] as int << 8) | (u[6] as int << 16) | (u[7] as int << 24);
   1104 	uv[2] = u[8] as int | (u[9] as int << 8) | (u[10] as int << 16) | (u[11] as int << 24);
   1105 	uv[3] = u[12] as int | (u[13] as int << 8) | (u[14] as int << 16) | (u[15] as int << 24);
   1106 	uv[4] = u[16] as int | (u[17] as int << 8) | (u[18] as int << 16) | (u[19] as int << 24);
   1107 	uv[5] = u[20] as int | (u[21] as int << 8) | (u[22] as int << 16) | (u[23] as int << 24);
   1108 	uv[6] = u[24] as int | (u[25] as int << 8) | (u[26] as int << 16) | (u[27] as int << 24);
   1109 	uv[7] = (u[28] as int | (u[29] as int << 8) | (u[30] as int << 16) | (u[31] as int << 24)) & (-1 >> 33);
   1110 
   1111 	ed25519_reduce(uv);
   1112 
   1113 	ed25519_a(v);
   1114 	ed25519_add(v, v, uv);
   1115 	ed25519_mul(v, v, uv);
   1116 	ed25519_mul(v, v, uv);
   1117 	ed25519_add(v, v, uv);
   1118 
   1119 	if !ed25519_sqrt(&uv[8], v) {
   1120 		return 0;
   1121 	}
   1122 
   1123 	return !ed25519_zerop(&uv[8]);
   1124 }
   1125 
   1126 func x25519_encode(u: *byte, uv: *int) {
   1127 	u[0] = uv[0] as byte;
   1128 	u[1] = (uv[0] >> 8) as byte;
   1129 	u[2] = (uv[0] >> 16) as byte;
   1130 	u[3] = (uv[0] >> 24) as byte;
   1131 	u[4] = uv[1] as byte;
   1132 	u[5] = (uv[1] >> 8) as byte;
   1133 	u[6] = (uv[1] >> 16) as byte;
   1134 	u[7] = (uv[1] >> 24) as byte;
   1135 	u[8] = uv[2] as byte;
   1136 	u[9] = (uv[2] >> 8) as byte;
   1137 	u[10] = (uv[2] >> 16) as byte;
   1138 	u[11] = (uv[2] >> 24) as byte;
   1139 	u[12] = uv[3] as byte;
   1140 	u[13] = (uv[3] >> 8) as byte;
   1141 	u[14] = (uv[3] >> 16) as byte;
   1142 	u[15] = (uv[3] >> 24) as byte;
   1143 	u[16] = uv[4] as byte;
   1144 	u[17] = (uv[4] >> 8) as byte;
   1145 	u[18] = (uv[4] >> 16) as byte;
   1146 	u[19] = (uv[4] >> 24) as byte;
   1147 	u[20] = uv[5] as byte;
   1148 	u[21] = (uv[5] >> 8) as byte;
   1149 	u[22] = (uv[5] >> 16) as byte;
   1150 	u[23] = (uv[5] >> 24) as byte;
   1151 	u[24] = uv[6] as byte;
   1152 	u[25] = (uv[6] >> 8) as byte;
   1153 	u[26] = (uv[6] >> 16) as byte;
   1154 	u[27] = (uv[6] >> 24) as byte;
   1155 	u[28] = uv[7] as byte;
   1156 	u[29] = (uv[7] >> 8) as byte;
   1157 	u[30] = (uv[7] >> 16) as byte;
   1158 	u[31] = (uv[7] >> 24) as byte;
   1159 }
   1160 
   1161 func x25519_base(u: *byte) {
   1162 	bzero(u, 32);
   1163 	u[0] = 9 as byte;
   1164 }
   1165 
   1166 func x25519(uk: *byte, u: *byte, k: *byte): int {
   1167 	var _uv: _ed25519_point;
   1168 	var _xy: _ed25519_point;
   1169 	var _kc: _ed25519_limb;
   1170 	var uv: *int;
   1171 	var xy: *int;
   1172 	var kc: *int;
   1173 
   1174 	uv = &_uv.x0;
   1175 	xy = &_xy.x0;
   1176 	kc = &_kc.x0;
   1177 
   1178 	if !x25519_decode(uv, u) {
   1179 		return 0;
   1180 	}
   1181 
   1182 	ed25519_of_cv25519(xy, uv);
   1183 	ed25519_clamp(kc, k);
   1184 	ed25519_pk(xy, xy, kc);
   1185 	cv25519_of_ed25519(uv, xy);
   1186 	x25519_encode(uk, uv);
   1187 	return 1;
   1188 }
   1189 
   1190 func ed25519_zerop(x: *int): int {
   1191 	var a: int;
   1192 	a = x[0] | x[1] | x[2] | x[3] | x[4] | x[5] | x[6] | x[7];
   1193 	a = (a >> 32) | a;
   1194 	a = (a >> 16) | a;
   1195 	a = (a >> 8) | a;
   1196 	a = (a >> 4) | a;
   1197 	a = (a >> 2) | a;
   1198 	a = (a >> 1) | a;
   1199 	return (a & 1) ^ 1;
   1200 }
   1201 
   1202 // cv25519: v**2 = u**3 + a*u**2 + u mod p
   1203 func x25519_check(uv: *int): int {
   1204 	var _a: _ed25519_limb;
   1205 	var _b: _ed25519_limb;
   1206 	var a: *int;
   1207 	var b: *int;
   1208 
   1209 	a = &_a.x0;
   1210 	b = &_b.x0;
   1211 
   1212 	ed25519_a(a);
   1213 	ed25519_mul(b, uv, uv);
   1214 	ed25519_mul(a, a, b);
   1215 	ed25519_mul(b, b, uv);
   1216 	ed25519_add(a, a, b);
   1217 	ed25519_add(a, a, uv);
   1218 
   1219 	ed25519_mul(b, &uv[8], &uv[8]);
   1220 	ed25519_sub(a, a, b);
   1221 
   1222 	return ed25519_zerop(a);
   1223 }
   1224 
   1225 // ed25519: -x**2 + y**2 = 1 + d*x**2*y**2 mod p
   1226 func ed25519_check(xy: *int): int {
   1227 	var _a: _ed25519_limb;
   1228 	var _b: _ed25519_limb;
   1229 	var _c: _ed25519_limb;
   1230 	var a: *int;
   1231 	var b: *int;
   1232 	var c: *int;
   1233 
   1234 	a = &_a.x0;
   1235 	b = &_b.x0;
   1236 	c = &_c.x0;
   1237 
   1238 	ed25519_mul(b, xy, xy);
   1239 	ed25519_mul(c, &xy[8], &xy[8]);
   1240 
   1241 	ed25519_one(a);
   1242 	ed25519_add(a, a, b);
   1243 	ed25519_sub(a, a, c);
   1244 
   1245 	ed25519_mul(b, b, c);
   1246 	ed25519_d(c);
   1247 	ed25519_mul(b, b, c);
   1248 
   1249 	ed25519_add(a, a, b);
   1250 
   1251 	return ed25519_zerop(a);
   1252 }
   1253 
   1254 func ed25519_set_lsb(xy: *int, lsb: int) {
   1255 	var _a: _ed25519_limb;
   1256 	var a: *int;
   1257 
   1258 	a = &_a.x0;
   1259 
   1260 	ed25519_zero(a);
   1261 	ed25519_sub(a, a, xy);
   1262 
   1263 	ed25519_selectl(xy, xy, a, (xy[0] ^ lsb) & 1);
   1264 }
   1265 
   1266 func ed25519_clamp(k: *int, b: *byte) {
   1267 	k[0] = (b[0] as int | (b[1] as int << 8) | (b[2] as int << 16) | (b[3] as int << 24)) & -8;
   1268 	k[1] = b[4] as int | (b[5] as int << 8) | (b[6] as int << 16) | (b[7] as int << 24);
   1269 	k[2] = b[8] as int | (b[9] as int << 8) | (b[10] as int << 16) | (b[11] as int << 24);
   1270 	k[3] = b[12] as int | (b[13] as int << 8) | (b[14] as int << 16) | (b[15] as int << 24);
   1271 	k[4] = b[16] as int | (b[17] as int << 8) | (b[18] as int << 16) | (b[19] as int << 24);
   1272 	k[5] = b[20] as int | (b[21] as int << 8) | (b[22] as int << 16) | (b[23] as int << 24);
   1273 	k[6] = b[24] as int | (b[25] as int << 8) | (b[26] as int << 16) | (b[27] as int << 24);
   1274 	k[7] = ((b[28] as int | (b[29] as int << 8) | (b[30] as int << 16) | (b[31] as int << 24)) & (-1 >> 33)) | (1 << 30);
   1275 }