os

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

commit c36c721b783548322986b5a15c66094938619351
parent 83d9fd50f6f583181c0b413d6fbf4b85060cd063
Author: erai <erai@omiltem.net>
Date:   Thu,  9 May 2024 02:45:07 -0400

Add ed25519

Diffstat:
Aed25519.c | 324+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aed25519_test.c | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 389 insertions(+), 0 deletions(-)

diff --git a/ed25519.c b/ed25519.c @@ -0,0 +1,324 @@ +// https://www.rfc-editor.org/rfc/rfc8032 +// y**2 = x**3 + 486662 * x**2 + x mod 2**252 - 19 + +struct _ed25519_limb { + x0: int; + x1: int; + x2: int; + x3: int; + x4: int; + x5: int; + x6: int; + x7: int; +} + +struct _ed25519_point { + x: _ed25519_limb; + y: _ed25519_limb; +} + +ed25519_reduce(r: *int) { + var c: int; + var k: int; + + c = (r[0] + 19) >> 32; + c = (c + r[1]) >> 32; + c = (c + r[2]) >> 32; + c = (c + r[3]) >> 32; + c = (c + r[4]) >> 32; + c = (c + r[5]) >> 32; + c = (c + r[6]) >> 32; + c = (c + r[7] + (1 << 31)) >> 32; + + k = -c >> 32; + + c = c + r[0] + (18 & k); r[0] = c & (-1 >> 32); c = c >> 32; + c = c + r[1]; r[1] = c & (-1 >> 32); c = c >> 32; + c = c + r[2]; r[2] = c & (-1 >> 32); c = c >> 32; + c = c + r[3]; r[3] = c & (-1 >> 32); c = c >> 32; + c = c + r[4]; r[4] = c & (-1 >> 32); c = c >> 32; + c = c + r[5]; r[5] = c & (-1 >> 32); c = c >> 32; + c = c + r[6]; r[6] = c & (-1 >> 32); c = c >> 32; + c = c + r[7] + ((1 << 31) & k); r[7] = c & (-1 >> 32); c = c >> 32; +} + +ed25519_add(r: *int, a: *int, b: *int) { + var c: int; + + c = a[0] + b[0]; r[0] = c & (-1 >> 32); c = c >> 32; + c = c + a[1] + b[1]; r[1] = c & (-1 >> 32); c = c >> 32; + c = c + a[2] + b[2]; r[2] = c & (-1 >> 32); c = c >> 32; + c = c + a[3] + b[3]; r[3] = c & (-1 >> 32); c = c >> 32; + c = c + a[4] + b[4]; r[4] = c & (-1 >> 32); c = c >> 32; + c = c + a[5] + b[5]; r[5] = c & (-1 >> 32); c = c >> 32; + c = c + a[6] + b[6]; r[6] = c & (-1 >> 32); c = c >> 32; + c = c + a[7] + b[7]; r[7] = c & (-1 >> 32); c = c >> 32; + + ed25519_reduce(r); +} + +ed25519_sub(r: *int, a: *int, b: *int) { + var c: int; + c = 1 + a[0] + (-19 & (-1 >> 32)) + (~b[0] & (-1 >> 32)); r[0] = c & (-1 >> 32); c = c >> 32; + c = c + a[1] + (-1 >> 32) + (~b[1] & (-1 >> 32)); r[1] = c & (-1 >> 32); c = c >> 32; + c = c + a[2] + (-1 >> 32) + (~b[2] & (-1 >> 32)); r[2] = c & (-1 >> 32); c = c >> 32; + c = c + a[3] + (-1 >> 32) + (~b[3] & (-1 >> 32)); r[3] = c & (-1 >> 32); c = c >> 32; + c = c + a[4] + (-1 >> 32) + (~b[4] & (-1 >> 32)); r[4] = c & (-1 >> 32); c = c >> 32; + c = c + a[5] + (-1 >> 32) + (~b[5] & (-1 >> 32)); r[5] = c & (-1 >> 32); c = c >> 32; + c = c + a[6] + (-1 >> 32) + (~b[6] & (-1 >> 32)); r[6] = c & (-1 >> 32); c = c >> 32; + c = c + a[7] + (-1 >> 33) + (~b[7] & (-1 >> 32)); r[7] = c & (-1 >> 33); + + //ed25519_reduce(r); + +} + +ed25519_mul(r: *int, a: *int, b: *int) { + var _x: _ed25519_point; + var x: *int; + var c: int; + var i: 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; + x[10] = 0; + x[11] = 0; + x[12] = 0; + x[13] = 0; + x[14] = 0; + x[15] = 0; + + i = 0; + loop { + if i == 8 { + break; + } + + c = x[i + 0] + a[i] * b[0]; x[i + 0] = c & (-1 >> 32); c = c >> 32; + c = c + x[i + 1] + a[i] * b[1]; x[i + 1] = c & (-1 >> 32); c = c >> 32; + c = c + x[i + 2] + a[i] * b[2]; x[i + 2] = c & (-1 >> 32); c = c >> 32; + c = c + x[i + 3] + a[i] * b[3]; x[i + 3] = c & (-1 >> 32); c = c >> 32; + c = c + x[i + 4] + a[i] * b[4]; x[i + 4] = c & (-1 >> 32); c = c >> 32; + c = c + x[i + 5] + a[i] * b[5]; x[i + 5] = c & (-1 >> 32); c = c >> 32; + c = c + x[i + 6] + a[i] * b[6]; x[i + 6] = c & (-1 >> 32); c = c >> 32; + c = c + x[i + 7] + a[i] * b[7]; x[i + 7] = c & (-1 >> 32); c = c >> 32; + c = c + x[i + 8]; x[i + 8] = c & (-1 >> 32); + + i = i + 1; + } + + c = x[0] + x[8] * 38; x[0] = c & (-1 >> 32); c = c >> 32; + c = c + x[1] + x[9] * 38; x[1] = c & (-1 >> 32); c = c >> 32; + c = c + x[2] + x[10] * 38; x[2] = c & (-1 >> 32); c = c >> 32; + c = c + x[3] + x[11] * 38; x[3] = c & (-1 >> 32); c = c >> 32; + c = c + x[4] + x[12] * 38; x[4] = c & (-1 >> 32); c = c >> 32; + c = c + x[5] + x[13] * 38; x[5] = c & (-1 >> 32); c = c >> 32; + c = c + x[6] + x[14] * 38; x[6] = c & (-1 >> 32); c = c >> 32; + c = c + x[7] + x[15] * 38; x[7] = c & (-1 >> 32); c = c >> 32; + + ed25519_reduce(x); + + c = c * 38 + x[0]; x[0] = c & (-1 >> 32); c = c >> 32; + c = c + x[1]; x[1] = c & (-1 >> 32); c = c >> 32; + c = c + x[2]; x[2] = c & (-1 >> 32); c = c >> 32; + c = c + x[3]; x[3] = c & (-1 >> 32); c = c >> 32; + c = c + x[4]; x[4] = c & (-1 >> 32); c = c >> 32; + c = c + x[5]; x[5] = c & (-1 >> 32); c = c >> 32; + c = c + x[6]; x[6] = c & (-1 >> 32); c = c >> 32; + c = c + x[7]; x[7] = c & (-1 >> 32); + + ed25519_reduce(x); + + r[0] = x[0]; + r[1] = x[1]; + r[2] = x[2]; + r[3] = x[3]; + r[4] = x[4]; + r[5] = x[5]; + r[6] = x[6]; + r[7] = x[7]; +} + +ed25519_inv(r: *int, a: *int) { + var _x: _ed25519_point; + var x: *int; + var i: int; + + x = (&_x):*int; + + i = 0; + loop { + if i == 8 { + break; + } + x[i] = a[i]; r[i] = a[i]; + i = i + 1; + } + + i = 0; + loop { + if i == 254 { + break; + } + ed25519_mul(r, r, r); + if (i != 249 && i != 251) { + ed25519_mul(r, r, x); + } + i = i + 1; + } +} + +ed25519_select(r: *int, a: *int, b: *int, k: int) { + r[0] = (a[0] & ~k) | (b[0] & k); + r[1] = (a[1] & ~k) | (b[1] & k); + r[2] = (a[2] & ~k) | (b[2] & k); + r[3] = (a[3] & ~k) | (b[3] & k); + r[4] = (a[4] & ~k) | (b[4] & k); + r[5] = (a[5] & ~k) | (b[5] & k); + r[6] = (a[6] & ~k) | (b[6] & k); + r[7] = (a[7] & ~k) | (b[7] & k); + r[8] = (a[8] & ~k) | (b[8] & k); + r[9] = (a[9] & ~k) | (b[9] & k); + r[10] = (a[10] & ~k) | (b[10] & k); + r[11] = (a[11] & ~k) | (b[11] & k); + r[12] = (a[12] & ~k) | (b[12] & k); + r[13] = (a[13] & ~k) | (b[13] & k); + r[14] = (a[14] & ~k) | (b[14] & k); + r[15] = (a[15] & ~k) | (b[15] & k); +} + +ed25519_one(r: *int) { + r[0] = 1; + r[1] = 0; + r[2] = 0; + r[3] = 0; + r[4] = 0; + r[5] = 0; + r[6] = 0; + r[7] = 0; +} + +//// x1 * y2 + x2 * y1 y1 * y2 - a * x1 * x2 +//// x3 = ---------------------------, y3 = --------------------------- +//// 1 + d * x1 * x2 * y1 * y2 1 - d * x1 * x2 * y1 * y2 +ed25519_pa(r: *int, a: *int, b: * int) { + var _y1y2: _ed25519_limb; + var y1y2: *int; + var _x1x2: _ed25519_limb; + var x1x2: *int; + var _x1y2: _ed25519_limb; + var x1y2: *int; + var _x2y1: _ed25519_limb; + var x2y1: *int; + var _dxy: _ed25519_limb; + var dxy: *int; + var _dxy1: _ed25519_limb; + var dxy1: *int; + var _dxy2: _ed25519_limb; + var dxy2: *int; + var _d: _ed25519_limb; + var d: *int; + + y1y2 = &_y1y2.x0; + x1x2 = &_x1x2.x0; + x1y2 = &_x1y2.x0; + x2y1 = &_x2y1.x0; + dxy = &_dxy.x0; + dxy1 = &_dxy1.x0; + dxy2 = &_dxy2.x0; + d = &_d.x0; + + d[7] = (0x5203 << 16) | 0x6cee; + d[6] = (0x2b6f << 16) | 0xfe73; + d[5] = (0x8cc7 << 16) | 0x4079; + d[4] = (0x7779 << 16) | 0xe898; + d[3] = (0x0070 << 16) | 0x0a4d; + d[2] = (0x4141 << 16) | 0xd8ab; + d[1] = (0x75eb << 16) | 0x4dca; + d[0] = (0x1359 << 16) | 0x78a3; + + ed25519_mul(y1y2, &a[8], &b[8]); + ed25519_mul(x1x2, a, b); + + ed25519_mul(x1y2, a, &b[8]); + ed25519_mul(x2y1, b, &a[8]); + + ed25519_mul(dxy, x1y2, x2y1); + ed25519_mul(dxy, d, dxy); + + ed25519_one(dxy1); + ed25519_add(dxy1, dxy1, dxy); + ed25519_inv(dxy1, dxy1); + + ed25519_add(r, x1y2, x2y1); + ed25519_mul(r, r, dxy1); + + ed25519_one(dxy2); + ed25519_sub(dxy2, dxy2, dxy); + ed25519_inv(dxy2, dxy2); + + ed25519_add(&r[8], y1y2, x1x2); + ed25519_mul(&r[8], &r[8], dxy2); +} + +ed25519_pk(r: *int, a: *int, k: *int) { + var _b: _ed25519_point; + var b: *int; + var _c: _ed25519_point; + var c: *int; + var e: int; + var i: int; + var j: int; + + b = (&_b):*int; + c = (&_c):*int; + + b[0] = a[0] & (-1 >> 32); r[0] = 0; + b[1] = a[1] & (-1 >> 32); r[1] = 0; + b[2] = a[2] & (-1 >> 32); r[2] = 0; + b[3] = a[3] & (-1 >> 32); r[3] = 0; + b[4] = a[4] & (-1 >> 32); r[4] = 0; + b[5] = a[5] & (-1 >> 32); r[5] = 0; + b[6] = a[6] & (-1 >> 32); r[6] = 0; + b[7] = a[7] & (-1 >> 32); r[7] = 0; + b[8] = a[8] & (-1 >> 32); r[8] = 1; + b[9] = a[9] & (-1 >> 32); r[9] = 0; + b[10] = a[10] & (-1 >> 32); r[10] = 0; + b[11] = a[11] & (-1 >> 32); r[11] = 0; + b[12] = a[12] & (-1 >> 32); r[12] = 0; + b[13] = a[13] & (-1 >> 32); r[13] = 0; + b[14] = a[14] & (-1 >> 32); r[14] = 0; + b[15] = a[15] & (-1 >> 32); r[15] = 0; + + i = 7; + loop { + e = k[i]; + + j = 0; + loop { + if j == 32 { + break; + } + ed25519_pa(r, r, r); + ed25519_pa(c, r, b); + ed25519_select(r, r, c, -((e >> 31) & 1)); + e = e << 1; + j = j + 1; + } + + if i == 0 { + break; + } + + i = i - 1; + } +} diff --git a/ed25519_test.c b/ed25519_test.c @@ -0,0 +1,65 @@ +main(c: int, v: **byte, e: **byte) { + var _r: _ed25519_point; + var _p: _ed25519_point; + var _k: _ed25519_point; + var r: *int; + var p: *int; + var k: *int; + + r = (&_r):*int; + p = (&_p):*int; + k = (&_k):*int; + + bzero(r: *byte, sizeof(_r)); + bzero(p: *byte, sizeof(_p)); + bzero(k: *byte, sizeof(_k)); + + p[7] = (0x2169 << 16) | 0x36d3; + p[6] = (0xcd6e << 16) | 0x53fe; + p[5] = (0xc0a4 << 16) | 0xe231; + p[4] = (0xfdd6 << 16) | 0xdc5c; + p[3] = (0x692c << 16) | 0xc760; + p[2] = (0x9525 << 16) | 0xa7b2; + p[1] = (0xc956 << 16) | 0x2d60; + p[0] = (0x8f25 << 16) | 0xd51a; + + p[15] = (0x6666 << 16) | 0x6666; + p[14] = (0x6666 << 16) | 0x6666; + p[13] = (0x6666 << 16) | 0x6666; + p[12] = (0x6666 << 16) | 0x6666; + p[11] = (0x6666 << 16) | 0x6666; + p[10] = (0x6666 << 16) | 0x6666; + p[9] = (0x6666 << 16) | 0x6666; + p[8] = (0x6666 << 16) | 0x6658; + + k[7] = (0x1000 << 16) | 0x0000; + k[6] = 0; + k[5] = 0; + k[4] = 0; + k[3] = (0x14de << 16) | 0xf9de; + k[2] = (0xa2f7 << 16) | 0x9cd6; + k[1] = (0x5812 << 16) | 0x631a; + k[0] = (0x5cf5 << 16) | 0xd3ed; + + ed25519_pk(r, p, k); + + fdputh32(1, r[7]); + fdputh32(1, r[6]); + fdputh32(1, r[5]); + fdputh32(1, r[4]); + fdputh32(1, r[3]); + fdputh32(1, r[2]); + fdputh32(1, r[1]); + fdputh32(1, r[0]); + fdputc(1, '\n'); + + fdputh32(1, r[15]); + fdputh32(1, r[14]); + fdputh32(1, r[13]); + fdputh32(1, r[12]); + fdputh32(1, r[11]); + fdputh32(1, r[10]); + fdputh32(1, r[9]); + fdputh32(1, r[8]); + fdputc(1, '\n'); +}