crypto_sign and crypto_scalarmult with webassembly curve arithmetic added

This commit is contained in:
Christophe Diederichs 2020-06-26 10:16:14 +02:00
parent 596f8c8f18
commit f1537df1e0
10 changed files with 12557 additions and 0 deletions

View File

@ -13,6 +13,23 @@ function crypto_hash_sha512 (out, m, n) {
return 0 return 0
} }
function crypto_hash_sha512_state () {
return sha512()
}
function crypto_hash_sha512_update (state, m, n) {
if (n === undefined) n = m.byteLength
state.update(m.subarray(0, n))
return 0
}
function crypto_hash_sha512_final (state, out) {
assert(out.byteLength === crypto_hash_sha512_BYTES, "out must be 'crypto_hash_sha512_BYTES' bytes long")
state.digest(out)
return 0
}
function crypto_hash (out, m, n) { function crypto_hash (out, m, n) {
return crypto_hash_sha512(out, m, n) return crypto_hash_sha512(out, m, n)
} }
@ -20,6 +37,9 @@ function crypto_hash (out, m, n) {
module.exports = { module.exports = {
crypto_hash, crypto_hash,
crypto_hash_sha512, crypto_hash_sha512,
crypto_hash_sha512_state,
crypto_hash_sha512_update,
crypto_hash_sha512_final,
crypto_hash_sha512_BYTES, crypto_hash_sha512_BYTES,
crypto_hash_BYTES crypto_hash_BYTES
} }

View File

@ -0,0 +1,325 @@
const assert = require('nanoassert')
const ec = require('./fe25519_25')
const { sodium_is_zero } = require('./')
module.exports = {
crypto_scalarmult_ed25519,
crypto_scalarmult_ed25519_base,
crypto_scalarmult_curve25519,
crypto_scalarmult_curve25519_base
}
const _121666buf = Buffer.alloc(32)
_121666buf.writeUInt32LE(121666)
const _121666 = ec.fe25519()
ec.fe25519_frombytes(_121666, _121666buf)
function _crypto_scalarmult_ed25519_is_inf (s) {
var c
var i
c = s[0] ^ 0x01
for (i = 1; i < 31; i++) {
c |= s[i]
}
c |= s[31] & 0x7f
return ((c - 1) >> 8) & 1
}
function _crypto_scalarmult_ed25519_clamp (k) {
k[0] &= 248
k[31] |= 64
}
function _crypto_scalarmult_ed25519 (q, n, p, clamp) {
var Q = ec.ge3()
var P = ec.ge3()
var t = q.slice()
var i
// if (ec.ge25519_is_canonical(p) == 0 || ec.ge25519_has_small_order(p) != 0 ||
if ( ec.ge25519_frombytes(P, p) != 0 || ec.ge25519_is_on_main_subgroup(P) == 0) {
return -1
}
for (i = 0; i < 32; ++i) {
t[i] = n[i]
}
if (clamp !== 0) {
_crypto_scalarmult_ed25519_clamp(t)
}
t[31] &= 127
ec.ge25519_scalarmult(Q, t, P)
ec.ge25519_p3_tobytes(q, Q)
if (_crypto_scalarmult_ed25519_is_inf(q) != 0 || sodium_is_zero(n, 32)) {
return -1
}
return 0
}
function crypto_scalarmult_ed25519 (q, n, p) {
assert(q instanceof Uint8Array && q.byteLength === 32)
assert(n instanceof Uint8Array && n.byteLength === 32)
assert(p instanceof Uint8Array && p.byteLength === 32)
return _crypto_scalarmult_ed25519(q, n, p, 1)
}
function crypto_scalarmult_ed25519_noclamp (q, n, p) {
assert(q instanceof Uint8Array && q.byteLength === 32)
assert(n instanceof Uint8Array && n.byteLength === 32)
assert(p instanceof Uint8Array && p.byteLength === 32)
return _crypto_scalarmult_ed25519(q, n, p, 0)
}
function _crypto_scalarmult_ed25519_base (q, n, clamp) {
var t = q.slice()
var Q = ec.ge3()
var i
for (i = 0; i < 32; ++i) {
t[i] = n[i]
}
if (clamp !== 0) {
_crypto_scalarmult_ed25519_clamp(t)
}
t[31] &= 127
ec.ge25519_scalarmult_base(Q, t)
ec.ge25519_p3_tobytes(q, Q)
if (_crypto_scalarmult_ed25519_is_inf(q) !== 0 || sodium_is_zero(n, 32)) {
return -1
}
return 0
}
function crypto_scalarmult_ed25519_base(q, n) {
assert(q instanceof Uint8Array && q.byteLength === 32)
assert(n instanceof Uint8Array && n.byteLength === 32)
return _crypto_scalarmult_ed25519_base(q, n, 1)
}
function crypto_scalarmult_ed25519_base_noclamp (q, n) {
return _crypto_scalarmult_ed25519_base(q, n, 0)
}
function crypto_scalarmult_ed25519_bytes () {
return crypto_scalarmult_ed25519_BYTES
}
function crypto_scalarmult_ed25519_scalarbytes () {
return crypto_scalarmult_ed25519_SCALARBYTES
}
function crypto_scalarmult_ristretto255 (q, n, p) {
assert(q instanceof Uint8Array && k.byteLength === 32)
assert(n instanceof Uint8Array && k.byteLength === 32)
assert(p instanceof Uint8Array && k.byteLength === 32)
var t = q.slice()
var Q = ec.ge3()
var P = ec.ge3()
var i
if (ec.ristretto255_frombytes(P, p) != 0) {
return -1
}
for (i = 0; i < 32; ++i) {
t[i] = n[i]
}
t[31] &= 127
ec.ge25519_scalarmult(Q, t, P)
ec.ristretto255_p3_tobytes(q, Q)
if (sodium_is_zero(q, 32)) {
return -1
}
return 0
}
function crypto_scalarmult_ristretto255_base (q, n) {
var t = q.slice
var Q = ec.ge3()
var i
for (i = 0; i < 32; ++i) {
t[i] = n[i]
}
t[31] &= 127
ec.ge25519_scalarmult_base(Q, t)
ec.ristretto255_p3_tobytes(q, Q)
if (sodium_is_zero(q, 32)) {
return -1
}
return 0
}
function crypto_scalarmult_ristretto255_bytes () {
return crypto_scalarmult_ristretto255_BYTES
}
function crypto_scalarmult_ristretto255_scalarbytes () {
return crypto_scalarmult_ristretto255_SCALARBYTES
}
function has_small_order (s) {
assert(s instanceof Uint8Array && s.byteLength === 32)
const blacklist = [
/* 0 (order 4) */
[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
/* 1 (order 1) */
[ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ],
/* 325606250916557431795983626356110631294008115727848805560023387167927233504
(order 8) */
[ 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3,
0xfa, 0xf1, 0x9f, 0xc4, 0x6a, 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32,
0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00 ],
/* 39382357235489614581723060781553021112529911719440698176882885853963445705823
(order 8) */
[ 0x5f, 0x9c, 0x95, 0xbc, 0xa3, 0x50, 0x8c, 0x24, 0xb1, 0xd0, 0xb1,
0x55, 0x9c, 0x83, 0xef, 0x5b, 0x04, 0x44, 0x5c, 0xc4, 0x58, 0x1c,
0x8e, 0x86, 0xd8, 0x22, 0x4e, 0xdd, 0xd0, 0x9f, 0x11, 0x57 ],
/* p-1 (order 2) */
[ 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f ],
/* p (=0, order 4) */
[ 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f ],
/* p+1 (=1, order 1) */
[ 0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f ]
]
const c = Buffer.alloc(7)
var k
var i, j
assert(blacklist.length === 7)
for (j = 0; j < 31; j++) {
for (i = 0; i < 7; i++) {
c[i] |= s[j] ^ blacklist[i][j]
}
}
for (i = 0; i < 7; i++) {
c[i] |= (s[j] & 0x7f) ^ blacklist[i][j]
}
k = 0
for (i = 0; i < 7; i++) {
k |= (c[i] - 1)
}
return ((k >> 8) & 1)
}
function crypto_scalarmult_curve25519 (q, n, p) {
var t = q.slice()
var i
var x1 = ec.fe25519()
var x2 = ec.fe25519()
var z2 = ec.fe25519()
var x3 = ec.fe25519()
var z3 = ec.fe25519()
var tmp0 = ec.fe25519()
var tmp1 = ec.fe25519()
var pos
var swap
var b
if (has_small_order(p)) {
return -1;
}
for (i = 0; i < 32; i++) {
t[i] = n[i]
}
t[0] &= 248
t[31] &= 127
t[31] |= 64
ec.fe25519_frombytes(x1, p)
ec.fe25519_1(x2)
ec.fe25519_0(z2)
ec.fe25519_copy(x3, x1)
ec.fe25519_1(z3)
swap = 0
for (pos = 254; pos >= 0; --pos) {
b = t[pos / 8] >> (pos & 7)
b &= 1
swap ^= b
ec.fe25519_cswap(x2, x3, swap)
ec.fe25519_cswap(z2, z3, swap)
swap = b
ec.fe25519_sub(tmp0, x3, z3)
ec.fe25519_sub(tmp1, x2, z2)
ec.fe25519_add(x2, x2, z2)
ec.fe25519_add(z2, x3, z3)
ec.fe25519_mul(z3, tmp0, x2)
ec.fe25519_mul(z2, z2, tmp1)
ec.fe25519_sq(tmp0, tmp1)
ec.fe25519_sq(tmp1, x2)
ec.fe25519_add(x3, z3, z2)
ec.fe25519_sub(z2, z3, z2)
ec.fe25519_mul(x2, tmp1, tmp0)
ec.fe25519_sub(tmp1, tmp1, tmp0)
ec.fe25519_sq(z2, z2)
// TODO
// ec.fe25519_mul32(z3, tmp1, 121666)
ec.fe25519_mul(z3, tmp1, _121666)
ec.fe25519_sq(x3, x3)
ec.fe25519_add(tmp0, tmp0, z3)
ec.fe25519_mul(z3, x1, z2)
ec.fe25519_mul(z2, tmp1, tmp0)
}
ec.fe25519_cswap(x2, x3, swap)
ec.fe25519_cswap(z2, z3, swap)
ec.fe25519_invert(z2, z2)
ec.fe25519_mul(x2, x2, z2)
ec.fe25519_tobytes(q, x2)
return 0
}
function edwards_to_montgomery(montgomeryX, edwardsY, edwardsZ) {
var tempX = ec.fe25519()
var tempZ = ec.fe25519()
ec.fe25519_add(tempX, edwardsZ, edwardsY)
ec.fe25519_sub(tempZ, edwardsZ, edwardsY)
ec.fe25519_invert(tempZ, tempZ)
ec.fe25519_mul(montgomeryX, tempX, tempZ)
}
function crypto_scalarmult_curve25519_base (q, n) {
var t = q.slice()
var A = ec.ge3()
var pk = ec.fe25519()
var i
for (i = 0; i < 32; i++) {
t[i] = n[i]
}
t[0] &= 248
t[31] &= 127
t[31] |= 64
ec.ge25519_scalarmult_base(A, t)
edwards_to_montgomery(pk, A[1], A[2])
ec.fe25519_tobytes(q, pk)
return 0
}

2050
crypto_sign.json Normal file

File diff suppressed because it is too large Load Diff

163
crypto_sign_ed25519.js Normal file
View File

@ -0,0 +1,163 @@
const { sodium_memzero, sodium_memcmp } = require('./')
const ec = require('./fe25519_25')
const {
crypto_hash_sha512, crypto_hash_sha512_update,
crypto_hash_sha512_state, crypto_hash_sha512_final
} = require('./crypto_hash.js')
const { crypto_verify_32 } = require('./crypto_verify')
var crypto_sign_ed25519_BYTES = 64
var crypto_sign_ed25519_SEEDBYTES = 32
var crypto_sign_ed25519_PUBLICKEYBYTES = 32
var crypto_sign_ed25519_SECRETKEYBYTES = 64
var crypto_sign_ed25519_MESSAGEBYTES_MAX = Number.MAX_SAFE_INTEGER
function _crypto_sign_ed25519_ref10_hinit (hs, prehashed) {
const DOM2PREFIX = Buffer.from('SigEd25519 no Ed25519 collisions ')
DOM2PREFIX[30] = 1
DOM2PREFIX[31] = 0
if (prehashed) {
crypto_hash_sha512_update(hs, DOM2PREFIX, DOM2PREFIX.byteLength)
}
}
function _crypto_sign_ed25519_clamp (k) {
k[0] &= 248
k[31] &= 127
k[31] |= 64
}
function _crypto_sign_ed25519_detached (sig, m, mlen, sk, prehashed) {
var state = crypto_hash_sha512_state()
var az = Buffer.alloc(64)
var nonce = Buffer.alloc(64)
var hram = Buffer.alloc(64)
var R = ec.ge3()
_crypto_sign_ed25519_ref10_hinit(state, prehashed)
crypto_hash_sha512(az, sk, 32)
crypto_hash_sha512_update(state, az.subarray(32), 32)
crypto_hash_sha512_update(state, m, mlen)
crypto_hash_sha512_final(state, nonce)
sig.set(sk.subarray(32, 64), 32)
ec.sc25519_reduce(nonce)
ec.ge25519_scalarmult_base(R, nonce)
ec.ge25519_p3_tobytes(sig, R)
state = crypto_hash_sha512_state()
_crypto_sign_ed25519_ref10_hinit(state, prehashed)
crypto_hash_sha512_update(state, sig, 64)
crypto_hash_sha512_update(state, m, mlen)
crypto_hash_sha512_final(state, hram)
ec.sc25519_reduce(hram)
_crypto_sign_ed25519_clamp(az)
ec.sc25519_muladd(sig.subarray(32), hram, az, nonce)
sodium_memzero(az)
sodium_memzero(nonce)
return 0
}
function crypto_sign_ed25519_detached (sig, m, mlen, sk) {
return _crypto_sign_ed25519_detached(sig, m, mlen, sk, 0)
}
function crypto_sign_ed25519 (sm, m, mlen, sk) {
var siglen
sm.set(m.subarray(0, mlen), crypto_sign_ed25519_BYTES)
/* LCOV_EXCL_START */
if (crypto_sign_ed25519_detached(sm, sm.subarray(crypto_sign_ed25519_BYTES), mlen, sk) !== 0) {
sm.fill(0, mlen + crypto_sign_ed25519_BYTES)
return -1
}
/* LCOV_EXCL_STOP */
return m.byteLength + 64
}
function crypto_sign (sm, m, sk) {
return crypto_sign_ed25519(sm, m, m.byteLength, sk)
}
function _crypto_sign_ed25519_verify_detached(sig, m, mlen, pk, prehashed) {
var hs = crypto_hash_sha512_state()
var h = Buffer.alloc(64)
var rcheck = Buffer.alloc(32)
var A = ec.ge3()
var R = ec.ge2()
// #ifdef ED25519_COMPAT
if (sig[63] & 224) {
return -1
}
// #else
// if ((sig[63] & 240) &&
// sc25519_is_canonical(sig + 32) == 0) {
// return -1;
// }
// if (ge25519_has_small_order(sig) != 0) {
// return -1;
// }
// if (ge25519_is_canonical(pk) == 0 ||
// ge25519_has_small_order(pk) != 0) {
// return -1;
// }
// #endif
if (ec.ge25519_frombytes_negate_vartime(A, pk) !== 0) {
return -1
}
ec.ge25519_tobytes(rcheck, A)
_crypto_sign_ed25519_ref10_hinit(hs, prehashed)
crypto_hash_sha512_update(hs, sig, 32)
crypto_hash_sha512_update(hs, pk, 32)
crypto_hash_sha512_update(hs, m, mlen)
crypto_hash_sha512_final(hs, h)
ec.sc25519_reduce(h)
ec.ge25519_double_scalarmult_vartime(R, h, A, sig.subarray(32))
ec.ge25519_tobytes(rcheck, R)
return crypto_verify_32(rcheck, 0, sig, 0) | sodium_memcmp(sig.subarray(0, 32), rcheck.subarray(0, 32))
}
function crypto_sign_ed25519_verify_detached (sig, m, mlen, pk) {
return _crypto_sign_ed25519_verify_detached(sig, m, mlen, pk, 0);
}
function crypto_sign_ed25519_open (m, sm, pk) {
var mlen = 0
if (sm.byteLength < 64 || sm.byteLength - 64 > crypto_sign_ed25519_MESSAGEBYTES_MAX) {
throw new Error('Bad signature.')
}
mlen = sm.byteLength - 64
if (!crypto_sign_ed25519_verify_detached(sm, sm.subarray(64), mlen, pk)) {
if (m.byteLength) m.fill(0)
throw new Error('Bad signature.')
}
if (m.byteLength) {
m.set(sm.subarray(64))
}
return true
}
function crypto_sign_open (m, sm, pk) {
return crypto_sign_ed25519_open(m, sm, pk)
}
module.exports = {
crypto_sign,
crypto_sign_open
}

280
fe-test.js Normal file
View File

@ -0,0 +1,280 @@
const ec = require('./fe25519_25.js')
const sodium = require('./')
// const crypto = require('crypto')
var f = new Int32Array(10)
var g = new Int32Array(10)
var h = new Int32Array(10)
var a = ec.ge3()
var r = ec.ge3()
f[0] = 23983080
a[2][0] = 1
// ec.fe25519_neg(g, f)
// ec.fe25519_reduce(g, g)
// ec.fe25519_add(h, f, g)
// ec.fe25519_reduce(h, h)
// ec.fe25519_sub(h, f, g)
// ec.fe25519_reduce(h, h)
// console.log(h)
// ec.fe25519_add(h, f, f)
// ec.fe25519_reduce(h, h)
// console.log(h)
// g[0] = 2
// for (let i = 1; i < 10; i++) g[i] = 0
// ec.fe25519_mul(h, f, g)
// console.log(h)
// ec.fe25519_reduce(h, h)
// console.log(h)
var an = Buffer.from([
171, 69, 129, 47, 90, 82, 223, 134,
6, 147, 54, 76, 55, 148, 252, 37,
234, 216, 113, 62, 223, 49, 33, 36,
172, 246, 18, 226, 50, 249, 198, 231
])
var bn = Buffer.from([
226, 38, 16, 80, 186, 183, 134, 239,
190, 24, 150, 125, 14, 254, 19, 44,
55, 112, 156, 5, 141, 230, 91, 84,
110, 130, 213, 39, 249, 107, 145, 140
])
var cn = Buffer.from([
190, 24, 150, 125, 14, 254, 19, 44,
55, 112, 156, 5, 141, 230, 91, 84,
110, 130, 213, 39, 249, 107, 145, 140,
226, 38, 16, 80, 186, 183, 134, 239
])
var s = Buffer.from([
190, 24, 150, 125, 14, 254, 19, 44,
55, 112, 156, 5, 141, 230, 91, 84,
110, 130, 213, 39, 249, 107, 145, 140,
226, 38, 16, 80, 186, 183, 134, 239,
190, 24, 150, 125, 14, 254, 19, 44,
55, 112, 156, 5, 141, 230, 91, 84,
110, 130, 213, 39, 249, 107, 145, 140,
226, 38, 16, 80, 186, 183, 134, 239
])
const p = Buffer.from([
0x38, 0xf4, 0x69, 0x6f, 0xcf, 0x62, 0xa0, 0xfd,
0x5a, 0xb7, 0x6e, 0x9f, 0xcb, 0xcd, 0x95, 0x3f,
0xed, 0xba, 0x30, 0xb2, 0x64, 0x42, 0xa4, 0x52,
0x27, 0xa6, 0x3e, 0xd2, 0xc8, 0xac, 0xa4, 0xed
])
function signedInt (i) {
return i < 0 ? 2 ** 32 + i : i
}
// console.log(Uint8Array.from(an))
// console.log(Uint8Array.from(bn))
// console.log(an.toString('hex'))
// console.log(bn.toString('hex'))
// for (let i = 0; i < 25; i++) an[i] = bn[i] = i
// var correct = true
// var dn = Buffer.alloc(32)
const mod = 2n ** 252n + 27742317777372353535851937790883648493n
const res = Buffer.alloc(32)
const res1 = Buffer.alloc(32)
var a = new Int32Array(10)
var b = new Int32Array(10)
var c = new Int32Array(10)
var g = new Int32Array(10)
const ge = ec.ge3()
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'))
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_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_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_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_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_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_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_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_double_scalarmult_vartime(gf, an, ge, bn)
ec.ge25519_p3_tobytes(res, gf)
console.log("smdbl :", res.toString('hex'))
console.log('canon :', ec.sc25519_is_canonical(bn))
/////////////////////////////////////////////////////
// console.log(((BigInt(ahex) * BigInt(ahex)) % mod).toString(16))
// console.log(res1.toString('hex'))
// const b = new Float64Array(16)
// const bi = new Float64Array(16)
// sodium.unpack25519(b, an)
// console.log(b)
// sodium.inv25519(bi, b)
// console.log(b)
// sodium.pack(res1, bi)
// console.log(res.toString('hex'))
// console.log(res1.toString('hex'))
// for (let j = 0; j < 10000; j++) {
// var an = crypto.randomBytes(32)
// var bn = crypto.randomBytes(32)
// var cn = crypto.randomBytes(32)
// dn.fill(0)
// ec.fe25519_invert(dn, an, bn, cn)
// var res = reverseEndian(dn)
// var bi = (((BigInt('0x' + reverseEndian(an)) * BigInt('0x' + reverseEndian(bn))) + BigInt('0x' + reverseEndian(cn))) % mod).toString(16).padStart(res.length, '0')
// correct &= res === bi
// }
// console.log(correct === 1)
// function reverseEndian (buf) {
// var str = ''
// let i = buf.length - 1
// while (buf[i] === 0) i--
// if (i === -1) return '0'
// for (; i >= 0; i--) {
// str += buf[i].toString(16).padStart(2, '0')
// }
// return str
// }
// const a237 = new Array(
// 0x0003e6b1n,
// 0x001d0353n,
// 0x00033a5dn,
// 0x000fcd68n,
// 0x000cd8c5n,
// 0x00172cd9n,
// 0x000dcf66n,
// 0x0014afffn,
// 0x0009f453n,
// 0x0006399cn,
// 0x000e9672n,
// 0x000ee4een
// )
// var a237 = []
// a237 = Array.from(a237).map(BigInt)
// var s = Buffer.alloc(32)
// s[0] = Number(a237[0] >> 0n)
// s[1] = Number(a237[0] >> 8n)
// s[2] = Number((a237[0] >> 16n) | (a237[1] * (1n << 5n)))
// s[3] = Number(a237[1] >> 3n)
// s[4] = Number(a237[1] >> 11n)
// s[5] = Number((a237[1] >> 19n) | (a237[2] * (1n << 2n)))
// s[6] = Number(a237[2] >> 6n)
// s[7] = Number((a237[2] >> 14n) | (a237[3] * (1n << 7n)))
// s[8] = Number(a237[3] >> 1n)
// s[9] = Number(a237[3] >> 9n)
// s[10] = Number((a237[3] >> 17n) | (a237[4] * (1n << 4n)))
// s[11] = Number(a237[4] >> 4n)
// s[12] = Number(a237[4] >> 12n)
// s[13] = Number((a237[4] >> 20n) | (a237[5] * (1n << 1n)))
// s[14] = Number(a237[5] >> 7n)
// s[15] = Number((a237[5] >> 15n) | (a237[6] * (1n << 6n)))
// s[16] = Number(a237[6] >> 2n)
// s[17] = Number(a237[6] >> 10n)
// s[18] = Number((a237[6] >> 18n) | (a237[7] * (1n << 3n)))
// s[19] = Number(a237[7] >> 5n)
// s[20] = Number(a237[7] >> 13n)
// s[21] = Number(a237[8] >> 0n)
// s[22] = Number(a237[8] >> 8n)
// s[23] = Number((a237[8] >> 16n) | (a237[9] * (1n << 5n)))
// s[24] = Number(a237[9] >> 3n)
// s[25] = Number(a237[9] >> 11n)
// s[26] = Number((a237[9] >> 19n) | (a237[10] * (1n << 2n)))
// s[27] = Number(a237[10] >> 6n)
// s[28] = Number((a237[10] >> 14n) | (a237[11] * (1n << 7n)))
// s[29] = Number(a237[11] >> 1n)
// s[30] = Number(a237[11] >> 9n)
// s[31] = Number(a237[11] >> 17n)
// console.log(reverseEndian(s))
// // console.log(a237.reduce((acc, a, i) => acc + a * 1n << (20n * BigInt(i))).toString(16))

2802
fe25519_25.js Normal file

File diff suppressed because it is too large Load Diff

1
fe25519_25/base.json Normal file

File diff suppressed because one or more lines are too long

60
fe25519_25/mult.js Normal file

File diff suppressed because one or more lines are too long

2745
fe25519_25/mult.wat Normal file

File diff suppressed because it is too large Load Diff

4111
fe25519_25/test.c Executable file

File diff suppressed because it is too large Load Diff