commit 36cebf29d26a62233a6ffeef069923d51991b8d6
parent 9ad099d9ada7dc701a181d2fe3ef9ae1fd8367a7
Author: erai <erai@omiltem.net>
Date: Sun, 19 May 2024 23:29:15 -0400
full ed25519
Diffstat:
M | ed25519.c | | | 485 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- |
M | ed25519_test.c | | | 29 | ++++++++--------------------- |
M | sha512.c | | | 61 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- |
M | x25519_test.c | | | 5 | ++++- |
4 files changed, 539 insertions(+), 41 deletions(-)
diff --git a/ed25519.c b/ed25519.c
@@ -1,4 +1,3 @@
-// https://www.rfc-editor.org/rfc/rfc7748
// https://www.rfc-editor.org/rfc/rfc8032
// p = 2**255 - 19
// = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed
@@ -50,8 +49,42 @@ struct _ed25519_limb {
}
struct _ed25519_point {
- x: _ed25519_limb;
- y: _ed25519_limb;
+ x0: int;
+ x1: int;
+ x2: int;
+ x3: int;
+ x4: int;
+ x5: int;
+ x6: int;
+ x7: int;
+ y0: int;
+ y1: int;
+ y2: int;
+ y3: int;
+ y4: int;
+ y5: int;
+ y6: int;
+ y7: int;
+}
+
+struct _ed25519_mod {
+ x0: int;
+ x1: int;
+ x2: int;
+ x3: int;
+ x4: int;
+ x5: int;
+ x6: int;
+ x7: int;
+ x8: int;
+ x9: int;
+ x10: int;
+ x11: int;
+ x12: int;
+ x13: int;
+ x14: int;
+ x15: int;
+ x16: int;
}
struct _x25519_block {
@@ -62,6 +95,24 @@ struct _x25519_block {
_x4: int;
}
+struct _ed25519_pub {
+ x0: int;
+ x1: int;
+ x2: int;
+ x3: int;
+}
+
+struct _ed25519_sig {
+ x0: int;
+ x1: int;
+ x2: int;
+ x3: int;
+ x4: int;
+ x5: int;
+ x6: int;
+ x7: int;
+}
+
ed25519_reduce(r: *int) {
var c: int;
var k: int;
@@ -343,8 +394,8 @@ ed25519_pk(r: *int, a: *int, k: *int) {
var i: int;
var j: int;
- b = &_b.x.x0;
- c = &_c.x.x0;
+ b = &_b.x0;
+ c = &_c.x0;
b[0] = a[0] & (-1 >> 32); r[0] = 0;
b[1] = a[1] & (-1 >> 32); r[1] = 0;
@@ -474,7 +525,60 @@ ed25519_sqrt(r: *int, x: *int): int {
}
// x**2 = (1 - y**2) / (d * y**2 - 1) mod p
-ed25519_decode(p: *int, src: *byte) {
+ed25519_decode(p: *int, y: *byte): int {
+ var _xy: _ed25519_point;
+ var xy: *int;
+ var _a: _ed25519_limb;
+ var a: *int;
+ var _b: _ed25519_limb;
+ var b: *int;
+
+ xy = &_xy.x0;
+ a = &_a.x0;
+ b = &_b.x0;
+
+ xy[8] = y[0]:int | (y[1]:int << 8) | (y[2]:int << 16) | (y[3]:int << 24);
+ xy[9] = y[4]:int | (y[5]:int << 8) | (y[6]:int << 16) | (y[7]:int << 24);
+ xy[10] = y[8]:int | (y[9]:int << 8) | (y[10]:int << 16) | (y[11]:int << 24);
+ xy[11] = y[12]:int | (y[13]:int << 8) | (y[14]:int << 16) | (y[15]:int << 24);
+ xy[12] = y[16]:int | (y[17]:int << 8) | (y[18]:int << 16) | (y[19]:int << 24);
+ xy[13] = y[20]:int | (y[21]:int << 8) | (y[22]:int << 16) | (y[23]:int << 24);
+ xy[14] = y[24]:int | (y[25]:int << 8) | (y[26]:int << 16) | (y[27]:int << 24);
+ xy[15] = (y[28]:int | (y[29]:int << 8) | (y[30]:int << 16) | (y[31]:int << 24)) & (-1 >> 33);
+
+ ed25519_mul(a, &xy[8], &xy[8]);
+ ed25519_d(b);
+ ed25519_mul(b, b, a);
+ ed25519_one(xy);
+ ed25519_sub(b, b, xy);
+ ed25519_sub(xy, xy, a);
+ ed25519_inv(b, b);
+ ed25519_mul(xy, xy, b);
+
+ if !ed25519_sqrt(xy, xy) {
+ return 0;
+ }
+
+ ed25519_set_lsb(xy, y[31]:int >> 7);
+
+ p[0] = xy[0];
+ p[1] = xy[1];
+ p[2] = xy[2];
+ p[3] = xy[3];
+ p[4] = xy[4];
+ p[5] = xy[5];
+ p[6] = xy[6];
+ p[7] = xy[7];
+ p[8] = xy[8];
+ p[9] = xy[9];
+ p[10] = xy[10];
+ p[11] = xy[11];
+ p[12] = xy[12];
+ p[13] = xy[13];
+ p[14] = xy[14];
+ p[15] = xy[15];
+
+ return 1;
}
ed25519_encode(dest: *byte, p: *int) {
@@ -512,29 +616,376 @@ ed25519_encode(dest: *byte, p: *int) {
dest[31] = (p[15] >> 24):byte | ((p[0] & 1) << 7):byte;
}
-ed25519_pub(p: *byte, k: *byte) {
+ed25519_pub(pub: *byte, b: *byte) {
+ var _h: _sha512_digest;
+ var h: *byte;
+ var _a: _ed25519_point;
+ var a: *int;
+ var _s: _ed25519_limb;
+ var s: *int;
+
+ h = (&_h):*byte;
+ a = &_a.x0;
+ s = &_s.x0;
+
// h || prefix = SHA-512(b)
+ sha512(h, b, 32);
+
// s = clamp(h)
+ ed25519_clamp(s, h);
+
// A = [s]B
+ ed25519_base(a);
+ ed25519_pk(a, a, s);
+
// public key = A
+ ed25519_encode(pub, a);
}
-ed25519_sign(k: *byte) {
+ed25519_sign(sig: *byte, b: *byte, msg: *byte, len: int) {
+ var _h: _sha512_digest;
+ var h: *byte;
+ var _hr: _sha512_digest;
+ var hr: *byte;
+ var _hk: _sha512_digest;
+ var hk: *byte;
+ var ctx: sha512_ctx;
+ var _a: _ed25519_point;
+ var a: *int;
+ var _pub: _ed25519_point;
+ var pub: *byte;
+ var _rb: _ed25519_point;
+ var rb: *int;
+ var _s: _ed25519_limb;
+ var s: *int;
+ var _r: _ed25519_limb;
+ var r: *int;
+ var _k: _ed25519_limb;
+ var k: *int;
+
+ h = (&_h):*byte;
+ hr = (&_hr):*byte;
+ hk = (&_hk):*byte;
+ a = &_a.x0;
+ pub = (&_pub):*byte;
+ rb = &_rb.x0;
+ s = &_s.x0;
+ r = &_r.x0;
+ k = &_k.x0;
+
// h || prefix = SHA-512(b)
+ sha512(h, b, 32);
+
// s = clamp(h)
+ ed25519_clamp(s, h);
+
// A = [s]B
+ ed25519_base(a);
+ ed25519_pk(a, a, s);
+ ed25519_encode(pub, a);
+
// r = SHA-512(prefix || M)
+ sha512_init(&ctx);
+ sha512_update(&ctx, &h[32], 32);
+ sha512_update(&ctx, msg, len);
+ sha512_final(hr, &ctx);
+ ed25519_reduce_l(r, hr);
+
// R = [r]B
+ ed25519_base(rb);
+ ed25519_pk(rb, rb, r);
+ ed25519_encode(sig, rb);
+
// k = SHA-512(R || A || M)
- // S = r + k * s mod L
- // signature = R || S
+ sha512_init(&ctx);
+ sha512_update(&ctx, sig, 32);
+ sha512_update(&ctx, pub, 32);
+ sha512_update(&ctx, msg, len);
+ sha512_final(hk, &ctx);
+ ed25519_reduce_l(k, hk);
+
+ // S = k * s + r mod L
+ ed25519_ma_l(s, s, k, r);
+ ed25519_encode_l(&sig[32], s);
+}
+
+ed25519_l(l: *int) {
+ l[7] = (0x1000 << 16) | 0x0000;
+ l[6] = (0x0000 << 16) | 0x0000;
+ l[5] = (0x0000 << 16) | 0x0000;
+ l[4] = (0x0000 << 16) | 0x0000;
+ l[3] = (0x14de << 16) | 0xf9de;
+ l[2] = (0xa2f7 << 16) | 0x9cd6;
+ l[1] = (0x5812 << 16) | 0x631a;
+ l[0] = (0x5cf5 << 16) | 0xd3ed;
+}
+
+ed25519_mod1(m: *int, l: *int, q: int) {
+ var c: int;
+ var r: int;
+
+ c = q * l[0]; r = 1 + m[0] + (~c & (-1 >> 32)); c = c >> 32; r = r >> 32;
+ c = c + q * l[1]; r = r + m[1] + (~c & (-1 >> 32)); c = c >> 32; r = r >> 32;
+ c = c + q * l[2]; r = r + m[2] + (~c & (-1 >> 32)); c = c >> 32; r = r >> 32;
+ c = c + q * l[3]; r = r + m[3] + (~c & (-1 >> 32)); c = c >> 32; r = r >> 32;
+ c = c + q * l[4]; r = r + m[4] + (~c & (-1 >> 32)); c = c >> 32; r = r >> 32;
+ c = c + q * l[5]; r = r + m[5] + (~c & (-1 >> 32)); c = c >> 32; r = r >> 32;
+ c = c + q * l[6]; r = r + m[6] + (~c & (-1 >> 32)); c = c >> 32; r = r >> 32;
+ c = c + q * l[7]; r = r + m[7] + (~c & (-1 >> 32)); c = c >> 32; r = r >> 32;
+ r = r + m[8] + (~c & (-1 >> 32)); c = c >> 32; r = r >> 32;
+
+ q = q - (r ^ 1);
+
+ c = q * l[0]; r = 1 + m[0] + (~c & (-1 >> 32)); m[0] = r & (-1 >> 32); c = c >> 32; r = r >> 32;
+ c = c + q * l[1]; r = r + m[1] + (~c & (-1 >> 32)); m[1] = r & (-1 >> 32); c = c >> 32; r = r >> 32;
+ c = c + q * l[2]; r = r + m[2] + (~c & (-1 >> 32)); m[2] = r & (-1 >> 32); c = c >> 32; r = r >> 32;
+ c = c + q * l[3]; r = r + m[3] + (~c & (-1 >> 32)); m[3] = r & (-1 >> 32); c = c >> 32; r = r >> 32;
+ c = c + q * l[4]; r = r + m[4] + (~c & (-1 >> 32)); m[4] = r & (-1 >> 32); c = c >> 32; r = r >> 32;
+ c = c + q * l[5]; r = r + m[5] + (~c & (-1 >> 32)); m[5] = r & (-1 >> 32); c = c >> 32; r = r >> 32;
+ c = c + q * l[6]; r = r + m[6] + (~c & (-1 >> 32)); m[6] = r & (-1 >> 32); c = c >> 32; r = r >> 32;
+ c = c + q * l[7]; r = r + m[7] + (~c & (-1 >> 32)); m[7] = r & (-1 >> 32); c = c >> 32; r = r >> 32;
+ r = r + m[8] + (~c & (-1 >> 32)); m[8] = r & (-1 >> 32); c = c >> 32; r = r >> 32;
+}
+
+// r = x mod L
+ed25519_mod_l(r: *int, x: *int) {
+ var _l: _ed25519_limb;
+ var l: *int;
+ var _m: _ed25519_mod;
+ var m: *int;
+
+ l = &_l.x0;
+ m = &_m.x0;
+
+ ed25519_l(l);
+
+ m[0] = x[0];
+ m[1] = x[1];
+ m[2] = x[2];
+ m[3] = x[3];
+ m[4] = x[4];
+ m[5] = x[5];
+ m[6] = x[6];
+ m[7] = x[7];
+ m[8] = x[8];
+ m[9] = x[9];
+ m[10] = x[10];
+ m[11] = x[11];
+ m[12] = x[12];
+ m[13] = x[13];
+ m[14] = x[14];
+ m[15] = x[15];
+ m[16] = 0;
+
+ ed25519_mod1(&m[8], l, m[15] >> 28);
+ ed25519_mod1(&m[7], l, (m[15] << 4) + (m[14] >> 28));
+ ed25519_mod1(&m[6], l, (m[14] << 4) + (m[13] >> 28));
+ ed25519_mod1(&m[5], l, (m[13] << 4) + (m[12] >> 28));
+ ed25519_mod1(&m[4], l, (m[12] << 4) + (m[11] >> 28));
+ ed25519_mod1(&m[3], l, (m[11] << 4) + (m[10] >> 28));
+ ed25519_mod1(&m[2], l, (m[10] << 4) + (m[9] >> 28));
+ ed25519_mod1(&m[1], l, (m[9] << 4) + (m[8] >> 28));
+ ed25519_mod1(&m[0], l, (m[8] << 4) + (m[7] >> 28));
+
+ r[0] = m[0];
+ r[1] = m[1];
+ r[2] = m[2];
+ r[3] = m[3];
+ r[4] = m[4];
+ r[5] = m[5];
+ r[6] = m[6];
+ r[7] = m[7];
+}
+
+// x = a * b + y mod L
+ed25519_ma_l(x: *int, a: *int, b: *int, y: *int) {
+ var _z: _ed25519_mod;
+ var z: *int;
+ var c: int;
+ var i: int;
+
+ z = (&_z):*int;
+
+ z[0] = 0;
+ z[1] = 0;
+ z[2] = 0;
+ z[3] = 0;
+ z[4] = 0;
+ z[5] = 0;
+ z[6] = 0;
+ z[7] = 0;
+ z[8] = 0;
+ z[9] = 0;
+ z[10] = 0;
+ z[11] = 0;
+ z[12] = 0;
+ z[13] = 0;
+ z[14] = 0;
+ z[15] = 0;
+
+ i = 0;
+ loop {
+ if i == 8 {
+ break;
+ }
+
+ c = z[i + 0] + a[i] * b[0]; z[i + 0] = c & (-1 >> 32); c = c >> 32;
+ c = c + z[i + 1] + a[i] * b[1]; z[i + 1] = c & (-1 >> 32); c = c >> 32;
+ c = c + z[i + 2] + a[i] * b[2]; z[i + 2] = c & (-1 >> 32); c = c >> 32;
+ c = c + z[i + 3] + a[i] * b[3]; z[i + 3] = c & (-1 >> 32); c = c >> 32;
+ c = c + z[i + 4] + a[i] * b[4]; z[i + 4] = c & (-1 >> 32); c = c >> 32;
+ c = c + z[i + 5] + a[i] * b[5]; z[i + 5] = c & (-1 >> 32); c = c >> 32;
+ c = c + z[i + 6] + a[i] * b[6]; z[i + 6] = c & (-1 >> 32); c = c >> 32;
+ c = c + z[i + 7] + a[i] * b[7]; z[i + 7] = c & (-1 >> 32); c = c >> 32;
+ c = c + z[i + 8]; z[i + 8] = c & (-1 >> 32);
+
+ i = i + 1;
+ }
+
+ ed25519_mod_l(z, z);
+
+ c = z[0] + y[0]; z[0] = c; c = c >> 32;
+ c = z[1] + y[1]; z[1] = c; c = c >> 32;
+ c = z[2] + y[2]; z[2] = c; c = c >> 32;
+ c = z[3] + y[3]; z[3] = c; c = c >> 32;
+ c = z[4] + y[4]; z[4] = c; c = c >> 32;
+ c = z[5] + y[5]; z[5] = c; c = c >> 32;
+ c = z[6] + y[6]; z[6] = c; c = c >> 32;
+ c = z[7] + y[7]; z[7] = c; c = c >> 32;
+ z[8] = 0;
+ z[9] = 0;
+ z[10] = 0;
+ z[11] = 0;
+ z[12] = 0;
+ z[13] = 0;
+ z[14] = 0;
+ z[15] = 0;
+
+ ed25519_mod_l(x, z);
}
-ed25519_verify(p: *byte) {
+// x = a_512 mod L
+ed25519_reduce_l(x: *int, a: *byte) {
+ var _z: _ed25519_point;
+ var z: *int;
+
+ z = (&_z):*int;
+
+ z[0] = a[0]:int | (a[1]:int << 8) | (a[2]:int << 16) | (a[3]:int << 24);
+ z[1] = a[4]:int | (a[5]:int << 8) | (a[6]:int << 16) | (a[7]:int << 24);
+ z[2] = a[8]:int | (a[9]:int << 8) | (a[10]:int << 16) | (a[11]:int << 24);
+ z[3] = a[12]:int | (a[13]:int << 8) | (a[14]:int << 16) | (a[15]:int << 24);
+ z[4] = a[16]:int | (a[17]:int << 8) | (a[18]:int << 16) | (a[19]:int << 24);
+ z[5] = a[20]:int | (a[21]:int << 8) | (a[22]:int << 16) | (a[23]:int << 24);
+ z[6] = a[24]:int | (a[25]:int << 8) | (a[26]:int << 16) | (a[27]:int << 24);
+ z[7] = a[28]:int | (a[29]:int << 8) | (a[30]:int << 16) | (a[31]:int << 24);
+ z[8] = a[32]:int | (a[33]:int << 8) | (a[34]:int << 16) | (a[35]:int << 24);
+ z[9] = a[36]:int | (a[37]:int << 8) | (a[38]:int << 16) | (a[39]:int << 24);
+ z[10] = a[40]:int | (a[41]:int << 8) | (a[42]:int << 16) | (a[43]:int << 24);
+ z[11] = a[44]:int | (a[45]:int << 8) | (a[46]:int << 16) | (a[47]:int << 24);
+ z[12] = a[48]:int | (a[49]:int << 8) | (a[50]:int << 16) | (a[51]:int << 24);
+ z[13] = a[52]:int | (a[53]:int << 8) | (a[54]:int << 16) | (a[55]:int << 24);
+ z[14] = a[56]:int | (a[57]:int << 8) | (a[58]:int << 16) | (a[59]:int << 24);
+ z[15] = a[60]:int | (a[61]:int << 8) | (a[62]:int << 16) | (a[63]:int << 24);
+
+ ed25519_mod_l(x, z);
+}
+
+ed25519_encode_l(dest: *byte, p: *int) {
+ dest[0] = p[0]:byte;
+ dest[1] = (p[0] >> 8):byte;
+ dest[2] = (p[0] >> 16):byte;
+ dest[3] = (p[0] >> 24):byte;
+ dest[4] = p[1]:byte;
+ dest[5] = (p[1] >> 8):byte;
+ dest[6] = (p[1] >> 16):byte;
+ dest[7] = (p[1] >> 24):byte;
+ dest[8] = p[2]:byte;
+ dest[9] = (p[2] >> 8):byte;
+ dest[10] = (p[2] >> 16):byte;
+ dest[11] = (p[2] >> 24):byte;
+ dest[12] = p[3]:byte;
+ dest[13] = (p[3] >> 8):byte;
+ dest[14] = (p[3] >> 16):byte;
+ dest[15] = (p[3] >> 24):byte;
+ dest[16] = p[4]:byte;
+ dest[17] = (p[4] >> 8):byte;
+ dest[18] = (p[4] >> 16):byte;
+ dest[19] = (p[4] >> 24):byte;
+ dest[20] = p[5]:byte;
+ dest[21] = (p[5] >> 8):byte;
+ dest[22] = (p[5] >> 16):byte;
+ dest[23] = (p[5] >> 24):byte;
+ dest[24] = p[6]:byte;
+ dest[25] = (p[6] >> 8):byte;
+ dest[26] = (p[6] >> 16):byte;
+ dest[27] = (p[6] >> 24):byte;
+ dest[28] = p[7]:byte;
+ dest[29] = (p[7] >> 8):byte;
+ dest[30] = (p[7] >> 16):byte;
+ dest[31] = (p[7] >> 24):byte;
+}
+
+ed25519_eq(a: *int, b: *int): int {
+ var x: int;
+ x = a[0] ^ b[0];
+ x = x | (a[1] ^ b[1]);
+ x = x | (a[2] ^ b[2]);
+ x = x | (a[3] ^ b[3]);
+ x = x | (a[4] ^ b[4]);
+ x = x | (a[5] ^ b[5]);
+ x = x | (a[6] ^ b[6]);
+ x = x | (a[7] ^ b[7]);
+ x = x | (a[8] ^ b[8]);
+ x = x | (a[9] ^ b[9]);
+ x = x | (a[10] ^ b[10]);
+ x = x | (a[11] ^ b[11]);
+ x = x | (a[12] ^ b[12]);
+ x = x | (a[13] ^ b[13]);
+ x = x | (a[14] ^ b[14]);
+ x = x | (a[15] ^ b[15]);
+ x = (x >> 32) | x;
+ x = (x >> 16) | x;
+ x = (x >> 8) | x;
+ x = (x >> 4) | x;
+ x = (x >> 2) | x;
+ x = (x >> 1) | x;
+ return (x & 1) ^ 1;
+}
+
+ed25519_verify(sig: *byte, pub: *byte, msg: *byte, len: int): int {
+ var ctx: sha512_ctx;
+ var a: *int;
+ var b: *int;
+ var r: *int;
+ var s: *int;
+ var k: *int;
+ var hk: *byte;
+
// A = public key
- // R || S = signature
+ ed25519_decode(a, pub);
+
+ // sig = R || S
+ ed25519_decode(r, sig);
+ ed25519_reduce_l(s, &sig[32]);
+
// k' = SHA-512(R || A || M)
- // [S]B = R + [k']A
+ sha512_init(&ctx);
+ sha512_update(&ctx, sig, 32);
+ sha512_update(&ctx, pub, 32);
+ sha512_update(&ctx, msg, len);
+ sha512_final(hk, &ctx);
+ ed25519_reduce_l(k, hk);
+
+ // RHS = R + [k']A
+ ed25519_pk(a, a, k);
+ ed25519_pa(a, a, r);
+
+ // LHS = [S]B
+ ed25519_base(b);
+ ed25519_pk(b, b, s);
+
+ return ed25519_eq(a, b);
}
ed25519_bi(d: *int) {
@@ -690,8 +1141,8 @@ x25519(uk: *byte, u: *byte, k: *byte): int {
var xy: *int;
var kc: *int;
- uv = &_uv.x.x0;
- xy = &_xy.x.x0;
+ uv = &_uv.x0;
+ xy = &_xy.x0;
kc = &_kc.x0;
if !x25519_decode(uv, u) {
@@ -770,7 +1221,7 @@ ed25519_check(xy: *int): int {
return ed25519_zerop(a);
}
-ed25519_set_sign(xy: *int, sign: int) {
+ed25519_set_lsb(xy: *int, lsb: int) {
var _a: _ed25519_limb;
var a: *int;
@@ -779,7 +1230,7 @@ ed25519_set_sign(xy: *int, sign: int) {
ed25519_zero(a);
ed25519_sub(a, a, &xy[8]);
- ed25519_selectl(&xy[8], &xy[8], a, ((xy[15] >> 30) ^ sign) & 1);
+ ed25519_selectl(&xy[8], &xy[8], a, (xy[0] ^ lsb) & 1);
}
ed25519_clamp(k: *int, b: *byte) {
diff --git a/ed25519_test.c b/ed25519_test.c
@@ -5,31 +5,18 @@ main(argc: int, argv: **byte, envp: **byte) {
var b: *byte;
var _c: _ed25519_point;
var c: *byte;
- var ret: int;
a = (&_a):*byte;
b = (&_b):*byte;
c = (&_c):*byte;
- assert(unhex(a, "e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c") == 32, "unhex");
- assert(unhex(b, "a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4") == 32, "unhex");
- assert(x25519(c, a, b), "decode");
- fdxxd(1, c, 32);
+ assert(unhex(a, "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60") == 32, "unhex");
+ ed25519_sign(c, a, "", 0);
+ fdxxd(1, c, 64);
+ fdputc(1, '\n');
- x25519_base(a);
- assert(unhex(b, "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a") == 32, "unhex");
- assert(x25519(c, a, b), "decode");
- fdxxd(1, c, 32);
-
- x25519_base(a);
- assert(unhex(b, "5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb") == 32, "unhex");
- assert(x25519(c, a, b), "decode");
- fdxxd(1, c, 32);
-
- x25519_base(a);
- assert(unhex(b, "5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb") == 32, "unhex");
- assert(x25519(c, a, b), "decode");
- assert(unhex(b, "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a") == 32, "unhex");
- assert(x25519(c, c, b), "decode");
- fdxxd(1, c, 32);
+ assert(unhex(a, "4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb") == 32, "unhex");
+ ed25519_sign(c, a, "r", 1);
+ fdxxd(1, c, 64);
+ fdputc(1, '\n');
}
diff --git a/sha512.c b/sha512.c
@@ -9,11 +9,27 @@ struct sha512_ctx {
f: int;
g: int;
h: int;
+ len: int;
+ block: _sha512_block;
}
struct _sha512_block {
- c0: sha512_ctx;
- c1: sha512_ctx;
+ c0: int;
+ c1: int;
+ c2: int;
+ c3: int;
+ c4: int;
+ c5: int;
+ c6: int;
+ c7: int;
+ c8: int;
+ c9: int;
+ c10: int;
+ c11: int;
+ c12: int;
+ c13: int;
+ c14: int;
+ c15: int;
}
struct _sha512_digest {
@@ -29,6 +45,7 @@ sha512_init(ctx: *sha512_ctx) {
ctx.f = (0x9b05 << 48) | (0x688c << 32) | (0x2b3e << 16) | 0x6c1f;
ctx.g = (0x1f83 << 48) | (0xd9ab << 32) | (0xfb41 << 16) | 0xbd6b;
ctx.h = (0x5be0 << 48) | (0xcd19 << 32) | (0x137e << 16) | 0x2179;
+ ctx.len = 0;
}
ror64(x: int, n: int): int {
@@ -317,3 +334,43 @@ sha512_hmac(mac: *byte, key: *byte, klen: int, data: *byte, dlen: int) {
sha512_finish(&ctx, 1, digest, 64);
sha512_digest(mac, &ctx);
}
+
+sha512_update(ctx: *sha512_ctx, msg: *byte, len: int) {
+ var o: int;
+ var r: int;
+
+ o = ctx.len & 127;
+ if o != 0 {
+ r = 128 - o;
+ if len < r {
+ memcpy(&(&ctx.block):*byte[o], msg, len);
+ ctx.len = ctx.len + len;
+ return;
+ } else {
+ memcpy(&(&ctx.block):*byte[o], msg, r);
+ sha512_rounds(ctx, (&ctx.block):*byte);
+ ctx.len = ctx.len + r;
+ len = len - r;
+ msg = &msg[r];
+ }
+ }
+
+ loop {
+ if len < 128 {
+ memcpy((&ctx.block):*byte, msg, len);
+ ctx.len = ctx.len + len;
+ return;
+ }
+
+ sha512_rounds(ctx, msg);
+
+ ctx.len = ctx.len + 128;
+ len = len - 128;
+ msg = &msg[128];
+ }
+}
+
+sha512_final(digest: *byte, ctx: *sha512_ctx) {
+ sha512_finish(ctx, ctx.len >> 7, (&ctx.block):*byte, ctx.len & 127);
+ sha512_digest(digest, ctx);
+}
diff --git a/x25519_test.c b/x25519_test.c
@@ -5,7 +5,6 @@ main(argc: int, argv: **byte, envp: **byte) {
var b: *byte;
var _c: _ed25519_point;
var c: *byte;
- var ret: int;
a = (&_a):*byte;
b = (&_b):*byte;
@@ -15,16 +14,19 @@ main(argc: int, argv: **byte, envp: **byte) {
assert(unhex(b, "a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4") == 32, "unhex");
assert(x25519(c, a, b), "decode");
fdxxd(1, c, 32);
+ fdputc(1, '\n');
x25519_base(a);
assert(unhex(b, "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a") == 32, "unhex");
assert(x25519(c, a, b), "decode");
fdxxd(1, c, 32);
+ fdputc(1, '\n');
x25519_base(a);
assert(unhex(b, "5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb") == 32, "unhex");
assert(x25519(c, a, b), "decode");
fdxxd(1, c, 32);
+ fdputc(1, '\n');
x25519_base(a);
assert(unhex(b, "5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb") == 32, "unhex");
@@ -32,4 +34,5 @@ main(argc: int, argv: **byte, envp: **byte) {
assert(unhex(b, "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a") == 32, "unhex");
assert(x25519(c, c, b), "decode");
fdxxd(1, c, 32);
+ fdputc(1, '\n');
}