diff --git a/crypto_scalarmult.js b/crypto_scalarmult.js index f7f41b6..28bad27 100644 --- a/crypto_scalarmult.js +++ b/crypto_scalarmult.js @@ -11,7 +11,9 @@ module.exports = { crypto_scalarmult_BYTES, crypto_scalarmult_SCALARBYTES } - +const b = Buffer.alloc(32) +pack25519(b, _9) +console.log(b.toString('hex')) function crypto_scalarmult (q, n, p) { check(q, crypto_scalarmult_BYTES) check(n, crypto_scalarmult_SCALARBYTES) diff --git a/crypto_sign.js b/crypto_sign.js index 133172a..c35a332 100644 --- a/crypto_sign.js +++ b/crypto_sign.js @@ -207,6 +207,7 @@ function crypto_sign(sm, m, sk) { } modL(sm.subarray(32), x); + // console.log(Buffer.from(sm).toString('hex')) return smlen } @@ -270,6 +271,7 @@ function crypto_sign_open(msg, sm, pk) { if (n < 64) return false; if (unpackneg(q, pk)) return false; + pack(t, q); for (i = 0; i < n; i++) m[i] = sm[i]; for (i = 0; i < 32; i++) m[i+32] = pk[i]; diff --git a/fe-test.js b/fe-test.js index 9668c75..64e62ed 100644 --- a/fe-test.js +++ b/fe-test.js @@ -71,7 +71,9 @@ const p = Buffer.from([ 0x27, 0xa6, 0x3e, 0xd2, 0xc8, 0xac, 0xa4, 0xed ]) - function signedInt (i) { +const pk_test = Buffer.from('d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a', 'hex') + +function signedInt (i) { return i < 0 ? 2 ** 32 + i : i } @@ -100,79 +102,83 @@ const gf = ec.ge3() /////////////////////////////////////////// ec.fe25519_frombytes(a, an) ec.fe25519_frombytes(b, bn) -// console.log('\na __________') -// for (let i = 0; i < 10; i++) console.log(`a${i}:`, signedInt(a[i]).toString(16).padStart(8, '0')) -// console.log('\nb __________') -// for (let i = 0; i < 10; i++) console.log(`b${i}:`, signedInt(b[i]).toString(16).padStart(8, '0')) -ec.fe25519_frombytes(c, bn) -ec.fe25519_tobytes(res, c) -console.log('tess :', res.toString('hex')) +// // console.log('\na __________') +// // for (let i = 0; i < 10; i++) console.log(`a${i}:`, signedInt(a[i]).toString(16).padStart(8, '0')) +// // console.log('\nb __________') +// // for (let i = 0; i < 10; i++) console.log(`b${i}:`, signedInt(b[i]).toString(16).padStart(8, '0')) +// ec.fe25519_frombytes(c, bn) +// ec.fe25519_tobytes(res, c) +// console.log('tess :', res.toString('hex')) ec.fe25519_mul(g, a, b) ec.fe25519_tobytes(res, g) console.log('fe_mul:', res.toString('hex')) -ec.fe25519_sq(g, a) -ec.fe25519_tobytes(res, g) -console.log('fe_sq :', res.toString('hex')) +// ec.fe25519_sq(g, a) +// ec.fe25519_tobytes(res, g) +// console.log('fe_sq :', res.toString('hex')) -ec.fe25519_reduce(g, c) -ec.fe25519_tobytes(res, g) -console.log('fe_red:', res.toString('hex')) +// ec.fe25519_reduce(g, c) +// ec.fe25519_tobytes(res, g) +// console.log('fe_red:', res.toString('hex')) -ec.fe25519_sqmul(a, 8734, b) -ec.fe25519_tobytes(res, a) -console.log('fe_sqm:', res.toString('hex')) +// ec.fe25519_sqmul(a, 8734, b) +// ec.fe25519_tobytes(res, a) +// console.log('fe_sqm:', res.toString('hex')) -ec.fe25519_invert(a, a) -ec.fe25519_tobytes(res, a) -console.log('fe_inv:', res.toString('hex')) +// ec.fe25519_invert(a, a) +// ec.fe25519_tobytes(res, a) +// console.log('fe_inv:', res.toString('hex')) -ec.fe25519_pow22523(a, a) -ec.fe25519_tobytes(res, a) -console.log('fe_p25:', res.toString('hex')) +// ec.fe25519_pow22523(a, a) +// ec.fe25519_tobytes(res, a) +// console.log('fe_p25:', res.toString('hex')) -ec.fe25519_cneg(a, a, 1) -ec.fe25519_tobytes(res, a) -console.log('fe_cng:', res.toString('hex')) +// ec.fe25519_cneg(a, a, 1) +// ec.fe25519_tobytes(res, a) +// console.log('fe_cng:', res.toString('hex')) -ec.sc25519_mul(res, an, bn) -console.log('sc_mul:', res.toString('hex')) +// ec.sc25519_mul(res, an, bn) +// console.log('sc_mul:', res.toString('hex')) -ec.sc25519_muladd(res, an, bn, cn) -console.log('sc_mad:', res.toString('hex')) +// ec.sc25519_muladd(res, an, bn, cn) +// console.log('sc_mad:', res.toString('hex')) -ec.sc25519_reduce(s) -console.log('sc_red:', s.subarray(0, 32).toString('hex')) +// ec.sc25519_reduce(s) +// console.log('sc_red:', s.subarray(0, 32).toString('hex')) -ec.sc25519_invert(res, cn) -console.log('sc_inv:', res.toString('hex')) +// ec.sc25519_invert(res, cn) +// console.log('sc_inv:', res.toString('hex')) -ec.ge25519_mont_to_ed(g, c, a, b) -ec.fe25519_tobytes(res, g) -console.log('g_m2ex:', res.toString('hex')) -ec.fe25519_tobytes(res, c) -console.log('g_m2ey:', res.toString('hex')) +// ec.ge25519_mont_to_ed(g, c, a, b) +// ec.fe25519_tobytes(res, g) +// console.log('g_m2ex:', res.toString('hex')) +// ec.fe25519_tobytes(res, c) +// console.log('g_m2ey:', res.toString('hex')) -ec.ge25519_frombytes(ge, p) -ec.ge25519_p3_tobytes(res, ge) -console.log("p :", res.toString('hex')) +// ec.ge25519_frombytes(ge, p) +// ec.ge25519_p3_tobytes(res, ge) +// console.log("p :", res.toString('hex')) -ec.ge25519_mul_l(gf, ge) -ec.ge25519_p3_tobytes(res, gf) -console.log("mul_l :", res.toString('hex')) +// ec.ge25519_mul_l(gf, ge) +// ec.ge25519_p3_tobytes(res, gf) +// console.log("mul_l :", res.toString('hex')) -ec.ge25519_scalarmult_base(gf, cn) -ec.ge25519_p3_tobytes(res, gf) -console.log("smultb:", res.toString('hex')) +// ec.ge25519_scalarmult_base(gf, cn) +// ec.ge25519_p3_tobytes(res, gf) +// console.log("smultb:", res.toString('hex')) -ec.ge25519_scalarmult(ge, bn, gf) -ec.ge25519_p3_tobytes(res, ge) -console.log("smult :", res.toString('hex')) +// ec.ge25519_scalarmult(ge, bn, gf) +// ec.ge25519_p3_tobytes(res, ge) +// console.log("smult :", res.toString('hex')) -ec.ge25519_double_scalarmult_vartime(gf, an, ge, bn) -ec.ge25519_p3_tobytes(res, gf) -console.log("smdbl :", res.toString('hex')) +// ec.ge25519_double_scalarmult_vartime(gf, an, ge, bn) +// ec.ge25519_p3_tobytes(res, gf) +// console.log("smdbl :", res.toString('hex')) + +// ec.ge25519_frombytes_negate_vartime(gf, pk_test) +// ec.ge25519_p3_tobytes(res, gf) +// console.log("smdbl :", res.toString('hex')) console.log('canon :', ec.sc25519_is_canonical(bn)) diff --git a/fe25519_25.js b/fe25519_25.js index 0a795bd..b11bc8a 100644 --- a/fe25519_25.js +++ b/fe25519_25.js @@ -14,6 +14,7 @@ const wasm = require('./fe25519_25/mult.js')({ } }) +console.log(wasm.buffer.byteLength) const base = require('./fe25519_25/base.json').map(a => a.map(b => ge2(b))) const printbuf =Buffer.alloc(32) @@ -726,7 +727,7 @@ function fe25519_mul (h, f, g) { wasm.memory.set(fbuf) wasm.memory.set(gbuf, 40) - wasm.exports.mul(80, 0, 40) + wasm.exports.fe255219_mul(0, 40) buf = Buffer.from(wasm.memory.slice(80, 120)) for (let i = 0; i < 10; i++) { diff --git a/fe25519_25/mult.js b/fe25519_25/mult.js index b1c9fce..e795020 100644 --- a/fe25519_25/mult.js +++ b/fe25519_25/mult.js @@ -7,7 +7,7 @@ function loadWebAssembly (opts) { if (!loadWebAssembly.supported) return null var imp = opts && opts.imports - var wasm = toUint8Array('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') + var wasm = toUint8Array('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') var ready = null var mod = { @@ -19,6 +19,7 @@ function loadWebAssembly (opts) { } onload(function () {}) + return mod function realloc (size) { diff --git a/fe25519_25/mult.wat b/fe25519_25/mult.wat index 394d934..e057982 100644 --- a/fe25519_25/mult.wat +++ b/fe25519_25/mult.wat @@ -56,7 +56,24 @@ (get_local $f) (i64.or)) - (func $mul (export "mul") (param $h i32) (param $f i32) (param $g i32) + (func $store_fe (export "store") (param $ptr i32) + (param $0 i64) (param $1 i64) (param $2 i64) (param $3 i64) (param $4 i64) + (param $5 i64) (param $6 i64) (param $7 i64) (param $8 i64) (param $9 i64) + + (i64.store32 offset=0 (get_local $ptr) (get_local $0)) + (i64.store32 offset=4 (get_local $ptr) (get_local $1)) + (i64.store32 offset=8 (get_local $ptr) (get_local $2)) + (i64.store32 offset=12 (get_local $ptr) (get_local $3)) + (i64.store32 offset=16 (get_local $ptr) (get_local $4)) + (i64.store32 offset=20 (get_local $ptr) (get_local $5)) + (i64.store32 offset=24 (get_local $ptr) (get_local $6)) + (i64.store32 offset=28 (get_local $ptr) (get_local $7)) + (i64.store32 offset=32 (get_local $ptr) (get_local $8)) + (i64.store32 offset=36 (get_local $ptr) (get_local $9))) + + (func $mul (param $f i32) (param $g i32) + (result i64 i64 i64 i64 i64 i64 i64 i64 i64 i64) + (local $f0 i64) (local $f1 i64) (local $f2 i64) @@ -484,17 +501,17 @@ (set_local $h1 (i64.add (get_local $h1) (get_local $carry0))) (set_local $h0 (i64.sub (get_local $h0) (i64.mul (get_local $carry0) (i64.shl (i64.const 1) (i64.const 26))))) - (i64.store32 offset=0 (get_local $h) (get_local $h0)) - (i64.store32 offset=4 (get_local $h) (get_local $h1)) - (i64.store32 offset=8 (get_local $h) (get_local $h2)) - (i64.store32 offset=12 (get_local $h) (get_local $h3)) - (i64.store32 offset=16 (get_local $h) (get_local $h4)) - (i64.store32 offset=20 (get_local $h) (get_local $h5)) - (i64.store32 offset=24 (get_local $h) (get_local $h6)) - (i64.store32 offset=28 (get_local $h) (get_local $h7)) - (i64.store32 offset=32 (get_local $h) (get_local $h8)) - (i64.store32 offset=36 (get_local $h) (get_local $h9))) - + (get_local $h0) + (get_local $h1) + (get_local $h2) + (get_local $h3) + (get_local $h4) + (get_local $h5) + (get_local $h6) + (get_local $h7) + (get_local $h8) + (get_local $h9)) + (func $sq (export "sq") (param $h i32) (param $f i32) (param $double i32) (local $tmp i64) @@ -781,8 +798,7 @@ (i64.store32 offset=24 (get_local $h) (get_local $h6)) (i64.store32 offset=28 (get_local $h) (get_local $h7)) (i64.store32 offset=32 (get_local $h) (get_local $h8)) - (i64.store32 offset=36 (get_local $h) (get_local $h9)) - ) + (i64.store32 offset=36 (get_local $h) (get_local $h9))) (func $sc25519_mul (export "sc25519_mul") (param $s i32) (param $a i32) (param $b i32) @@ -2742,4 +2758,12 @@ (i64.or) (i64.store offset=24)) + + (func $fe25519_mul (export "fe25519_mul") (param $h i32) (param $f i32) (param $g i32) + (get_local $h) + (call $mul (get_local $f) (get_local $g)) + (call $store_fe)) + + ;; (func $pow22325 (export "pow22325") (param $out i32) (param $z i32) + )