crypto_sign and crypto_scalarmult with webassembly curve arithmetic added
This commit is contained in:
parent
596f8c8f18
commit
f1537df1e0
@ -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
|
||||||
}
|
}
|
||||||
|
325
crypto_scalarmult_ed25519.js
Normal file
325
crypto_scalarmult_ed25519.js
Normal 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
2050
crypto_sign.json
Normal file
File diff suppressed because it is too large
Load Diff
163
crypto_sign_ed25519.js
Normal file
163
crypto_sign_ed25519.js
Normal 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
280
fe-test.js
Normal 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
2802
fe25519_25.js
Normal file
File diff suppressed because it is too large
Load Diff
1
fe25519_25/base.json
Normal file
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
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
2745
fe25519_25/mult.wat
Normal file
File diff suppressed because it is too large
Load Diff
4111
fe25519_25/test.c
Executable file
4111
fe25519_25/test.c
Executable file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user