diff --git a/src/Home/TweetNaCl/TweetNaCl.ZC b/src/Home/TweetNaCl/TweetNaCl.ZC index bf81ba63..7546f246 100644 --- a/src/Home/TweetNaCl/TweetNaCl.ZC +++ b/src/Home/TweetNaCl/TweetNaCl.ZC @@ -305,18 +305,18 @@ I64 crypto_secretbox_open(U8 *m, U8 *c, U64 d, U8 *n, U8 *k) { return 0; } -I64 crypto_scalarmult_base(U8 *q, U8 *n) { - return crypto_scalarmult(q, n, _9); +I64 crypto_Scalarmult_base(U8 *q, U8 *n) { + return crypto_Scalarmult(q, n, _9); } I64 crypto_box_keypair(U8 *y, U8 *x) { randombytes(x, 32); - return crypto_scalarmult_base(y, x); + return crypto_Scalarmult_base(y, x); } I64 crypto_box_beforenm(U8 *k, U8 *y, U8 *x) { U8 s[32]; - crypto_scalarmult(s, x, y); + crypto_Scalarmult(s, x, y); return crypto_core_hsalsa20(k, _0, s, sigma); } @@ -395,6 +395,78 @@ U0 Pack25519(U8 *o, I64 *n) { } } +I64 Neq25519(gf a, gf b) { + U8 c[32], d[32]; + Pack25519(c, a); + Pack25519(d, b); + return CryptoVerify32(c, d); +} + +U8 Par25519(gf a) { + U8 d[32]; + Pack25519(d, a); + return d[0] & 1; +} + +U0 Unpack25519(gf *o, U8 *n) { + I64 i; + for(i=0;i<16;++i) { + o->data[i] = n[2 * i] + (n[2 * i + 1] << 8); + } + o->data[15] &= 0x7fff; +} + +// addition +U0 A(gf o, gf a, gf b) +{ + I64 i; + for (i = 0;i < 16;++i) o[i] = a[i] + b[i]; +} + +// substraction +U0 Z(gf o, gf a, gf b) { + I64 i; + for (i = 0;i < 16;++i) o[i] = a[i] - b[i]; +} +// multiply +U0 M(gf o, gf a, gf b) { + I64 i, j, t[31]; + for (i = 0;i < 31;++i) t[i] = 0; + for (i = 0;i < 16;++i) { for (j = 0;j < 16;++j) {t[i + j] += a[i] * b[j];} } + for (i = 0;i < 15;++i) t[i] += 38 * t[i + 16]; + for (i = 0;i < 16;++i) o[i] = t[i]; + Car25519(o); + Car25519(o); +} +// square +U0 S(gf o, gf a) { + M(o, a, a); +} + +U0 Inv25519(gf *o, gf i) { + gf c; + I64 a; + + for (a = 0; a < 16; ++a) c.data[a] = i.data[a]; + for (a = 253; a >= 0; --a) { + S(c.data, c.data); + if (a != 2 && a != 4) M(c.data, c.data, i.data); + } + for (a = 0; a < 16; ++a) o->data[a] = c.data[a]; +} + +U0 Pow2523(gf *o, gf i) { + gf c; + I64 a; + + for (a = 0; a < 16; ++a) c.data[a] = i.data[a]; + for (a = 250; a >= 0; --a) { + S(c.data, c.data); + if (a != 1) M(c.data, c.data, i.data); + } + for (a = 0; a < 16; ++a) o->data[a] = c.data[a]; +} + U0 Add(gf *p, gf *q) { gf a, b, c, d, t, e, f, g, h; @@ -419,43 +491,44 @@ U0 Add(gf *p, gf *q) { M(p[3].data, e.data, h.data); } -U0 cswap(gf p[4], gf q[4], U8 b) { - I64 i; - for (i = 0;i < 4;++i) Sel25519(p[i], q[i], b); +U0 Cswap(gf *p, gf *q, U8 b) { + I64 i; + for (i = 0; i < 4; ++i) { + Sel25519(p[i].data, q[i].data, b); + } } -U0 pack(U8 *r, gf p[4]) { - gf tx, ty, zi; - inv25519(zi, p[2]); - M(tx, p[0], zi); - M(ty, p[1], zi); - Pack25519(r, ty); - r[31] ^= par25519(tx) << 7; +U0 Pack(U8 *r, gf *p) { + gf tx, ty, zi; + Inv25519(zi.data, p[2].data); + M(tx.data, p[0].data, zi.data); + M(ty.data, p[1].data, zi.data); + Pack25519(r, ty.data); + r[31] ^= Par25519(tx.data) << 7; } -U0 scalarmult(gf p[4], gf q[4], U8 *s) { - I64 i; - Set25519(p[0], gf0); - Set25519(p[1], gf1); - Set25519(p[2], gf1); - Set25519(p[3], gf0); - for (i = 255; i >= 0; --i) { - U8 b; - b = (s[i / 8] >> (i & 7)) & 1; - cswap(p, q, b); - add(q, p); - add(p, p); - cswap(p, q, b); - } +U0 Scalarmult(gf *p, gf *q, U8 *s) { + I64 i; + Set25519(p[0].data, gf0.data); + Set25519(p[1].data, gf1.data); + Set25519(p[2].data, gf1.data); + Set25519(p[3].data, gf0.data); + for (i = 255; i >= 0; --i) { + U8 b = (s[i / 8] >> (i & 7)) & 1; + Cswap(p, q, b); + Add(q, p); + Add(p, p); + Cswap(p, q, b); + } } -U0 scalarbase(gf p[4], U8 *s) { - gf q[4]; - Set25519(q[0], X); - Set25519(q[1], Y); - Set25519(q[2], gf1); - M(q[3], X, Y); - scalarmult(p, q, s); +U0 Scalarbase(gf *p, U8 *s) { + gf q[4]; + Set25519(q[0].data, X.data); + Set25519(q[1].data, Y.data); + Set25519(q[2].data, gf1.data); + M(q[3].data, X.data, Y.data); + Scalarmult(p, q, s); } I64 crypto_sign_keypair(U8 *pk, U8 *sk) @@ -470,15 +543,15 @@ I64 crypto_sign_keypair(U8 *pk, U8 *sk) d[31] &= 127; d[31] |= 64; - scalarbase(p,d); - pack(pk,p); + Scalarbase(p,d); + Pack(pk,p); for (i = 0; i < 32; i++) sk[32 + i] = pk[i]; return 0; } -I64 crypto_scalarmult(U8 *q, U8 *n, U8 *p) { +I64 crypto_Scalarmult(U8 *q, U8 *n, U8 *p) { U8 z[32]; I64 x[80], r, i; gf a, b, c, d, e, f; @@ -486,7 +559,7 @@ I64 crypto_scalarmult(U8 *q, U8 *n, U8 *p) { for (i = 0;i < 31;++i) z[i] = n[i]; z[31] = (n[31] & 127) | 64; z[0] &= 248; - unPack25519(x, p); + Unpack25519(x, p); for (i = 0;i < 16;++i) { b[i] = x[i]; d[i] = a[i] = c[i] = 0; @@ -494,8 +567,8 @@ I64 crypto_scalarmult(U8 *q, U8 *n, U8 *p) { a[0] = d[0] = 1; for (i = 254; i >= 0; --i) { r = (z[i >> 3] >> (i & 7)) & 1; - cswap(a, b, r); - cswap(c, d, r); + Cswap(a, b, r); + Cswap(c, d, r); A(e, a, c); Z(a, a, c); A(c, b, d); @@ -514,8 +587,8 @@ I64 crypto_scalarmult(U8 *q, U8 *n, U8 *p) { M(a, d, f); M(d, b, x); S(b, e); - cswap(a, b, r); - cswap(c, d, r); + Cswap(a, b, r); + Cswap(c, d, r); } for (i = 0;i < 16;++i) { x[i + 16] = a[i]; @@ -647,23 +720,23 @@ U0 add(U16 p[4][16], U16 q[4][16]) M(p[3], e, h); } -U0 cswap(U16 p[4][16], U16 q[4][16], U8 b) +U0 Cswap(U16 p[4][16], U16 q[4][16], U8 b) { I64 i; for (i = 0;i < 4;++i) Sel25519(p[i],q[i],b); } -U0 pack(U8 *r, U16 p[4][16]) +U0 Pack(U8 *r, U16 p[4][16]) { U16 tx[16], ty[16], zi[16]; inv25519(zi, p[2]); M(tx, p[0], zi); M(ty, p[1], zi); Pack25519(r, ty); - r[31] ^= par25519(tx) << 7; + r[31] ^= Par25519(tx) << 7; } -U0 scalarmult(U16 p[4][16], U16 q[4][16], U8 *s) +U0 Scalarmult(U16 p[4][16], U16 q[4][16], U8 *s) { I64 i; Set25519(p[0],gf0); @@ -672,49 +745,21 @@ U0 scalarmult(U16 p[4][16], U16 q[4][16], U8 *s) Set25519(p[3],gf0); for (i = 255;i >= 0;--i) { U8 b = (s[i/8]>>(i&7))&1; - cswap(p,q,b); + Cswap(p,q,b); add(q,p); add(p,p); - cswap(p,q,b); + Cswap(p,q,b); } } -U0 scalarbase(U16 p[4][16], U8 *s) +U0 Scalarbase(U16 p[4][16], U8 *s) { U16 q[4][16]; Set25519(q[0],X); Set25519(q[1],Y); Set25519(q[2],gf1); M(q[3],X,Y); - scalarmult(p,q,s); -} - - -// addition -U0 A(gf o, gf a, gf b) -{ - I64 i; - for (i = 0;i < 16;++i) o[i] = a[i] + b[i]; -} - -// substraction -U0 Z(gf o, gf a, gf b) { - I64 i; - for (i = 0;i < 16;++i) o[i] = a[i] - b[i]; -} -// multiply -U0 M(gf o, gf a, gf b) { - I64 i, j, t[31]; - for (i = 0;i < 31;++i) t[i] = 0; - for (i = 0;i < 16;++i) { for (j = 0;j < 16;++j) {t[i + j] += a[i] * b[j];} } - for (i = 0;i < 15;++i) t[i] += 38 * t[i + 16]; - for (i = 0;i < 16;++i) o[i] = t[i]; - Car25519(o); - Car25519(o); -} -// square -U0 S(gf o, gf a) { - M(o, a, a); + Scalarmult(p,q,s); } U64 L[] = {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10}; @@ -770,8 +815,8 @@ I64 crypto_sign(U8 *sm, U64 *smlen, U8 *m, U64 n, U8 *sk) crypto_hash(r, sm+32, n+32); reduce(r); - scalarbase(p,r); - pack(sm,p); + Scalarbase(p,r); + Pack(sm,p); for (i = 0; i < 32; i++) sm[i+32] = sk[i+32]; crypto_hash(h,sm,n + 64); @@ -784,41 +829,39 @@ I64 crypto_sign(U8 *sm, U64 *smlen, U8 *m, U64 n, U8 *sk) return 0; } +I64 UnpackNeg(gf *r, U8 *p) { + gf t, chk, num, den, den2, den4, den6; + Set25519(r[2].data, gf1.data); + Unpack25519(r[1].data, p); + S(num.data, r[1].data); + M(den.data, num.data, D.data); + Z(num.data, num.data, r[2].data); + A(den.data, r[2].data, den.data); -I64 unpackneg(gf r[4], U8 p[32]) -{ - gf t, chk, num, den, den2, den4, den6; - Set25519(r[2],gf1); - unPack25519(r[1],p); - S(num,r[1]); - M(den,num,D); - Z(num,num,r[2]); - A(den,r[2],den); + S(den2.data, den.data); + S(den4.data, den2.data); + M(den6.data, den4.data, den2.data); + M(t.data, den6.data, num.data); + M(t.data, t.data, den.data); - S(den2,den); - S(den4,den2); - M(den6,den4,den2); - M(t,den6,num); - M(t,t,den); + Pow2523(t.data, t.data); + M(t.data, t.data, num.data); + M(t.data, t.data, den.data); + M(t.data, t.data, den.data); + M(r[0].data, t.data, den.data); - pow2523(t,t); - M(t,t,num); - M(t,t,den); - M(t,t,den); - M(r[0],t,den); + S(chk.data, r[0].data); + M(chk.data, chk.data, den.data); + if (Neq25519(chk.data, num.data)) M(r[0].data, r[0].data, I.data); - S(chk,r[0]); - M(chk,chk,den); - if (neq25519(chk, num)) M(r[0],r[0],I); + S(chk.data, r[0].data); + M(chk.data, chk.data, den.data); + if (Neq25519(chk.data, num.data)) return -1; - S(chk,r[0]); - M(chk,chk,den); - if (neq25519(chk, num)) return -1; + if (Par25519(r[0].data) == (p[31] >> 7)) Z(r[0].data, gf0.data, r[0].data); - if (par25519(r[0]) == (p[31]>>7)) Z(r[0],gf0,r[0]); - - M(r[3],r[0],r[1]); - return 0; + M(r[3].data, r[0].data, r[1].data); + return 0; } I64 crypto_sign_open(U8 *m, U64 *mlen, U8 *sm, U64 n, U8 *pk) @@ -830,17 +873,17 @@ I64 crypto_sign_open(U8 *m, U64 *mlen, U8 *sm, U64 n, U8 *pk) *mlen = -1; if (n < 64) return -1; - if (unpackneg(q, pk)) return -1; + if (UnpackNeg(q, pk)) return -1; for (i = 0; i < n; i++) m[i] = sm[i]; for (i = 0; i < 32; i++) m[i+32] = pk[i]; crypto_hash(h, m, n); reduce(h); - scalarmult(p, q, h); + Scalarmult(p, q, h); - scalarbase(q, sm + 32); + Scalarbase(q, sm + 32); add(p, q); - pack(t, p); + Pack(t, p); n -= 64; if (crypto_verify_32(sm, t)) {