Compare commits

..

90 Commits

Author SHA1 Message Date
Christophe Diederichs
38a0d034d4 add crypto_pwhash test 2023-06-02 15:58:36 +01:00
Christophe Diederichs
2b515e6b71 use argon2hash-wasm module 2023-06-02 15:45:24 +01:00
Christophe Diederichs
4465a532c4 add crypto_pwhash api 2023-06-02 15:35:52 +01:00
Christophe Diederichs
64089d1fca add crypto_tweak api 2023-05-23 18:21:23 +01:00
Christophe Diederichs
c428394bb6 fix minor api mismatch 2023-05-23 17:28:44 +01:00
Christophe Diederichs
713becb400 Merge branch 'master' into curve 2023-05-23 17:13:50 +01:00
Christophe Diederichs
5dfe656dc5 ad tweak to ed-wasm test 2023-05-23 16:44:50 +01:00
Christophe Diederichs
081ca46654 use wasm implementations 2023-05-23 16:44:24 +01:00
Christophe Diederichs
facf602fdc add randombytes_buf_deterministic 2022-11-21 17:17:47 +00:00
Christophe Diederichs
ee481d0096 typo fixes in crypto_box and crypto_aead 2022-11-21 17:17:09 +00:00
Christophe Diederichs
4a97dfeebe fe25519_25 standard fixes 2022-11-21 17:16:35 +00:00
Christophe Diederichs
dbc8196148 add fe25519_25 constants 2022-11-21 17:16:13 +00:00
Christophe Diederichs
056b13362b add crypto_sign ed to curve25519 methods 2022-11-21 16:49:58 +00:00
Christophe Diederichs
f62c993d48 crypto_sign_keypair_seed typo 2022-11-21 16:46:00 +00:00
Christophe Diederichs
2f4480f2f1 scalarmult fixes 2022-11-21 13:13:52 +00:00
Christophe Diederichs
d6869faa13 add ristretto methods 2022-11-21 13:12:30 +00:00
Christophe Diederichs
b619401719 standard fix crypto_core 2022-11-21 13:11:59 +00:00
Christophe Diederichs
52d5899c54 crypto_core fixes 2022-11-18 12:21:38 +00:00
Christophe Diederichs
919353ba53 fe25519_25 fix imports and exports 2022-11-18 12:20:21 +00:00
Christophe Diederichs
7cad891d0e ge25519_from_uniform fix 2022-11-18 12:18:32 +00:00
Christophe Diederichs
bfa677d67f add crypto_sign keypair methods 2022-11-18 08:59:20 +00:00
Christophe Diederichs
37c8f2db79 fix scalarmult exports 2022-11-18 08:57:55 +00:00
Christophe Diederichs
c42c442eab add crypto_core methods 2022-11-18 08:56:18 +00:00
Christophe Diederichs
58947e04ce add fe25519_mul32 2022-11-17 19:38:08 +00:00
Christophe Diederichs
c54ff9636e add ristretto methods 2022-01-05 22:50:20 +00:00
Christophe Diederichs
88862d3669 scalarmult_curve25519 implemented in wasm 2020-10-30 10:46:51 +01:00
Christophe Diederichs
bafe8f8fac first attempt at wassm scalarmult 2020-10-16 01:10:52 +02:00
Christophe Diederichs
a02899bfe2 scalarmult internal loop in wasm 2020-10-13 16:10:47 +02:00
Christophe Diederichs
40bced0da1 use tables to share functions between modules 2020-10-12 16:41:06 +02:00
Christophe Diederichs
3c2f81c3f3 add js ed25519_pk_to_curve25519 2020-08-28 04:40:23 +02:00
Christophe Diederichs
3753006318 latest working state 2020-08-28 00:52:54 +02:00
Christophe Diederichs
65639e537e remove old files 2020-07-08 15:30:13 +02:00
Christophe Diederichs
3dfe6daec0 add invert, pow22523 wat files 2020-07-08 15:28:32 +02:00
Christophe Diederichs
885541ad1f rename to fe25519_mul.wat 2020-07-07 17:05:18 +02:00
Christophe Diederichs
e5dff8b785 move wasm modules into individual files 2020-07-07 17:03:16 +02:00
Christophe Diederichs
8c23d7a3af save working state 2020-07-02 17:19:58 +02:00
Christophe Diederichs
3ecb669b6f tests for ed25519 wasm methods 2020-06-26 10:16:35 +02:00
Christophe Diederichs
f1537df1e0 crypto_sign and crypto_scalarmult with webassembly curve arithmetic added 2020-06-26 10:16:14 +02:00
Christophe Diederichs
596f8c8f18 export constant: crypto_hash_sha512_BYTES 2020-06-18 14:22:32 +02:00
Christophe Diederichs
21051f3392 correct filename: crypto_hash_sha256 2020-06-18 14:17:58 +02:00
Christophe Diederichs
759cec5b5a add endian check: all other modules require members of this set 2020-06-18 14:11:22 +02:00
Christophe Diederichs
aa0305154f move crypto_hash_sha256 to module to uncouple wasm dependencies 2020-06-18 14:09:12 +02:00
Christophe Diederichs
cb1fe07efe bump chacha20 to 1.0.4: remove Buffer dep 2020-06-18 13:34:38 +02:00
Christophe Diederichs
b6201cc0f1 standard fixes 2020-06-18 11:38:44 +02:00
Christophe Diederichs
9d29d467e4 add sha-wasm deps to package.json 2020-06-18 11:35:47 +02:00
Christophe Diederichs
5473cafdfe reduce code branching, align return values with sodium-native 2020-06-18 11:12:35 +02:00
Christophe Diederichs
d2d84df55e bump to chacha 1.0.3 - remove Buffer dependency 2020-06-17 17:29:37 +02:00
Christophe Diederichs
fdfc09a157 change checks to assertions 2020-06-17 17:27:28 +02:00
Christophe Diederichs
d626fb2ca5 use Uint8Arrays instead of buffers 2020-06-17 17:26:50 +02:00
Christophe Diederichs
b6b39638cf move chacha20 alg to external module 2020-06-17 15:07:17 +02:00
Christophe Diederichs
56416de1d5 throw if crypto_aead cannot validate, fix typo in crypto_verify 2020-06-17 14:44:35 +02:00
Christophe Diederichs
e35adc6823 catch syntax error 2020-06-17 13:31:54 +02:00
Christophe Diederichs
ec9cac17d0 added: sodium_is_zero 2020-06-17 13:19:05 +02:00
Christophe Diederichs
b7a0d1f2e5 sodium_memcmp returns boolean 2020-06-17 13:13:05 +02:00
Christophe Diederichs
9b78e675e4 export crypto_verify module 2020-06-17 13:10:21 +02:00
Christophe Diederichs
2214a59711 export sodium_memcmp 2020-06-17 13:07:28 +02:00
Christophe Diederichs
0b37ca03ec added: sodium_memcmp 2020-06-17 13:06:30 +02:00
Christophe Diederichs
6a0e8e7236 add null check on ad param 2020-06-17 13:00:52 +02:00
Christophe Diederichs
68bd4b4a68 chacha: readUint32Le generalised for uint8array; aead: standard fix 2020-06-17 12:50:27 +02:00
Christophe Diederichs
272ac68f6b add assertions 2020-06-17 11:12:20 +02:00
Christophe Diederichs
e423d00ebc listen to linter 2020-06-17 01:29:42 +02:00
Christophe Diederichs
caa8390691 added: crypto_aead_chacha20poly1305_ietf methods 2020-06-17 00:56:59 +02:00
Christophe Diederichs
04bebb09c9 tidy: remove legacy functions 2020-06-16 16:58:58 +02:00
Christophe Diederichs
e69a73279a update sodium_memzero function to arr.fill(0) 2020-06-16 16:57:58 +02:00
Christophe Diederichs
79273d499e rename memzero -> sodium-memzero 2020-06-16 16:54:51 +02:00
Christophe Diederichs
e589c6a5d6 declare constants about exports 2020-06-16 16:52:57 +02:00
Christophe Diederichs
96266128af removed duplicate module.exports declaraion 2020-06-16 16:03:27 +02:00
Christophe Diederichs
84bf4229e4 add: crypto_box_seed_keypair 2020-06-16 16:02:42 +02:00
Christophe Diederichs
7d7249ddc2 export _9 constant field element 2020-06-16 15:55:26 +02:00
Christophe Diederichs
f969d1f707 correction: crypto_kx is not actually an alias of crypto_box 2020-06-16 15:54:44 +02:00
Christophe Diederichs
67a4ba77cb scalarmult: import curve methods; be standard 2020-06-16 15:53:27 +02:00
Christophe Diederichs
8aae7efea2 add: crypto_box_seed_keypair; alias crypto_kx methods to crypto_box 2020-06-16 14:18:32 +02:00
Christophe Diederichs
d57736bf8b be standard 2020-06-16 14:17:31 +02:00
Christophe Diederichs
7141f00ff0 fix bugs in crypto_sign 2020-06-16 14:16:50 +02:00
Christophe Diederichs
7e5ea3b5ed update sha512 to wasm module 2020-06-16 14:15:33 +02:00
Christophe Diederichs
30b8e83417 add chacha20; align API with PR#21 2020-06-12 17:06:31 +02:00
Christophe Diederichs
311905883a update: crypto_hash 2020-05-23 13:37:54 +02:00
Christophe Diederichs
895d4312af require ed25519.js 2020-05-04 21:17:27 +02:00
Christophe Diederichs
d1aaacd3a7 tidy up 2020-05-04 21:13:24 +02:00
Christophe Diederichs
6a9696c86f module: crypto_box 2020-05-04 21:12:44 +02:00
Christophe Diederichs
5dd22a0957 module: crypto_onetimeauth 2020-05-04 21:11:30 +02:00
Christophe Diederichs
a4cab9dfd4 leftover crypto_stream functions 2020-05-04 21:10:22 +02:00
Christophe Diederichs
00d47225ff move verify functions to crypto_verify module 2020-05-04 21:08:29 +02:00
Christophe Diederichs
1e447c23d6 module: crypto_secretbox 2020-05-04 21:04:41 +02:00
Christophe Diederichs
6428fb8222 module: crypto_sign 2020-05-04 20:58:36 +02:00
Christophe Diederichs
b30cf7348e module: crypto_hash 2020-05-04 20:52:17 +02:00
Christophe Diederichs
ff28f5a888 module: crypto_scalarmult 2020-05-04 20:49:21 +02:00
Christophe Diederichs
03fb607709 module: poly1305 2020-05-04 20:44:56 +02:00
Christophe Diederichs
d7ca21cbf1 move ed25519 arithmetic to separate module 2020-05-04 18:59:59 +02:00
Christophe Diederichs
942c2a6db0 crypto_stream: signature change needed to modularise 2020-05-04 18:47:52 +02:00
39 changed files with 16595 additions and 10 deletions

View File

@ -1,7 +1,7 @@
/* eslint-disable camelcase */
const { crypto_hash_sha512 } = require('./crypto_hash')
const { crypto_scalarmult, crypto_scalarmult_base } = require('./crypto_scalarmult')
const { randombytes } = require('./randombytes')
const { randombytes_buf } = require('./randombytes')
const { crypto_generichash_batch } = require('./crypto_generichash')
const { crypto_stream_xsalsa20_MESSAGEBYTES_MAX } = require('./crypto_stream')
const {
@ -32,6 +32,8 @@ const crypto_box_MESSAGEBYTES_MAX =
module.exports = {
crypto_box_easy,
crypto_box_open_easy,
crypto_box_detached,
crypto_box_open_detached,
crypto_box_keypair,
crypto_box_seed_keypair,
crypto_box_seal,
@ -50,7 +52,7 @@ module.exports = {
function crypto_box_keypair (pk, sk) {
check(pk, crypto_box_PUBLICKEYBYTES)
check(sk, crypto_box_SECRETKEYBYTES)
randombytes(sk, 32)
randombytes_buf(sk, 32)
return crypto_scalarmult_base(pk, sk)
}
function crypto_box_seed_keypair (pk, sk, seed) {

269
crypto_core.js Normal file
View File

@ -0,0 +1,269 @@
const b4a = require('b4a')
const assert = require('nanoassert')
const {
ge25519_p3,
ge25519_p1p1,
ge25519_cached,
ge25519_frombytes,
ge25519_p3_tobytes,
ge25519_p1p1_to_p3,
ge25519_p3_to_cached,
ge25519_is_on_curve,
ge25519_is_canonical,
ge25519_is_on_main_subgroup,
ge25519_has_small_order,
ge25519_add_cached,
ge25519_sub_cached,
ge25519_from_uniform,
sc25519_reduce,
sc25519_mul,
sc25519_invert,
sc25519_is_canonical
} = require('./fe25519_25.js')
const { randombytes_buf } = require('./randombytes')
const {
sodium_add,
sodium_sub,
sodium_is_zero,
sodium_memzero
} = require('./utils')
function crypto_core_ed25519_is_valid_point (p) {
const p_p3 = ge25519_p3()
if (ge25519_is_canonical(p) == 0 ||
ge25519_has_small_order(p) != 0 ||
ge25519_frombytes(p_p3, p) != 0 ||
ge25519_is_on_curve(p_p3) == 0 ||
ge25519_is_on_main_subgroup(p_p3) == 0) {
return false
}
return true
}
function crypto_core_ed25519_add (r, p, q) {
const p_p3 = ge25519_p3()
const q_p3 = ge25519_p3()
const r_p3 = ge25519_p3()
const r_p1p1 = ge25519_p1p1()
const q_cached = ge25519_cached()
if (ge25519_frombytes(p_p3, p) != 0 || ge25519_is_on_curve(p_p3) == 0 ||
ge25519_frombytes(q_p3, q) != 0 || ge25519_is_on_curve(q_p3) == 0) {
throw new Error('Operands must be valid points.')
}
ge25519_p3_to_cached(q_cached, q_p3)
ge25519_add_cached(r_p1p1, p_p3, q_cached)
ge25519_p1p1_to_p3(r_p3, r_p1p1)
ge25519_p3_tobytes(r, r_p3)
}
function crypto_core_ed25519_sub (r, p, q) {
const p_p3 = ge25519_p3()
const q_p3 = ge25519_p3()
const r_p3 = ge25519_p3()
const r_p1p1 = ge25519_p1p1()
const q_cached = ge25519_cached()
if (ge25519_frombytes(p_p3, p) != 0 || ge25519_is_on_curve(p_p3) == 0 ||
ge25519_frombytes(q_p3, q) != 0 || ge25519_is_on_curve(q_p3) == 0) {
throw new Error('Operands must be valid points.')
}
ge25519_p3_to_cached(q_cached, q_p3)
ge25519_sub_cached(r_p1p1, p_p3, q_cached)
ge25519_p1p1_to_p3(r_p3, r_p1p1)
ge25519_p3_tobytes(r, r_p3)
}
function crypto_core_ed25519_from_uniform (p, r) {
ge25519_from_uniform(p, r)
}
// const HASH_GE_L = 48
// function _string_to_points (px, n, ctx, msg, msg_len, hash_alg) {
// const h = b4a.alloc(crypto_core_ed25519_HASHBYTES)
// const h_be = b4a.alloc(2 * HASH_GE_L)
// let i
// let j
// if (n > 2) {
// // abort(); /* LCOV_EXCL_LINE */
// throw new Error('abort')
// }
// if (core_h2c_string_to_hash(h_be, n * HASH_GE_L, ctx, msg, msg_len,
// hash_alg) != 0) {
// return -1;
// }
// COMPILER_ASSERT(sizeof h >= HASH_GE_L);
// for (i = 0U; i < n; i++) {
// for (j = 0U; j < HASH_GE_L; j++) {
// h[j] = h_be[i * HASH_GE_L + HASH_GE_L - 1U - j];
// }
// memset(&h[j], 0, (sizeof h) - j);
// ge25519_from_hash(&px[i * crypto_core_ed25519_BYTES], h);
// }
// return 0;
// }
// int
// crypto_core_ed25519_from_string(unsigned char p[crypto_core_ed25519_BYTES],
// const char *ctx, msg,
// size_t msg_len, int hash_alg)
// {
// return _string_to_points(p, 1, ctx, msg, msg_len, hash_alg);
// }
// int
// crypto_core_ed25519_from_string_ro(unsigned char p[crypto_core_ed25519_BYTES],
// const char *ctx, msg,
// size_t msg_len, int hash_alg)
// {
// unsigned char px[2 * crypto_core_ed25519_BYTES];
// if (_string_to_points(px, 2, ctx, msg, msg_len, hash_alg) != 0) {
// return -1;
// }
// return crypto_core_ed25519_add(p, &px[0], &px[crypto_core_ed25519_BYTES]);
// }
function crypto_core_ed25519_random (p) {
const h = b4a.alloc(crypto_core_ed25519_UNIFORMBYTES)
randombytes_buf(h)
crypto_core_ed25519_from_uniform(p, h)
}
function crypto_core_ed25519_scalar_random (r) {
do {
randombytes_buf(r, crypto_core_ed25519_SCALARBYTES)
r[crypto_core_ed25519_SCALARBYTES - 1] &= 0x1f
} while (sc25519_is_canonical(r) == 0 ||
sodium_is_zero(r, crypto_core_ed25519_SCALARBYTES))
}
function crypto_core_ed25519_scalar_invert (recip, s) {
sc25519_invert(recip, s)
if (sodium_is_zero(s, crypto_core_ed25519_SCALARBYTES)) {
throw new Error('Zero point')
}
}
/* 2^252+27742317777372353535851937790883648493 */
const L = b4a.from([
0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7,
0xa2, 0xde, 0xf9, 0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10
])
function crypto_core_ed25519_scalar_negate (neg, s) {
const t_ = b4a.alloc(crypto_core_ed25519_NONREDUCEDSCALARBYTES)
const s_ = b4a.alloc(crypto_core_ed25519_NONREDUCEDSCALARBYTES)
assert(crypto_core_ed25519_NONREDUCEDSCALARBYTES >=
2 * crypto_core_ed25519_SCALARBYTES)
t_.fill(0)
s_.fill(0)
t_.set(L.subarray(0, crypto_core_ed25519_SCALARBYTES), crypto_core_ed25519_SCALARBYTES)
s_.set(s.subarray(0, crypto_core_ed25519_SCALARBYTES))
sodium_sub(t_, s_, crypto_core_ed25519_NONREDUCEDSCALARBYTES)
sc25519_reduce(t_)
neg.set(t_.subarray(0, crypto_core_ed25519_SCALARBYTES))
}
function crypto_core_ed25519_scalar_complement (comp, s) {
const t_ = b4a.alloc(crypto_core_ed25519_NONREDUCEDSCALARBYTES)
const s_ = b4a.alloc(crypto_core_ed25519_NONREDUCEDSCALARBYTES)
assert(crypto_core_ed25519_NONREDUCEDSCALARBYTES >=
2 * crypto_core_ed25519_SCALARBYTES)
t_.fill(0)
s_.fill(0)
t_[0]++
t_.set(L.subarray(0, crypto_core_ed25519_SCALARBYTES), crypto_core_ed25519_SCALARBYTES)
s_.set(s.subarray(0, crypto_core_ed25519_SCALARBYTES))
sodium_sub(t_, s_, crypto_core_ed25519_NONREDUCEDSCALARBYTES)
sc25519_reduce(t_)
comp.set(t_.subarray(0, crypto_core_ed25519_SCALARBYTES))
}
function crypto_core_ed25519_scalar_add (z, x, y) {
const x_ = b4a.alloc(crypto_core_ed25519_NONREDUCEDSCALARBYTES)
const y_ = b4a.alloc(crypto_core_ed25519_NONREDUCEDSCALARBYTES)
x_.fill(0)
y_.fill(0)
x_.set(x.subarray(0, crypto_core_ed25519_SCALARBYTES))
y_.set(y.subarray(0, crypto_core_ed25519_SCALARBYTES))
sodium_add(x_, y_, crypto_core_ed25519_SCALARBYTES)
crypto_core_ed25519_scalar_reduce(z, x_)
}
function crypto_core_ed25519_scalar_sub (z, x, y) {
const yn = b4a.alloc(crypto_core_ed25519_SCALARBYTES)
crypto_core_ed25519_scalar_negate(yn, y)
crypto_core_ed25519_scalar_add(z, x, yn)
}
function crypto_core_ed25519_scalar_mul (z, x, y) {
sc25519_mul(z, x, y)
}
function crypto_core_ed25519_scalar_reduce (r, s) {
const t = b4a.alloc(crypto_core_ed25519_NONREDUCEDSCALARBYTES)
t.set(s)
sc25519_reduce(t)
r.set(t.subarray(0, crypto_core_ed25519_SCALARBYTES))
sodium_memzero(t)
}
function crypto_core_ed25519_scalar_is_canonical (s) {
return sc25519_is_canonical(s)
}
const crypto_core_ed25519_BYTES = 32
const crypto_core_ed25519_UNIFORMBYTES = 32
const crypto_core_ed25519_SCALARBYTES = 32
const crypto_core_ed25519_NONREDUCEDSCALARBYTES = 64
module.exports = {
crypto_core_ed25519_is_valid_point,
crypto_core_ed25519_add,
crypto_core_ed25519_sub,
crypto_core_ed25519_from_uniform,
crypto_core_ed25519_random,
crypto_core_ed25519_scalar_random,
crypto_core_ed25519_scalar_invert,
crypto_core_ed25519_scalar_negate,
crypto_core_ed25519_scalar_complement,
crypto_core_ed25519_scalar_add,
crypto_core_ed25519_scalar_sub,
crypto_core_ed25519_scalar_mul,
crypto_core_ed25519_scalar_reduce,
crypto_core_ed25519_scalar_is_canonical,
crypto_core_ed25519_BYTES,
crypto_core_ed25519_UNIFORMBYTES,
crypto_core_ed25519_SCALARBYTES,
crypto_core_ed25519_NONREDUCEDSCALARBYTES
}

147
crypto_core_ristretto255.js Normal file
View File

@ -0,0 +1,147 @@
const b4a = require('b4a')
const { randombytes_buf } = require('./randombytes')
const {
ge25519_p3,
ge25519_p1p1,
ge25519_cached,
ge25519_p3_to_cached,
ge25519_add_cached,
ge25519_p1p1_to_p3,
ge25519_sub_cached,
ristretto255_frombytes,
ristretto255_p3_tobytes,
ristretto255_from_hash,
sc25519_mul,
sc25519_is_canonical
} = require('./fe25519_25')
const {
crypto_core_ed25519_scalar_random,
crypto_core_ed25519_scalar_invert,
crypto_core_ed25519_scalar_negate,
crypto_core_ed25519_scalar_complement,
crypto_core_ed25519_scalar_add,
crypto_core_ed25519_scalar_sub,
crypto_core_ed25519_scalar_reduce
} = require('./crypto_core')
const crypto_core_ristretto255_BYTES = 32
const crypto_core_ristretto255_NONREDUCEDSCALARBYTES = 64
const crypto_core_ristretto255_HASHBYTES = 64
const crypto_core_ristretto255_SCALARBYTES = 32
module.exports = {
crypto_core_ristretto255_BYTES,
crypto_core_ristretto255_NONREDUCEDSCALARBYTES,
crypto_core_ristretto255_HASHBYTES,
crypto_core_ristretto255_SCALARBYTES,
crypto_core_ristretto255_is_valid_point,
crypto_core_ristretto255_add,
crypto_core_ristretto255_sub,
crypto_core_ristretto255_from_hash,
crypto_core_ristretto255_random,
crypto_core_ristretto255_scalar_random,
crypto_core_ristretto255_scalar_invert,
crypto_core_ristretto255_scalar_negate,
crypto_core_ristretto255_scalar_complement,
crypto_core_ristretto255_scalar_add,
crypto_core_ristretto255_scalar_sub,
crypto_core_ristretto255_scalar_mul,
crypto_core_ristretto255_scalar_reduce,
crypto_core_ristretto255_scalar_is_canonical
}
function crypto_core_ristretto255_is_valid_point (p) {
const p_p3 = ge25519_p3()
if (ristretto255_frombytes(p_p3, p) != 0) {
return false
}
return true
}
function crypto_core_ristretto255_add (r, p, q) {
const p_p3 = ge25519_p3()
const q_p3 = ge25519_p3()
const r_p3 = ge25519_p3()
const r_p1p1 = ge25519_p1p1()
const q_cached = ge25519_cached()
if (ristretto255_frombytes(p_p3, p) != 0 ||
ristretto255_frombytes(q_p3, q) != 0) {
return -1
}
ge25519_p3_to_cached(q_cached, q_p3)
ge25519_add_cached(r_p1p1, p_p3, q_cached)
ge25519_p1p1_to_p3(r_p3, r_p1p1)
ristretto255_p3_tobytes(r, r_p3)
return 0
}
function crypto_core_ristretto255_sub (r, p, q) {
const p_p3 = ge25519_p3()
const q_p3 = ge25519_p3()
const r_p3 = ge25519_p3()
const r_p1p1 = ge25519_p1p1()
const q_cached = ge25519_cached()
if (ristretto255_frombytes(p_p3, p) != 0 ||
ristretto255_frombytes(q_p3, q) != 0) {
return -1
}
ge25519_p3_to_cached(q_cached, q_p3)
ge25519_sub_cached(r_p1p1, p_p3, q_cached)
ge25519_p1p1_to_p3(r_p3, r_p1p1)
ristretto255_p3_tobytes(r, r_p3)
return 0
}
function crypto_core_ristretto255_from_hash (p, r) {
ristretto255_from_hash(p, r)
return 0
}
function crypto_core_ristretto255_random (p) {
const h = b4a.alloc(crypto_core_ristretto255_HASHBYTES)
randombytes_buf(h)
crypto_core_ristretto255_from_hash(p, h)
}
function crypto_core_ristretto255_scalar_random (r) {
crypto_core_ed25519_scalar_random(r)
}
function crypto_core_ristretto255_scalar_invert (recip, s) {
return crypto_core_ed25519_scalar_invert(recip, s)
}
function crypto_core_ristretto255_scalar_negate (neg, s) {
crypto_core_ed25519_scalar_negate(neg, s)
}
function crypto_core_ristretto255_scalar_complement (comp, s) {
crypto_core_ed25519_scalar_complement(comp, s)
}
function crypto_core_ristretto255_scalar_add (z, x, y) {
crypto_core_ed25519_scalar_add(z, x, y)
}
function crypto_core_ristretto255_scalar_sub (z, x, y) {
crypto_core_ed25519_scalar_sub(z, x, y)
}
function crypto_core_ristretto255_scalar_mul (z, x, y) {
sc25519_mul(z, x, y)
}
function crypto_core_ristretto255_scalar_reduce (r, s) {
crypto_core_ed25519_scalar_reduce(r, s)
}
function crypto_core_ristretto255_scalar_is_canonical (s) {
return sc25519_is_canonical(s)
}

View File

@ -14,6 +14,23 @@ function crypto_hash_sha512 (out, m, n) {
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) {
return crypto_hash_sha512(out, m, n)
}
@ -21,6 +38,9 @@ function crypto_hash (out, m, n) {
module.exports = {
crypto_hash,
crypto_hash_sha512,
crypto_hash_sha512_state,
crypto_hash_sha512_update,
crypto_hash_sha512_final,
crypto_hash_sha512_BYTES,
crypto_hash_BYTES
}

264
crypto_pwhash.js Normal file
View File

@ -0,0 +1,264 @@
/* eslint-disable camelcase */
const b4a = require('b4a')
const argon2 = require('argon2hash-wasm')
const { randombytes_buf } = require('./randombytes')
const crypto_pwhash_argon2i_ALG_ARGON2I13 = 1
const crypto_pwhash_argon2i_BYTES_MIN = 16
const crypto_pwhash_argon2i_BYTES_MAX = 4294967295
const crypto_pwhash_argon2i_PASSWD_MIN = 0
const crypto_pwhash_argon2i_PASSWD_MAX = 4294967295
const crypto_pwhash_argon2i_SALTBYTES = 16
const crypto_pwhash_argon2i_STRBYTES = 128
const crypto_pwhash_argon2i_STRPREFIX = '$argon2i$'
const crypto_pwhash_argon2i_OPSLIMIT_MIN = 3
const crypto_pwhash_argon2i_OPSLIMIT_MAX = 4294967295
const crypto_pwhash_argon2i_MEMLIMIT_MIN = 8192
const crypto_pwhash_argon2i_MEMLIMIT_MAX = 2147483648
const crypto_pwhash_argon2i_OPSLIMIT_INTERACTIVE = 4
const crypto_pwhash_argon2i_MEMLIMIT_INTERACTIVE = 33554432
const crypto_pwhash_argon2i_OPSLIMIT_MODERATE = 6
const crypto_pwhash_argon2i_MEMLIMIT_MODERATE = 134217728
const crypto_pwhash_argon2i_OPSLIMIT_SENSITIVE = 8
const crypto_pwhash_argon2i_MEMLIMIT_SENSITIVE = 536870912
const crypto_pwhash_argon2id_ALG_ARGON2ID13 = 2
const crypto_pwhash_argon2id_BYTES_MIN = 16
const crypto_pwhash_argon2id_BYTES_MAX = 4294967295
const crypto_pwhash_argon2id_PASSWD_MIN = 0
const crypto_pwhash_argon2id_PASSWD_MAX = 4294967295
const crypto_pwhash_argon2id_SALTBYTES = 16
const crypto_pwhash_argon2id_STRBYTES = 128
const crypto_pwhash_argon2id_STRPREFIX = '$argon2id$'
const crypto_pwhash_argon2id_OPSLIMIT_MIN = 1
const crypto_pwhash_argon2id_OPSLIMIT_MAX = 4294967295
const crypto_pwhash_argon2id_MEMLIMIT_MIN = 8192
const crypto_pwhash_argon2id_MEMLIMIT_MAX = 2147483648
const crypto_pwhash_argon2id_OPSLIMIT_INTERACTIVE = 2
const crypto_pwhash_argon2id_MEMLIMIT_INTERACTIVE = 67108864
const crypto_pwhash_argon2id_OPSLIMIT_MODERATE = 3
const crypto_pwhash_argon2id_MEMLIMIT_MODERATE = 268435456
const crypto_pwhash_argon2id_OPSLIMIT_SENSITIVE = 4
const crypto_pwhash_argon2id_MEMLIMIT_SENSITIVE = 1073741824
const crypto_pwhash_ALG_ARGON2I13 = crypto_pwhash_argon2i_ALG_ARGON2I13
const crypto_pwhash_ALG_ARGON2ID13 = crypto_pwhash_argon2id_ALG_ARGON2ID13
const crypto_pwhash_ALG_DEFAULT = crypto_pwhash_ALG_ARGON2ID13
const crypto_pwhash_BYTES_MIN = crypto_pwhash_argon2id_BYTES_MIN
const crypto_pwhash_BYTES_MAX = crypto_pwhash_argon2id_BYTES_MAX
const crypto_pwhash_PASSWD_MIN = crypto_pwhash_argon2id_PASSWD_MIN
const crypto_pwhash_PASSWD_MAX = crypto_pwhash_argon2id_PASSWD_MAX
const crypto_pwhash_SALTBYTES = crypto_pwhash_argon2id_SALTBYTES
const crypto_pwhash_STRBYTES = crypto_pwhash_argon2id_STRBYTES
const crypto_pwhash_STRPREFIX = crypto_pwhash_argon2id_STRPREFIX
const crypto_pwhash_OPSLIMIT_MIN = crypto_pwhash_argon2id_OPSLIMIT_MIN
const crypto_pwhash_OPSLIMIT_MAX = crypto_pwhash_argon2id_OPSLIMIT_MAX
const crypto_pwhash_MEMLIMIT_MIN = crypto_pwhash_argon2id_MEMLIMIT_MIN
const crypto_pwhash_MEMLIMIT_MAX = crypto_pwhash_argon2id_MEMLIMIT_MAX
const crypto_pwhash_OPSLIMIT_INTERACTIVE = crypto_pwhash_argon2id_OPSLIMIT_INTERACTIVE
const crypto_pwhash_MEMLIMIT_INTERACTIVE = crypto_pwhash_argon2id_MEMLIMIT_INTERACTIVE
const crypto_pwhash_OPSLIMIT_MODERATE = crypto_pwhash_argon2id_OPSLIMIT_MODERATE
const crypto_pwhash_MEMLIMIT_MODERATE = crypto_pwhash_argon2id_MEMLIMIT_MODERATE
const crypto_pwhash_OPSLIMIT_SENSITIVE = crypto_pwhash_argon2id_OPSLIMIT_SENSITIVE
const crypto_pwhash_MEMLIMIT_SENSITIVE = crypto_pwhash_argon2id_MEMLIMIT_SENSITIVE
module.exports = {
crypto_pwhash_ALG_ARGON2I13,
crypto_pwhash_ALG_ARGON2ID13,
crypto_pwhash_ALG_DEFAULT,
crypto_pwhash_BYTES_MIN,
crypto_pwhash_BYTES_MAX,
crypto_pwhash_PASSWD_MIN,
crypto_pwhash_PASSWD_MAX,
crypto_pwhash_SALTBYTES,
crypto_pwhash_STRBYTES,
crypto_pwhash_STRPREFIX,
crypto_pwhash_OPSLIMIT_MIN,
crypto_pwhash_OPSLIMIT_MAX,
crypto_pwhash_MEMLIMIT_MIN,
crypto_pwhash_MEMLIMIT_MAX,
crypto_pwhash_OPSLIMIT_INTERACTIVE,
crypto_pwhash_MEMLIMIT_INTERACTIVE,
crypto_pwhash_OPSLIMIT_MODERATE,
crypto_pwhash_MEMLIMIT_MODERATE,
crypto_pwhash_OPSLIMIT_SENSITIVE,
crypto_pwhash_MEMLIMIT_SENSITIVE,
crypto_pwhash_argon2i,
crypto_pwhash_argon2id,
crypto_pwhash_argon2i_str,
crypto_pwhash_argon2id_str,
crypto_pwhash,
crypto_pwhash_str,
crypto_pwhash_str_verify,
crypto_pwhash_str_needs_rehash
}
function crypto_pwhash_argon2i (out, passwd, salt, passes, memory, alg) {
const outlen = out.byteLength
const passwdlen = passwd.byteLength
out.fill(0)
if (outlen > crypto_pwhash_argon2i_BYTES_MAX) {
throw new Error('Too large')
}
if (outlen < crypto_pwhash_argon2i_BYTES_MIN) {
throw new Error('Invalid opts')
}
if (passwdlen > crypto_pwhash_argon2i_PASSWD_MAX ||
passes > crypto_pwhash_argon2i_OPSLIMIT_MAX ||
memory > crypto_pwhash_argon2i_MEMLIMIT_MAX) {
throw new Error('Too large')
}
if (passwdlen < crypto_pwhash_argon2i_PASSWD_MIN ||
(passes && passes < crypto_pwhash_argon2i_OPSLIMIT_MIN) ||
(memory && memory < crypto_pwhash_argon2i_MEMLIMIT_MIN)) {
throw new Error('Invalid opts')
}
switch (alg) {
case crypto_pwhash_argon2i_ALG_ARGON2I13: {
const buf = argon2(passwd, salt, null, null, 'binary', { memory: memory >> 10, passes, outlen, type: argon2.ARGON2I })
out.set(buf)
return 0
}
default:
throw new Error('Invalid input')
}
}
function crypto_pwhash_argon2id (out, passwd, salt, passes, memory, alg) {
const outlen = out.byteLength
const passwdlen = passwd.byteLength
out.fill(0)
if (outlen > crypto_pwhash_argon2id_BYTES_MAX) {
throw new Error('Too large')
}
if (outlen < crypto_pwhash_argon2id_BYTES_MIN) {
throw new Error('Invalid opts')
}
if (passwdlen > crypto_pwhash_argon2id_PASSWD_MAX ||
passes > crypto_pwhash_argon2id_OPSLIMIT_MAX ||
memory > crypto_pwhash_argon2id_MEMLIMIT_MAX) {
throw new Error('Too large')
}
if (passwdlen < crypto_pwhash_argon2id_PASSWD_MIN ||
(passes && passes < crypto_pwhash_argon2id_OPSLIMIT_MIN) ||
(memory && memory < crypto_pwhash_argon2id_MEMLIMIT_MIN)) {
throw new Error('Invalid opts')
}
switch (alg) {
case crypto_pwhash_argon2id_ALG_ARGON2ID13: {
const buf = argon2(passwd, salt, null, null, 'binary', { memory: memory >> 10, passes, outlen, type: argon2.ARGON2ID })
out.set(buf)
return 0
}
default:
throw new Error('Invalid input')
}
}
function crypto_pwhash_argon2i_str (out, passwd, salt, passes, memory, alg) {
const outlen = 32
const passwdlen = passwd.byteLength
if (passwdlen > crypto_pwhash_argon2i_PASSWD_MAX ||
passes > crypto_pwhash_argon2i_OPSLIMIT_MAX ||
memory > crypto_pwhash_argon2i_MEMLIMIT_MAX) {
throw new Error('Too large')
}
if (passwdlen < crypto_pwhash_argon2i_PASSWD_MIN ||
(passes && passes < crypto_pwhash_argon2i_OPSLIMIT_MIN) ||
(memory && memory < crypto_pwhash_argon2i_MEMLIMIT_MIN)) {
throw new Error('Invalid opts')
}
switch (alg) {
case crypto_pwhash_argon2i_ALG_ARGON2I13:
return argon2(passwd, salt, null, null, { memory: memory >> 10, passes, outlen, type: argon2.ARGON2I })
default:
throw new Error('Invalid input')
}
}
function crypto_pwhash_argon2id_str (out, passwd, salt, passes, memory, alg) {
const outlen = 32
const passwdlen = passwd.byteLength
if (passwdlen > crypto_pwhash_argon2id_PASSWD_MAX ||
passes > crypto_pwhash_argon2id_OPSLIMIT_MAX ||
memory > crypto_pwhash_argon2id_MEMLIMIT_MAX) {
throw new Error('Too large')
}
if (passwdlen < crypto_pwhash_argon2id_PASSWD_MIN ||
(passes && passes < crypto_pwhash_argon2id_OPSLIMIT_MIN) ||
(memory && memory < crypto_pwhash_argon2id_MEMLIMIT_MIN)) {
throw new Error('Invalid opts')
}
switch (alg) {
case crypto_pwhash_argon2id_ALG_ARGON2ID13:
out.write(argon2(passwd, salt, null, null, { memory: memory >> 10, passes, outlen, type: argon2.ARGON2ID }))
return
default:
throw new Error('Invalid input')
}
}
function crypto_pwhash (out, passwd, salt, opslimit, memlimit, alg) {
switch (alg) {
case crypto_pwhash_argon2i_ALG_ARGON2I13:
return crypto_pwhash_argon2i(out, passwd, salt, opslimit, memlimit, alg)
case crypto_pwhash_argon2id_ALG_ARGON2ID13:
return crypto_pwhash_argon2id(out, passwd, salt, opslimit, memlimit, alg)
}
}
function crypto_pwhash_str (out, passwd, opslimit, memlimit) {
const salt = b4a.alloc(crypto_pwhash_SALTBYTES)
randombytes_buf(salt)
return crypto_pwhash_argon2id_str(out, passwd, salt, opslimit, memlimit, crypto_pwhash_ALG_DEFAULT)
}
function crypto_pwhash_str_verify (str, passwd) {
if (b4a.isBuffer(str)) return crypto_pwhash_str_verify(str.toString(), passwd)
if (str.slice(0, crypto_pwhash_argon2id_STRPREFIX.length) === crypto_pwhash_argon2id_STRPREFIX) {
return argon2.verify(str, passwd, null)
}
if (str.slice(0, crypto_pwhash_argon2i_STRPREFIX.length) === crypto_pwhash_argon2i_STRPREFIX) {
return argon2.verify(str, passwd, null)
}
return false
}
function crypto_pwhash_str_needs_rehash (str, opslimit, memlimit, type) {
memlimit >>= 10
if ((opslimit | memlimit) > 0xffffffff || (str.byteLength > crypto_pwhash_STRBYTES)) {
throw new Error('Invalid opts.')
}
try {
return argon2.needsRehash(str, opslimit, memlimit, type)
} catch {
return true
}
}

View File

@ -0,0 +1,398 @@
const assert = require('nanoassert')
const ec = require('./fe25519_25')
const crypto_scalarmult_ed25519_BYTES = 32
const crypto_scalarmult_ed25519_SCALARBYTES = 32
module.exports = {
crypto_scalarmult_ed25519,
crypto_scalarmult_ed25519_noclamp,
crypto_scalarmult_ed25519_base,
crypto_scalarmult: crypto_scalarmult_curve25519,
crypto_scalarmult_base: crypto_scalarmult_curve25519_base,
crypto_scalarmult_ed25519_base_noclamp,
crypto_scalarmult_curve25519,
crypto_scalarmult_curve25519_1,
crypto_scalarmult_curve25519_base,
crypto_scalarmult_ristretto255,
crypto_scalarmult_ristretto255_base,
crypto_scalarmult_BYTES: crypto_scalarmult_ed25519_BYTES,
crypto_scalarmult_SCALARBYTES: crypto_scalarmult_ed25519_SCALARBYTES,
crypto_scalarmult_ed25519_BYTES,
crypto_scalarmult_ed25519_SCALARBYTES,
crypto_scalarmult_curve25519_BYTES: 32,
crypto_scalarmult_curve25519_SCALARBYTES: 32
}
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 ||
ec.ge25519_frombytes(P, p) != 0 || ec.ge25519_is_on_main_subgroup(P) == 0) {
throw new Error('Invalid base point')
}
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)) {
throw new Error('Point multiplication failed')
}
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 && q.byteLength === 32)
assert(n instanceof Uint8Array && n.byteLength === 32)
assert(p instanceof Uint8Array && p.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)
for (pos = 254; pos >= 0; --pos) {
b = t[Math.floor(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 crypto_scalarmult_curve25519_1 (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 pos
var swap
var b
var _q = Buffer.alloc(32)
if (has_small_order(p)) {
return -1;
}
t.set(n)
t[0] &= 248
t[31] &= 127
t[31] |= 64
ec.fe25519_frombytes(x1, p)
swap = ec.scalarmult_curve25519_inner_loop(x1, x2, t)
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 Q = ec.ge3()
const pk = ec.fe25519()
var i
for (i = 0; i < 32; i++) {
t[i] = n[i]
}
t[0] &= 248
t[31] |= 64
t[31] &= 127
ec.ge25519_scalarmult_base(Q, t)
edwards_to_montgomery(pk, Q[1], Q[2]);
ec.fe25519_tobytes(q, pk)
return 0
}
function print32 (num) {
if (num < 0) return print32(0x100000000 + num)
console.log(num.toString(16).padStart(16, '0'))
}
function printfe (fe) {
for (let i of fe) print32(i)
}
function sodium_is_zero (n) {
let i
let d = 0
for (let i = 0; i < n.length; i++) {
d |= n[i]
}
return 1 & ((d - 1) >> 8)
}

2050
crypto_sign.json Normal file

File diff suppressed because it is too large Load Diff

377
crypto_sign_ed25519.js Normal file
View File

@ -0,0 +1,377 @@
const { sodium_memzero } = require('./utils')
const { randombytes_buf } = require('./randombytes')
const ec = require('./fe25519_25')
const {
crypto_hash_sha512,
crypto_hash_sha512_update,
crypto_hash_sha512_state,
crypto_hash_sha512_final,
crypto_hash_sha512_BYTES
} = require('./crypto_hash.js')
const { crypto_verify_32 } = require('./crypto_verify')
const {
crypto_scalarmult_base,
crypto_scalarmult_curve25519_BYTES
} = require('./crypto_scalarmult_ed25519')
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
const crypto_sign_BYTES = crypto_sign_ed25519_BYTES
const crypto_sign_PUBLICKEYBYTES = crypto_sign_ed25519_PUBLICKEYBYTES
const crypto_sign_SECRETKEYBYTES = crypto_sign_ed25519_SECRETKEYBYTES
const crypto_sign_SEEDBYTES = crypto_sign_ed25519_SEEDBYTES
function crypto_sign_seed_keypair (pk, sk, seed) {
const A = ec.ge25519_p3()
crypto_hash_sha512(sk, seed, 32)
sk[0] &= 248
sk[31] &= 127
sk[31] |= 64
ec.ge25519_scalarmult_base(A, sk)
ec.ge25519_p3_tobytes(pk, A)
sk.set(seed)
sk.set(pk, 32)
}
function crypto_sign_keypair (pk, sk) {
const seed = Buffer.alloc(32)
randombytes_buf(seed)
crypto_sign_seed_keypair(pk, sk, seed)
sodium_memzero(seed)
}
function crypto_sign_ed25519_pk_to_curve25519 (curve25519_pk, ed25519_pk) {
const A = ec.ge25519_p3()
const x = ec.fe25519()
const one_minus_y = ec.fe25519()
if (ec.ge25519_has_small_order(ed25519_pk) != 0 ||
ec.ge25519_frombytes_negate_vartime(A, ed25519_pk) != 0 ||
ec.ge25519_is_on_main_subgroup(A) == 0) {
throw new Error('Invalid public key')
}
ec.fe25519_1(one_minus_y)
ec.fe25519_sub(one_minus_y, one_minus_y, A[1])
ec.fe25519_1(x)
ec.fe25519_add(x, x, A[1])
ec.fe25519_invert(one_minus_y, one_minus_y)
ec.fe25519_mul(x, x, one_minus_y)
ec.fe25519_tobytes(curve25519_pk, x)
}
function crypto_sign_ed25519_sk_to_curve25519 (curve25519_sk, ed25519_sk) {
const h = Buffer.alloc(crypto_hash_sha512_BYTES)
crypto_hash_sha512(h, ed25519_sk, 32)
h[0] &= 248
h[31] &= 127
h[31] |= 64
curve25519_sk.set(h.subarray(0, crypto_scalarmult_curve25519_BYTES))
sodium_memzero(h)
}
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, 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)
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)
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, sk) {
return _crypto_sign_ed25519_detached(sig, m, sk, 0)
}
function crypto_sign_detached (sig, m, sk) {
return _crypto_sign_ed25519_detached(sig, m, sk, 0)
}
function crypto_sign_ed25519 (sm, m, sk) {
sm.set(m, crypto_sign_ed25519_BYTES)
/* LCOV_EXCL_START */
if (crypto_sign_detached(sm, sm.subarray(crypto_sign_ed25519_BYTES), sk) !== 0) {
sm.fill(0, m.byteLength + 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, sk)
}
function _crypto_sign_ed25519_verify_detached(sig, m, 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()
if ((sig[63] & 240) &&
ec.sc25519_is_canonical(sig + 32) == 0) {
return false
}
if (ec.ge25519_has_small_order(sig.subarray(0, 32)) != 0) {
return false
}
if (ec.ge25519_is_canonical(pk) == 0 ||
ec.ge25519_has_small_order(pk) != 0) {
return false
}
if (ec.ge25519_frombytes_negate_vartime(A, pk) !== 0) {
}
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)
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)
}
function crypto_sign_ed25519_verify_detached (sig, m, pk) {
return _crypto_sign_ed25519_verify_detached(sig, m, pk, 0);
}
function crypto_sign_ed25519_open (m, sm, pk) {
if (sm.byteLength < 64 || sm.byteLength - 64 > crypto_sign_ed25519_MESSAGEBYTES_MAX) {
return false
}
if (!crypto_sign_ed25519_verify_detached(sm, sm.subarray(64), pk)) {
if (m.byteLength) m.fill(0)
return false
}
if (m.byteLength) {
m.set(sm.subarray(64))
}
return true
}
function crypto_sign_ed25519_sk_to_pk (pk, sk) {
pk.set(sk.subarray(crypto_sign_ed25519_SEEDBYTES))
}
function crypto_sign_open (m, sm, pk) {
return crypto_sign_ed25519_open(m, sm, pk)
}
function crypto_sign_verify_detached (m, sm, pk) {
return crypto_sign_ed25519_verify_detached(m, sm, pk)
}
function _crypto_sign_ristretto25519_detached (sig, m, 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)
crypto_hash_sha512_final(state, nonce)
sig.set(sk.subarray(32, 64), 32)
ec.sc25519_reduce(nonce)
ec.ge25519_scalarmult_base(R, nonce)
ec.ristretto255_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)
crypto_hash_sha512_final(state, hram)
ec.sc25519_reduce(hram)
az[31] &= 127
// az[0] &= 248
// az[0] |= 1
// console.log(az[31] & 128)
// console.log(nonce[31] & 128)
// console.log(hram[31] & 128)
ec.sc25519_muladd(sig.subarray(32), hram, az, nonce)
sodium_memzero(az)
sodium_memzero(nonce)
return 0
var rcheck = Buffer.alloc(32)
var A = ec.ge3()
var _A = ec.ge3()
var h = Buffer.alloc(64)
var hs = crypto_hash_sha512_state()
var pk = sk.subarray(32).slice()
// pk[31] &= 127
ec.ristretto255_frombytes(A, pk, true)
ec.ge25519_scalarmult_base(_A, az)
ec.ge25519_p3_add(_A, _A, A)
ec.ge25519_p3_tobytes(rcheck, _A)
// console.log(rcheck.toString('hex'))
_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)
crypto_hash_sha512_final(hs, h)
ec.sc25519_reduce(h)
ec.ge25519_double_scalarmult_vartime(R, h, A, sig.subarray(32))
ec.ristretto255_p3_tobytes(rcheck, R)
}
function _crypto_sign_ristretto25519_verify_detached(sig, m, 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.ge3()
// #ifdef ED25519_COMPAT
// if (sig[63] & 224) {
// return -1
// }
// #else
if ((sig[63] & 240) &&
ec.sc25519_is_canonical(sig + 32) == 0) {
return false
}
if (ec.ge25519_has_small_order(sig) != 0) {
return false
}
if (ec.ge25519_is_canonical(pk) == 0 ||
ec.ge25519_has_small_order(pk) != 0) {
return false
}
// #endif
if (ec.ristretto255_frombytes(A, pk, true) !== 0) {
return false
}
_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)
crypto_hash_sha512_final(hs, h)
ec.sc25519_reduce(h)
ec.ge25519_double_scalarmult_vartime(R, h, A, sig.subarray(32))
ec.ristretto255_p3_tobytes(rcheck, R)
return crypto_verify_32(rcheck, 0, sig, 0)// | sodium_memcmp(sig.subarray(0, 32), rcheck.subarray(0, 32))
}
function crypto_sign_ristretto25519_detached (sig, m, sk) {
return _crypto_sign_ristretto25519_detached(sig, m, sk)
}
function crypto_sign_ristretto25519_verify_detached (sig, m, pk) {
return _crypto_sign_ristretto25519_verify_detached(sig, m, pk, 0)
}
function crypto_sign_ristretto25519 (sm, m, sk) {
var siglen
sm.set(m.subarray(0, mlen), crypto_sign_ristretto25519_BYTES)
/* LCOV_EXCL_START */
if (crypto_sign_ristretto25519_detached(sm, sm.subarray(crypto_sign_ristretto25519_BYTES), mlen, sk) !== 0) {
sm.fill(0, mlen + crypto_sign_ristretto25519_BYTES)
return -1
}
/* LCOV_EXCL_STOP */
return m.byteLength + 64
}
module.exports = {
crypto_sign_keypair,
crypto_sign_seed_keypair,
crypto_sign_ed25519_pk_to_curve25519,
crypto_sign_ed25519_sk_to_curve25519,
crypto_sign_ed25519_sk_to_pk,
crypto_sign,
crypto_sign_open,
crypto_sign_ed25519_detached,
crypto_sign_detached,
crypto_sign_ristretto25519_detached,
crypto_sign_ristretto25519_verify_detached,
crypto_sign_verify_detached,
crypto_sign_BYTES,
crypto_sign_PUBLICKEYBYTES,
crypto_sign_SECRETKEYBYTES,
crypto_sign_SEEDBYTES,
crypto_sign_ed25519_PUBLICKEYBYTES,
crypto_sign_ed25519_SECRETKEYBYTES,
crypto_sign_ed25519_SEEDBYTES
}

View File

@ -3,6 +3,8 @@ const xsalsa20 = require('xsalsa20')
if (new Uint16Array([1])[0] !== 1) throw new Error('Big endian architecture is not supported.')
if (new Uint16Array([1])[0] !== 1) throw new Error('Big endian architecture is not supported.')
exports.crypto_stream_KEYBYTES = 32
exports.crypto_stream_NONCEBYTES = 24
exports.crypto_stream_PRIMITIVE = 'xsalsa20'

216
crypto_tweak.js Normal file
View File

@ -0,0 +1,216 @@
const b4a = require('b4a')
const {
crypto_scalarmult_ed25519,
crypto_scalarmult_ed25519_noclamp,
crypto_scalarmult_ed25519_base,
crypto_scalarmult_ed25519_base_noclamp,
crypto_scalarmult_ed25519_SCALARBYTES
} = require('./crypto_scalarmult_ed25519')
const {
crypto_sign_keypair_seed,
crypto_sign_ed25519_PUBLICKEYBYTES
} = require('./crypto_sign_ed25519')
const {
crypto_hash_sha512_state,
crypto_hash_sha512_update,
crypto_hash_sha512_final,
crypto_hash
} = require('./crypto_hash')
const {
crypto_core_ed25519_is_valid_point,
crypto_core_ed25519_scalar_reduce,
crypto_core_ed25519_scalar_add,
crypto_core_ed25519_scalar_mul,
crypto_core_ed25519_add
} = require('./crypto_core')
const { curve25519_h: COFACTOR } = require('./fe25519_25')
const { sodium_memzero } = require('./utils')
/*
*EXPERIMENTAL API*
This module is an experimental implementation of a key tweaking protocol
over ed25519 keys. The signature algorithm has been reimplemented from
libsodium, but the nonce generation algorithm is *non-standard*.
Use at your own risk
*/
const crypto_tweak_ed25519_BYTES = crypto_sign_ed25519_PUBLICKEYBYTES
const crypto_tweak_ed25519_SCALARBYTES = crypto_scalarmult_ed25519_SCALARBYTES
function _crypto_tweak_nonce (nonce, n, m, mlen) {
// dom2(x, y) with x = 0 (not prehashed) and y = "crypto_tweak_ed25519"
const prefix = b4a.alloc(54)
prefix.write('SigEd25519 no Ed25519 collisions\x00\x14crypto_tweak_ed25519')
const hs = crypto_hash_sha512_state()
crypto_hash_sha512_update(hs, prefix)
crypto_hash_sha512_update(hs, n, 32)
crypto_hash_sha512_update(hs, m, m.byteLength)
crypto_hash_sha512_final(hs, nonce)
}
function _crypto_sign_ed25519_clamp (k) {
k[0] &= 248
k[31] &= 127
k[31] |= 64
}
function _crypto_tweak_ed25519(q, n, ns) {
sodium_memzero(q)
crypto_hash(n, ns)
n[31] &= 127 // clear highest bit
crypto_scalarmult_ed25519_base_noclamp(q, n)
// hash tweak until we get a valid tweaked q
while (crypto_core_ed25519_is_valid_point(q) != 1) {
crypto_hash(n, n, 32)
n[31] &= 127 // clear highest bit
crypto_scalarmult_ed25519_base_noclamp(q, n)
}
}
function crypto_tweak_ed25519_base (n, q, ns) {
sodium_memzero(q)
const n64 = b4a.alloc(64)
_crypto_tweak_ed25519(q, n64, ns)
n.set(n64.subarray(0, 32))
}
// TODO: check pk is correct if we pass it
function crypto_tweak_ed25519_sign_detached (sig, m, n, pk = null) {
const hs = crypto_hash_sha512_state()
const nonce = b4a.alloc(64)
const R = b4a.alloc(32)
const hram = b4a.alloc(64)
const _pk = b4a.alloc(32)
// check if pk was passed
if (pk === null) {
pk = _pk
// derive pk from scalar
crypto_scalarmult_ed25519_base_noclamp(pk, n)
}
_crypto_tweak_nonce(nonce, n, m)
crypto_core_ed25519_scalar_reduce(nonce, nonce)
// R = G ^ nonce : curve point from nonce
crypto_scalarmult_ed25519_base_noclamp(R, nonce)
// generate challenge as h(ram) = hash(R, pk, message)
crypto_hash_sha512_update(hs, R, 32)
crypto_hash_sha512_update(hs, pk, 32)
crypto_hash_sha512_update(hs, m, m.byteLength)
crypto_hash_sha512_final(hs, hram)
crypto_core_ed25519_scalar_reduce(hram, hram)
// sig = nonce + n * h(ram)
crypto_core_ed25519_scalar_mul(sig.subarray(0, 32), hram.subarray(0, 32), n)
crypto_core_ed25519_scalar_add(sig.subarray(32, 64), nonce.subarray(0, 32), sig)
sig.set(R)
return 0
}
// get scalar from secret key
function crypto_tweak_ed25519_sk_to_scalar (n, sk) {
const n64 = b4a.alloc(64)
// get sk scalar from seed, cf. crypto_sign_keypair_seed
crypto_hash(n64, sk, 32)
_crypto_sign_ed25519_clamp(n64)
n.set(n64.subarray(0, 32))
}
// tweak a secret key
function crypto_tweak_ed25519_scalar (scalar_out, scalar, ns) {
const q = b4a.alloc(32)
const n = b4a.alloc(64)
const n32 = n.subarray(0, 32)
_crypto_tweak_ed25519(q, n, ns)
crypto_tweak_ed25519_scalar_add(scalar_out, n32, scalar)
}
// tweak a public key
function crypto_tweak_ed25519_pk (tpk, pk, ns) {
const n = b4a.alloc(64)
const q = b4a.alloc(32)
_crypto_tweak_ed25519(q, n, ns)
return crypto_core_ed25519_add(tpk, q, pk)
}
function crypto_tweak_ed25519_keypair (pk, scalar_out, scalar, ns) {
const n64 = b4a.alloc(64)
crypto_hash(n64, ns)
n64[31] &= 127 // clear highest bit
crypto_tweak_ed25519_scalar_add(scalar_out, scalar, n64)
crypto_scalarmult_ed25519_base_noclamp(pk, scalar_out)
// hash tweak until we get a valid tweaked point
while (crypto_core_ed25519_is_valid_point(pk) != 1) {
crypto_hash(n64, n64, 32)
n64[31] &= 127 // clear highest bit
crypto_tweak_ed25519_scalar_add(scalar_out, scalar, n64)
crypto_scalarmult_ed25519_base_noclamp(pk, scalar_out)
}
}
// add tweak to scalar
function crypto_tweak_ed25519_scalar_add (scalar_out, scalar, n) {
crypto_core_ed25519_scalar_add(scalar_out, scalar, n)
}
// add tweak point to public key
function crypto_tweak_ed25519_pk_add (tpk, pk, q) {
crypto_core_ed25519_add(tpk, pk, q)
}
// add tweak to scalar
function crypto_tweak_ed25519_scalar_mul (scalar_out, scalar, n) {
crypto_core_ed25519_scalar_mul(scalar_out, scalar, n)
}
// add tweak point to public key
function crypto_tweak_ed25519_publickey_mul (tpk, pk, n) {
crypto_scalarmult_ed25519_noclamp(tpk, n, pk)
}
module.exports = {
crypto_tweak_ed25519_base,
crypto_tweak_ed25519_sign_detached,
crypto_tweak_ed25519_sk_to_scalar,
crypto_tweak_ed25519_scalar,
crypto_tweak_ed25519_pk,
crypto_tweak_ed25519_keypair,
crypto_tweak_ed25519_scalar_add,
crypto_tweak_ed25519_pk_add,
crypto_tweak_ed25519_BYTES,
crypto_tweak_ed25519_SCALARBYTES
}

236
ed-wasm.js Normal file
View File

@ -0,0 +1,236 @@
const sodium = require('./')
const native = require('sodium-native')
const { crypto_scalarmult_ed25519, crypto_scalarmult_ed25519_base, crypto_scalarmult_curve25519, crypto_scalarmult_curve25519_1, crypto_scalarmult_curve25519_base } = require('./crypto_scalarmult_ed25519')
const { crypto_sign, crypto_sign_open, crypto_sign_verify_detached } = require('./crypto_sign_ed25519')
const sign = require('./crypto_sign')
const ed = require('./ed25519')
const ec = require('./fe25519_25')
const { crypto_tweak_ed25519 } = require('./crypto_tweak')
console.log(crypto_scalarmult_ed25519)
let sm = Buffer.alloc(1024 + sodium.crypto_sign_BYTES)
let sm1 = Buffer.alloc(1024 + sodium.crypto_sign_BYTES)
let skpk = Buffer.alloc(sodium.crypto_sign_SECRETKEYBYTES)
let pk = Buffer.alloc(sodium.crypto_sign_PUBLICKEYBYTES)
let sk = Buffer.alloc(sodium.crypto_sign_SECRETKEYBYTES)
let smlen
let smlen1
let i
let test
// sig.fill(0)
var an = Buffer.from([
0x77, 0x07, 0x6d, 0x0a, 0x73, 0x18, 0xa5, 0x7d, 0x3c, 0x16, 0xc1,
0x72, 0x51, 0xb2, 0x66, 0x45, 0xdf, 0x4c, 0x2f, 0x87, 0xeb, 0xc0,
0x99, 0x2a, 0xb1, 0x77, 0xfb, 0xa5, 0x1d, 0xb9, 0x2c, 0x2a
])
var bn = Buffer.from([
0x5d, 0xab, 0x08, 0x7e, 0x62, 0x4a, 0x8a, 0x4b, 0x79, 0xe1, 0x7f,
0x8b, 0x83, 0x80, 0x0e, 0xe6, 0x6f, 0x3b, 0xb1, 0x29, 0x26, 0x18,
0xb6, 0xfd, 0x1c, 0x2f, 0x8b, 0x27, 0xff, 0x88, 0xe0, 0xeb
])
var bobpk = Buffer.from('de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f', 'hex')
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
])
const res = Buffer.alloc(32)
var fixtures = require('./crypto_sign.json').map(a => parseTest(a))
var pass = true
// test = parseTest(fixture)
// console.time('hello')
// for (let test of fixtures) {
// skpk.set(test.sk)
// skpk.set(test.pk, sodium.crypto_sign_SEEDBYTES)
// smlen = sodium.crypto_sign(sm, test.m, skpk)
// sodium.crypto_sign_open(test.m, sm.subarray(0, smlen), test.pk)
// }
// console.timeEnd('hello')
// console.time('ed')
// for (let test of fixtures) {
// skpk.set(test.sk)
// skpk.set(test.pk, sodium.crypto_sign_SEEDBYTES)
// smlen = crypto_sign(sm, test.m, skpk)
// crypto_sign_open(test.m, sm.subarray(0, smlen), test.pk)
// }
// console.timeEnd('ed')
// for (let i = 0; i < fixtures.length; i++) {
// let pass = true
// sm.fill(0)
// sm1.fill(0)
// test = fixtures[i]
// skpk.set(test.sk)
// skpk.set(test.pk, sodium.crypto_sign_SEEDBYTES)
// smlen = sodium.crypto_sign(sm, test.m, skpk)
// smlen1 = crypto_sign(sm1, test.m, skpk)
// pass &= sodium.crypto_sign_open(test.m, sm1.subarray(0, smlen1), test.pk)
// pass &= crypto_sign_open(test.m, sm.subarray(0, smlen), test.pk)
// if (Buffer.compare(sm, sm1) !== 0 || !pass) console.log('test fails at fixture #' + i)
// }
// //////////////////////////////
// sodium.crypto_scalarmult(res, an, bn)
// console.log(res.toString('hex'))
function main () {
const b = 3;
const pos = 21;
const p = ec.ge2();
const res = Buffer.alloc(32)
// static char hex[32];
// printf("hello\n");
ec.ge25519_cmov8_base(p, pos, b);
// printf("hello\n");
ec.ge25519_tobytes(res, p);
console.log(res.toString('hex'))
}
console.log('====================')
main()
console.log('====================')
/////////////////////////////////////////
res.fill(0)
crypto_scalarmult_curve25519(res, an, bobpk)
console.log(res.toString('hex'))
// console.time('whole')
crypto_scalarmult_curve25519_1(res, an, bobpk)
// console.timeEnd('whole')
console.log('scmult wasm', res.toString('hex'))
native.crypto_scalarmult(res, an, bobpk)
console.log('scmult nati', res.toString('hex'))
sodium.crypto_scalarmult(res, an, bobpk)
console.log('scmult js ', res.toString('hex'))
sodium.crypto_scalarmult_base(res, an)
console.log('scmultb js', res.toString('hex'))
// const basepoint = Buffer.alloc(32)
// res.fill(0)
// native.crypto_scalarmult_base(basepoint, res)
// console.log('---------------', basepoint.toString('hex'))
native.crypto_scalarmult_base(res, an)
console.log('scmultb nat', res.toString('hex'))
// res.fill(0)
// const p = ec.ge3()
// ec.ge25519_scalarmult_base(p, an)
// ec.ge25519_tobytes(res, p)
crypto_scalarmult_curve25519_base(res, an)
console.log('scmultb was', res.toString('hex'))
native.crypto_scalarmult(res, fixtures[1].sk, fixtures[1].pk)
console.log(res.toString('hex'))
crypto_scalarmult_curve25519(res, fixtures[1].sk, fixtures[1].pk)
console.log('wasm naive', res.toString('hex'))
crypto_scalarmult_curve25519_1(res, fixtures[1].sk, fixtures[1].pk)
console.log('wasm inner loop', res.toString('hex'))
native.crypto_scalarmult(res, fixtures[1].sk, fixtures[1].pk)
console.log('native', res.toString('hex'))
crypto_scalarmult_ed25519(res, fixtures[1].sk, fixtures[1].pk)
console.log(res.toString('hex'))
const tweak = Buffer.alloc(32)
const ns = Buffer.alloc(32)
native.crypto_generichash(ns, Buffer.from('namespace'))
crypto_tweak_ed25519(tweak, fixtures[1].pk, ns)
console.log('js', tweak.toString('hex'))
native.experimental_crypto_tweak_ed25519(tweak, fixtures[1].pk, ns)
console.log('native', tweak.toString('hex'))
// const a = Buffer.alloc(32)
// a[i] = 9
// crypto_scalarmult_curve25519_base(res, an)
// console.log(res.toString('hex'))
// console.time('hello')
// for (let test of fixtures) {
// sodium.crypto_scalarmult(res, test.sk, test.pk)
// }
// console.timeEnd('hello')
// console.log(res.toString('hex'))
// const res1 = Buffer.from(res)
// console.time('ed')
// for (let test of fixtures) {
// crypto_scalarmult_curve25519(res, test.sk, test.pk)
// }
// console.timeEnd('ed')
// console.time('wasm')
// for (let test of fixtures) {
// crypto_scalarmult_curve25519_1(res1, test.sk, test.pk)
// }
// console.timeEnd('wasm')
// console.time('native')
// for (let test of fixtures) {
// native.crypto_scalarmult(res1, test.sk, test.pk)
// }
// console.timeEnd('native')
// console.log(res.toString('hex'))
// console.log(res1.toString('hex'))
/////////////////////////////////////////
// console.log(sm.toString('hex'))
native.crypto_sign_keypair(pk, sk)
let sig = Buffer.alloc(sodium.crypto_sign_BYTES + 32)
const m = Buffer.alloc(32)
const m2 = Buffer.alloc(32)
for (let i = 0; i < 32; i++) m[i] = i
crypto_sign(sig, m, sk)
// pass &= smlen === sodium.crypto_sign_BYTES + test.m.byteLength
// pass &= Buffer.compare(test.sig, sm.subarray(0, 64)) === 0
// pass &= sodium.crypto_sign_open(test.m, sm.subarray(0, smlen), test.pk)
console.log('sig', sig.toString('hex'))
console.log(sodium.crypto_sign_open(m2, sig, pk))
console.log(crypto_sign_open(m2, sig, pk))
console.log(m2.toString('hex'))
// // pass &= sig.byteLength !== 0 && sig.byteLength <= sodium.crypto_sign_BYTES
// // pass &= Buffer.compare(test.sig, sig) === 0
// pass &= sodium.crypto_sign_verify_detached(sig, test.m.subarray(0, i), test.pk)
function parseTest (t) {
return {
sk: Buffer.from(t[0]),
pk: Buffer.from(t[1]),
sig: Buffer.from(t[2]),
m: Buffer.from(t[3])
}
}
// 92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00720

483
ed25519.js Normal file
View File

@ -0,0 +1,483 @@
if (new Uint16Array([1])[0] !== 1) throw new Error('Big endian architecture is not supported.')
var gf = function(init) {
var i, r = new Float64Array(16);
if (init) for (i = 0; i < init.length; i++) r[i] = init[i];
return r;
}
var _0 = new Uint8Array(16);
var _9 = new Uint8Array(32); _9[0] = 9;
var gf0 = gf(),
gf1 = gf([1]),
_121665 = gf([0xdb41, 1]),
D = gf([0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203]),
D2 = gf([0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406]),
X = gf([0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169]),
Y = gf([0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666]),
I = gf([0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83]);
function A(o, a, b) {
for (var i = 0; i < 16; i++) o[i] = a[i] + b[i];
}
function Z(o, a, b) {
for (var i = 0; i < 16; i++) o[i] = a[i] - b[i];
}
function M(o, a, b) {
var v, c,
t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0,
t8 = 0, t9 = 0, t10 = 0, t11 = 0, t12 = 0, t13 = 0, t14 = 0, t15 = 0,
t16 = 0, t17 = 0, t18 = 0, t19 = 0, t20 = 0, t21 = 0, t22 = 0, t23 = 0,
t24 = 0, t25 = 0, t26 = 0, t27 = 0, t28 = 0, t29 = 0, t30 = 0,
b0 = b[0],
b1 = b[1],
b2 = b[2],
b3 = b[3],
b4 = b[4],
b5 = b[5],
b6 = b[6],
b7 = b[7],
b8 = b[8],
b9 = b[9],
b10 = b[10],
b11 = b[11],
b12 = b[12],
b13 = b[13],
b14 = b[14],
b15 = b[15];
v = a[0];
t0 += v * b0;
t1 += v * b1;
t2 += v * b2;
t3 += v * b3;
t4 += v * b4;
t5 += v * b5;
t6 += v * b6;
t7 += v * b7;
t8 += v * b8;
t9 += v * b9;
t10 += v * b10;
t11 += v * b11;
t12 += v * b12;
t13 += v * b13;
t14 += v * b14;
t15 += v * b15;
v = a[1];
t1 += v * b0;
t2 += v * b1;
t3 += v * b2;
t4 += v * b3;
t5 += v * b4;
t6 += v * b5;
t7 += v * b6;
t8 += v * b7;
t9 += v * b8;
t10 += v * b9;
t11 += v * b10;
t12 += v * b11;
t13 += v * b12;
t14 += v * b13;
t15 += v * b14;
t16 += v * b15;
v = a[2];
t2 += v * b0;
t3 += v * b1;
t4 += v * b2;
t5 += v * b3;
t6 += v * b4;
t7 += v * b5;
t8 += v * b6;
t9 += v * b7;
t10 += v * b8;
t11 += v * b9;
t12 += v * b10;
t13 += v * b11;
t14 += v * b12;
t15 += v * b13;
t16 += v * b14;
t17 += v * b15;
v = a[3];
t3 += v * b0;
t4 += v * b1;
t5 += v * b2;
t6 += v * b3;
t7 += v * b4;
t8 += v * b5;
t9 += v * b6;
t10 += v * b7;
t11 += v * b8;
t12 += v * b9;
t13 += v * b10;
t14 += v * b11;
t15 += v * b12;
t16 += v * b13;
t17 += v * b14;
t18 += v * b15;
v = a[4];
t4 += v * b0;
t5 += v * b1;
t6 += v * b2;
t7 += v * b3;
t8 += v * b4;
t9 += v * b5;
t10 += v * b6;
t11 += v * b7;
t12 += v * b8;
t13 += v * b9;
t14 += v * b10;
t15 += v * b11;
t16 += v * b12;
t17 += v * b13;
t18 += v * b14;
t19 += v * b15;
v = a[5];
t5 += v * b0;
t6 += v * b1;
t7 += v * b2;
t8 += v * b3;
t9 += v * b4;
t10 += v * b5;
t11 += v * b6;
t12 += v * b7;
t13 += v * b8;
t14 += v * b9;
t15 += v * b10;
t16 += v * b11;
t17 += v * b12;
t18 += v * b13;
t19 += v * b14;
t20 += v * b15;
v = a[6];
t6 += v * b0;
t7 += v * b1;
t8 += v * b2;
t9 += v * b3;
t10 += v * b4;
t11 += v * b5;
t12 += v * b6;
t13 += v * b7;
t14 += v * b8;
t15 += v * b9;
t16 += v * b10;
t17 += v * b11;
t18 += v * b12;
t19 += v * b13;
t20 += v * b14;
t21 += v * b15;
v = a[7];
t7 += v * b0;
t8 += v * b1;
t9 += v * b2;
t10 += v * b3;
t11 += v * b4;
t12 += v * b5;
t13 += v * b6;
t14 += v * b7;
t15 += v * b8;
t16 += v * b9;
t17 += v * b10;
t18 += v * b11;
t19 += v * b12;
t20 += v * b13;
t21 += v * b14;
t22 += v * b15;
v = a[8];
t8 += v * b0;
t9 += v * b1;
t10 += v * b2;
t11 += v * b3;
t12 += v * b4;
t13 += v * b5;
t14 += v * b6;
t15 += v * b7;
t16 += v * b8;
t17 += v * b9;
t18 += v * b10;
t19 += v * b11;
t20 += v * b12;
t21 += v * b13;
t22 += v * b14;
t23 += v * b15;
v = a[9];
t9 += v * b0;
t10 += v * b1;
t11 += v * b2;
t12 += v * b3;
t13 += v * b4;
t14 += v * b5;
t15 += v * b6;
t16 += v * b7;
t17 += v * b8;
t18 += v * b9;
t19 += v * b10;
t20 += v * b11;
t21 += v * b12;
t22 += v * b13;
t23 += v * b14;
t24 += v * b15;
v = a[10];
t10 += v * b0;
t11 += v * b1;
t12 += v * b2;
t13 += v * b3;
t14 += v * b4;
t15 += v * b5;
t16 += v * b6;
t17 += v * b7;
t18 += v * b8;
t19 += v * b9;
t20 += v * b10;
t21 += v * b11;
t22 += v * b12;
t23 += v * b13;
t24 += v * b14;
t25 += v * b15;
v = a[11];
t11 += v * b0;
t12 += v * b1;
t13 += v * b2;
t14 += v * b3;
t15 += v * b4;
t16 += v * b5;
t17 += v * b6;
t18 += v * b7;
t19 += v * b8;
t20 += v * b9;
t21 += v * b10;
t22 += v * b11;
t23 += v * b12;
t24 += v * b13;
t25 += v * b14;
t26 += v * b15;
v = a[12];
t12 += v * b0;
t13 += v * b1;
t14 += v * b2;
t15 += v * b3;
t16 += v * b4;
t17 += v * b5;
t18 += v * b6;
t19 += v * b7;
t20 += v * b8;
t21 += v * b9;
t22 += v * b10;
t23 += v * b11;
t24 += v * b12;
t25 += v * b13;
t26 += v * b14;
t27 += v * b15;
v = a[13];
t13 += v * b0;
t14 += v * b1;
t15 += v * b2;
t16 += v * b3;
t17 += v * b4;
t18 += v * b5;
t19 += v * b6;
t20 += v * b7;
t21 += v * b8;
t22 += v * b9;
t23 += v * b10;
t24 += v * b11;
t25 += v * b12;
t26 += v * b13;
t27 += v * b14;
t28 += v * b15;
v = a[14];
t14 += v * b0;
t15 += v * b1;
t16 += v * b2;
t17 += v * b3;
t18 += v * b4;
t19 += v * b5;
t20 += v * b6;
t21 += v * b7;
t22 += v * b8;
t23 += v * b9;
t24 += v * b10;
t25 += v * b11;
t26 += v * b12;
t27 += v * b13;
t28 += v * b14;
t29 += v * b15;
v = a[15];
t15 += v * b0;
t16 += v * b1;
t17 += v * b2;
t18 += v * b3;
t19 += v * b4;
t20 += v * b5;
t21 += v * b6;
t22 += v * b7;
t23 += v * b8;
t24 += v * b9;
t25 += v * b10;
t26 += v * b11;
t27 += v * b12;
t28 += v * b13;
t29 += v * b14;
t30 += v * b15;
t0 += 38 * t16;
t1 += 38 * t17;
t2 += 38 * t18;
t3 += 38 * t19;
t4 += 38 * t20;
t5 += 38 * t21;
t6 += 38 * t22;
t7 += 38 * t23;
t8 += 38 * t24;
t9 += 38 * t25;
t10 += 38 * t26;
t11 += 38 * t27;
t12 += 38 * t28;
t13 += 38 * t29;
t14 += 38 * t30;
// t15 left as is
// first car
c = 1;
v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536;
v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536;
v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536;
v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536;
v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536;
v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536;
v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536;
v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536;
v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536;
v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536;
v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536;
v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536;
v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536;
v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536;
v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536;
v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536;
t0 += c-1 + 37 * (c-1);
// second car
c = 1;
v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536;
v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536;
v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536;
v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536;
v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536;
v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536;
v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536;
v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536;
v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536;
v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536;
v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536;
v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536;
v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536;
v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536;
v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536;
v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536;
t0 += c-1 + 37 * (c-1);
o[ 0] = t0;
o[ 1] = t1;
o[ 2] = t2;
o[ 3] = t3;
o[ 4] = t4;
o[ 5] = t5;
o[ 6] = t6;
o[ 7] = t7;
o[ 8] = t8;
o[ 9] = t9;
o[10] = t10;
o[11] = t11;
o[12] = t12;
o[13] = t13;
o[14] = t14;
o[15] = t15;
}
function S(o, a) {
M(o, a, a);
}
function sel25519(p, q, b) {
var t, c = ~(b-1);
for (var i = 0; i < 16; i++) {
t = c & (p[i] ^ q[i]);
p[i] ^= t;
q[i] ^= t;
}
}
function pack25519(o, n) {
var i, j, b;
var m = gf(), t = gf();
for (i = 0; i < 16; i++) t[i] = n[i];
car25519(t);
car25519(t);
car25519(t);
for (j = 0; j < 2; j++) {
m[0] = t[0] - 0xffed;
for (i = 1; i < 15; i++) {
m[i] = t[i] - 0xffff - ((m[i-1]>>16) & 1);
m[i-1] &= 0xffff;
}
m[15] = t[15] - 0x7fff - ((m[14]>>16) & 1);
b = (m[15]>>16) & 1;
m[14] &= 0xffff;
sel25519(t, m, 1-b);
}
for (i = 0; i < 16; i++) {
o[2*i] = t[i] & 0xff;
o[2*i+1] = t[i]>>8;
}
}
function unpack25519(o, n) {
var i;
for (i = 0; i < 16; i++) o[i] = n[2*i] + (n[2*i+1] << 8);
o[15] &= 0x7fff;
}
function inv25519(o, i) {
var c = gf();
var a;
for (a = 0; a < 16; a++) c[a] = i[a];
for (a = 253; a >= 0; a--) {
S(c, c);
if(a !== 2 && a !== 4) M(c, c, i);
}
for (a = 0; a < 16; a++) o[a] = c[a];
}
function car25519(o) {
var i, v, c = 1;
for (i = 0; i < 16; i++) {
v = o[i] + c + 65535;
c = Math.floor(v / 65536);
o[i] = v - c * 65536;
}
o[0] += c-1 + 37 * (c-1);
}
module.exports = {
gf,
A,
Z,
M,
S,
sel25519,
pack25519,
unpack25519,
inv25519,
gf0,
gf1,
_9,
_121665,
D,
D2,
X,
Y,
I
}

333
fe-test.js Normal file
View File

@ -0,0 +1,333 @@
const ec = require('./fe25519_25.js')
const sodium = require('./')
const invert = require('./fe25519_25/fe25519_invert')({
imports: {
debug: {
log (...args) {
console.log(...args.map(int => (int >>> 0).toString(16).padStart(8, '0')))
},
log_tee (arg) {
console.log((arg >>> 0).toString(16).padStart(8, '0'))
return arg
}
}
}
})
const pow = require('./fe25519_25/fe25519_pow22523')({
imports: {
debug: {
log (...args) {
console.log(...args.map(int => (int >>> 0).toString(16).padStart(8, '0')))
},
log_tee (arg) {
console.log((arg >>> 0).toString(16).padStart(8, '0'))
return arg
}
}
}
})
// 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()
function wasm_inv (h, f) {
var buf = Buffer.from(f.buffer)
invert.memory.set(buf)
invert.exports.fe25519_invert(40, 0)
buf = Buffer.from(invert.memory.slice(40, 80))
for (let i = 0; i < 10; i++) {
h[i] = buf.readUInt32LE(4 * i)
}
}
function wasm_pow (h, f) {
var buf = Buffer.from(f.buffer)
pow.memory.set(buf)
pow.exports.fe25519_pow22523(40, 0)
buf = Buffer.from(pow.memory.slice(40, 80))
for (let i = 0; i < 10; i++) {
h[i] = buf.readUInt32LE(4 * i)
}
}
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
])
const pk_test = Buffer.from('d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a', 'hex')
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)
ec.fe25519_mul(c, b, a)
// // 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.time('standard')
for (let i = 0; i < 10000; i++) ec.fe25519_invert(b, a)
console.timeEnd('standard')
ec.fe25519_tobytes(res, b)
console.log('tess :', res.toString('hex'))
console.time('pure invert')
for (let i = 0; i < 10000; i++) ec.fe25519_invert_1(b, a)
console.timeEnd('pure invert')
ec.fe25519_tobytes(res, b)
console.log('tess :', 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'))
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))
/////////////////////////////////////////////////////
// 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))

2962
fe25519_25.js Normal file

File diff suppressed because it is too large Load Diff

1346
fe25519_25/base.json Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

61
fe25519_25/fe25519_mul.js Normal file
View File

@ -0,0 +1,61 @@
module.exports = loadWebAssembly
loadWebAssembly.supported = typeof WebAssembly !== 'undefined'
function loadWebAssembly (opts) {
if (!loadWebAssembly.supported) return null
var imp = opts && opts.imports
var wasm = toUint8Array('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')
var ready = null
var mod = {
buffer: wasm,
memory: null,
exports: null,
realloc: realloc,
onload: onload
}
onload(function () {})
return mod
function realloc (size) {
mod.exports.memory.grow(Math.max(0, Math.ceil(Math.abs(size - mod.memory.length) / 65536)))
mod.memory = new Uint8Array(mod.exports.memory.buffer)
}
function onload (cb) {
if (mod.exports) return cb()
if (ready) {
ready.then(cb.bind(null, null)).catch(cb)
return
}
try {
if (opts && opts.async) throw new Error('async')
setup({instance: new WebAssembly.Instance(new WebAssembly.Module(wasm), imp)})
} catch (err) {
ready = WebAssembly.instantiate(wasm, imp).then(setup)
}
onload(cb)
}
function setup (w) {
mod.exports = w.instance.exports
mod.memory = mod.exports.memory && mod.exports.memory.buffer && new Uint8Array(mod.exports.memory.buffer)
}
}
function toUint8Array (s) {
if (typeof atob === 'function') return new Uint8Array(atob(s).split('').map(charCodeAt))
return (require('buf' + 'fer').Buffer).from(s, 'base64')
}
function charCodeAt (c) {
return c.charCodeAt(0)
}

440
fe25519_25/fe25519_mul.wat Normal file
View File

@ -0,0 +1,440 @@
(module
(import "js" "table" (table 4 anyfunc))
(import "js" "mem" (memory 1))
(elem (i32.const 1) $fe_mul)
;; (func $i32.log (import "debug" "log") (param i32))
;; (func $i32.log_tee (import "debug" "log_tee") (param i32) (result i32))
;; ;; No i64 interop with JS yet - but maybe coming with WebAssembly BigInt
;; ;; So we can instead fake this by splitting the i64 into two i32 limbs,
;; ;; however these are WASM functions using i32x2.log:
;; (func $i32x2.log (import "debug" "log") (param i32) (param i32))
;; (func $f32.log (import "debug" "log") (param f32))
;; (func $f32.log_tee (import "debug" "log_tee") (param f32) (result f32))
;; (func $f64.log (import "debug" "log") (param f64))
;; (func $f64.log_tee (import "debug" "log_tee") (param f64) (result f64))
;; ;; i64 logging by splitting into two i32 limbs
;; (func $i64.log
;; (param $0 i64)
;; (call $i32x2.log
;; ;; Upper limb
;; (i32.wrap/i64
;; (i64.shr_s (get_local $0)
;; (i64.const 32)))
;; ;; Lower limb
;; (i32.wrap/i64 (get_local $0))))
;; (func $i64.log_tee
;; (param $0 i64)
;; (result i64)
;; (call $i64.log (get_local $0))
;; (return (get_local $0)))
(func $fe_mul
(param $f0 i64)
(param $f1 i64)
(param $f2 i64)
(param $f3 i64)
(param $f4 i64)
(param $f5 i64)
(param $f6 i64)
(param $f7 i64)
(param $f8 i64)
(param $f9 i64)
(param $g0 i64)
(param $g1 i64)
(param $g2 i64)
(param $g3 i64)
(param $g4 i64)
(param $g5 i64)
(param $g6 i64)
(param $g7 i64)
(param $g8 i64)
(param $g9 i64)
(param $h i32)
(local $h0 i64)
(local $h1 i64)
(local $h2 i64)
(local $h3 i64)
(local $h4 i64)
(local $h5 i64)
(local $h6 i64)
(local $h7 i64)
(local $h8 i64)
(local $h9 i64)
(local $carry0 i64)
(local $carry1 i64)
(local $carry2 i64)
(local $carry3 i64)
(local $carry4 i64)
(local $carry5 i64)
(local $carry6 i64)
(local $carry7 i64)
(local $carry8 i64)
(local $carry9 i64)
(local $g1_19 i64)
(local $g2_19 i64)
(local $g3_19 i64)
(local $g4_19 i64)
(local $g5_19 i64)
(local $g6_19 i64)
(local $g7_19 i64)
(local $g8_19 i64)
(local $g9_19 i64)
(local $f1_2 i64)
(local $f3_2 i64)
(local $f5_2 i64)
(local $f7_2 i64)
(local $f9_2 i64)
(local $f0g0 i64)
(local $f0g1 i64)
(local $f0g2 i64)
(local $f0g3 i64)
(local $f0g4 i64)
(local $f0g5 i64)
(local $f0g6 i64)
(local $f0g7 i64)
(local $f0g8 i64)
(local $f0g9 i64)
(local $f1g0 i64)
(local $f1g1_2 i64)
(local $f1g2 i64)
(local $f1g3_2 i64)
(local $f1g4 i64)
(local $f1g5_2 i64)
(local $f1g6 i64)
(local $f1g7_2 i64)
(local $f1g8 i64)
(local $f1g9_38 i64)
(local $f2g0 i64)
(local $f2g1 i64)
(local $f2g2 i64)
(local $f2g3 i64)
(local $f2g4 i64)
(local $f2g5 i64)
(local $f2g6 i64)
(local $f2g7 i64)
(local $f2g8_19 i64)
(local $f2g9_19 i64)
(local $f3g0 i64)
(local $f3g1_2 i64)
(local $f3g2 i64)
(local $f3g3_2 i64)
(local $f3g4 i64)
(local $f3g5_2 i64)
(local $f3g6 i64)
(local $f3g7_38 i64)
(local $f3g8_19 i64)
(local $f3g9_38 i64)
(local $f4g0 i64)
(local $f4g1 i64)
(local $f4g2 i64)
(local $f4g3 i64)
(local $f4g4 i64)
(local $f4g5 i64)
(local $f4g6_19 i64)
(local $f4g7_19 i64)
(local $f4g8_19 i64)
(local $f4g9_19 i64)
(local $f5g0 i64)
(local $f5g1_2 i64)
(local $f5g2 i64)
(local $f5g3_2 i64)
(local $f5g4 i64)
(local $f5g5_38 i64)
(local $f5g6_19 i64)
(local $f5g7_38 i64)
(local $f5g8_19 i64)
(local $f5g9_38 i64)
(local $f6g0 i64)
(local $f6g1 i64)
(local $f6g2 i64)
(local $f6g3 i64)
(local $f6g4_19 i64)
(local $f6g5_19 i64)
(local $f6g6_19 i64)
(local $f6g7_19 i64)
(local $f6g8_19 i64)
(local $f6g9_19 i64)
(local $f7g0 i64)
(local $f7g1_2 i64)
(local $f7g2 i64)
(local $f7g3_38 i64)
(local $f7g4_19 i64)
(local $f7g5_38 i64)
(local $f7g6_19 i64)
(local $f7g7_38 i64)
(local $f7g8_19 i64)
(local $f7g9_38 i64)
(local $f8g0 i64)
(local $f8g1 i64)
(local $f8g2_19 i64)
(local $f8g3_19 i64)
(local $f8g4_19 i64)
(local $f8g5_19 i64)
(local $f8g6_19 i64)
(local $f8g7_19 i64)
(local $f8g8_19 i64)
(local $f8g9_19 i64)
(local $f9g0 i64)
(local $f9g1_38 i64)
(local $f9g2_19 i64)
(local $f9g3_38 i64)
(local $f9g4_19 i64)
(local $f9g5_38 i64)
(local $f9g6_19 i64)
(local $f9g7_38 i64)
(local $f9g8_19 i64)
(local $f9g9_38 i64)
(set_local $f0 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f0))))
(set_local $f1 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f1))))
(set_local $f2 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f2))))
(set_local $f3 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f3))))
(set_local $f4 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f4))))
(set_local $f5 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f5))))
(set_local $f6 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f6))))
(set_local $f7 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f7))))
(set_local $f8 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f8))))
(set_local $f9 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f9))))
(set_local $g0 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g0))))
(set_local $g1 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g1))))
(set_local $g2 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g2))))
(set_local $g3 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g3))))
(set_local $g4 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g4))))
(set_local $g5 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g5))))
(set_local $g6 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g6))))
(set_local $g7 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g7))))
(set_local $g8 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g8))))
(set_local $g9 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g9))))
(set_local $g1_19 (i64.sub (i64.mul (i64.const 19) (get_local $g1)) (i64.mul (i64.shl (i64.and (get_local $g1) (i64.const 0x80000000)) (i64.const 1)) (i64.const 19))))
(set_local $g2_19 (i64.sub (i64.mul (i64.const 19) (get_local $g2)) (i64.mul (i64.shl (i64.and (get_local $g2) (i64.const 0x80000000)) (i64.const 1)) (i64.const 19))))
(set_local $g3_19 (i64.sub (i64.mul (i64.const 19) (get_local $g3)) (i64.mul (i64.shl (i64.and (get_local $g3) (i64.const 0x80000000)) (i64.const 1)) (i64.const 19))))
(set_local $g4_19 (i64.sub (i64.mul (i64.const 19) (get_local $g4)) (i64.mul (i64.shl (i64.and (get_local $g4) (i64.const 0x80000000)) (i64.const 1)) (i64.const 19))))
(set_local $g5_19 (i64.sub (i64.mul (i64.const 19) (get_local $g5)) (i64.mul (i64.shl (i64.and (get_local $g5) (i64.const 0x80000000)) (i64.const 1)) (i64.const 19))))
(set_local $g6_19 (i64.sub (i64.mul (i64.const 19) (get_local $g6)) (i64.mul (i64.shl (i64.and (get_local $g6) (i64.const 0x80000000)) (i64.const 1)) (i64.const 19))))
(set_local $g7_19 (i64.sub (i64.mul (i64.const 19) (get_local $g7)) (i64.mul (i64.shl (i64.and (get_local $g7) (i64.const 0x80000000)) (i64.const 1)) (i64.const 19))))
(set_local $g8_19 (i64.sub (i64.mul (i64.const 19) (get_local $g8)) (i64.mul (i64.shl (i64.and (get_local $g8) (i64.const 0x80000000)) (i64.const 1)) (i64.const 19))))
(set_local $g9_19 (i64.sub (i64.mul (i64.const 19) (get_local $g9)) (i64.mul (i64.shl (i64.and (get_local $g9) (i64.const 0x80000000)) (i64.const 1)) (i64.const 19))))
(set_local $f1_2 (i64.sub (i64.mul (i64.const 2) (get_local $f1)) (i64.mul (i64.shl (i64.and (get_local $f1) (i64.const 0x80000000)) (i64.const 1)) (i64.const 2))))
(set_local $f3_2 (i64.sub (i64.mul (i64.const 2) (get_local $f3)) (i64.mul (i64.shl (i64.and (get_local $f3) (i64.const 0x80000000)) (i64.const 1)) (i64.const 2))))
(set_local $f5_2 (i64.sub (i64.mul (i64.const 2) (get_local $f5)) (i64.mul (i64.shl (i64.and (get_local $f5) (i64.const 0x80000000)) (i64.const 1)) (i64.const 2))))
(set_local $f7_2 (i64.sub (i64.mul (i64.const 2) (get_local $f7)) (i64.mul (i64.shl (i64.and (get_local $f7) (i64.const 0x80000000)) (i64.const 1)) (i64.const 2))))
(set_local $f9_2 (i64.sub (i64.mul (i64.const 2) (get_local $f9)) (i64.mul (i64.shl (i64.and (get_local $f9) (i64.const 0x80000000)) (i64.const 1)) (i64.const 2))))
(set_local $g1_19 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g1_19))))
(set_local $g2_19 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g2_19))))
(set_local $g3_19 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g3_19))))
(set_local $g4_19 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g4_19))))
(set_local $g5_19 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g5_19))))
(set_local $g6_19 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g6_19))))
(set_local $g7_19 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g7_19))))
(set_local $g8_19 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g8_19))))
(set_local $g9_19 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g9_19))))
(set_local $f1_2 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f1_2))))
(set_local $f3_2 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f3_2))))
(set_local $f5_2 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f5_2))))
(set_local $f7_2 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f7_2))))
(set_local $f9_2 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f9_2))))
(set_local $f0g0 (i64.mul (get_local $f0 ) (get_local $g0)))
(set_local $f0g1 (i64.mul (get_local $f0 ) (get_local $g1)))
(set_local $f0g2 (i64.mul (get_local $f0 ) (get_local $g2)))
(set_local $f0g3 (i64.mul (get_local $f0 ) (get_local $g3)))
(set_local $f0g4 (i64.mul (get_local $f0 ) (get_local $g4)))
(set_local $f0g5 (i64.mul (get_local $f0 ) (get_local $g5)))
(set_local $f0g6 (i64.mul (get_local $f0 ) (get_local $g6)))
(set_local $f0g7 (i64.mul (get_local $f0 ) (get_local $g7)))
(set_local $f0g8 (i64.mul (get_local $f0 ) (get_local $g8)))
(set_local $f0g9 (i64.mul (get_local $f0 ) (get_local $g9)))
(set_local $f1g0 (i64.mul (get_local $f1 ) (get_local $g0)))
(set_local $f1g1_2 (i64.mul (get_local $f1_2) (get_local $g1)))
(set_local $f1g2 (i64.mul (get_local $f1 ) (get_local $g2)))
(set_local $f1g3_2 (i64.mul (get_local $f1_2) (get_local $g3)))
(set_local $f1g4 (i64.mul (get_local $f1 ) (get_local $g4)))
(set_local $f1g5_2 (i64.mul (get_local $f1_2) (get_local $g5)))
(set_local $f1g6 (i64.mul (get_local $f1 ) (get_local $g6)))
(set_local $f1g7_2 (i64.mul (get_local $f1_2) (get_local $g7)))
(set_local $f1g8 (i64.mul (get_local $f1 ) (get_local $g8)))
(set_local $f1g9_38 (i64.mul (get_local $f1_2) (get_local $g9_19)))
(set_local $f2g0 (i64.mul (get_local $f2 ) (get_local $g0)))
(set_local $f2g1 (i64.mul (get_local $f2 ) (get_local $g1)))
(set_local $f2g2 (i64.mul (get_local $f2 ) (get_local $g2)))
(set_local $f2g3 (i64.mul (get_local $f2 ) (get_local $g3)))
(set_local $f2g4 (i64.mul (get_local $f2 ) (get_local $g4)))
(set_local $f2g5 (i64.mul (get_local $f2 ) (get_local $g5)))
(set_local $f2g6 (i64.mul (get_local $f2 ) (get_local $g6)))
(set_local $f2g7 (i64.mul (get_local $f2 ) (get_local $g7)))
(set_local $f2g8_19 (i64.mul (get_local $f2 ) (get_local $g8_19)))
(set_local $f2g9_19 (i64.mul (get_local $f2 ) (get_local $g9_19)))
(set_local $f3g0 (i64.mul (get_local $f3 ) (get_local $g0)))
(set_local $f3g1_2 (i64.mul (get_local $f3_2) (get_local $g1)))
(set_local $f3g2 (i64.mul (get_local $f3 ) (get_local $g2)))
(set_local $f3g3_2 (i64.mul (get_local $f3_2) (get_local $g3)))
(set_local $f3g4 (i64.mul (get_local $f3 ) (get_local $g4)))
(set_local $f3g5_2 (i64.mul (get_local $f3_2) (get_local $g5)))
(set_local $f3g6 (i64.mul (get_local $f3 ) (get_local $g6)))
(set_local $f3g7_38 (i64.mul (get_local $f3_2) (get_local $g7_19)))
(set_local $f3g8_19 (i64.mul (get_local $f3 ) (get_local $g8_19)))
(set_local $f3g9_38 (i64.mul (get_local $f3_2) (get_local $g9_19)))
(set_local $f4g0 (i64.mul (get_local $f4) (get_local $g0)))
(set_local $f4g1 (i64.mul (get_local $f4) (get_local $g1)))
(set_local $f4g2 (i64.mul (get_local $f4) (get_local $g2)))
(set_local $f4g3 (i64.mul (get_local $f4) (get_local $g3)))
(set_local $f4g4 (i64.mul (get_local $f4) (get_local $g4)))
(set_local $f4g5 (i64.mul (get_local $f4) (get_local $g5)))
(set_local $f4g6_19 (i64.mul (get_local $f4) (get_local $g6_19)))
(set_local $f4g7_19 (i64.mul (get_local $f4) (get_local $g7_19)))
(set_local $f4g8_19 (i64.mul (get_local $f4) (get_local $g8_19)))
(set_local $f4g9_19 (i64.mul (get_local $f4) (get_local $g9_19)))
(set_local $f5g0 (i64.mul (get_local $f5) (get_local $g0)))
(set_local $f5g1_2 (i64.mul (get_local $f5_2) (get_local $g1)))
(set_local $f5g2 (i64.mul (get_local $f5) (get_local $g2)))
(set_local $f5g3_2 (i64.mul (get_local $f5_2) (get_local $g3)))
(set_local $f5g4 (i64.mul (get_local $f5) (get_local $g4)))
(set_local $f5g5_38 (i64.mul (get_local $f5_2) (get_local $g5_19)))
(set_local $f5g6_19 (i64.mul (get_local $f5) (get_local $g6_19)))
(set_local $f5g7_38 (i64.mul (get_local $f5_2) (get_local $g7_19)))
(set_local $f5g8_19 (i64.mul (get_local $f5) (get_local $g8_19)))
(set_local $f5g9_38 (i64.mul (get_local $f5_2) (get_local $g9_19)))
(set_local $f6g0 (i64.mul (get_local $f6) (get_local $g0)))
(set_local $f6g1 (i64.mul (get_local $f6) (get_local $g1)))
(set_local $f6g2 (i64.mul (get_local $f6) (get_local $g2)))
(set_local $f6g3 (i64.mul (get_local $f6) (get_local $g3)))
(set_local $f6g4_19 (i64.mul (get_local $f6) (get_local $g4_19)))
(set_local $f6g5_19 (i64.mul (get_local $f6) (get_local $g5_19)))
(set_local $f6g6_19 (i64.mul (get_local $f6) (get_local $g6_19)))
(set_local $f6g7_19 (i64.mul (get_local $f6) (get_local $g7_19)))
(set_local $f6g8_19 (i64.mul (get_local $f6) (get_local $g8_19)))
(set_local $f6g9_19 (i64.mul (get_local $f6) (get_local $g9_19)))
(set_local $f7g0 (i64.mul (get_local $f7) (get_local $g0)))
(set_local $f7g1_2 (i64.mul (get_local $f7_2) (get_local $g1)))
(set_local $f7g2 (i64.mul (get_local $f7) (get_local $g2)))
(set_local $f7g3_38 (i64.mul (get_local $f7_2) (get_local $g3_19)))
(set_local $f7g4_19 (i64.mul (get_local $f7) (get_local $g4_19)))
(set_local $f7g5_38 (i64.mul (get_local $f7_2) (get_local $g5_19)))
(set_local $f7g6_19 (i64.mul (get_local $f7) (get_local $g6_19)))
(set_local $f7g7_38 (i64.mul (get_local $f7_2) (get_local $g7_19)))
(set_local $f7g8_19 (i64.mul (get_local $f7) (get_local $g8_19)))
(set_local $f7g9_38 (i64.mul (get_local $f7_2) (get_local $g9_19)))
(set_local $f8g0 (i64.mul (get_local $f8) (get_local $g0)))
(set_local $f8g1 (i64.mul (get_local $f8) (get_local $g1)))
(set_local $f8g2_19 (i64.mul (get_local $f8) (get_local $g2_19)))
(set_local $f8g3_19 (i64.mul (get_local $f8) (get_local $g3_19)))
(set_local $f8g4_19 (i64.mul (get_local $f8) (get_local $g4_19)))
(set_local $f8g5_19 (i64.mul (get_local $f8) (get_local $g5_19)))
(set_local $f8g6_19 (i64.mul (get_local $f8) (get_local $g6_19)))
(set_local $f8g7_19 (i64.mul (get_local $f8) (get_local $g7_19)))
(set_local $f8g8_19 (i64.mul (get_local $f8) (get_local $g8_19)))
(set_local $f8g9_19 (i64.mul (get_local $f8) (get_local $g9_19)))
(set_local $f9g0 (i64.mul (get_local $f9) (get_local $g0)))
(set_local $f9g1_38 (i64.mul (get_local $f9_2) (get_local $g1_19)))
(set_local $f9g2_19 (i64.mul (get_local $f9) (get_local $g2_19)))
(set_local $f9g3_38 (i64.mul (get_local $f9_2) (get_local $g3_19)))
(set_local $f9g4_19 (i64.mul (get_local $f9) (get_local $g4_19)))
(set_local $f9g5_38 (i64.mul (get_local $f9_2) (get_local $g5_19)))
(set_local $f9g6_19 (i64.mul (get_local $f9) (get_local $g6_19)))
(set_local $f9g7_38 (i64.mul (get_local $f9_2) (get_local $g7_19)))
(set_local $f9g8_19 (i64.mul (get_local $f9) (get_local $g8_19)))
(set_local $f9g9_38 (i64.mul (get_local $f9_2) (get_local $g9_19)))
(set_local $h0 (i64.add (get_local $f0g0) (i64.add (get_local $f1g9_38) (i64.add (get_local $f2g8_19) (i64.add (get_local $f3g7_38) (i64.add (get_local $f4g6_19) (i64.add (get_local $f5g5_38) (i64.add (get_local $f6g4_19) (i64.add (get_local $f7g3_38) (i64.add (get_local $f8g2_19) (get_local $f9g1_38)))))))))))
(set_local $h1 (i64.add (get_local $f0g1) (i64.add (get_local $f1g0) (i64.add (get_local $f2g9_19) (i64.add (get_local $f3g8_19) (i64.add (get_local $f4g7_19) (i64.add (get_local $f5g6_19) (i64.add (get_local $f6g5_19) (i64.add (get_local $f7g4_19) (i64.add (get_local $f8g3_19) (get_local $f9g2_19)))))))))))
(set_local $h2 (i64.add (get_local $f0g2) (i64.add (get_local $f1g1_2) (i64.add (get_local $f2g0) (i64.add (get_local $f3g9_38) (i64.add (get_local $f4g8_19) (i64.add (get_local $f5g7_38) (i64.add (get_local $f6g6_19) (i64.add (get_local $f7g5_38) (i64.add (get_local $f8g4_19) (get_local $f9g3_38)))))))))))
(set_local $h3 (i64.add (get_local $f0g3) (i64.add (get_local $f1g2) (i64.add (get_local $f2g1) (i64.add (get_local $f3g0) (i64.add (get_local $f4g9_19) (i64.add (get_local $f5g8_19) (i64.add (get_local $f6g7_19) (i64.add (get_local $f7g6_19) (i64.add (get_local $f8g5_19) (get_local $f9g4_19)))))))))))
(set_local $h4 (i64.add (get_local $f0g4) (i64.add (get_local $f1g3_2) (i64.add (get_local $f2g2) (i64.add (get_local $f3g1_2) (i64.add (get_local $f4g0) (i64.add (get_local $f5g9_38) (i64.add (get_local $f6g8_19) (i64.add (get_local $f7g7_38) (i64.add (get_local $f8g6_19) (get_local $f9g5_38)))))))))))
(set_local $h5 (i64.add (get_local $f0g5) (i64.add (get_local $f1g4) (i64.add (get_local $f2g3) (i64.add (get_local $f3g2) (i64.add (get_local $f4g1) (i64.add (get_local $f5g0) (i64.add (get_local $f6g9_19) (i64.add (get_local $f7g8_19) (i64.add (get_local $f8g7_19) (get_local $f9g6_19)))))))))))
(set_local $h6 (i64.add (get_local $f0g6) (i64.add (get_local $f1g5_2) (i64.add (get_local $f2g4) (i64.add (get_local $f3g3_2) (i64.add (get_local $f4g2) (i64.add (get_local $f5g1_2) (i64.add (get_local $f6g0) (i64.add (get_local $f7g9_38) (i64.add (get_local $f8g8_19) (get_local $f9g7_38)))))))))))
(set_local $h7 (i64.add (get_local $f0g7) (i64.add (get_local $f1g6) (i64.add (get_local $f2g5) (i64.add (get_local $f3g4) (i64.add (get_local $f4g3) (i64.add (get_local $f5g2) (i64.add (get_local $f6g1) (i64.add (get_local $f7g0) (i64.add (get_local $f8g9_19) (get_local $f9g8_19)))))))))))
(set_local $h8 (i64.add (get_local $f0g8) (i64.add (get_local $f1g7_2) (i64.add (get_local $f2g6) (i64.add (get_local $f3g5_2) (i64.add (get_local $f4g4) (i64.add (get_local $f5g3_2) (i64.add (get_local $f6g2) (i64.add (get_local $f7g1_2) (i64.add (get_local $f8g0) (get_local $f9g9_38)))))))))))
(set_local $h9 (i64.add (get_local $f0g9) (i64.add (get_local $f1g8) (i64.add (get_local $f2g7) (i64.add (get_local $f3g6) (i64.add (get_local $f4g5) (i64.add (get_local $f5g4) (i64.add (get_local $f6g3) (i64.add (get_local $f7g2) (i64.add (get_local $f8g1) (get_local $f9g0)))))))))))
(set_local $carry0 (i64.shr_s (i64.add (get_local $h0) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
(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)))))
(set_local $carry4 (i64.shr_s (i64.add (get_local $h4) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
(set_local $h5 (i64.add (get_local $h5) (get_local $carry4)))
(set_local $h4 (i64.sub (get_local $h4) (i64.mul (get_local $carry4) (i64.shl (i64.const 1) (i64.const 26)))))
(set_local $carry1 (i64.shr_s (i64.add (get_local $h1) (i64.shl (i64.const 1) (i64.const 24))) (i64.const 25)))
(set_local $h2 (i64.add (get_local $h2) (get_local $carry1)))
(set_local $h1 (i64.sub (get_local $h1) (i64.mul (get_local $carry1) (i64.shl (i64.const 1) (i64.const 25)))))
(set_local $carry5 (i64.shr_s (i64.add (get_local $h5) (i64.shl (i64.const 1) (i64.const 24))) (i64.const 25)))
(set_local $h6 (i64.add (get_local $h6) (get_local $carry5)))
(set_local $h5 (i64.sub (get_local $h5) (i64.mul (get_local $carry5) (i64.shl (i64.const 1) (i64.const 25)))))
(set_local $carry2 (i64.shr_s (i64.add (get_local $h2) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
(set_local $h3 (i64.add (get_local $h3) (get_local $carry2)))
(set_local $h2 (i64.sub (get_local $h2) (i64.mul (get_local $carry2) (i64.shl (i64.const 1) (i64.const 26)))))
(set_local $carry6 (i64.shr_s (i64.add (get_local $h6) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
(set_local $h7 (i64.add (get_local $h7) (get_local $carry6)))
(set_local $h6 (i64.sub (get_local $h6) (i64.mul (get_local $carry6) (i64.shl (i64.const 1) (i64.const 26)))))
(set_local $carry3 (i64.shr_s (i64.add (get_local $h3) (i64.shl (i64.const 1) (i64.const 24))) (i64.const 25)))
(set_local $h4 (i64.add (get_local $h4) (get_local $carry3)))
(set_local $h3 (i64.sub (get_local $h3) (i64.mul (get_local $carry3) (i64.shl (i64.const 1) (i64.const 25)))))
(set_local $carry7 (i64.shr_s (i64.add (get_local $h7) (i64.shl (i64.const 1) (i64.const 24))) (i64.const 25)))
(set_local $h8 (i64.add (get_local $h8) (get_local $carry7)))
(set_local $h7 (i64.sub (get_local $h7) (i64.mul (get_local $carry7) (i64.shl (i64.const 1) (i64.const 25)))))
(set_local $carry4 (i64.shr_s (i64.add (get_local $h4) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
(set_local $h5 (i64.add (get_local $h5) (get_local $carry4)))
(set_local $h4 (i64.sub (get_local $h4) (i64.mul (get_local $carry4) (i64.shl (i64.const 1) (i64.const 26)))))
(set_local $carry8 (i64.shr_s (i64.add (get_local $h8) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
(set_local $h9 (i64.add (get_local $h9) (get_local $carry8)))
(set_local $h8 (i64.sub (get_local $h8) (i64.mul (get_local $carry8) (i64.shl (i64.const 1) (i64.const 26)))))
(set_local $carry9 (i64.shr_s (i64.add (get_local $h9) (i64.shl (i64.const 1) (i64.const 24))) (i64.const 25)))
(set_local $h0 (i64.add (get_local $h0) (i64.mul (get_local $carry9) (i64.const 19))))
(set_local $h9 (i64.sub (get_local $h9) (i64.mul (get_local $carry9) (i64.shl (i64.const 1) (i64.const 25)))))
(set_local $carry0 (i64.shr_s (i64.add (get_local $h0) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
(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)))
(func $fe25519_mul (export "fe25519_mul") (param $h i32) (param $f i32) (param $g i32)
(i64.load32_u offset=0 (get_local $f))
(i64.load32_u offset=4 (get_local $f))
(i64.load32_u offset=8 (get_local $f))
(i64.load32_u offset=12 (get_local $f))
(i64.load32_u offset=16 (get_local $f))
(i64.load32_u offset=20 (get_local $f))
(i64.load32_u offset=24 (get_local $f))
(i64.load32_u offset=28 (get_local $f))
(i64.load32_u offset=32 (get_local $f))
(i64.load32_u offset=36 (get_local $f))
(i64.load32_u offset=0 (get_local $g))
(i64.load32_u offset=4 (get_local $g))
(i64.load32_u offset=8 (get_local $g))
(i64.load32_u offset=12 (get_local $g))
(i64.load32_u offset=16 (get_local $g))
(i64.load32_u offset=20 (get_local $g))
(i64.load32_u offset=24 (get_local $g))
(i64.load32_u offset=28 (get_local $g))
(i64.load32_u offset=32 (get_local $g))
(i64.load32_u offset=36 (get_local $g))
(get_local $h)
(call $fe_mul)))

View File

@ -0,0 +1,61 @@
module.exports = loadWebAssembly
loadWebAssembly.supported = typeof WebAssembly !== 'undefined'
function loadWebAssembly (opts) {
if (!loadWebAssembly.supported) return null
var imp = opts && opts.imports
var wasm = toUint8Array('AGFzbQEAAAABFgJgDH5+fn5+fn5+fn5/fwBgA39/fwADAwIAAQUDAQABBxoCBm1lbW9yeQIADWZlMjU1MTlfbXVsMzIAAQrcBAKeBAEVfiAKrCEMIACnrCEAIAGnrCEBIAKnrCECIAOnrCEDIASnrCEEIAWnrCEFIAanrCEGIAenrCEHIAinrCEIIAmnrCEJIAAgDH4hDSABIAx+IQ4gAiAMfiEPIAMgDH4hECAEIAx+IREgBSAMfiESIAYgDH4hEyAHIAx+IRQgCCAMfiEVIAkgDH4hFiAWQgFCGIZ8QhmHISAgDSAgQhN+fCENIBYgIEIBQhmGfn0hFiAOQgFCGIZ8QhmHIRggDyAYfCEPIA4gGEIBQhmGfn0hDiAQQgFCGIZ8QhmHIRogESAafCERIBAgGkIBQhmGfn0hECASQgFCGIZ8QhmHIRwgEyAcfCETIBIgHEIBQhmGfn0hEiAUQgFCGIZ8QhmHIR4gFSAefCEVIBQgHkIBQhmGfn0hFCANQgFCGYZ8QhqHIRcgDiAXfCEOIA0gF0IBQhqGfn0hDSAPQgFCGYZ8QhqHIRkgECAZfCEQIA8gGUIBQhqGfn0hDyARQgFCGYZ8QhqHIRsgEiAbfCESIBEgG0IBQhqGfn0hESATQgFCGYZ8QhqHIR0gFCAdfCEUIBMgHUIBQhqGfn0hEyAVQgFCGYZ8QhqHIR8gFiAffCEWIBUgH0IBQhqGfn0hFSALIA0+AgAgCyAOPgIEIAsgDz4CCCALIBA+AgwgCyARPgIQIAsgEj4CFCALIBM+AhggCyAUPgIcIAsgFT4CICALIBY+AiQLOgAgATUCACABNQIEIAE1AgggATUCDCABNQIQIAE1AhQgATUCGCABNQIcIAE1AiAgATUCJCACIAAQAAs=')
var ready = null
var mod = {
buffer: wasm,
memory: null,
exports: null,
realloc: realloc,
onload: onload
}
onload(function () {})
return mod
function realloc (size) {
mod.exports.memory.grow(Math.max(0, Math.ceil(Math.abs(size - mod.memory.length) / 65536)))
mod.memory = new Uint8Array(mod.exports.memory.buffer)
}
function onload (cb) {
if (mod.exports) return cb()
if (ready) {
ready.then(cb.bind(null, null)).catch(cb)
return
}
try {
if (opts && opts.async) throw new Error('async')
setup({instance: new WebAssembly.Instance(new WebAssembly.Module(wasm), imp)})
} catch (err) {
ready = WebAssembly.instantiate(wasm, imp).then(setup)
}
onload(cb)
}
function setup (w) {
mod.exports = w.instance.exports
mod.memory = mod.exports.memory && mod.exports.memory.buffer && new Uint8Array(mod.exports.memory.buffer)
}
}
function toUint8Array (s) {
if (typeof atob === 'function') return new Uint8Array(atob(s).split('').map(charCodeAt))
return (require('buf' + 'fer').Buffer).from(s, 'base64')
}
function charCodeAt (c) {
return c.charCodeAt(0)
}

View File

@ -0,0 +1,161 @@
(module
(memory $0 1)
(export "memory" (memory $0))
;; (func $i32.log (import "debug" "log") (param i32))
;; (func $i32.log_tee (import "debug" "log_tee") (param i32) (result i32))
;; ;; No i64 interop with JS yet - but maybe coming with WebAssembly BigInt
;; ;; So we can instead fake this by splitting the i64 into two i32 limbs,
;; ;; however these are WASM functions using i32x2.log:
;; (func $i32x2.log (import "debug" "log") (param i32) (param i32))
;; (func $f32.log (import "debug" "log") (param f32))
;; (func $f32.log_tee (import "debug" "log_tee") (param f32) (result f32))
;; (func $f64.log (import "debug" "log") (param f64))
;; (func $f64.log_tee (import "debug" "log_tee") (param f64) (result f64))
;; ;; i64 logging by splitting into two i32 limbs
;; (func $i64.log
;; (param $0 i64)
;; (call $i32x2.log
;; ;; Upper limb
;; (i32.wrap/i64
;; (i64.shr_s (get_local $0)
;; (i64.const 32)))
;; ;; Lower limb
;; (i32.wrap/i64 (get_local $0))))
;; (func $i64.log_tee
;; (param $0 i64)
;; (result i64)
;; (call $i64.log (get_local $0))
;; (return (get_local $0)))
(func $fe_mul32
(param $f0 i64)
(param $f1 i64)
(param $f2 i64)
(param $f3 i64)
(param $f4 i64)
(param $f5 i64)
(param $f6 i64)
(param $f7 i64)
(param $f8 i64)
(param $f9 i64)
(param $n i32)
(param $h i32)
(local $sn i64)
(local $h0 i64)
(local $h1 i64)
(local $h2 i64)
(local $h3 i64)
(local $h4 i64)
(local $h5 i64)
(local $h6 i64)
(local $h7 i64)
(local $h8 i64)
(local $h9 i64)
(local $carry0 i64)
(local $carry1 i64)
(local $carry2 i64)
(local $carry3 i64)
(local $carry4 i64)
(local $carry5 i64)
(local $carry6 i64)
(local $carry7 i64)
(local $carry8 i64)
(local $carry9 i64)
(set_local $sn (i64.extend_s/i32 (get_local $n)))
(set_local $f0 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f0))))
(set_local $f1 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f1))))
(set_local $f2 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f2))))
(set_local $f3 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f3))))
(set_local $f4 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f4))))
(set_local $f5 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f5))))
(set_local $f6 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f6))))
(set_local $f7 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f7))))
(set_local $f8 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f8))))
(set_local $f9 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f9))))
(set_local $h0 (i64.mul (get_local $f0) (get_local $sn)))
(set_local $h1 (i64.mul (get_local $f1) (get_local $sn)))
(set_local $h2 (i64.mul (get_local $f2) (get_local $sn)))
(set_local $h3 (i64.mul (get_local $f3) (get_local $sn)))
(set_local $h4 (i64.mul (get_local $f4) (get_local $sn)))
(set_local $h5 (i64.mul (get_local $f5) (get_local $sn)))
(set_local $h6 (i64.mul (get_local $f6) (get_local $sn)))
(set_local $h7 (i64.mul (get_local $f7) (get_local $sn)))
(set_local $h8 (i64.mul (get_local $f8) (get_local $sn)))
(set_local $h9 (i64.mul (get_local $f9) (get_local $sn)))
(set_local $carry9 (i64.shr_s (i64.add (get_local $h9) (i64.shl (i64.const 1) (i64.const 24))) (i64.const 25)))
(set_local $h0 (i64.add (get_local $h0) (i64.mul (get_local $carry9) (i64.const 19))))
(set_local $h9 (i64.sub (get_local $h9) (i64.mul (get_local $carry9) (i64.shl (i64.const 1) (i64.const 25)))))
(set_local $carry1 (i64.shr_s (i64.add (get_local $h1) (i64.shl (i64.const 1) (i64.const 24))) (i64.const 25)))
(set_local $h2 (i64.add (get_local $h2) (get_local $carry1)))
(set_local $h1 (i64.sub (get_local $h1) (i64.mul (get_local $carry1) (i64.shl (i64.const 1) (i64.const 25)))))
(set_local $carry3 (i64.shr_s (i64.add (get_local $h3) (i64.shl (i64.const 1) (i64.const 24))) (i64.const 25)))
(set_local $h4 (i64.add (get_local $h4) (get_local $carry3)))
(set_local $h3 (i64.sub (get_local $h3) (i64.mul (get_local $carry3) (i64.shl (i64.const 1) (i64.const 25)))))
(set_local $carry5 (i64.shr_s (i64.add (get_local $h5) (i64.shl (i64.const 1) (i64.const 24))) (i64.const 25)))
(set_local $h6 (i64.add (get_local $h6) (get_local $carry5)))
(set_local $h5 (i64.sub (get_local $h5) (i64.mul (get_local $carry5) (i64.shl (i64.const 1) (i64.const 25)))))
(set_local $carry7 (i64.shr_s (i64.add (get_local $h7) (i64.shl (i64.const 1) (i64.const 24))) (i64.const 25)))
(set_local $h8 (i64.add (get_local $h8) (get_local $carry7)))
(set_local $h7 (i64.sub (get_local $h7) (i64.mul (get_local $carry7) (i64.shl (i64.const 1) (i64.const 25)))))
(set_local $carry0 (i64.shr_s (i64.add (get_local $h0) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
(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)))))
(set_local $carry2 (i64.shr_s (i64.add (get_local $h2) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
(set_local $h3 (i64.add (get_local $h3) (get_local $carry2)))
(set_local $h2 (i64.sub (get_local $h2) (i64.mul (get_local $carry2) (i64.shl (i64.const 1) (i64.const 26)))))
(set_local $carry4 (i64.shr_s (i64.add (get_local $h4) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
(set_local $h5 (i64.add (get_local $h5) (get_local $carry4)))
(set_local $h4 (i64.sub (get_local $h4) (i64.mul (get_local $carry4) (i64.shl (i64.const 1) (i64.const 26)))))
(set_local $carry6 (i64.shr_s (i64.add (get_local $h6) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
(set_local $h7 (i64.add (get_local $h7) (get_local $carry6)))
(set_local $h6 (i64.sub (get_local $h6) (i64.mul (get_local $carry6) (i64.shl (i64.const 1) (i64.const 26)))))
(set_local $carry8 (i64.shr_s (i64.add (get_local $h8) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
(set_local $h9 (i64.add (get_local $h9) (get_local $carry8)))
(set_local $h8 (i64.sub (get_local $h8) (i64.mul (get_local $carry8) (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)))
(func $fe25519_mul32 (export "fe25519_mul32") (param $h i32) (param $f i32) (param $n i32)
(i64.load32_u offset=0 (get_local $f))
(i64.load32_u offset=4 (get_local $f))
(i64.load32_u offset=8 (get_local $f))
(i64.load32_u offset=12 (get_local $f))
(i64.load32_u offset=16 (get_local $f))
(i64.load32_u offset=20 (get_local $f))
(i64.load32_u offset=24 (get_local $f))
(i64.load32_u offset=28 (get_local $f))
(i64.load32_u offset=32 (get_local $f))
(i64.load32_u offset=36 (get_local $f))
(get_local $n)
(get_local $h)
(call $fe_mul32)))

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

61
fe25519_25/fe25519_sq.js Normal file
View File

@ -0,0 +1,61 @@
module.exports = loadWebAssembly
loadWebAssembly.supported = typeof WebAssembly !== 'undefined'
function loadWebAssembly (opts) {
if (!loadWebAssembly.supported) return null
var imp = opts && opts.imports
var wasm = toUint8Array('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')
var ready = null
var mod = {
buffer: wasm,
memory: null,
exports: null,
realloc: realloc,
onload: onload
}
onload(function () {})
return mod
function realloc (size) {
mod.exports.memory.grow(Math.max(0, Math.ceil(Math.abs(size - mod.memory.length) / 65536)))
mod.memory = new Uint8Array(mod.exports.memory.buffer)
}
function onload (cb) {
if (mod.exports) return cb()
if (ready) {
ready.then(cb.bind(null, null)).catch(cb)
return
}
try {
if (opts && opts.async) throw new Error('async')
setup({instance: new WebAssembly.Instance(new WebAssembly.Module(wasm), imp)})
} catch (err) {
ready = WebAssembly.instantiate(wasm, imp).then(setup)
}
onload(cb)
}
function setup (w) {
mod.exports = w.instance.exports
mod.memory = mod.exports.memory && mod.exports.memory.buffer && new Uint8Array(mod.exports.memory.buffer)
}
}
function toUint8Array (s) {
if (typeof atob === 'function') return new Uint8Array(atob(s).split('').map(charCodeAt))
return (require('buf' + 'fer').Buffer).from(s, 'base64')
}
function charCodeAt (c) {
return c.charCodeAt(0)
}

328
fe25519_25/fe25519_sq.wat Normal file
View File

@ -0,0 +1,328 @@
(module
(import "js" "table" (table 1 anyfunc))
(import "js" "mem" (memory 1))
(elem (i32.const 2) $fe_sq)
(func $i32.log (import "debug" "log") (param i32))
(func $i32.log_tee (import "debug" "log_tee") (param i32) (result i32))
;; No i64 interop with JS yet - but maybe coming with WebAssembly BigInt
;; So we can instead fake this by splitting the i64 into two i32 limbs,
;; however these are WASM functions using i32x2.log:
(func $i32x2.log (import "debug" "log") (param i32) (param i32))
(func $f32.log (import "debug" "log") (param f32))
(func $f32.log_tee (import "debug" "log_tee") (param f32) (result f32))
(func $f64.log (import "debug" "log") (param f64))
(func $f64.log_tee (import "debug" "log_tee") (param f64) (result f64))
;; i64 logging by splitting into two i32 limbs
(func $i64.log
(param $0 i64)
(call $i32x2.log
;; Upper limb
(i32.wrap/i64
(i64.shr_s (get_local $0)
(i64.const 32)))
;; Lower limb
(i32.wrap/i64 (get_local $0))))
(func $i64.log_tee
(param $0 i64)
(result i64)
(call $i64.log (get_local $0))
(return (get_local $0)))
(func $fe_sq
(param $f0 i64)
(param $f1 i64)
(param $f2 i64)
(param $f3 i64)
(param $f4 i64)
(param $f5 i64)
(param $f6 i64)
(param $f7 i64)
(param $f8 i64)
(param $f9 i64)
(param $double i32)
(param $repeat i32)
(param $h i32)
(local $count i32)
(local $tmp i64)
(local $h0 i64)
(local $h1 i64)
(local $h2 i64)
(local $h3 i64)
(local $h4 i64)
(local $h5 i64)
(local $h6 i64)
(local $h7 i64)
(local $h8 i64)
(local $h9 i64)
(local $carry0 i64)
(local $carry1 i64)
(local $carry2 i64)
(local $carry3 i64)
(local $carry4 i64)
(local $carry5 i64)
(local $carry6 i64)
(local $carry7 i64)
(local $carry8 i64)
(local $carry9 i64)
(local $f0_2 i64)
(local $f1_2 i64)
(local $f2_2 i64)
(local $f3_2 i64)
(local $f4_2 i64)
(local $f5_2 i64)
(local $f6_2 i64)
(local $f7_2 i64)
(local $f5_38 i64)
(local $f6_19 i64)
(local $f7_38 i64)
(local $f8_19 i64)
(local $f9_38 i64)
(local $f0f0 i64)
(local $f0f1_2 i64)
(local $f0f2_2 i64)
(local $f0f3_2 i64)
(local $f0f4_2 i64)
(local $f0f5_2 i64)
(local $f0f6_2 i64)
(local $f0f7_2 i64)
(local $f0f8_2 i64)
(local $f0f9_2 i64)
(local $f1f1_2 i64)
(local $f1f2_2 i64)
(local $f1f3_4 i64)
(local $f1f4_2 i64)
(local $f1f5_4 i64)
(local $f1f6_2 i64)
(local $f1f7_4 i64)
(local $f1f8_2 i64)
(local $f1f9_76 i64)
(local $f2f2 i64)
(local $f2f3_2 i64)
(local $f2f4_2 i64)
(local $f2f5_2 i64)
(local $f2f6_2 i64)
(local $f2f7_2 i64)
(local $f2f8_38 i64)
(local $f2f9_38 i64)
(local $f3f3_2 i64)
(local $f3f4_2 i64)
(local $f3f5_4 i64)
(local $f3f6_2 i64)
(local $f3f7_76 i64)
(local $f3f8_38 i64)
(local $f3f9_76 i64)
(local $f4f4 i64)
(local $f4f5_2 i64)
(local $f4f6_38 i64)
(local $f4f7_38 i64)
(local $f4f8_38 i64)
(local $f4f9_38 i64)
(local $f5f5_38 i64)
(local $f5f6_38 i64)
(local $f5f7_76 i64)
(local $f5f8_38 i64)
(local $f5f9_76 i64)
(local $f6f6_19 i64)
(local $f6f7_38 i64)
(local $f6f8_38 i64)
(local $f6f9_38 i64)
(local $f7f7_38 i64)
(local $f7f8_38 i64)
(local $f7f9_76 i64)
(local $f8f8_19 i64)
(local $f8f9_38 i64)
(local $f9f9_38 i64)
(block $end
(loop $again
(set_local $f0 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f0))))
(set_local $f1 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f1))))
(set_local $f2 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f2))))
(set_local $f3 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f3))))
(set_local $f4 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f4))))
(set_local $f5 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f5))))
(set_local $f6 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f6))))
(set_local $f7 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f7))))
(set_local $f8 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f8))))
(set_local $f9 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f9))))
(set_local $f0_2 (i64.mul (i64.const 2 (get_local $f0))))
(set_local $f1_2 (i64.mul (i64.const 2 (get_local $f1))))
(set_local $f2_2 (i64.mul (i64.const 2 (get_local $f2))))
(set_local $f3_2 (i64.mul (i64.const 2 (get_local $f3))))
(set_local $f4_2 (i64.mul (i64.const 2 (get_local $f4))))
(set_local $f5_2 (i64.mul (i64.const 2 (get_local $f5))))
(set_local $f6_2 (i64.mul (i64.const 2 (get_local $f6))))
(set_local $f7_2 (i64.mul (i64.const 2 (get_local $f7))))
(set_local $f5_38 (i64.mul (i64.const 38 (get_local $f5))))
(set_local $f6_19 (i64.mul (i64.const 19 (get_local $f6))))
(set_local $f7_38 (i64.mul (i64.const 38 (get_local $f7))))
(set_local $f8_19 (i64.mul (i64.const 19 (get_local $f8))))
(set_local $f9_38 (i64.mul (i64.const 38 (get_local $f9))))
(set_local $f0f0 (i64.mul (get_local $f0) (get_local $f0)))
(set_local $f0f1_2 (i64.mul (get_local $f0_2) (get_local $f1)))
(set_local $f0f2_2 (i64.mul (get_local $f0_2) (get_local $f2)))
(set_local $f0f3_2 (i64.mul (get_local $f0_2) (get_local $f3)))
(set_local $f0f4_2 (i64.mul (get_local $f0_2) (get_local $f4)))
(set_local $f0f5_2 (i64.mul (get_local $f0_2) (get_local $f5)))
(set_local $f0f6_2 (i64.mul (get_local $f0_2) (get_local $f6)))
(set_local $f0f7_2 (i64.mul (get_local $f0_2) (get_local $f7)))
(set_local $f0f8_2 (i64.mul (get_local $f0_2) (get_local $f8)))
(set_local $f0f9_2 (i64.mul (get_local $f0_2) (get_local $f9)))
(set_local $f1f1_2 (i64.mul (get_local $f1_2) (get_local $f1)))
(set_local $f1f2_2 (i64.mul (get_local $f1_2) (get_local $f2)))
(set_local $f1f3_4 (i64.mul (get_local $f1_2) (get_local $f3_2)))
(set_local $f1f4_2 (i64.mul (get_local $f1_2) (get_local $f4)))
(set_local $f1f5_4 (i64.mul (get_local $f1_2) (get_local $f5_2)))
(set_local $f1f6_2 (i64.mul (get_local $f1_2) (get_local $f6)))
(set_local $f1f7_4 (i64.mul (get_local $f1_2) (get_local $f7_2)))
(set_local $f1f8_2 (i64.mul (get_local $f1_2) (get_local $f8)))
(set_local $f1f9_76 (i64.mul (get_local $f1_2) (get_local $f9_38)))
(set_local $f2f2 (i64.mul (get_local $f2) (get_local $f2)))
(set_local $f2f3_2 (i64.mul (get_local $f2_2) (get_local $f3)))
(set_local $f2f4_2 (i64.mul (get_local $f2_2) (get_local $f4)))
(set_local $f2f5_2 (i64.mul (get_local $f2_2) (get_local $f5)))
(set_local $f2f6_2 (i64.mul (get_local $f2_2) (get_local $f6)))
(set_local $f2f7_2 (i64.mul (get_local $f2_2) (get_local $f7)))
(set_local $f2f8_38 (i64.mul (get_local $f2_2) (get_local $f8_19)))
(set_local $f2f9_38 (i64.mul (get_local $f2) (get_local $f9_38)))
(set_local $f3f3_2 (i64.mul (get_local $f3_2) (get_local $f3)))
(set_local $f3f4_2 (i64.mul (get_local $f3_2) (get_local $f4)))
(set_local $f3f5_4 (i64.mul (get_local $f3_2) (get_local $f5_2)))
(set_local $f3f6_2 (i64.mul (get_local $f3_2) (get_local $f6)))
(set_local $f3f7_76 (i64.mul (get_local $f3_2) (get_local $f7_38)))
(set_local $f3f8_38 (i64.mul (get_local $f3_2) (get_local $f8_19)))
(set_local $f3f9_76 (i64.mul (get_local $f3_2) (get_local $f9_38)))
(set_local $f4f4 (i64.mul (get_local $f4) (get_local $f4)))
(set_local $f4f5_2 (i64.mul (get_local $f4_2) (get_local $f5)))
(set_local $f4f6_38 (i64.mul (get_local $f4_2) (get_local $f6_19)))
(set_local $f4f7_38 (i64.mul (get_local $f4) (get_local $f7_38)))
(set_local $f4f8_38 (i64.mul (get_local $f4_2) (get_local $f8_19)))
(set_local $f4f9_38 (i64.mul (get_local $f4) (get_local $f9_38)))
(set_local $f5f5_38 (i64.mul (get_local $f5) (get_local $f5_38)))
(set_local $f5f6_38 (i64.mul (get_local $f5_2) (get_local $f6_19)))
(set_local $f5f7_76 (i64.mul (get_local $f5_2) (get_local $f7_38)))
(set_local $f5f8_38 (i64.mul (get_local $f5_2) (get_local $f8_19)))
(set_local $f5f9_76 (i64.mul (get_local $f5_2) (get_local $f9_38)))
(set_local $f6f6_19 (i64.mul (get_local $f6) (get_local $f6_19)))
(set_local $f6f7_38 (i64.mul (get_local $f6) (get_local $f7_38)))
(set_local $f6f8_38 (i64.mul (get_local $f6_2) (get_local $f8_19)))
(set_local $f6f9_38 (i64.mul (get_local $f6) (get_local $f9_38)))
(set_local $f7f7_38 (i64.mul (get_local $f7) (get_local $f7_38)))
(set_local $f7f8_38 (i64.mul (get_local $f7_2) (get_local $f8_19)))
(set_local $f7f9_76 (i64.mul (get_local $f7_2) (get_local $f9_38)))
(set_local $f8f8_19 (i64.mul (get_local $f8) (get_local $f8_19)))
(set_local $f8f9_38 (i64.mul (get_local $f8) (get_local $f9_38)))
(set_local $f9f9_38 (i64.mul (get_local $f9) (get_local $f9_38)))
(set_local $h0 (i64.add (get_local $f0f0) (i64.add (get_local $f1f9_76) (i64.add (get_local $f2f8_38) (i64.add (get_local $f3f7_76) (i64.add (get_local $f4f6_38) (get_local $f5f5_38)))))))
(set_local $h1 (i64.add (get_local $f0f1_2) (i64.add (get_local $f2f9_38) (i64.add (get_local $f3f8_38) (i64.add (get_local $f4f7_38) (get_local $f5f6_38))))))
(set_local $h2 (i64.add (get_local $f0f2_2) (i64.add (get_local $f1f1_2) (i64.add (get_local $f3f9_76) (i64.add (get_local $f4f8_38) (i64.add (get_local $f5f7_76) (get_local $f6f6_19)))))))
(set_local $h3 (i64.add (get_local $f0f3_2) (i64.add (get_local $f1f2_2) (i64.add (get_local $f4f9_38) (i64.add (get_local $f5f8_38) (get_local $f6f7_38))))))
(set_local $h4 (i64.add (get_local $f0f4_2) (i64.add (get_local $f1f3_4) (i64.add (get_local $f2f2) (i64.add (get_local $f5f9_76) (i64.add (get_local $f6f8_38) (get_local $f7f7_38)))))))
(set_local $h5 (i64.add (get_local $f0f5_2) (i64.add (get_local $f1f4_2) (i64.add (get_local $f2f3_2) (i64.add (get_local $f6f9_38) (get_local $f7f8_38))))))
(set_local $h6 (i64.add (get_local $f0f6_2) (i64.add (get_local $f1f5_4) (i64.add (get_local $f2f4_2) (i64.add (get_local $f3f3_2) (i64.add (get_local $f7f9_76) (get_local $f8f8_19)))))))
(set_local $h7 (i64.add (get_local $f0f7_2) (i64.add (get_local $f1f6_2) (i64.add (get_local $f2f5_2) (i64.add (get_local $f3f4_2) (get_local $f8f9_38))))))
(set_local $h8 (i64.add (get_local $f0f8_2) (i64.add (get_local $f1f7_4) (i64.add (get_local $f2f6_2) (i64.add (get_local $f3f5_4) (i64.add (get_local $f4f4) (get_local $f9f9_38)))))))
(set_local $h9 (i64.add (get_local $f0f9_2) (i64.add (get_local $f1f8_2) (i64.add (get_local $f2f7_2) (i64.add (get_local $f3f6_2) (get_local $f4f5_2 ))))))
(br_if $end (i32.eq (get_local $count) (get_local $repeat)))
(set_local $count (i32.add (get_local $count) (i32.const 1)))
(br $again)))
(if (i32.eq (get_local $double) (i32.const 1))
(then
(set_local $h0 (i64.add (get_local $h0) (get_local $h0)))
(set_local $h1 (i64.add (get_local $h1) (get_local $h1)))
(set_local $h2 (i64.add (get_local $h2) (get_local $h2)))
(set_local $h3 (i64.add (get_local $h3) (get_local $h3)))
(set_local $h4 (i64.add (get_local $h4) (get_local $h4)))
(set_local $h5 (i64.add (get_local $h5) (get_local $h5)))
(set_local $h6 (i64.add (get_local $h6) (get_local $h6)))
(set_local $h7 (i64.add (get_local $h7) (get_local $h7)))
(set_local $h8 (i64.add (get_local $h8) (get_local $h8)))
(set_local $h9 (i64.add (get_local $h9) (get_local $h9)))))
(set_local $carry0 (i64.shr_s (i64.add (get_local $h0) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
(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)))))
(set_local $carry4 (i64.shr_s (i64.add (get_local $h4) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
(set_local $h5 (i64.add (get_local $h5) (get_local $carry4)))
(set_local $h4 (i64.sub (get_local $h4) (i64.mul (get_local $carry4) (i64.shl (i64.const 1) (i64.const 26)))))
(set_local $carry1 (i64.shr_s (i64.add (get_local $h1) (i64.shl (i64.const 1) (i64.const 24))) (i64.const 25)))
(set_local $h2 (i64.add (get_local $h2) (get_local $carry1)))
(set_local $h1 (i64.sub (get_local $h1) (i64.mul (get_local $carry1) (i64.shl (i64.const 1) (i64.const 25)))))
(set_local $carry5 (i64.shr_s (i64.add (get_local $h5) (i64.shl (i64.const 1) (i64.const 24))) (i64.const 25)))
(set_local $h6 (i64.add (get_local $h6) (get_local $carry5)))
(set_local $h5 (i64.sub (get_local $h5) (i64.mul (get_local $carry5) (i64.shl (i64.const 1) (i64.const 25)))))
(set_local $carry2 (i64.shr_s (i64.add (get_local $h2) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
(set_local $h3 (i64.add (get_local $h3) (get_local $carry2)))
(set_local $h2 (i64.sub (get_local $h2) (i64.mul (get_local $carry2) (i64.shl (i64.const 1) (i64.const 26)))))
(set_local $carry6 (i64.shr_s (i64.add (get_local $h6) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
(set_local $h7 (i64.add (get_local $h7) (get_local $carry6)))
(set_local $h6 (i64.sub (get_local $h6) (i64.mul (get_local $carry6) (i64.shl (i64.const 1) (i64.const 26)))))
(set_local $carry3 (i64.shr_s (i64.add (get_local $h3) (i64.shl (i64.const 1) (i64.const 24))) (i64.const 25)))
(set_local $h4 (i64.add (get_local $h4) (get_local $carry3)))
(set_local $h3 (i64.sub (get_local $h3) (i64.mul (get_local $carry3) (i64.shl (i64.const 1) (i64.const 25)))))
(set_local $carry7 (i64.shr_s (i64.add (get_local $h7) (i64.shl (i64.const 1) (i64.const 24))) (i64.const 25)))
(set_local $h8 (i64.add (get_local $h8) (get_local $carry7)))
(set_local $h7 (i64.sub (get_local $h7) (i64.mul (get_local $carry7) (i64.shl (i64.const 1) (i64.const 25)))))
(set_local $carry4 (i64.shr_s (i64.add (get_local $h4) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
(set_local $h5 (i64.add (get_local $h5) (get_local $carry4)))
(set_local $h4 (i64.sub (get_local $h4) (i64.mul (get_local $carry4) (i64.shl (i64.const 1) (i64.const 26)))))
(set_local $carry8 (i64.shr_s (i64.add (get_local $h8) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
(set_local $h9 (i64.add (get_local $h9) (get_local $carry8)))
(set_local $h8 (i64.sub (get_local $h8) (i64.mul (get_local $carry8) (i64.shl (i64.const 1) (i64.const 26)))))
(set_local $carry9 (i64.shr_s (i64.add (get_local $h9) (i64.shl (i64.const 1) (i64.const 24))) (i64.const 25)))
(set_local $h0 (i64.add (get_local $h0) (i64.mul (get_local $carry9) (i64.const 19))))
(set_local $h9 (i64.sub (get_local $h9) (i64.mul (get_local $carry9) (i64.shl (i64.const 1) (i64.const 25)))))
(set_local $carry0 (i64.shr_s (i64.add (get_local $h0) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
(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)))
(func $sq (export "sq") (param $h i32) (param $f i32) (param $double i32) (param $repeat i32)
(i64.load32_u offset=0 (get_local $f))
(i64.load32_u offset=4 (get_local $f))
(i64.load32_u offset=8 (get_local $f))
(i64.load32_u offset=12 (get_local $f))
(i64.load32_u offset=16 (get_local $f))
(i64.load32_u offset=20 (get_local $f))
(i64.load32_u offset=24 (get_local $f))
(i64.load32_u offset=28 (get_local $f))
(i64.load32_u offset=32 (get_local $f))
(i64.load32_u offset=36 (get_local $f))
(get_local $double)
(get_local $repeat)
(get_local $h)
(call $fe_sq)))

61
fe25519_25/sc25519_mul.js Normal file
View File

@ -0,0 +1,61 @@
module.exports = loadWebAssembly
loadWebAssembly.supported = typeof WebAssembly !== 'undefined'
function loadWebAssembly (opts) {
if (!loadWebAssembly.supported) return null
var imp = opts && opts.imports
var wasm = toUint8Array('AGFzbQEAAAABIwJgGX9+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn4AYAN/f38AAg4BAmpzBXRhYmxlAXAAAQMCAQEFAwEAAQcYAgZtZW1vcnkCAAtzYzI1NTE5X211bAAACugPAeUPAUh+IAE1AgAhBCABNQIEIQUgATUCCCEGIAE1AgwhByABNQIQIQggATUCFCEJIAE1AhghCiABNQIcIQsgATUCICEMIAE1AiQhDSABNQIoIQ4gATUCLCEPIAI1AgAhECACNQIEIREgAjUCCCESIAI1AgwhEyACNQIQIRQgAjUCFCEVIAI1AhghFiACNQIcIRcgAjUCICEYIAI1AiQhGSACNQIoIRogAjUCLCEbIASnrCEEIAWnrCEFIAanrCEGIAenrCEHIAinrCEIIAmnrCEJIAqnrCEKIAunrCELIAynrCEMIA2nrCENIA6nrCEOIA+nrCEPIBCnrCEQIBGnrCERIBKnrCESIBOnrCETIBSnrCEUIBWnrCEVIBanrCEWIBenrCEXIBinrCEYIBmnrCEZIBqnrCEaIBunrCEbIAQgEH4hHCAEIBF+IAUgEH58IR0gBCASfiAFIBF+IAYgEH58fCEeIAQgE34gBSASfiAGIBF+IAcgEH58fHwhHyAEIBR+IAUgE34gBiASfiAHIBF+IAggEH58fHx8ISAgBCAVfiAFIBR+IAYgE34gByASfiAIIBF+IAkgEH58fHx8fCEhIAQgFn4gBSAVfiAGIBR+IAcgE34gCCASfiAJIBF+IAogEH58fHx8fHwhIiAEIBd+IAUgFn4gBiAVfiAHIBR+IAggE34gCSASfiAKIBF+IAsgEH58fHx8fHx8ISMgBCAYfiAFIBd+IAYgFn4gByAVfiAIIBR+IAkgE34gCiASfiALIBF+IAwgEH58fHx8fHx8fCEkIAQgGX4gBSAYfiAGIBd+IAcgFn4gCCAVfiAJIBR+IAogE34gCyASfiAMIBF+IA0gEH58fHx8fHx8fHwhJSAEIBp+IAUgGX4gBiAYfiAHIBd+IAggFn4gCSAVfiAKIBR+IAsgE34gDCASfiANIBF+IA4gEH58fHx8fHx8fHx8ISYgBCAbfiAFIBp+IAYgGX4gByAYfiAIIBd+IAkgFn4gCiAVfiALIBR+IAwgE34gDSASfiAOIBF+IA8gEH58fHx8fHx8fHx8fCEnIAUgG34gBiAafiAHIBl+IAggGH4gCSAXfiAKIBZ+IAsgFX4gDCAUfiANIBN+IA4gEn4gDyARfnx8fHx8fHx8fHwhKCAGIBt+IAcgGn4gCCAZfiAJIBh+IAogF34gCyAWfiAMIBV+IA0gFH4gDiATfiAPIBJ+fHx8fHx8fHx8ISkgByAbfiAIIBp+IAkgGX4gCiAYfiALIBd+IAwgFn4gDSAVfiAOIBR+IA8gE358fHx8fHx8fCEqIAggG34gCSAafiAKIBl+IAsgGH4gDCAXfiANIBZ+IA4gFX4gDyAUfnx8fHx8fHwhKyAJIBt+IAogGn4gCyAZfiAMIBh+IA0gF34gDiAWfiAPIBV+fHx8fHx8ISwgCiAbfiALIBp+IAwgGX4gDSAYfiAOIBd+IA8gFn58fHx8fCEtIAsgG34gDCAafiANIBl+IA4gGH4gDyAXfnx8fHwhLiAMIBt+IA0gGn4gDiAZfiAPIBh+fHx8IS8gDSAbfiAOIBp+IA8gGX58fCEwIA4gG34gDyAafnwhMSAPIBt+ITJCACEzIBxCAUIUhnxCFYchNCAdIDR8IR0gHCA0QgFCFYZ+fSEcIB5CAUIUhnxCFYchNiAfIDZ8IR8gHiA2QgFCFYZ+fSEeICBCAUIUhnxCFYchOCAhIDh8ISEgICA4QgFCFYZ+fSEgICJCAUIUhnxCFYchOiAjIDp8ISMgIiA6QgFCFYZ+fSEiICRCAUIUhnxCFYchPCAlIDx8ISUgJCA8QgFCFYZ+fSEkICZCAUIUhnxCFYchPiAnID58IScgJiA+QgFCFYZ+fSEmIChCAUIUhnxCFYchQCApIEB8ISkgKCBAQgFCFYZ+fSEoICpCAUIUhnxCFYchQiArIEJ8ISsgKiBCQgFCFYZ+fSEqICxCAUIUhnxCFYchRCAtIER8IS0gLCBEQgFCFYZ+fSEsIC5CAUIUhnxCFYchRiAvIEZ8IS8gLiBGQgFCFYZ+fSEuIDBCAUIUhnxCFYchSCAxIEh8ITEgMCBIQgFCFYZ+fSEwIDJCAUIUhnxCFYchSiAzIEp8ITMgMiBKQgFCFYZ+fSEyIB1CAUIUhnxCFYchNSAeIDV8IR4gHSA1QgFCFYZ+fSEdIB9CAUIUhnxCFYchNyAgIDd8ISAgHyA3QgFCFYZ+fSEfICFCAUIUhnxCFYchOSAiIDl8ISIgISA5QgFCFYZ+fSEhICNCAUIUhnxCFYchOyAkIDt8ISQgIyA7QgFCFYZ+fSEjICVCAUIUhnxCFYchPSAmID18ISYgJSA9QgFCFYZ+fSElICdCAUIUhnxCFYchPyAoID98ISggJyA/QgFCFYZ+fSEnIClCAUIUhnxCFYchQSAqIEF8ISogKSBBQgFCFYZ+fSEpICtCAUIUhnxCFYchQyAsIEN8ISwgKyBDQgFCFYZ+fSErIC1CAUIUhnxCFYchRSAuIEV8IS4gLSBFQgFCFYZ+fSEtIC9CAUIUhnxCFYchRyAwIEd8ITAgLyBHQgFCFYZ+fSEvIDFCAUIUhnxCFYchSSAyIEl8ITIgMSBJQgFCFYZ+fSExIAAgHCAdIB4gHyAgICEgIiAjICQgJSAmICcgKCApICogKyAsIC0gLiAvIDAgMSAyIDNBABEAAAs=')
var ready = null
var mod = {
buffer: wasm,
memory: null,
exports: null,
realloc: realloc,
onload: onload
}
onload(function () {})
return mod
function realloc (size) {
mod.exports.memory.grow(Math.max(0, Math.ceil(Math.abs(size - mod.memory.length) / 65536)))
mod.memory = new Uint8Array(mod.exports.memory.buffer)
}
function onload (cb) {
if (mod.exports) return cb()
if (ready) {
ready.then(cb.bind(null, null)).catch(cb)
return
}
try {
if (opts && opts.async) throw new Error('async')
setup({instance: new WebAssembly.Instance(new WebAssembly.Module(wasm), imp)})
} catch (err) {
ready = WebAssembly.instantiate(wasm, imp).then(setup)
}
onload(cb)
}
function setup (w) {
mod.exports = w.instance.exports
mod.memory = mod.exports.memory && mod.exports.memory.buffer && new Uint8Array(mod.exports.memory.buffer)
}
}
function toUint8Array (s) {
if (typeof atob === 'function') return new Uint8Array(atob(s).split('').map(charCodeAt))
return (require('buf' + 'fer').Buffer).from(s, 'base64')
}
function charCodeAt (c) {
return c.charCodeAt(0)
}

308
fe25519_25/sc25519_mul.wat Normal file
View File

@ -0,0 +1,308 @@
(module
(import "js" "table" (table 1 anyfunc))
(type $to_void (func
(param $s i32)
(param $s0 i64)
(param $s1 i64)
(param $s2 i64)
(param $s3 i64)
(param $s4 i64)
(param $s5 i64)
(param $s6 i64)
(param $s7 i64)
(param $s8 i64)
(param $s9 i64)
(param $s10 i64)
(param $s11 i64)
(param $s12 i64)
(param $s13 i64)
(param $s14 i64)
(param $s15 i64)
(param $s16 i64)
(param $s17 i64)
(param $s18 i64)
(param $s19 i64)
(param $s20 i64)
(param $s21 i64)
(param $s22 i64)
(param $s23 i64)))
(memory $0 1)
(export "memory" (memory $0))
(func $sc25519_mul (export "sc25519_mul") (param $s i32) (param $a i32) (param $b i32)
(local $tmp i64)
(local $a0 i64)
(local $a1 i64)
(local $a2 i64)
(local $a3 i64)
(local $a4 i64)
(local $a5 i64)
(local $a6 i64)
(local $a7 i64)
(local $a8 i64)
(local $a9 i64)
(local $a10 i64)
(local $a11 i64)
(local $b0 i64)
(local $b1 i64)
(local $b2 i64)
(local $b3 i64)
(local $b4 i64)
(local $b5 i64)
(local $b6 i64)
(local $b7 i64)
(local $b8 i64)
(local $b9 i64)
(local $b10 i64)
(local $b11 i64)
(local $s0 i64)
(local $s1 i64)
(local $s2 i64)
(local $s3 i64)
(local $s4 i64)
(local $s5 i64)
(local $s6 i64)
(local $s7 i64)
(local $s8 i64)
(local $s9 i64)
(local $s10 i64)
(local $s11 i64)
(local $s12 i64)
(local $s13 i64)
(local $s14 i64)
(local $s15 i64)
(local $s16 i64)
(local $s17 i64)
(local $s18 i64)
(local $s19 i64)
(local $s20 i64)
(local $s21 i64)
(local $s22 i64)
(local $s23 i64)
(local $carry0 i64)
(local $carry1 i64)
(local $carry2 i64)
(local $carry3 i64)
(local $carry4 i64)
(local $carry5 i64)
(local $carry6 i64)
(local $carry7 i64)
(local $carry8 i64)
(local $carry9 i64)
(local $carry10 i64)
(local $carry11 i64)
(local $carry12 i64)
(local $carry13 i64)
(local $carry14 i64)
(local $carry15 i64)
(local $carry16 i64)
(local $carry17 i64)
(local $carry18 i64)
(local $carry19 i64)
(local $carry20 i64)
(local $carry21 i64)
(local $carry22 i64)
(set_local $a0 (i64.load32_u offset=0 (get_local $a)))
(set_local $a1 (i64.load32_u offset=4 (get_local $a)))
(set_local $a2 (i64.load32_u offset=8 (get_local $a)))
(set_local $a3 (i64.load32_u offset=12 (get_local $a)))
(set_local $a4 (i64.load32_u offset=16 (get_local $a)))
(set_local $a5 (i64.load32_u offset=20 (get_local $a)))
(set_local $a6 (i64.load32_u offset=24 (get_local $a)))
(set_local $a7 (i64.load32_u offset=28 (get_local $a)))
(set_local $a8 (i64.load32_u offset=32 (get_local $a)))
(set_local $a9 (i64.load32_u offset=36 (get_local $a)))
(set_local $a10 (i64.load32_u offset=40 (get_local $a)))
(set_local $a11 (i64.load32_u offset=44 (get_local $a)))
(set_local $b0 (i64.load32_u offset=0 (get_local $b)))
(set_local $b1 (i64.load32_u offset=4 (get_local $b)))
(set_local $b2 (i64.load32_u offset=8 (get_local $b)))
(set_local $b3 (i64.load32_u offset=12 (get_local $b)))
(set_local $b4 (i64.load32_u offset=16 (get_local $b)))
(set_local $b5 (i64.load32_u offset=20 (get_local $b)))
(set_local $b6 (i64.load32_u offset=24 (get_local $b)))
(set_local $b7 (i64.load32_u offset=28 (get_local $b)))
(set_local $b8 (i64.load32_u offset=32 (get_local $b)))
(set_local $b9 (i64.load32_u offset=36 (get_local $b)))
(set_local $b10 (i64.load32_u offset=40 (get_local $b)))
(set_local $b11 (i64.load32_u offset=44 (get_local $b)))
(set_local $a0 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a0))))
(set_local $a1 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a1))))
(set_local $a2 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a2))))
(set_local $a3 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a3))))
(set_local $a4 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a4))))
(set_local $a5 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a5))))
(set_local $a6 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a6))))
(set_local $a7 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a7))))
(set_local $a8 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a8))))
(set_local $a9 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a9))))
(set_local $a10 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a10))))
(set_local $a11 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a11))))
(set_local $b0 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b0))))
(set_local $b1 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b1))))
(set_local $b2 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b2))))
(set_local $b3 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b3))))
(set_local $b4 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b4))))
(set_local $b5 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b5))))
(set_local $b6 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b6))))
(set_local $b7 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b7))))
(set_local $b8 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b8))))
(set_local $b9 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b9))))
(set_local $b10 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b10))))
(set_local $b11 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b11))))
(set_local $s0 (i64.mul (get_local $a0) (get_local $b0)))
(set_local $s1 (i64.add (i64.mul (get_local $a0) (get_local $b1 )) (i64.mul (get_local $a1) (get_local $b0))))
(set_local $s2 (i64.add (i64.mul (get_local $a0) (get_local $b2 )) (i64.add (i64.mul (get_local $a1) (get_local $b1 )) (i64.mul (get_local $a2) (get_local $b0)))))
(set_local $s3 (i64.add (i64.mul (get_local $a0) (get_local $b3 )) (i64.add (i64.mul (get_local $a1) (get_local $b2 )) (i64.add (i64.mul (get_local $a2) (get_local $b1)) (i64.mul (get_local $a3) (get_local $b0))))))
(set_local $s4 (i64.add (i64.mul (get_local $a0) (get_local $b4 )) (i64.add (i64.mul (get_local $a1) (get_local $b3 )) (i64.add (i64.mul (get_local $a2) (get_local $b2)) (i64.add (i64.mul (get_local $a3) (get_local $b1)) (i64.mul (get_local $a4) (get_local $b0)))))))
(set_local $s5 (i64.add (i64.mul (get_local $a0) (get_local $b5 )) (i64.add (i64.mul (get_local $a1) (get_local $b4 )) (i64.add (i64.mul (get_local $a2) (get_local $b3)) (i64.add (i64.mul (get_local $a3) (get_local $b2)) (i64.add (i64.mul (get_local $a4) (get_local $b1)) (i64.mul (get_local $a5) (get_local $b0))))))))
(set_local $s6 (i64.add (i64.mul (get_local $a0) (get_local $b6 )) (i64.add (i64.mul (get_local $a1) (get_local $b5 )) (i64.add (i64.mul (get_local $a2) (get_local $b4)) (i64.add (i64.mul (get_local $a3) (get_local $b3)) (i64.add (i64.mul (get_local $a4) (get_local $b2)) (i64.add (i64.mul (get_local $a5) (get_local $b1)) (i64.mul (get_local $a6) (get_local $b0)))))))))
(set_local $s7 (i64.add (i64.mul (get_local $a0) (get_local $b7 )) (i64.add (i64.mul (get_local $a1) (get_local $b6 )) (i64.add (i64.mul (get_local $a2) (get_local $b5)) (i64.add (i64.mul (get_local $a3) (get_local $b4)) (i64.add (i64.mul (get_local $a4) (get_local $b3)) (i64.add (i64.mul (get_local $a5) (get_local $b2)) (i64.add (i64.mul (get_local $a6) (get_local $b1)) (i64.mul (get_local $a7) (get_local $b0))))))))))
(set_local $s8 (i64.add (i64.mul (get_local $a0) (get_local $b8 )) (i64.add (i64.mul (get_local $a1) (get_local $b7 )) (i64.add (i64.mul (get_local $a2) (get_local $b6)) (i64.add (i64.mul (get_local $a3) (get_local $b5)) (i64.add (i64.mul (get_local $a4) (get_local $b4)) (i64.add (i64.mul (get_local $a5) (get_local $b3)) (i64.add (i64.mul (get_local $a6) (get_local $b2)) (i64.add (i64.mul (get_local $a7) (get_local $b1)) (i64.mul (get_local $a8) (get_local $b0)))))))))))
(set_local $s9 (i64.add (i64.mul (get_local $a0) (get_local $b9 )) (i64.add (i64.mul (get_local $a1) (get_local $b8 )) (i64.add (i64.mul (get_local $a2) (get_local $b7)) (i64.add (i64.mul (get_local $a3) (get_local $b6)) (i64.add (i64.mul (get_local $a4) (get_local $b5)) (i64.add (i64.mul (get_local $a5) (get_local $b4)) (i64.add (i64.mul (get_local $a6) (get_local $b3)) (i64.add (i64.mul (get_local $a7) (get_local $b2)) (i64.add (i64.mul (get_local $a8) (get_local $b1)) (i64.mul (get_local $a9) (get_local $b0))))))))))))
(set_local $s10 (i64.add (i64.mul (get_local $a0) (get_local $b10)) (i64.add (i64.mul (get_local $a1) (get_local $b9 )) (i64.add (i64.mul (get_local $a2) (get_local $b8)) (i64.add (i64.mul (get_local $a3) (get_local $b7)) (i64.add (i64.mul (get_local $a4) (get_local $b6)) (i64.add (i64.mul (get_local $a5) (get_local $b5)) (i64.add (i64.mul (get_local $a6) (get_local $b4)) (i64.add (i64.mul (get_local $a7) (get_local $b3)) (i64.add (i64.mul (get_local $a8) (get_local $b2)) (i64.add (i64.mul (get_local $a9) (get_local $b1)) (i64.mul (get_local $a10) (get_local $b0)))))))))))))
(set_local $s11 (i64.add (i64.mul (get_local $a0) (get_local $b11)) (i64.add (i64.mul (get_local $a1) (get_local $b10)) (i64.add (i64.mul (get_local $a2) (get_local $b9)) (i64.add (i64.mul (get_local $a3) (get_local $b8)) (i64.add (i64.mul (get_local $a4) (get_local $b7)) (i64.add (i64.mul (get_local $a5) (get_local $b6)) (i64.add (i64.mul (get_local $a6) (get_local $b5)) (i64.add (i64.mul (get_local $a7) (get_local $b4)) (i64.add (i64.mul (get_local $a8) (get_local $b3)) (i64.add (i64.mul (get_local $a9) (get_local $b2)) (i64.add (i64.mul (get_local $a10) (get_local $b1)) (i64.mul (get_local $a11) (get_local $b0))))))))))))))
(set_local $s12 (i64.add (i64.mul (get_local $a1) (get_local $b11)) (i64.add (i64.mul (get_local $a2) (get_local $b10)) (i64.add (i64.mul (get_local $a3) (get_local $b9)) (i64.add (i64.mul (get_local $a4) (get_local $b8)) (i64.add (i64.mul (get_local $a5) (get_local $b7)) (i64.add (i64.mul (get_local $a6) (get_local $b6)) (i64.add (i64.mul (get_local $a7) (get_local $b5)) (i64.add (i64.mul (get_local $a8) (get_local $b4)) (i64.add (i64.mul (get_local $a9) (get_local $b3)) (i64.add (i64.mul (get_local $a10) (get_local $b2)) (i64.mul (get_local $a11) (get_local $b1)))))))))))))
(set_local $s13 (i64.add (i64.mul (get_local $a2) (get_local $b11)) (i64.add (i64.mul (get_local $a3) (get_local $b10)) (i64.add (i64.mul (get_local $a4) (get_local $b9)) (i64.add (i64.mul (get_local $a5) (get_local $b8)) (i64.add (i64.mul (get_local $a6) (get_local $b7)) (i64.add (i64.mul (get_local $a7) (get_local $b6)) (i64.add (i64.mul (get_local $a8) (get_local $b5)) (i64.add (i64.mul (get_local $a9) (get_local $b4)) (i64.add (i64.mul (get_local $a10) (get_local $b3)) (i64.mul (get_local $a11) (get_local $b2))))))))))))
(set_local $s14 (i64.add (i64.mul (get_local $a3) (get_local $b11)) (i64.add (i64.mul (get_local $a4) (get_local $b10)) (i64.add (i64.mul (get_local $a5) (get_local $b9)) (i64.add (i64.mul (get_local $a6) (get_local $b8)) (i64.add (i64.mul (get_local $a7) (get_local $b7)) (i64.add (i64.mul (get_local $a8) (get_local $b6)) (i64.add (i64.mul (get_local $a9) (get_local $b5)) (i64.add (i64.mul (get_local $a10) (get_local $b4)) (i64.mul (get_local $a11) (get_local $b3)))))))))))
(set_local $s15 (i64.add (i64.mul (get_local $a4) (get_local $b11)) (i64.add (i64.mul (get_local $a5) (get_local $b10)) (i64.add (i64.mul (get_local $a6) (get_local $b9)) (i64.add (i64.mul (get_local $a7) (get_local $b8)) (i64.add (i64.mul (get_local $a8) (get_local $b7)) (i64.add (i64.mul (get_local $a9) (get_local $b6)) (i64.add (i64.mul (get_local $a10) (get_local $b5)) (i64.mul (get_local $a11) (get_local $b4))))))))))
(set_local $s16 (i64.add (i64.mul (get_local $a5) (get_local $b11)) (i64.add (i64.mul (get_local $a6) (get_local $b10)) (i64.add (i64.mul (get_local $a7) (get_local $b9)) (i64.add (i64.mul (get_local $a8) (get_local $b8)) (i64.add (i64.mul (get_local $a9) (get_local $b7)) (i64.add (i64.mul (get_local $a10) (get_local $b6)) (i64.mul (get_local $a11) (get_local $b5)))))))))
(set_local $s17 (i64.add (i64.mul (get_local $a6) (get_local $b11)) (i64.add (i64.mul (get_local $a7) (get_local $b10)) (i64.add (i64.mul (get_local $a8) (get_local $b9)) (i64.add (i64.mul (get_local $a9) (get_local $b8)) (i64.add (i64.mul (get_local $a10) (get_local $b7)) (i64.mul (get_local $a11) (get_local $b6))))))))
(set_local $s18 (i64.add (i64.mul (get_local $a7) (get_local $b11)) (i64.add (i64.mul (get_local $a8) (get_local $b10)) (i64.add (i64.mul (get_local $a9) (get_local $b9)) (i64.add (i64.mul (get_local $a10) (get_local $b8)) (i64.mul (get_local $a11) (get_local $b7)))))))
(set_local $s19 (i64.add (i64.mul (get_local $a8) (get_local $b11)) (i64.add (i64.mul (get_local $a9) (get_local $b10)) (i64.add (i64.mul (get_local $a10) (get_local $b9)) (i64.mul (get_local $a11) (get_local $b8))))))
(set_local $s20 (i64.add (i64.mul (get_local $a9) (get_local $b11)) (i64.add (i64.mul (get_local $a10) (get_local $b10)) (i64.mul (get_local $a11) (get_local $b9)))))
(set_local $s21 (i64.add (i64.mul (get_local $a10) (get_local $b11)) (i64.mul (get_local $a11) (get_local $b10))))
(set_local $s22 (i64.mul (get_local $a11) (get_local $b11)))
(set_local $s23 (i64.const 0))
(set_local $carry0 (i64.shr_s (i64.add (get_local $s0) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s1 (i64.add (get_local $s1) (get_local $carry0)))
(set_local $s0 (i64.sub (get_local $s0) (i64.mul (get_local $carry0) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry2 (i64.shr_s (i64.add (get_local $s2) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s3 (i64.add (get_local $s3) (get_local $carry2)))
(set_local $s2 (i64.sub (get_local $s2) (i64.mul (get_local $carry2) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry4 (i64.shr_s (i64.add (get_local $s4) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s5 (i64.add (get_local $s5) (get_local $carry4)))
(set_local $s4 (i64.sub (get_local $s4) (i64.mul (get_local $carry4) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry6 (i64.shr_s (i64.add (get_local $s6) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s7 (i64.add (get_local $s7) (get_local $carry6)))
(set_local $s6 (i64.sub (get_local $s6) (i64.mul (get_local $carry6) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry8 (i64.shr_s (i64.add (get_local $s8) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s9 (i64.add (get_local $s9) (get_local $carry8)))
(set_local $s8 (i64.sub (get_local $s8) (i64.mul (get_local $carry8) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry10 (i64.shr_s (i64.add (get_local $s10) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s11 (i64.add (get_local $s11) (get_local $carry10)))
(set_local $s10 (i64.sub (get_local $s10) (i64.mul (get_local $carry10) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry12 (i64.shr_s (i64.add (get_local $s12) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s13 (i64.add (get_local $s13) (get_local $carry12)))
(set_local $s12 (i64.sub (get_local $s12) (i64.mul (get_local $carry12) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry14 (i64.shr_s (i64.add (get_local $s14) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s15 (i64.add (get_local $s15) (get_local $carry14)))
(set_local $s14 (i64.sub (get_local $s14) (i64.mul (get_local $carry14) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry16 (i64.shr_s (i64.add (get_local $s16) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s17 (i64.add (get_local $s17) (get_local $carry16)))
(set_local $s16 (i64.sub (get_local $s16) (i64.mul (get_local $carry16) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry18 (i64.shr_s (i64.add (get_local $s18) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s19 (i64.add (get_local $s19) (get_local $carry18)))
(set_local $s18 (i64.sub (get_local $s18) (i64.mul (get_local $carry18) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry20 (i64.shr_s (i64.add (get_local $s20) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s21 (i64.add (get_local $s21) (get_local $carry20)))
(set_local $s20 (i64.sub (get_local $s20) (i64.mul (get_local $carry20) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry22 (i64.shr_s (i64.add (get_local $s22) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s23 (i64.add (get_local $s23) (get_local $carry22)))
(set_local $s22 (i64.sub (get_local $s22) (i64.mul (get_local $carry22) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry1 (i64.shr_s (i64.add (get_local $s1) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s2 (i64.add (get_local $s2) (get_local $carry1)))
(set_local $s1 (i64.sub (get_local $s1) (i64.mul (get_local $carry1) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry3 (i64.shr_s (i64.add (get_local $s3) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s4 (i64.add (get_local $s4) (get_local $carry3)))
(set_local $s3 (i64.sub (get_local $s3) (i64.mul (get_local $carry3) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry5 (i64.shr_s (i64.add (get_local $s5) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s6 (i64.add (get_local $s6) (get_local $carry5)))
(set_local $s5 (i64.sub (get_local $s5) (i64.mul (get_local $carry5) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry7 (i64.shr_s (i64.add (get_local $s7) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s8 (i64.add (get_local $s8) (get_local $carry7)))
(set_local $s7 (i64.sub (get_local $s7) (i64.mul (get_local $carry7) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry9 (i64.shr_s (i64.add (get_local $s9) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s10 (i64.add (get_local $s10) (get_local $carry9)))
(set_local $s9 (i64.sub (get_local $s9) (i64.mul (get_local $carry9) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry11 (i64.shr_s (i64.add (get_local $s11) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s12 (i64.add (get_local $s12) (get_local $carry11)))
(set_local $s11 (i64.sub (get_local $s11) (i64.mul (get_local $carry11) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry13 (i64.shr_s (i64.add (get_local $s13) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s14 (i64.add (get_local $s14) (get_local $carry13)))
(set_local $s13 (i64.sub (get_local $s13) (i64.mul (get_local $carry13) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry15 (i64.shr_s (i64.add (get_local $s15) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s16 (i64.add (get_local $s16) (get_local $carry15)))
(set_local $s15 (i64.sub (get_local $s15) (i64.mul (get_local $carry15) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry17 (i64.shr_s (i64.add (get_local $s17) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s18 (i64.add (get_local $s18) (get_local $carry17)))
(set_local $s17 (i64.sub (get_local $s17) (i64.mul (get_local $carry17) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry19 (i64.shr_s (i64.add (get_local $s19) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s20 (i64.add (get_local $s20) (get_local $carry19)))
(set_local $s19 (i64.sub (get_local $s19) (i64.mul (get_local $carry19) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry21 (i64.shr_s (i64.add (get_local $s21) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s22 (i64.add (get_local $s22) (get_local $carry21)))
(set_local $s21 (i64.sub (get_local $s21) (i64.mul (get_local $carry21) (i64.shl (i64.const 1) (i64.const 21)))))
(get_local $s)
(get_local $s0)
(get_local $s1)
(get_local $s2)
(get_local $s3)
(get_local $s4)
(get_local $s5)
(get_local $s6)
(get_local $s7)
(get_local $s8)
(get_local $s9)
(get_local $s10)
(get_local $s11)
(get_local $s12)
(get_local $s13)
(get_local $s14)
(get_local $s15)
(get_local $s16)
(get_local $s17)
(get_local $s18)
(get_local $s19)
(get_local $s20)
(get_local $s21)
(get_local $s22)
(get_local $s23)
(i32.const 0)
(call_indirect (type $to_void))))
;; TODO: export muladd and call in reduce

View File

@ -0,0 +1,61 @@
module.exports = loadWebAssembly
loadWebAssembly.supported = typeof WebAssembly !== 'undefined'
function loadWebAssembly (opts) {
if (!loadWebAssembly.supported) return null
var imp = opts && opts.imports
var wasm = toUint8Array('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')
var ready = null
var mod = {
buffer: wasm,
memory: null,
exports: null,
realloc: realloc,
onload: onload
}
onload(function () {})
return mod
function realloc (size) {
mod.exports.memory.grow(Math.max(0, Math.ceil(Math.abs(size - mod.memory.length) / 65536)))
mod.memory = new Uint8Array(mod.exports.memory.buffer)
}
function onload (cb) {
if (mod.exports) return cb()
if (ready) {
ready.then(cb.bind(null, null)).catch(cb)
return
}
try {
if (opts && opts.async) throw new Error('async')
setup({instance: new WebAssembly.Instance(new WebAssembly.Module(wasm), imp)})
} catch (err) {
ready = WebAssembly.instantiate(wasm, imp).then(setup)
}
onload(cb)
}
function setup (w) {
mod.exports = w.instance.exports
mod.memory = mod.exports.memory && mod.exports.memory.buffer && new Uint8Array(mod.exports.memory.buffer)
}
}
function toUint8Array (s) {
if (typeof atob === 'function') return new Uint8Array(atob(s).split('').map(charCodeAt))
return (require('buf' + 'fer').Buffer).from(s, 'base64')
}
function charCodeAt (c) {
return c.charCodeAt(0)
}

View File

@ -0,0 +1,373 @@
(module
(import "js" "table" (table 1 anyfunc))
(type $to_void (func
(param $s i32)
(param $s0 i64)
(param $s1 i64)
(param $s2 i64)
(param $s3 i64)
(param $s4 i64)
(param $s5 i64)
(param $s6 i64)
(param $s7 i64)
(param $s8 i64)
(param $s9 i64)
(param $s10 i64)
(param $s11 i64)
(param $s12 i64)
(param $s13 i64)
(param $s14 i64)
(param $s15 i64)
(param $s16 i64)
(param $s17 i64)
(param $s18 i64)
(param $s19 i64)
(param $s20 i64)
(param $s21 i64)
(param $s22 i64)
(param $s23 i64)))
(func $i32.log (import "debug" "log") (param i32))
(func $i32.log_tee (import "debug" "log_tee") (param i32) (result i32))
;; No i64 interop with JS yet - but maybe coming with WebAssembly BigInt
;; So we can instead fake this by splitting the i64 into two i32 limbs,
;; however these are WASM functions using i32x2.log:
(func $i32x2.log (import "debug" "log") (param i32) (param i32))
(func $f32.log (import "debug" "log") (param f32))
(func $f32.log_tee (import "debug" "log_tee") (param f32) (result f32))
(func $f64.log (import "debug" "log") (param f64))
(func $f64.log_tee (import "debug" "log_tee") (param f64) (result f64))
;; i64 logging by splitting into two i32 limbs
(func $i64.log
(param $0 i64)
(call $i32x2.log
;; Upper limb
(i32.wrap/i64
(i64.shr_s (get_local $0)
(i64.const 32)))
;; Lower limb
(i32.wrap/i64 (get_local $0))))
(func $i64.log_tee
(param $0 i64)
(result i64)
(call $i64.log (get_local $0))
(return (get_local $0)))
(memory $0 1)
(export "memory" (memory $0))
(func $sc25519_muladd (export "sc25519_muladd") (param $s i32) (param $a i32) (param $b i32) (param $c i32)
(local $tmp i64)
(local $a0 i64)
(local $a1 i64)
(local $a2 i64)
(local $a3 i64)
(local $a4 i64)
(local $a5 i64)
(local $a6 i64)
(local $a7 i64)
(local $a8 i64)
(local $a9 i64)
(local $a10 i64)
(local $a11 i64)
(local $b0 i64)
(local $b1 i64)
(local $b2 i64)
(local $b3 i64)
(local $b4 i64)
(local $b5 i64)
(local $b6 i64)
(local $b7 i64)
(local $b8 i64)
(local $b9 i64)
(local $b10 i64)
(local $b11 i64)
(local $c0 i64)
(local $c1 i64)
(local $c2 i64)
(local $c3 i64)
(local $c4 i64)
(local $c5 i64)
(local $c6 i64)
(local $c7 i64)
(local $c8 i64)
(local $c9 i64)
(local $c10 i64)
(local $c11 i64)
(local $s0 i64)
(local $s1 i64)
(local $s2 i64)
(local $s3 i64)
(local $s4 i64)
(local $s5 i64)
(local $s6 i64)
(local $s7 i64)
(local $s8 i64)
(local $s9 i64)
(local $s10 i64)
(local $s11 i64)
(local $s12 i64)
(local $s13 i64)
(local $s14 i64)
(local $s15 i64)
(local $s16 i64)
(local $s17 i64)
(local $s18 i64)
(local $s19 i64)
(local $s20 i64)
(local $s21 i64)
(local $s22 i64)
(local $s23 i64)
(local $carry0 i64)
(local $carry1 i64)
(local $carry2 i64)
(local $carry3 i64)
(local $carry4 i64)
(local $carry5 i64)
(local $carry6 i64)
(local $carry7 i64)
(local $carry8 i64)
(local $carry9 i64)
(local $carry10 i64)
(local $carry11 i64)
(local $carry12 i64)
(local $carry13 i64)
(local $carry14 i64)
(local $carry15 i64)
(local $carry16 i64)
(local $carry17 i64)
(local $carry18 i64)
(local $carry19 i64)
(local $carry20 i64)
(local $carry21 i64)
(local $carry22 i64)
(set_local $a0 (i64.load32_u offset=0 (get_local $a)))
(set_local $a1 (i64.load32_u offset=4 (get_local $a)))
(set_local $a2 (i64.load32_u offset=8 (get_local $a)))
(set_local $a3 (i64.load32_u offset=12 (get_local $a)))
(set_local $a4 (i64.load32_u offset=16 (get_local $a)))
(set_local $a5 (i64.load32_u offset=20 (get_local $a)))
(set_local $a6 (i64.load32_u offset=24 (get_local $a)))
(set_local $a7 (i64.load32_u offset=28 (get_local $a)))
(set_local $a8 (i64.load32_u offset=32 (get_local $a)))
(set_local $a9 (i64.load32_u offset=36 (get_local $a)))
(set_local $a10 (i64.load32_u offset=40 (get_local $a)))
(set_local $a11 (i64.load32_u offset=44 (get_local $a)))
(set_local $b0 (i64.load32_u offset=0 (get_local $b)))
(set_local $b1 (i64.load32_u offset=4 (get_local $b)))
(set_local $b2 (i64.load32_u offset=8 (get_local $b)))
(set_local $b3 (i64.load32_u offset=12 (get_local $b)))
(set_local $b4 (i64.load32_u offset=16 (get_local $b)))
(set_local $b5 (i64.load32_u offset=20 (get_local $b)))
(set_local $b6 (i64.load32_u offset=24 (get_local $b)))
(set_local $b7 (i64.load32_u offset=28 (get_local $b)))
(set_local $b8 (i64.load32_u offset=32 (get_local $b)))
(set_local $b9 (i64.load32_u offset=36 (get_local $b)))
(set_local $b10 (i64.load32_u offset=40 (get_local $b)))
(set_local $b11 (i64.load32_u offset=44 (get_local $b)))
(set_local $c0 (i64.load32_u offset=0 (get_local $c)))
(set_local $c1 (i64.load32_u offset=4 (get_local $c)))
(set_local $c2 (i64.load32_u offset=8 (get_local $c)))
(set_local $c3 (i64.load32_u offset=12 (get_local $c)))
(set_local $c4 (i64.load32_u offset=16 (get_local $c)))
(set_local $c5 (i64.load32_u offset=20 (get_local $c)))
(set_local $c6 (i64.load32_u offset=24 (get_local $c)))
(set_local $c7 (i64.load32_u offset=28 (get_local $c)))
(set_local $c8 (i64.load32_u offset=32 (get_local $c)))
(set_local $c9 (i64.load32_u offset=36 (get_local $c)))
(set_local $c10 (i64.load32_u offset=40 (get_local $c)))
(set_local $c11 (i64.load32_u offset=44 (get_local $c)))
(set_local $a0 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a0))))
(set_local $a1 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a1))))
(set_local $a2 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a2))))
(set_local $a3 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a3))))
(set_local $a4 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a4))))
(set_local $a5 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a5))))
(set_local $a6 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a6))))
(set_local $a7 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a7))))
(set_local $a8 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a8))))
(set_local $a9 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a9))))
(set_local $a10 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a10))))
(set_local $a11 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a11))))
(set_local $b0 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b0))))
(set_local $b1 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b1))))
(set_local $b2 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b2))))
(set_local $b3 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b3))))
(set_local $b4 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b4))))
(set_local $b5 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b5))))
(set_local $b6 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b6))))
(set_local $b7 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b7))))
(set_local $b8 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b8))))
(set_local $b9 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b9))))
(set_local $b10 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b10))))
(set_local $b11 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b11))))
(set_local $c0 (i64.extend_s/i32 (i32.wrap/i64 (get_local $c0))))
(set_local $c1 (i64.extend_s/i32 (i32.wrap/i64 (get_local $c1))))
(set_local $c2 (i64.extend_s/i32 (i32.wrap/i64 (get_local $c2))))
(set_local $c3 (i64.extend_s/i32 (i32.wrap/i64 (get_local $c3))))
(set_local $c4 (i64.extend_s/i32 (i32.wrap/i64 (get_local $c4))))
(set_local $c5 (i64.extend_s/i32 (i32.wrap/i64 (get_local $c5))))
(set_local $c6 (i64.extend_s/i32 (i32.wrap/i64 (get_local $c6))))
(set_local $c7 (i64.extend_s/i32 (i32.wrap/i64 (get_local $c7))))
(set_local $c8 (i64.extend_s/i32 (i32.wrap/i64 (get_local $c8))))
(set_local $c9 (i64.extend_s/i32 (i32.wrap/i64 (get_local $c9))))
(set_local $c10 (i64.extend_s/i32 (i32.wrap/i64 (get_local $c10))))
(set_local $c11 (i64.extend_s/i32 (i32.wrap/i64 (get_local $c11))))
(set_local $s0 (i64.add (get_local $c0 ) (i64.mul (get_local $a0) (get_local $b0))))
(set_local $s1 (i64.add (get_local $c1 ) (i64.add (i64.mul (get_local $a0) (get_local $b1 )) (i64.mul (get_local $a1) (get_local $b0)))))
(set_local $s2 (i64.add (get_local $c2 ) (i64.add (i64.mul (get_local $a0) (get_local $b2 )) (i64.add (i64.mul (get_local $a1) (get_local $b1 )) (i64.mul (get_local $a2) (get_local $b0))))))
(set_local $s3 (i64.add (get_local $c3 ) (i64.add (i64.mul (get_local $a0) (get_local $b3 )) (i64.add (i64.mul (get_local $a1) (get_local $b2 )) (i64.add (i64.mul (get_local $a2) (get_local $b1)) (i64.mul (get_local $a3) (get_local $b0)))))))
(set_local $s4 (i64.add (get_local $c4 ) (i64.add (i64.mul (get_local $a0) (get_local $b4 )) (i64.add (i64.mul (get_local $a1) (get_local $b3 )) (i64.add (i64.mul (get_local $a2) (get_local $b2)) (i64.add (i64.mul (get_local $a3) (get_local $b1)) (i64.mul (get_local $a4) (get_local $b0))))))))
(set_local $s5 (i64.add (get_local $c5 ) (i64.add (i64.mul (get_local $a0) (get_local $b5 )) (i64.add (i64.mul (get_local $a1) (get_local $b4 )) (i64.add (i64.mul (get_local $a2) (get_local $b3)) (i64.add (i64.mul (get_local $a3) (get_local $b2)) (i64.add (i64.mul (get_local $a4) (get_local $b1)) (i64.mul (get_local $a5) (get_local $b0)))))))))
(set_local $s6 (i64.add (get_local $c6 ) (i64.add (i64.mul (get_local $a0) (get_local $b6 )) (i64.add (i64.mul (get_local $a1) (get_local $b5 )) (i64.add (i64.mul (get_local $a2) (get_local $b4)) (i64.add (i64.mul (get_local $a3) (get_local $b3)) (i64.add (i64.mul (get_local $a4) (get_local $b2)) (i64.add (i64.mul (get_local $a5) (get_local $b1)) (i64.mul (get_local $a6) (get_local $b0))))))))))
(set_local $s7 (i64.add (get_local $c7 ) (i64.add (i64.mul (get_local $a0) (get_local $b7 )) (i64.add (i64.mul (get_local $a1) (get_local $b6 )) (i64.add (i64.mul (get_local $a2) (get_local $b5)) (i64.add (i64.mul (get_local $a3) (get_local $b4)) (i64.add (i64.mul (get_local $a4) (get_local $b3)) (i64.add (i64.mul (get_local $a5) (get_local $b2)) (i64.add (i64.mul (get_local $a6) (get_local $b1)) (i64.mul (get_local $a7) (get_local $b0)))))))))))
(set_local $s8 (i64.add (get_local $c8 ) (i64.add (i64.mul (get_local $a0) (get_local $b8 )) (i64.add (i64.mul (get_local $a1) (get_local $b7 )) (i64.add (i64.mul (get_local $a2) (get_local $b6)) (i64.add (i64.mul (get_local $a3) (get_local $b5)) (i64.add (i64.mul (get_local $a4) (get_local $b4)) (i64.add (i64.mul (get_local $a5) (get_local $b3)) (i64.add (i64.mul (get_local $a6) (get_local $b2)) (i64.add (i64.mul (get_local $a7) (get_local $b1)) (i64.mul (get_local $a8) (get_local $b0))))))))))))
(set_local $s9 (i64.add (get_local $c9 ) (i64.add (i64.mul (get_local $a0) (get_local $b9 )) (i64.add (i64.mul (get_local $a1) (get_local $b8 )) (i64.add (i64.mul (get_local $a2) (get_local $b7)) (i64.add (i64.mul (get_local $a3) (get_local $b6)) (i64.add (i64.mul (get_local $a4) (get_local $b5)) (i64.add (i64.mul (get_local $a5) (get_local $b4)) (i64.add (i64.mul (get_local $a6) (get_local $b3)) (i64.add (i64.mul (get_local $a7) (get_local $b2)) (i64.add (i64.mul (get_local $a8) (get_local $b1)) (i64.mul (get_local $a9) (get_local $b0)))))))))))))
(set_local $s10 (i64.add (get_local $c10) (i64.add (i64.mul (get_local $a0) (get_local $b10)) (i64.add (i64.mul (get_local $a1) (get_local $b9 )) (i64.add (i64.mul (get_local $a2) (get_local $b8)) (i64.add (i64.mul (get_local $a3) (get_local $b7)) (i64.add (i64.mul (get_local $a4) (get_local $b6)) (i64.add (i64.mul (get_local $a5) (get_local $b5)) (i64.add (i64.mul (get_local $a6) (get_local $b4)) (i64.add (i64.mul (get_local $a7) (get_local $b3)) (i64.add (i64.mul (get_local $a8) (get_local $b2)) (i64.add (i64.mul (get_local $a9) (get_local $b1)) (i64.mul (get_local $a10) (get_local $b0))))))))))))))
(set_local $s11 (i64.add (get_local $c11) (i64.add (i64.mul (get_local $a0) (get_local $b11)) (i64.add (i64.mul (get_local $a1) (get_local $b10)) (i64.add (i64.mul (get_local $a2) (get_local $b9)) (i64.add (i64.mul (get_local $a3) (get_local $b8)) (i64.add (i64.mul (get_local $a4) (get_local $b7)) (i64.add (i64.mul (get_local $a5) (get_local $b6)) (i64.add (i64.mul (get_local $a6) (get_local $b5)) (i64.add (i64.mul (get_local $a7) (get_local $b4)) (i64.add (i64.mul (get_local $a8) (get_local $b3)) (i64.add (i64.mul (get_local $a9) (get_local $b2)) (i64.add (i64.mul (get_local $a10) (get_local $b1)) (i64.mul (get_local $a11) (get_local $b0)))))))))))))))
(set_local $s12 (i64.add (i64.mul (get_local $a1) (get_local $b11)) (i64.add (i64.mul (get_local $a2) (get_local $b10)) (i64.add (i64.mul (get_local $a3) (get_local $b9)) (i64.add (i64.mul (get_local $a4) (get_local $b8)) (i64.add (i64.mul (get_local $a5) (get_local $b7)) (i64.add (i64.mul (get_local $a6) (get_local $b6)) (i64.add (i64.mul (get_local $a7) (get_local $b5)) (i64.add (i64.mul (get_local $a8) (get_local $b4)) (i64.add (i64.mul (get_local $a9) (get_local $b3)) (i64.add (i64.mul (get_local $a10) (get_local $b2)) (i64.mul (get_local $a11) (get_local $b1)))))))))))))
(set_local $s13 (i64.add (i64.mul (get_local $a2) (get_local $b11)) (i64.add (i64.mul (get_local $a3) (get_local $b10)) (i64.add (i64.mul (get_local $a4) (get_local $b9)) (i64.add (i64.mul (get_local $a5) (get_local $b8)) (i64.add (i64.mul (get_local $a6) (get_local $b7)) (i64.add (i64.mul (get_local $a7) (get_local $b6)) (i64.add (i64.mul (get_local $a8) (get_local $b5)) (i64.add (i64.mul (get_local $a9) (get_local $b4)) (i64.add (i64.mul (get_local $a10) (get_local $b3)) (i64.mul (get_local $a11) (get_local $b2))))))))))))
(set_local $s14 (i64.add (i64.mul (get_local $a3) (get_local $b11)) (i64.add (i64.mul (get_local $a4) (get_local $b10)) (i64.add (i64.mul (get_local $a5) (get_local $b9)) (i64.add (i64.mul (get_local $a6) (get_local $b8)) (i64.add (i64.mul (get_local $a7) (get_local $b7)) (i64.add (i64.mul (get_local $a8) (get_local $b6)) (i64.add (i64.mul (get_local $a9) (get_local $b5)) (i64.add (i64.mul (get_local $a10) (get_local $b4)) (i64.mul (get_local $a11) (get_local $b3)))))))))))
(set_local $s15 (i64.add (i64.mul (get_local $a4) (get_local $b11)) (i64.add (i64.mul (get_local $a5) (get_local $b10)) (i64.add (i64.mul (get_local $a6) (get_local $b9)) (i64.add (i64.mul (get_local $a7) (get_local $b8)) (i64.add (i64.mul (get_local $a8) (get_local $b7)) (i64.add (i64.mul (get_local $a9) (get_local $b6)) (i64.add (i64.mul (get_local $a10) (get_local $b5)) (i64.mul (get_local $a11) (get_local $b4))))))))))
(set_local $s16 (i64.add (i64.mul (get_local $a5) (get_local $b11)) (i64.add (i64.mul (get_local $a6) (get_local $b10)) (i64.add (i64.mul (get_local $a7) (get_local $b9)) (i64.add (i64.mul (get_local $a8) (get_local $b8)) (i64.add (i64.mul (get_local $a9) (get_local $b7)) (i64.add (i64.mul (get_local $a10) (get_local $b6)) (i64.mul (get_local $a11) (get_local $b5)))))))))
(set_local $s17 (i64.add (i64.mul (get_local $a6) (get_local $b11)) (i64.add (i64.mul (get_local $a7) (get_local $b10)) (i64.add (i64.mul (get_local $a8) (get_local $b9)) (i64.add (i64.mul (get_local $a9) (get_local $b8)) (i64.add (i64.mul (get_local $a10) (get_local $b7)) (i64.mul (get_local $a11) (get_local $b6))))))))
(set_local $s18 (i64.add (i64.mul (get_local $a7) (get_local $b11)) (i64.add (i64.mul (get_local $a8) (get_local $b10)) (i64.add (i64.mul (get_local $a9) (get_local $b9)) (i64.add (i64.mul (get_local $a10) (get_local $b8)) (i64.mul (get_local $a11) (get_local $b7)))))))
(set_local $s19 (i64.add (i64.mul (get_local $a8) (get_local $b11)) (i64.add (i64.mul (get_local $a9) (get_local $b10)) (i64.add (i64.mul (get_local $a10) (get_local $b9)) (i64.mul (get_local $a11) (get_local $b8))))))
(set_local $s20 (i64.add (i64.mul (get_local $a9) (get_local $b11)) (i64.add (i64.mul (get_local $a10) (get_local $b10)) (i64.mul (get_local $a11) (get_local $b9)))))
(set_local $s21 (i64.add (i64.mul (get_local $a10) (get_local $b11)) (i64.mul (get_local $a11) (get_local $b10))))
(set_local $s22 (i64.mul (get_local $a11) (get_local $b11)))
(set_local $s23 (i64.const 0))
(set_local $carry0 (i64.shr_s (i64.add (get_local $s0) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s1 (i64.add (get_local $s1) (get_local $carry0)))
(set_local $s0 (i64.sub (get_local $s0) (i64.mul (get_local $carry0) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry2 (i64.shr_s (i64.add (get_local $s2) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s3 (i64.add (get_local $s3) (get_local $carry2)))
(set_local $s2 (i64.sub (get_local $s2) (i64.mul (get_local $carry2) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry4 (i64.shr_s (i64.add (get_local $s4) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s5 (i64.add (get_local $s5) (get_local $carry4)))
(set_local $s4 (i64.sub (get_local $s4) (i64.mul (get_local $carry4) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry6 (i64.shr_s (i64.add (get_local $s6) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s7 (i64.add (get_local $s7) (get_local $carry6)))
(set_local $s6 (i64.sub (get_local $s6) (i64.mul (get_local $carry6) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry8 (i64.shr_s (i64.add (get_local $s8) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s9 (i64.add (get_local $s9) (get_local $carry8)))
(set_local $s8 (i64.sub (get_local $s8) (i64.mul (get_local $carry8) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry10 (i64.shr_s (i64.add (get_local $s10) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s11 (i64.add (get_local $s11) (get_local $carry10)))
(set_local $s10 (i64.sub (get_local $s10) (i64.mul (get_local $carry10) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry12 (i64.shr_s (i64.add (get_local $s12) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s13 (i64.add (get_local $s13) (get_local $carry12)))
(set_local $s12 (i64.sub (get_local $s12) (i64.mul (get_local $carry12) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry14 (i64.shr_s (i64.add (get_local $s14) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s15 (i64.add (get_local $s15) (get_local $carry14)))
(set_local $s14 (i64.sub (get_local $s14) (i64.mul (get_local $carry14) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry16 (i64.shr_s (i64.add (get_local $s16) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s17 (i64.add (get_local $s17) (get_local $carry16)))
(set_local $s16 (i64.sub (get_local $s16) (i64.mul (get_local $carry16) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry18 (i64.shr_s (i64.add (get_local $s18) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s19 (i64.add (get_local $s19) (get_local $carry18)))
(set_local $s18 (i64.sub (get_local $s18) (i64.mul (get_local $carry18) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry20 (i64.shr_s (i64.add (get_local $s20) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s21 (i64.add (get_local $s21) (get_local $carry20)))
(set_local $s20 (i64.sub (get_local $s20) (i64.mul (get_local $carry20) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry22 (i64.shr_s (i64.add (get_local $s22) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s23 (i64.add (get_local $s23) (get_local $carry22)))
(set_local $s22 (i64.sub (get_local $s22) (i64.mul (get_local $carry22) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry1 (i64.shr_s (i64.add (get_local $s1) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s2 (i64.add (get_local $s2) (get_local $carry1)))
(set_local $s1 (i64.sub (get_local $s1) (i64.mul (get_local $carry1) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry3 (i64.shr_s (i64.add (get_local $s3) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s4 (i64.add (get_local $s4) (get_local $carry3)))
(set_local $s3 (i64.sub (get_local $s3) (i64.mul (get_local $carry3) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry5 (i64.shr_s (i64.add (get_local $s5) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s6 (i64.add (get_local $s6) (get_local $carry5)))
(set_local $s5 (i64.sub (get_local $s5) (i64.mul (get_local $carry5) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry7 (i64.shr_s (i64.add (get_local $s7) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s8 (i64.add (get_local $s8) (get_local $carry7)))
(set_local $s7 (i64.sub (get_local $s7) (i64.mul (get_local $carry7) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry9 (i64.shr_s (i64.add (get_local $s9) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s10 (i64.add (get_local $s10) (get_local $carry9)))
(set_local $s9 (i64.sub (get_local $s9) (i64.mul (get_local $carry9) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry11 (i64.shr_s (i64.add (get_local $s11) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s12 (i64.add (get_local $s12) (get_local $carry11)))
(set_local $s11 (i64.sub (get_local $s11) (i64.mul (get_local $carry11) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry13 (i64.shr_s (i64.add (get_local $s13) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s14 (i64.add (get_local $s14) (get_local $carry13)))
(set_local $s13 (i64.sub (get_local $s13) (i64.mul (get_local $carry13) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry15 (i64.shr_s (i64.add (get_local $s15) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s16 (i64.add (get_local $s16) (get_local $carry15)))
(set_local $s15 (i64.sub (get_local $s15) (i64.mul (get_local $carry15) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry17 (i64.shr_s (i64.add (get_local $s17) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s18 (i64.add (get_local $s18) (get_local $carry17)))
(set_local $s17 (i64.sub (get_local $s17) (i64.mul (get_local $carry17) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry19 (i64.shr_s (i64.add (get_local $s19) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s20 (i64.add (get_local $s20) (get_local $carry19)))
(set_local $s19 (i64.sub (get_local $s19) (i64.mul (get_local $carry19) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry21 (i64.shr_s (i64.add (get_local $s21) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s22 (i64.add (get_local $s22) (get_local $carry21)))
(set_local $s21 (i64.sub (get_local $s21) (i64.mul (get_local $carry21) (i64.shl (i64.const 1) (i64.const 21)))))
(get_local $s)
(get_local $s0)
(get_local $s1)
(get_local $s2)
(get_local $s3)
(get_local $s4)
(get_local $s5)
(get_local $s6)
(get_local $s7)
(get_local $s8)
(get_local $s9)
(get_local $s10)
(get_local $s11)
(get_local $s12)
(get_local $s13)
(get_local $s14)
(get_local $s15)
(get_local $s16)
(get_local $s17)
(get_local $s18)
(get_local $s19)
(get_local $s20)
(get_local $s21)
(get_local $s22)
(get_local $s23)
(i32.const 0)
(call_indirect (type $to_void))))

61
fe25519_25/sc_reduce.js Normal file
View File

@ -0,0 +1,61 @@
module.exports = loadWebAssembly
loadWebAssembly.supported = typeof WebAssembly !== 'undefined'
function loadWebAssembly (opts) {
if (!loadWebAssembly.supported) return null
var imp = opts && opts.imports
var wasm = toUint8Array('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')
var ready = null
var mod = {
buffer: wasm,
memory: null,
exports: null,
realloc: realloc,
onload: onload
}
onload(function () {})
return mod
function realloc (size) {
mod.exports.memory.grow(Math.max(0, Math.ceil(Math.abs(size - mod.memory.length) / 65536)))
mod.memory = new Uint8Array(mod.exports.memory.buffer)
}
function onload (cb) {
if (mod.exports) return cb()
if (ready) {
ready.then(cb.bind(null, null)).catch(cb)
return
}
try {
if (opts && opts.async) throw new Error('async')
setup({instance: new WebAssembly.Instance(new WebAssembly.Module(wasm), imp)})
} catch (err) {
ready = WebAssembly.instantiate(wasm, imp).then(setup)
}
onload(cb)
}
function setup (w) {
mod.exports = w.instance.exports
mod.memory = mod.exports.memory && mod.exports.memory.buffer && new Uint8Array(mod.exports.memory.buffer)
}
}
function toUint8Array (s) {
if (typeof atob === 'function') return new Uint8Array(atob(s).split('').map(charCodeAt))
return (require('buf' + 'fer').Buffer).from(s, 'base64')
}
function charCodeAt (c) {
return c.charCodeAt(0)
}

542
fe25519_25/sc_reduce.wat Normal file
View File

@ -0,0 +1,542 @@
(module
(import "js" "table" (table 1 anyfunc))
(elem (i32.const 0) $sc_reduce)
(func $i32.log (import "debug" "log") (param i32))
(func $i32.log_tee (import "debug" "log_tee") (param i32) (result i32))
;; No i64 interop with JS yet - but maybe coming with WebAssembly BigInt
;; So we can instead fake this by splitting the i64 into two i32 limbs,
;; however these are WASM functions using i32x2.log:
(func $i32x2.log (import "debug" "log") (param i32) (param i32))
(func $f32.log (import "debug" "log") (param f32))
(func $f32.log_tee (import "debug" "log_tee") (param f32) (result f32))
(func $f64.log (import "debug" "log") (param f64))
(func $f64.log_tee (import "debug" "log_tee") (param f64) (result f64))
;; i64 logging by splitting into two i32 limbs
(func $i64.log
(param $0 i64)
(call $i32x2.log
;; Upper limb
(i32.wrap/i64
(i64.shr_s (get_local $0)
(i64.const 32)))
;; Lower limb
(i32.wrap/i64 (get_local $0))))
(func $i64.log_tee
(param $0 i64)
(result i64)
(call $i64.log (get_local $0))
(return (get_local $0)))
(memory $0 1)
(export "memory" (memory $0))
(func $sc_reduce (export "sc_reduce")
(param $s i32)
(param $s0 i64)
(param $s1 i64)
(param $s2 i64)
(param $s3 i64)
(param $s4 i64)
(param $s5 i64)
(param $s6 i64)
(param $s7 i64)
(param $s8 i64)
(param $s9 i64)
(param $s10 i64)
(param $s11 i64)
(param $s12 i64)
(param $s13 i64)
(param $s14 i64)
(param $s15 i64)
(param $s16 i64)
(param $s17 i64)
(param $s18 i64)
(param $s19 i64)
(param $s20 i64)
(param $s21 i64)
(param $s22 i64)
(param $s23 i64)
(local $carry0 i64)
(local $carry1 i64)
(local $carry2 i64)
(local $carry3 i64)
(local $carry4 i64)
(local $carry5 i64)
(local $carry6 i64)
(local $carry7 i64)
(local $carry8 i64)
(local $carry9 i64)
(local $carry10 i64)
(local $carry11 i64)
(local $carry12 i64)
(local $carry13 i64)
(local $carry14 i64)
(local $carry15 i64)
(local $carry16 i64)
(set_local $s11 (i64.add (get_local $s11) (i64.mul (get_local $s23) (i64.const 666643))))
(set_local $s12 (i64.add (get_local $s12) (i64.mul (get_local $s23) (i64.const 470296))))
(set_local $s13 (i64.add (get_local $s13) (i64.mul (get_local $s23) (i64.const 654183))))
(set_local $s14 (i64.sub (get_local $s14) (i64.mul (get_local $s23) (i64.const 997805))))
(set_local $s15 (i64.add (get_local $s15) (i64.mul (get_local $s23) (i64.const 136657))))
(set_local $s16 (i64.sub (get_local $s16) (i64.mul (get_local $s23) (i64.const 683901))))
(set_local $s10 (i64.add (get_local $s10) (i64.mul (get_local $s22) (i64.const 666643))))
(set_local $s11 (i64.add (get_local $s11) (i64.mul (get_local $s22) (i64.const 470296))))
(set_local $s12 (i64.add (get_local $s12) (i64.mul (get_local $s22) (i64.const 654183))))
(set_local $s13 (i64.sub (get_local $s13) (i64.mul (get_local $s22) (i64.const 997805))))
(set_local $s14 (i64.add (get_local $s14) (i64.mul (get_local $s22) (i64.const 136657))))
(set_local $s15 (i64.sub (get_local $s15) (i64.mul (get_local $s22) (i64.const 683901))))
(set_local $s9 (i64.add (get_local $s9 ) (i64.mul (get_local $s21) (i64.const 666643))))
(set_local $s10 (i64.add (get_local $s10) (i64.mul (get_local $s21) (i64.const 470296))))
(set_local $s11 (i64.add (get_local $s11) (i64.mul (get_local $s21) (i64.const 654183))))
(set_local $s12 (i64.sub (get_local $s12) (i64.mul (get_local $s21) (i64.const 997805))))
(set_local $s13 (i64.add (get_local $s13) (i64.mul (get_local $s21) (i64.const 136657))))
(set_local $s14 (i64.sub (get_local $s14) (i64.mul (get_local $s21) (i64.const 683901))))
(set_local $s8 (i64.add (get_local $s8 ) (i64.mul (get_local $s20) (i64.const 666643))))
(set_local $s9 (i64.add (get_local $s9 ) (i64.mul (get_local $s20) (i64.const 470296))))
(set_local $s10 (i64.add (get_local $s10) (i64.mul (get_local $s20) (i64.const 654183))))
(set_local $s11 (i64.sub (get_local $s11) (i64.mul (get_local $s20) (i64.const 997805))))
(set_local $s12 (i64.add (get_local $s12) (i64.mul (get_local $s20) (i64.const 136657))))
(set_local $s13 (i64.sub (get_local $s13) (i64.mul (get_local $s20) (i64.const 683901))))
(set_local $s7 (i64.add (get_local $s7 ) (i64.mul (get_local $s19) (i64.const 666643))))
(set_local $s8 (i64.add (get_local $s8 ) (i64.mul (get_local $s19) (i64.const 470296))))
(set_local $s9 (i64.add (get_local $s9 ) (i64.mul (get_local $s19) (i64.const 654183))))
(set_local $s10 (i64.sub (get_local $s10) (i64.mul (get_local $s19) (i64.const 997805))))
(set_local $s11 (i64.add (get_local $s11) (i64.mul (get_local $s19) (i64.const 136657))))
(set_local $s12 (i64.sub (get_local $s12) (i64.mul (get_local $s19) (i64.const 683901))))
(set_local $s6 (i64.add (get_local $s6 ) (i64.mul (get_local $s18) (i64.const 666643))))
(set_local $s7 (i64.add (get_local $s7 ) (i64.mul (get_local $s18) (i64.const 470296))))
(set_local $s8 (i64.add (get_local $s8 ) (i64.mul (get_local $s18) (i64.const 654183))))
(set_local $s9 (i64.sub (get_local $s9 ) (i64.mul (get_local $s18) (i64.const 997805))))
(set_local $s10 (i64.add (get_local $s10) (i64.mul (get_local $s18) (i64.const 136657))))
(set_local $s11 (i64.sub (get_local $s11) (i64.mul (get_local $s18) (i64.const 683901))))
(set_local $carry6 (i64.shr_s (i64.add (get_local $s6) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s7 (i64.add (get_local $s7) (get_local $carry6)))
(set_local $s6 (i64.sub (get_local $s6) (i64.mul (get_local $carry6) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry8 (i64.shr_s (i64.add (get_local $s8) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s9 (i64.add (get_local $s9) (get_local $carry8)))
(set_local $s8 (i64.sub (get_local $s8) (i64.mul (get_local $carry8) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry10 (i64.shr_s (i64.add (get_local $s10) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s11 (i64.add (get_local $s11) (get_local $carry10)))
(set_local $s10 (i64.sub (get_local $s10) (i64.mul (get_local $carry10) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry12 (i64.shr_s (i64.add (get_local $s12) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s13 (i64.add (get_local $s13) (get_local $carry12)))
(set_local $s12 (i64.sub (get_local $s12) (i64.mul (get_local $carry12) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry14 (i64.shr_s (i64.add (get_local $s14) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s15 (i64.add (get_local $s15) (get_local $carry14)))
(set_local $s14 (i64.sub (get_local $s14) (i64.mul (get_local $carry14) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry16 (i64.shr_s (i64.add (get_local $s16) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s17 (i64.add (get_local $s17) (get_local $carry16)))
(set_local $s16 (i64.sub (get_local $s16) (i64.mul (get_local $carry16) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry7 (i64.shr_s (i64.add (get_local $s7) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s8 (i64.add (get_local $s8) (get_local $carry7)))
(set_local $s7 (i64.sub (get_local $s7) (i64.mul (get_local $carry7) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry9 (i64.shr_s (i64.add (get_local $s9) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s10 (i64.add (get_local $s10) (get_local $carry9)))
(set_local $s9 (i64.sub (get_local $s9) (i64.mul (get_local $carry9) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry11 (i64.shr_s (i64.add (get_local $s11) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s12 (i64.add (get_local $s12) (get_local $carry11)))
(set_local $s11 (i64.sub (get_local $s11) (i64.mul (get_local $carry11) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry13 (i64.shr_s (i64.add (get_local $s13) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s14 (i64.add (get_local $s14) (get_local $carry13)))
(set_local $s13 (i64.sub (get_local $s13) (i64.mul (get_local $carry13) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry15 (i64.shr_s (i64.add (get_local $s15) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s16 (i64.add (get_local $s16) (get_local $carry15)))
(set_local $s15 (i64.sub (get_local $s15) (i64.mul (get_local $carry15) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $s5 (i64.add (get_local $s5 ) (i64.mul (get_local $s17) (i64.const 666643))))
(set_local $s6 (i64.add (get_local $s6 ) (i64.mul (get_local $s17) (i64.const 470296))))
(set_local $s7 (i64.add (get_local $s7 ) (i64.mul (get_local $s17) (i64.const 654183))))
(set_local $s8 (i64.sub (get_local $s8 ) (i64.mul (get_local $s17) (i64.const 997805))))
(set_local $s9 (i64.add (get_local $s9 ) (i64.mul (get_local $s17) (i64.const 136657))))
(set_local $s10 (i64.sub (get_local $s10) (i64.mul (get_local $s17) (i64.const 683901))))
(set_local $s4 (i64.add (get_local $s4) (i64.mul (get_local $s16) (i64.const 666643))))
(set_local $s5 (i64.add (get_local $s5) (i64.mul (get_local $s16) (i64.const 470296))))
(set_local $s6 (i64.add (get_local $s6) (i64.mul (get_local $s16) (i64.const 654183))))
(set_local $s7 (i64.sub (get_local $s7) (i64.mul (get_local $s16) (i64.const 997805))))
(set_local $s8 (i64.add (get_local $s8) (i64.mul (get_local $s16) (i64.const 136657))))
(set_local $s9 (i64.sub (get_local $s9) (i64.mul (get_local $s16) (i64.const 683901))))
(set_local $s3 (i64.add (get_local $s3) (i64.mul (get_local $s15) (i64.const 666643))))
(set_local $s4 (i64.add (get_local $s4) (i64.mul (get_local $s15) (i64.const 470296))))
(set_local $s5 (i64.add (get_local $s5) (i64.mul (get_local $s15) (i64.const 654183))))
(set_local $s6 (i64.sub (get_local $s6) (i64.mul (get_local $s15) (i64.const 997805))))
(set_local $s7 (i64.add (get_local $s7) (i64.mul (get_local $s15) (i64.const 136657))))
(set_local $s8 (i64.sub (get_local $s8) (i64.mul (get_local $s15) (i64.const 683901))))
(set_local $s2 (i64.add (get_local $s2) (i64.mul (get_local $s14) (i64.const 666643))))
(set_local $s3 (i64.add (get_local $s3) (i64.mul (get_local $s14) (i64.const 470296))))
(set_local $s4 (i64.add (get_local $s4) (i64.mul (get_local $s14) (i64.const 654183))))
(set_local $s5 (i64.sub (get_local $s5) (i64.mul (get_local $s14) (i64.const 997805))))
(set_local $s6 (i64.add (get_local $s6) (i64.mul (get_local $s14) (i64.const 136657))))
(set_local $s7 (i64.sub (get_local $s7) (i64.mul (get_local $s14) (i64.const 683901))))
(set_local $s1 (i64.add (get_local $s1) (i64.mul (get_local $s13) (i64.const 666643))))
(set_local $s2 (i64.add (get_local $s2) (i64.mul (get_local $s13) (i64.const 470296))))
(set_local $s3 (i64.add (get_local $s3) (i64.mul (get_local $s13) (i64.const 654183))))
(set_local $s4 (i64.sub (get_local $s4) (i64.mul (get_local $s13) (i64.const 997805))))
(set_local $s5 (i64.add (get_local $s5) (i64.mul (get_local $s13) (i64.const 136657))))
(set_local $s6 (i64.sub (get_local $s6) (i64.mul (get_local $s13) (i64.const 683901))))
(set_local $s0 (i64.add (get_local $s0) (i64.mul (get_local $s12) (i64.const 666643))))
(set_local $s1 (i64.add (get_local $s1) (i64.mul (get_local $s12) (i64.const 470296))))
(set_local $s2 (i64.add (get_local $s2) (i64.mul (get_local $s12) (i64.const 654183))))
(set_local $s3 (i64.sub (get_local $s3) (i64.mul (get_local $s12) (i64.const 997805))))
(set_local $s4 (i64.add (get_local $s4) (i64.mul (get_local $s12) (i64.const 136657))))
(set_local $s5 (i64.sub (get_local $s5) (i64.mul (get_local $s12) (i64.const 683901))))
(set_local $s12 (i64.const 0))
(set_local $carry0 (i64.shr_s (i64.add (get_local $s0) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s1 (i64.add (get_local $s1) (get_local $carry0)))
(set_local $s0 (i64.sub (get_local $s0) (i64.mul (get_local $carry0) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry2 (i64.shr_s (i64.add (get_local $s2) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s3 (i64.add (get_local $s3) (get_local $carry2)))
(set_local $s2 (i64.sub (get_local $s2) (i64.mul (get_local $carry2) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry4 (i64.shr_s (i64.add (get_local $s4) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s5 (i64.add (get_local $s5) (get_local $carry4)))
(set_local $s4 (i64.sub (get_local $s4) (i64.mul (get_local $carry4) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry6 (i64.shr_s (i64.add (get_local $s6) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s7 (i64.add (get_local $s7) (get_local $carry6)))
(set_local $s6 (i64.sub (get_local $s6) (i64.mul (get_local $carry6) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry8 (i64.shr_s (i64.add (get_local $s8) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s9 (i64.add (get_local $s9) (get_local $carry8)))
(set_local $s8 (i64.sub (get_local $s8) (i64.mul (get_local $carry8) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry10 (i64.shr_s (i64.add (get_local $s10) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s11 (i64.add (get_local $s11) (get_local $carry10)))
(set_local $s10 (i64.sub (get_local $s10) (i64.mul (get_local $carry10) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry1 (i64.shr_s (i64.add (get_local $s1) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s2 (i64.add (get_local $s2) (get_local $carry1)))
(set_local $s1 (i64.sub (get_local $s1) (i64.mul (get_local $carry1) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry3 (i64.shr_s (i64.add (get_local $s3) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s4 (i64.add (get_local $s4) (get_local $carry3)))
(set_local $s3 (i64.sub (get_local $s3) (i64.mul (get_local $carry3) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry5 (i64.shr_s (i64.add (get_local $s5) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s6 (i64.add (get_local $s6) (get_local $carry5)))
(set_local $s5 (i64.sub (get_local $s5) (i64.mul (get_local $carry5) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry7 (i64.shr_s (i64.add (get_local $s7) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s8 (i64.add (get_local $s8) (get_local $carry7)))
(set_local $s7 (i64.sub (get_local $s7) (i64.mul (get_local $carry7) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry9 (i64.shr_s (i64.add (get_local $s9) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s10 (i64.add (get_local $s10) (get_local $carry9)))
(set_local $s9 (i64.sub (get_local $s9) (i64.mul (get_local $carry9) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry11 (i64.shr_s (i64.add (get_local $s11) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
(set_local $s12 (i64.add (get_local $s12) (get_local $carry11)))
(set_local $s11 (i64.sub (get_local $s11) (i64.mul (get_local $carry11) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $s0 (i64.add (get_local $s0) (i64.mul (get_local $s12) (i64.const 666643))))
(set_local $s1 (i64.add (get_local $s1) (i64.mul (get_local $s12) (i64.const 470296))))
(set_local $s2 (i64.add (get_local $s2) (i64.mul (get_local $s12) (i64.const 654183))))
(set_local $s3 (i64.sub (get_local $s3) (i64.mul (get_local $s12) (i64.const 997805))))
(set_local $s4 (i64.add (get_local $s4) (i64.mul (get_local $s12) (i64.const 136657))))
(set_local $s5 (i64.sub (get_local $s5) (i64.mul (get_local $s12) (i64.const 683901))))
(set_local $s12 (i64.const 0))
(set_local $carry0 (i64.shr_s (get_local $s0) (i64.const 21)))
(set_local $s1 (i64.add (get_local $s1) (get_local $carry0)))
(set_local $s0 (i64.sub (get_local $s0) (i64.mul (get_local $carry0) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry1 (i64.shr_s (get_local $s1) (i64.const 21)))
(set_local $s2 (i64.add (get_local $s2) (get_local $carry1)))
(set_local $s1 (i64.sub (get_local $s1) (i64.mul (get_local $carry1) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry2 (i64.shr_s (get_local $s2) (i64.const 21)))
(set_local $s3 (i64.add (get_local $s3) (get_local $carry2)))
(set_local $s2 (i64.sub (get_local $s2) (i64.mul (get_local $carry2) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry3 (i64.shr_s (get_local $s3) (i64.const 21)))
(set_local $s4 (i64.add (get_local $s4) (get_local $carry3)))
(set_local $s3 (i64.sub (get_local $s3) (i64.mul (get_local $carry3) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry4 (i64.shr_s (get_local $s4) (i64.const 21)))
(set_local $s5 (i64.add (get_local $s5) (get_local $carry4)))
(set_local $s4 (i64.sub (get_local $s4) (i64.mul (get_local $carry4) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry5 (i64.shr_s (get_local $s5) (i64.const 21)))
(set_local $s6 (i64.add (get_local $s6) (get_local $carry5)))
(set_local $s5 (i64.sub (get_local $s5) (i64.mul (get_local $carry5) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry6 (i64.shr_s (get_local $s6) (i64.const 21)))
(set_local $s7 (i64.add (get_local $s7) (get_local $carry6)))
(set_local $s6 (i64.sub (get_local $s6) (i64.mul (get_local $carry6) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry7 (i64.shr_s (get_local $s7) (i64.const 21)))
(set_local $s8 (i64.add (get_local $s8) (get_local $carry7)))
(set_local $s7 (i64.sub (get_local $s7) (i64.mul (get_local $carry7) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry8 (i64.shr_s (get_local $s8) (i64.const 21)))
(set_local $s9 (i64.add (get_local $s9) (get_local $carry8)))
(set_local $s8 (i64.sub (get_local $s8) (i64.mul (get_local $carry8) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry9 (i64.shr_s (get_local $s9) (i64.const 21)))
(set_local $s10 (i64.add (get_local $s10) (get_local $carry9)))
(set_local $s9 (i64.sub (get_local $s9) (i64.mul (get_local $carry9) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry10 (i64.shr_s (get_local $s10) (i64.const 21)))
(set_local $s11 (i64.add (get_local $s11) (get_local $carry10)))
(set_local $s10 (i64.sub (get_local $s10) (i64.mul (get_local $carry10) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry11 (i64.shr_s (get_local $s11) (i64.const 21)))
(set_local $s12 (i64.add (get_local $s12) (get_local $carry11)))
(set_local $s11 (i64.sub (get_local $s11) (i64.mul (get_local $carry11) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $s0 (i64.add (get_local $s0) (i64.mul (get_local $s12) (i64.const 666643))))
(set_local $s1 (i64.add (get_local $s1) (i64.mul (get_local $s12) (i64.const 470296))))
(set_local $s2 (i64.add (get_local $s2) (i64.mul (get_local $s12) (i64.const 654183))))
(set_local $s3 (i64.sub (get_local $s3) (i64.mul (get_local $s12) (i64.const 997805))))
(set_local $s4 (i64.add (get_local $s4) (i64.mul (get_local $s12) (i64.const 136657))))
(set_local $s5 (i64.sub (get_local $s5) (i64.mul (get_local $s12) (i64.const 683901))))
(set_local $carry0 (i64.shr_s (get_local $s0) (i64.const 21)))
(set_local $s1 (i64.add (get_local $s1) (get_local $carry0)))
(set_local $s0 (i64.sub (get_local $s0) (i64.mul (get_local $carry0) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry1 (i64.shr_s (get_local $s1) (i64.const 21)))
(set_local $s2 (i64.add (get_local $s2) (get_local $carry1)))
(set_local $s1 (i64.sub (get_local $s1) (i64.mul (get_local $carry1) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry2 (i64.shr_s (get_local $s2) (i64.const 21)))
(set_local $s3 (i64.add (get_local $s3) (get_local $carry2)))
(set_local $s2 (i64.sub (get_local $s2) (i64.mul (get_local $carry2) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry3 (i64.shr_s (get_local $s3) (i64.const 21)))
(set_local $s4 (i64.add (get_local $s4) (get_local $carry3)))
(set_local $s3 (i64.sub (get_local $s3) (i64.mul (get_local $carry3) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry4 (i64.shr_s (get_local $s4) (i64.const 21)))
(set_local $s5 (i64.add (get_local $s5) (get_local $carry4)))
(set_local $s4 (i64.sub (get_local $s4) (i64.mul (get_local $carry4) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry5 (i64.shr_s (get_local $s5) (i64.const 21)))
(set_local $s6 (i64.add (get_local $s6) (get_local $carry5)))
(set_local $s5 (i64.sub (get_local $s5) (i64.mul (get_local $carry5) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry6 (i64.shr_s (get_local $s6) (i64.const 21)))
(set_local $s7 (i64.add (get_local $s7) (get_local $carry6)))
(set_local $s6 (i64.sub (get_local $s6) (i64.mul (get_local $carry6) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry7 (i64.shr_s (get_local $s7) (i64.const 21)))
(set_local $s8 (i64.add (get_local $s8) (get_local $carry7)))
(set_local $s7 (i64.sub (get_local $s7) (i64.mul (get_local $carry7) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry8 (i64.shr_s (get_local $s8) (i64.const 21)))
(set_local $s9 (i64.add (get_local $s9) (get_local $carry8)))
(set_local $s8 (i64.sub (get_local $s8) (i64.mul (get_local $carry8) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry9 (i64.shr_s (get_local $s9) (i64.const 21)))
(set_local $s10 (i64.add (get_local $s10) (get_local $carry9)))
(set_local $s9 (i64.sub (get_local $s9) (i64.mul (get_local $carry9) (i64.shl (i64.const 1) (i64.const 21)))))
(set_local $carry10 (i64.shr_s (get_local $s10) (i64.const 21)))
(set_local $s11 (i64.add (get_local $s11) (get_local $carry10)))
(set_local $s10 (i64.sub (get_local $s10) (i64.mul (get_local $carry10) (i64.shl (i64.const 1) (i64.const 21)))))
(get_local $s)
(i64.and (get_local $s0) (i64.const 0xff))
(i64.and (get_local $s0) (i64.const 0xff00))
(i64.or)
(get_local $s0)
(i64.shl (i64.mul (get_local $s1) (i64.const 32)) (i64.const 16))
(i64.or)
(i64.const 0xff0000)
(i64.and)
(i64.or)
(i64.shl (get_local $s1) (i64.const 21))
(i64.const 0xff000000)
(i64.and)
(i64.or)
(i64.shl (get_local $s1) (i64.const 21))
(i64.const 0xff00000000)
(i64.and)
(i64.or)
(i64.shl (get_local $s1) (i64.const 21))
(i64.shl (i64.mul (get_local $s2) (i64.const 4)) (i64.const 40))
(i64.or)
(i64.const 0xff0000000000)
(i64.and)
(i64.or)
(i64.shl (get_local $s2) (i64.const 42))
(i64.const 0xff000000000000)
(i64.and)
(i64.or)
(i64.shl (get_local $s2) (i64.const 42))
(i64.shl (i64.mul (get_local $s3) (i64.const 128)) (i64.const 56))
(i64.or)
(i64.const 0xff00000000000000)
(i64.and)
(i64.or)
(i64.store offset=0)
(get_local $s)
(i64.and (i64.shr_s (get_local $s3) (i64.const 1)) (i64.const 0xff))
(i64.and (i64.shr_s (get_local $s3) (i64.const 1)) (i64.const 0xff00))
(i64.or)
(i64.shr_s (get_local $s3) (i64.const 1))
(i64.shl (i64.mul (get_local $s4) (i64.const 16)) (i64.const 16))
(i64.or)
(i64.const 0xff0000)
(i64.and)
(i64.or)
(i64.shl (get_local $s4) (i64.const 20))
(i64.const 0xff000000)
(i64.and)
(i64.or)
(i64.shl (get_local $s4) (i64.const 20))
(i64.const 0xff00000000)
(i64.and)
(i64.or)
(i64.shl (get_local $s4) (i64.const 20))
(i64.shl (i64.mul (get_local $s5) (i64.const 2)) (i64.const 40))
(i64.or)
(i64.const 0xff0000000000)
(i64.and)
(i64.or)
(i64.shl (get_local $s5) (i64.const 41))
(i64.const 0xff000000000000)
(i64.and)
(i64.or)
(i64.shl (get_local $s5) (i64.const 41))
(i64.shl (i64.mul (get_local $s6) (i64.const 64)) (i64.const 56))
(i64.or)
(i64.const 0xff00000000000000)
(i64.and)
(i64.or)
(i64.store offset=8)
(get_local $s)
(i64.and (i64.shr_s (get_local $s6) (i64.const 2)) (i64.const 0xff))
(i64.and (i64.shr_s (get_local $s6) (i64.const 2)) (i64.const 0xff00))
(i64.or)
(i64.shr_s (get_local $s6) (i64.const 2))
(i64.shl (i64.mul (get_local $s7) (i64.const 8)) (i64.const 16))
(i64.or)
(i64.const 0xff0000)
(i64.and)
(i64.or)
(i64.shl (get_local $s7) (i64.const 19))
(i64.const 0xff000000)
(i64.and)
(i64.or)
(i64.shl (get_local $s7) (i64.const 19))
(i64.const 0xff00000000)
(i64.and)
(i64.or)
(i64.shl (get_local $s8) (i64.const 40))
(i64.const 0xff0000000000)
(i64.and)
(i64.or)
(i64.shl (get_local $s8) (i64.const 40))
(i64.const 0xff000000000000)
(i64.and)
(i64.or)
(i64.shl (get_local $s8) (i64.const 40))
(i64.shl (i64.mul (get_local $s9) (i64.const 32)) (i64.const 56))
(i64.or)
(i64.const 0xff00000000000000)
(i64.and)
(i64.or)
(i64.store offset=16)
(get_local $s)
(i64.and (i64.shr_s (get_local $s9) (i64.const 3)) (i64.const 0xff))
(i64.and (i64.shr_s (get_local $s9) (i64.const 3)) (i64.const 0xff00))
(i64.or)
(i64.shr_s (get_local $s9) (i64.const 3))
(i64.shl (i64.mul (get_local $s10) (i64.const 4)) (i64.const 16))
(i64.or)
(i64.const 0xff0000)
(i64.and)
(i64.or)
(i64.shl (get_local $s10) (i64.const 18))
(i64.const 0xff000000)
(i64.and)
(i64.or)
(i64.shl (get_local $s10) (i64.const 18))
(i64.shl (i64.mul (get_local $s11) (i64.const 128)) (i64.const 32))
(i64.or)
(i64.const 0xff00000000)
(i64.and)
(i64.or)
(i64.shl (get_local $s11) (i64.const 39))
(i64.const 0xff0000000000)
(i64.and)
(i64.or)
(i64.shl (get_local $s11) (i64.const 39))
(i64.const 0xff000000000000)
(i64.and)
(i64.or)
(i64.shl (get_local $s11) (i64.const 39))
(i64.const 0xff00000000000000)
(i64.and)
(i64.or)
(i64.store offset=24))
(func $sc25519_reduce (export "sc25519_reduce") (param $s i32)
(get_local $s)
(i64.load32_u offset=0 (get_local $s))
(i64.load32_u offset=4 (get_local $s))
(i64.load32_u offset=8 (get_local $s))
(i64.load32_u offset=12 (get_local $s))
(i64.load32_u offset=16 (get_local $s))
(i64.load32_u offset=20 (get_local $s))
(i64.load32_u offset=24 (get_local $s))
(i64.load32_u offset=28 (get_local $s))
(i64.load32_u offset=32 (get_local $s))
(i64.load32_u offset=36 (get_local $s))
(i64.load32_u offset=40 (get_local $s))
(i64.load32_u offset=44 (get_local $s))
(i64.load32_u offset=48 (get_local $s))
(i64.load32_u offset=52 (get_local $s))
(i64.load32_u offset=56 (get_local $s))
(i64.load32_u offset=60 (get_local $s))
(i64.load32_u offset=64 (get_local $s))
(i64.load32_u offset=68 (get_local $s))
(i64.load32_u offset=72 (get_local $s))
(i64.load32_u offset=76 (get_local $s))
(i64.load32_u offset=80 (get_local $s))
(i64.load32_u offset=84 (get_local $s))
(i64.load32_u offset=88 (get_local $s))
(i64.load32_u offset=92 (get_local $s))
(call $sc_reduce)))

View File

@ -0,0 +1,61 @@
module.exports = loadWebAssembly
loadWebAssembly.supported = typeof WebAssembly !== 'undefined'
function loadWebAssembly (opts) {
if (!loadWebAssembly.supported) return null
var imp = opts && opts.imports
var wasm = toUint8Array('AGFzbQEAAAABZg1gFX5+fn5+fn5+fn5+fn5+fn5+fn5+fwBgDX5+fn5+fn5+fn5/f38AYAt+fn5+fn5+fn5+fwBgAX8AYAF/AX9gAn9/AGABfQBgAX0BfWABfABgAXwBfGABfgBgAX4BfmADf39/AAJ4CQJqcwV0YWJsZQFwAAMCanMDbWVtAgABBWRlYnVnA2xvZwADBWRlYnVnB2xvZ190ZWUABAVkZWJ1ZwNsb2cABQVkZWJ1ZwNsb2cABgVkZWJ1Zwdsb2dfdGVlAAcFZGVidWcDbG9nAAgFZGVidWcHbG9nX3RlZQAJAwQDCgsMBw4BCnNjYWxhcm11bHQACQqLGQMNACAAQiCHpyAApxACCwkAIAAQByAADwvwGAIHf0x+QZADIQZBuAMhB0HgAyEIQYgEIQkgAikDACEMIAIpAwghDSACKQMQIQ4gAikDGCEPIAE1AgAhECABNQIEIREgATUCCCESIAE1AgwhEyABNQIQIRQgATUCFCEVIAE1AhghFiABNQIcIRcgATUCICEYIAE1AiQhGUIBIRpCACEbQgAhHEIAIR1CACEeQgAhH0IAISBCACEhQgAhIkIAISMgATUCACEuIAE1AgQhLyABNQIIITAgATUCDCExIAE1AhAhMiABNQIUITMgATUCGCE0IAE1AhwhNSABNQIgITYgATUCJCE3QgAhJEIAISVCACEmQgAhJ0IAIShCACEpQgAhKkIAIStCACEsQgAhLUIBIThCACE5QgAhOkIAITtCACE8QgAhPUIAIT5CACE/QgAhQEIAIUFB/gEhBQJAA0AgBUEASA0BAkACQAJAAkACQAJAIAVBwABuDgMEAwIBCwsgDyELDAMLIA4hCwwCCyANIQsMAQsgDCELCyALIAVBCG5BCHBBCGytiEL/AYMgBUEHca2IQgGDpyEEIAMgBHMhA0EAIANrrSEKIBogLoUgCoMhQiAbIC+FIAqDIUMgHCAwhSAKgyFEIB0gMYUgCoMhRSAeIDKFIAqDIUYgHyAzhSAKgyFHICAgNIUgCoMhSCAhIDWFIAqDIUkgIiA2hSAKgyFKICMgN4UgCoMhSyAaIEKFIRogGyBDhSEbIBwgRIUhHCAdIEWFIR0gHiBGhSEeIB8gR4UhHyAgIEiFISAgISBJhSEhICIgSoUhIiAjIEuFISMgLiBChSEuIC8gQ4UhLyAwIESFITAgMSBFhSExIDIgRoUhMiAzIEeFITMgNCBIhSE0IDUgSYUhNSA2IEqFITYgNyBLhSE3IDggJIUgCoMhQiA5ICWFIAqDIUMgOiAmhSAKgyFEIDsgJ4UgCoMhRSA8ICiFIAqDIUYgPSAphSAKgyFHID4gKoUgCoMhSCA/ICuFIAqDIUkgQCAshSAKgyFKIEEgLYUgCoMhSyAkIEKFISQgJSBDhSElICYgRIUhJiAnIEWFIScgKCBGhSEoICkgR4UhKSAqIEiFISogKyBJhSErICwgSoUhLCAtIEuFIS0gOCBChSE4IDkgQ4UhOSA6IESFITogOyBFhSE7IDwgRoUhPCA9IEeFIT0gPiBIhSE+ID8gSYUhPyBAIEqFIUAgQSBLhSFBIAQhAyAuIDh9IUIgLyA5fSFDIDAgOn0hRCAxIDt9IUUgMiA8fSFGIDMgPX0hRyA0ID59IUggNSA/fSFJIDYgQH0hSiA3IEF9IUsgGiAkfSFMIBsgJX0hTSAcICZ9IU4gHSAnfSFPIB4gKH0hUCAfICl9IVEgICAqfSFSICEgK30hUyAiICx9IVQgIyAtfSFVIBogJHwhGiAbICV8IRsgHCAmfCEcIB0gJ3whHSAeICh8IR4gHyApfCEfICAgKnwhICAhICt8ISEgIiAsfCEiICMgLXwhIyAuIDh8ISQgLyA5fCElIDAgOnwhJiAxIDt8IScgMiA8fCEoIDMgPXwhKSA0ID58ISogNSA/fCErIDYgQHwhLCA3IEF8IS0gGiAbIBwgHSAeIB8gICAhICIgIyBCIEMgRCBFIEYgRyBIIEkgSiBLIAZBAREAACBMIE0gTiBPIFAgUSBSIFMgVCBVICQgJSAmICcgKCApICogKyAsIC0gB0EBEQAAIEwgTSBOIE8gUCBRIFIgUyBUIFVBAEEAIAhBAhEBACAaIBsgHCAdIB4gHyAgICEgIiAjQQBBACAJQQIRAQAgBjUCACE4IAY1AgQhOSAGNQIIITogBjUCDCE7IAY1AhAhPCAGNQIUIT0gBjUCGCE+IAY1AhwhPyAGNQIgIUAgBjUCJCFBIAc1AgAhJCAHNQIEISUgBzUCCCEmIAc1AgwhJyAHNQIQISggBzUCFCEpIAc1AhghKiAHNQIcISsgBzUCICEsIAc1AiQhLSAINQIAIUIgCDUCBCFDIAg1AgghRCAINQIMIUUgCDUCECFGIAg1AhQhRyAINQIYIUggCDUCHCFJIAg1AiAhSiAINQIkIUsgCTUCACFMIAk1AgQhTSAJNQIIIU4gCTUCDCFPIAk1AhAhUCAJNQIUIVEgCTUCGCFSIAk1AhwhUyAJNQIgIVQgCTUCJCFVIDggJHwhLiA5ICV8IS8gOiAmfCEwIDsgJ3whMSA8ICh8ITIgPSApfCEzID4gKnwhNCA/ICt8ITUgQCAsfCE2IEEgLXwhNyA4ICR9ISQgOSAlfSElIDogJn0hJiA7ICd9IScgPCAofSEoID0gKX0hKSA+ICp9ISogPyArfSErIEAgLH0hLCBBIC19IS0gTCBNIE4gTyBQIFEgUiBTIFQgVSBCIEMgRCBFIEYgRyBIIEkgSiBLIAZBAREAACBMIEJ9IUwgTSBDfSFNIE4gRH0hTiBPIEV9IU8gUCBGfSFQIFEgR30hUSBSIEh9IVIgUyBJfSFTIFQgSn0hVCBVIEt9IVUgJCAlICYgJyAoICkgKiArICwgLUEAQQAgB0ECEQEAQsK2B0IAQgBCAEIAQgBCAEIAQgBCACBMIE0gTiBPIFAgUSBSIFMgVCBVIAhBAREAACAuIC8gMCAxIDIgMyA0IDUgNiA3QQBBACAJQQIRAQAgBjUCACEaIAY1AgQhGyAGNQIIIRwgBjUCDCEdIAY1AhAhHiAGNQIUIR8gBjUCGCEgIAY1AhwhISAGNQIgISIgBjUCJCEjIAc1AgAhJCAHNQIEISUgBzUCCCEmIAc1AgwhJyAHNQIQISggBzUCFCEpIAc1AhghKiAHNQIcISsgBzUCICEsIAc1AiQhLSAINQIAITggCDUCBCE5IAg1AgghOiAINQIMITsgCDUCECE8IAg1AhQhPSAINQIYIT4gCDUCHCE/IAg1AiAhQCAINQIkIUEgCTUCACEuIAk1AgQhLyAJNQIIITAgCTUCDCExIAk1AhAhMiAJNQIUITMgCTUCGCE0IAk1AhwhNSAJNQIgITYgCTUCJCE3IEIgOHwhQiBDIDl8IUMgRCA6fCFEIEUgO3whRSBGIDx8IUYgRyA9fCFHIEggPnwhSCBJID98IUkgSiBAfCFKIEsgQXwhSyAQIBEgEiATIBQgFSAWIBcgGCAZICQgJSAmICcgKCApICogKyAsIC0gB0EBEQAAIEIgQyBEIEUgRiBHIEggSSBKIEsgTCBNIE4gTyBQIFEgUiBTIFQgVSAGQQERAAAgBjUCACEkIAY1AgQhJSAGNQIIISYgBjUCDCEnIAY1AhAhKCAGNQIUISkgBjUCGCEqIAY1AhwhKyAGNQIgISwgBjUCJCEtIAc1AgAhOCAHNQIEITkgBzUCCCE6IAc1AgwhOyAHNQIQITwgBzUCFCE9IAc1AhghPiAHNQIcIT8gBzUCICFAIAc1AiQhQSAFQQFrIQUMAAsLQQAgA2utIQogGiAuhSAKgyFCIBsgL4UgCoMhQyAcIDCFIAqDIUQgHSAxhSAKgyFFIB4gMoUgCoMhRiAfIDOFIAqDIUcgICA0hSAKgyFIICEgNYUgCoMhSSAiIDaFIAqDIUogIyA3hSAKgyFLIBogQoUhGiAbIEOFIRsgHCBEhSEcIB0gRYUhHSAeIEaFIR4gHyBHhSEfICAgSIUhICAhIEmFISEgIiBKhSEiICMgS4UhIyAuIEKFIS4gLyBDhSEvIDAgRIUhMCAxIEWFITEgMiBGhSEyIDMgR4UhMyA0IEiFITQgNSBJhSE1IDYgSoUhNiA3IEuFITcgJCA4hSAKgyFCICUgOYUgCoMhQyAmIDqFIAqDIUQgJyA7hSAKgyFFICggPIUgCoMhRiApID2FIAqDIUcgKiA+hSAKgyFIICsgP4UgCoMhSSAsIECFIAqDIUogLSBBhSAKgyFLICQgQoUhJCAlIEOFISUgJiBEhSEmICcgRYUhJyAoIEaFISggKSBHhSEpICogSIUhKiArIEmFISsgLCBKhSEsIC0gS4UhLSA4IEKFITggOSBDhSE5IDogRIUhOiA7IEWFITsgPCBGhSE8ID0gR4UhPSA+IEiFIT4gPyBJhSE/IEAgSoUhQCBBIEuFIUEgJCAlICYgJyAoICkgKiArICwgLSAGQQMRAgAgBjUCACAGNQIEIAY1AgggBjUCDCAGNQIQIAY1AhQgBjUCGCAGNQIcIAY1AiAgBjUCJCAaIBsgHCAdIB4gHyAgICEgIiAjIABBAREAAAs=')
var ready = null
var mod = {
buffer: wasm,
memory: null,
exports: null,
realloc: realloc,
onload: onload
}
onload(function () {})
return mod
function realloc (size) {
mod.exports.memory.grow(Math.max(0, Math.ceil(Math.abs(size - mod.memory.length) / 65536)))
mod.memory = new Uint8Array(mod.exports.memory.buffer)
}
function onload (cb) {
if (mod.exports) return cb()
if (ready) {
ready.then(cb.bind(null, null)).catch(cb)
return
}
try {
if (opts && opts.async) throw new Error('async')
setup({instance: new WebAssembly.Instance(new WebAssembly.Module(wasm), imp)})
} catch (err) {
ready = WebAssembly.instantiate(wasm, imp).then(setup)
}
onload(cb)
}
function setup (w) {
mod.exports = w.instance.exports
mod.memory = mod.exports.memory && mod.exports.memory.buffer && new Uint8Array(mod.exports.memory.buffer)
}
}
function toUint8Array (s) {
if (typeof atob === 'function') return new Uint8Array(atob(s).split('').map(charCodeAt))
return (require('buf' + 'fer').Buffer).from(s, 'base64')
}
function charCodeAt (c) {
return c.charCodeAt(0)
}

File diff suppressed because it is too large Load Diff

View File

@ -11,23 +11,31 @@
forward(require('./randombytes'))
forward(require('./memory'))
forward(require('./helpers'))
forward(require('./crypto_verify'))
forward(require('./utils'))
forward(require('./crypto_aead'))
forward(require('./crypto_auth'))
forward(require('./crypto_box'))
forward(require('./crypto_core'))
forward(require('./crypto_core_ristretto255'))
forward(require('./crypto_generichash'))
forward(require('./crypto_hash'))
forward(require('./crypto_hash_sha256'))
forward(require('./crypto_kdf'))
forward(require('./crypto_kx'))
forward(require('./crypto_aead'))
forward(require('./crypto_pwhash'))
forward(require('./crypto_onetimeauth'))
forward(require('./crypto_scalarmult_ed25519'))
// forward(require('./crypto_scalarmult'))
forward(require('./crypto_scalarmult'))
forward(require('./crypto_secretbox'))
forward(require('./crypto_secretstream'))
forward(require('./crypto_shorthash'))
forward(require('./crypto_sign'))
// forward(require('./crypto_sign'))
forward(require('./crypto_sign_ed25519'))
forward(require('./crypto_stream'))
forward(require('./crypto_stream_chacha20'))
forward(require('./crypto_tweak'))
forward(require('./crypto_verify'))
function forward (submodule) {
Object.keys(submodule).forEach(function (prop) {

View File

@ -4,6 +4,7 @@
"description": "WIP - a pure javascript version of sodium-native",
"main": "index.js",
"dependencies": {
"argon2hash-wasm": "^1.0.0",
"blake2b": "^2.1.1",
"chacha20-universal": "^1.0.4",
"nanoassert": "^2.0.0",
@ -14,17 +15,16 @@
},
"devDependencies": {
"brittle": "^3.2.1",
"browser-run": "^4.0.2",
"browserify": "^16.5.1",
"sodium-native": "^3.4.1",
"standard": "^15.0.1"
},
"standard": {
"ignore": [
"/internal/**/*.js",
"/test/fixtures/*.js"
],
"rules": {
"camelcase": "off"
}
]
},
"browser": {
"crypto": false,

360
poly1305.js Normal file
View File

@ -0,0 +1,360 @@
/*
* Port of Andrew Moon's Poly1305-donna-16. Public domain.
* https://github.com/floodyberry/poly1305-donna
*/
if (new Uint16Array([1])[0] !== 1) throw new Error('Big endian architecture is not supported.')
var poly1305 = function(key) {
this.buffer = new Uint8Array(16);
this.r = new Uint16Array(10);
this.h = new Uint16Array(10);
this.pad = new Uint16Array(8);
this.leftover = 0;
this.fin = 0;
var t0, t1, t2, t3, t4, t5, t6, t7;
t0 = key[ 0] & 0xff | (key[ 1] & 0xff) << 8; this.r[0] = ( t0 ) & 0x1fff;
t1 = key[ 2] & 0xff | (key[ 3] & 0xff) << 8; this.r[1] = ((t0 >>> 13) | (t1 << 3)) & 0x1fff;
t2 = key[ 4] & 0xff | (key[ 5] & 0xff) << 8; this.r[2] = ((t1 >>> 10) | (t2 << 6)) & 0x1f03;
t3 = key[ 6] & 0xff | (key[ 7] & 0xff) << 8; this.r[3] = ((t2 >>> 7) | (t3 << 9)) & 0x1fff;
t4 = key[ 8] & 0xff | (key[ 9] & 0xff) << 8; this.r[4] = ((t3 >>> 4) | (t4 << 12)) & 0x00ff;
this.r[5] = ((t4 >>> 1)) & 0x1ffe;
t5 = key[10] & 0xff | (key[11] & 0xff) << 8; this.r[6] = ((t4 >>> 14) | (t5 << 2)) & 0x1fff;
t6 = key[12] & 0xff | (key[13] & 0xff) << 8; this.r[7] = ((t5 >>> 11) | (t6 << 5)) & 0x1f81;
t7 = key[14] & 0xff | (key[15] & 0xff) << 8; this.r[8] = ((t6 >>> 8) | (t7 << 8)) & 0x1fff;
this.r[9] = ((t7 >>> 5)) & 0x007f;
this.pad[0] = key[16] & 0xff | (key[17] & 0xff) << 8;
this.pad[1] = key[18] & 0xff | (key[19] & 0xff) << 8;
this.pad[2] = key[20] & 0xff | (key[21] & 0xff) << 8;
this.pad[3] = key[22] & 0xff | (key[23] & 0xff) << 8;
this.pad[4] = key[24] & 0xff | (key[25] & 0xff) << 8;
this.pad[5] = key[26] & 0xff | (key[27] & 0xff) << 8;
this.pad[6] = key[28] & 0xff | (key[29] & 0xff) << 8;
this.pad[7] = key[30] & 0xff | (key[31] & 0xff) << 8;
};
poly1305.prototype.blocks = function(m, mpos, bytes) {
var hibit = this.fin ? 0 : (1 << 11);
var t0, t1, t2, t3, t4, t5, t6, t7, c;
var d0, d1, d2, d3, d4, d5, d6, d7, d8, d9;
var h0 = this.h[0],
h1 = this.h[1],
h2 = this.h[2],
h3 = this.h[3],
h4 = this.h[4],
h5 = this.h[5],
h6 = this.h[6],
h7 = this.h[7],
h8 = this.h[8],
h9 = this.h[9];
var r0 = this.r[0],
r1 = this.r[1],
r2 = this.r[2],
r3 = this.r[3],
r4 = this.r[4],
r5 = this.r[5],
r6 = this.r[6],
r7 = this.r[7],
r8 = this.r[8],
r9 = this.r[9];
while (bytes >= 16) {
t0 = m[mpos+ 0] & 0xff | (m[mpos+ 1] & 0xff) << 8; h0 += ( t0 ) & 0x1fff;
t1 = m[mpos+ 2] & 0xff | (m[mpos+ 3] & 0xff) << 8; h1 += ((t0 >>> 13) | (t1 << 3)) & 0x1fff;
t2 = m[mpos+ 4] & 0xff | (m[mpos+ 5] & 0xff) << 8; h2 += ((t1 >>> 10) | (t2 << 6)) & 0x1fff;
t3 = m[mpos+ 6] & 0xff | (m[mpos+ 7] & 0xff) << 8; h3 += ((t2 >>> 7) | (t3 << 9)) & 0x1fff;
t4 = m[mpos+ 8] & 0xff | (m[mpos+ 9] & 0xff) << 8; h4 += ((t3 >>> 4) | (t4 << 12)) & 0x1fff;
h5 += ((t4 >>> 1)) & 0x1fff;
t5 = m[mpos+10] & 0xff | (m[mpos+11] & 0xff) << 8; h6 += ((t4 >>> 14) | (t5 << 2)) & 0x1fff;
t6 = m[mpos+12] & 0xff | (m[mpos+13] & 0xff) << 8; h7 += ((t5 >>> 11) | (t6 << 5)) & 0x1fff;
t7 = m[mpos+14] & 0xff | (m[mpos+15] & 0xff) << 8; h8 += ((t6 >>> 8) | (t7 << 8)) & 0x1fff;
h9 += ((t7 >>> 5)) | hibit;
c = 0;
d0 = c;
d0 += h0 * r0;
d0 += h1 * (5 * r9);
d0 += h2 * (5 * r8);
d0 += h3 * (5 * r7);
d0 += h4 * (5 * r6);
c = (d0 >>> 13); d0 &= 0x1fff;
d0 += h5 * (5 * r5);
d0 += h6 * (5 * r4);
d0 += h7 * (5 * r3);
d0 += h8 * (5 * r2);
d0 += h9 * (5 * r1);
c += (d0 >>> 13); d0 &= 0x1fff;
d1 = c;
d1 += h0 * r1;
d1 += h1 * r0;
d1 += h2 * (5 * r9);
d1 += h3 * (5 * r8);
d1 += h4 * (5 * r7);
c = (d1 >>> 13); d1 &= 0x1fff;
d1 += h5 * (5 * r6);
d1 += h6 * (5 * r5);
d1 += h7 * (5 * r4);
d1 += h8 * (5 * r3);
d1 += h9 * (5 * r2);
c += (d1 >>> 13); d1 &= 0x1fff;
d2 = c;
d2 += h0 * r2;
d2 += h1 * r1;
d2 += h2 * r0;
d2 += h3 * (5 * r9);
d2 += h4 * (5 * r8);
c = (d2 >>> 13); d2 &= 0x1fff;
d2 += h5 * (5 * r7);
d2 += h6 * (5 * r6);
d2 += h7 * (5 * r5);
d2 += h8 * (5 * r4);
d2 += h9 * (5 * r3);
c += (d2 >>> 13); d2 &= 0x1fff;
d3 = c;
d3 += h0 * r3;
d3 += h1 * r2;
d3 += h2 * r1;
d3 += h3 * r0;
d3 += h4 * (5 * r9);
c = (d3 >>> 13); d3 &= 0x1fff;
d3 += h5 * (5 * r8);
d3 += h6 * (5 * r7);
d3 += h7 * (5 * r6);
d3 += h8 * (5 * r5);
d3 += h9 * (5 * r4);
c += (d3 >>> 13); d3 &= 0x1fff;
d4 = c;
d4 += h0 * r4;
d4 += h1 * r3;
d4 += h2 * r2;
d4 += h3 * r1;
d4 += h4 * r0;
c = (d4 >>> 13); d4 &= 0x1fff;
d4 += h5 * (5 * r9);
d4 += h6 * (5 * r8);
d4 += h7 * (5 * r7);
d4 += h8 * (5 * r6);
d4 += h9 * (5 * r5);
c += (d4 >>> 13); d4 &= 0x1fff;
d5 = c;
d5 += h0 * r5;
d5 += h1 * r4;
d5 += h2 * r3;
d5 += h3 * r2;
d5 += h4 * r1;
c = (d5 >>> 13); d5 &= 0x1fff;
d5 += h5 * r0;
d5 += h6 * (5 * r9);
d5 += h7 * (5 * r8);
d5 += h8 * (5 * r7);
d5 += h9 * (5 * r6);
c += (d5 >>> 13); d5 &= 0x1fff;
d6 = c;
d6 += h0 * r6;
d6 += h1 * r5;
d6 += h2 * r4;
d6 += h3 * r3;
d6 += h4 * r2;
c = (d6 >>> 13); d6 &= 0x1fff;
d6 += h5 * r1;
d6 += h6 * r0;
d6 += h7 * (5 * r9);
d6 += h8 * (5 * r8);
d6 += h9 * (5 * r7);
c += (d6 >>> 13); d6 &= 0x1fff;
d7 = c;
d7 += h0 * r7;
d7 += h1 * r6;
d7 += h2 * r5;
d7 += h3 * r4;
d7 += h4 * r3;
c = (d7 >>> 13); d7 &= 0x1fff;
d7 += h5 * r2;
d7 += h6 * r1;
d7 += h7 * r0;
d7 += h8 * (5 * r9);
d7 += h9 * (5 * r8);
c += (d7 >>> 13); d7 &= 0x1fff;
d8 = c;
d8 += h0 * r8;
d8 += h1 * r7;
d8 += h2 * r6;
d8 += h3 * r5;
d8 += h4 * r4;
c = (d8 >>> 13); d8 &= 0x1fff;
d8 += h5 * r3;
d8 += h6 * r2;
d8 += h7 * r1;
d8 += h8 * r0;
d8 += h9 * (5 * r9);
c += (d8 >>> 13); d8 &= 0x1fff;
d9 = c;
d9 += h0 * r9;
d9 += h1 * r8;
d9 += h2 * r7;
d9 += h3 * r6;
d9 += h4 * r5;
c = (d9 >>> 13); d9 &= 0x1fff;
d9 += h5 * r4;
d9 += h6 * r3;
d9 += h7 * r2;
d9 += h8 * r1;
d9 += h9 * r0;
c += (d9 >>> 13); d9 &= 0x1fff;
c = (((c << 2) + c)) | 0;
c = (c + d0) | 0;
d0 = c & 0x1fff;
c = (c >>> 13);
d1 += c;
h0 = d0;
h1 = d1;
h2 = d2;
h3 = d3;
h4 = d4;
h5 = d5;
h6 = d6;
h7 = d7;
h8 = d8;
h9 = d9;
mpos += 16;
bytes -= 16;
}
this.h[0] = h0;
this.h[1] = h1;
this.h[2] = h2;
this.h[3] = h3;
this.h[4] = h4;
this.h[5] = h5;
this.h[6] = h6;
this.h[7] = h7;
this.h[8] = h8;
this.h[9] = h9;
};
poly1305.prototype.finish = function(mac, macpos) {
var g = new Uint16Array(10);
var c, mask, f, i;
if (this.leftover) {
i = this.leftover;
this.buffer[i++] = 1;
for (; i < 16; i++) this.buffer[i] = 0;
this.fin = 1;
this.blocks(this.buffer, 0, 16);
}
c = this.h[1] >>> 13;
this.h[1] &= 0x1fff;
for (i = 2; i < 10; i++) {
this.h[i] += c;
c = this.h[i] >>> 13;
this.h[i] &= 0x1fff;
}
this.h[0] += (c * 5);
c = this.h[0] >>> 13;
this.h[0] &= 0x1fff;
this.h[1] += c;
c = this.h[1] >>> 13;
this.h[1] &= 0x1fff;
this.h[2] += c;
g[0] = this.h[0] + 5;
c = g[0] >>> 13;
g[0] &= 0x1fff;
for (i = 1; i < 10; i++) {
g[i] = this.h[i] + c;
c = g[i] >>> 13;
g[i] &= 0x1fff;
}
g[9] -= (1 << 13);
mask = (c ^ 1) - 1;
for (i = 0; i < 10; i++) g[i] &= mask;
mask = ~mask;
for (i = 0; i < 10; i++) this.h[i] = (this.h[i] & mask) | g[i];
this.h[0] = ((this.h[0] ) | (this.h[1] << 13) ) & 0xffff;
this.h[1] = ((this.h[1] >>> 3) | (this.h[2] << 10) ) & 0xffff;
this.h[2] = ((this.h[2] >>> 6) | (this.h[3] << 7) ) & 0xffff;
this.h[3] = ((this.h[3] >>> 9) | (this.h[4] << 4) ) & 0xffff;
this.h[4] = ((this.h[4] >>> 12) | (this.h[5] << 1) | (this.h[6] << 14)) & 0xffff;
this.h[5] = ((this.h[6] >>> 2) | (this.h[7] << 11) ) & 0xffff;
this.h[6] = ((this.h[7] >>> 5) | (this.h[8] << 8) ) & 0xffff;
this.h[7] = ((this.h[8] >>> 8) | (this.h[9] << 5) ) & 0xffff;
f = this.h[0] + this.pad[0];
this.h[0] = f & 0xffff;
for (i = 1; i < 8; i++) {
f = (((this.h[i] + this.pad[i]) | 0) + (f >>> 16)) | 0;
this.h[i] = f & 0xffff;
}
mac[macpos+ 0] = (this.h[0] >>> 0) & 0xff;
mac[macpos+ 1] = (this.h[0] >>> 8) & 0xff;
mac[macpos+ 2] = (this.h[1] >>> 0) & 0xff;
mac[macpos+ 3] = (this.h[1] >>> 8) & 0xff;
mac[macpos+ 4] = (this.h[2] >>> 0) & 0xff;
mac[macpos+ 5] = (this.h[2] >>> 8) & 0xff;
mac[macpos+ 6] = (this.h[3] >>> 0) & 0xff;
mac[macpos+ 7] = (this.h[3] >>> 8) & 0xff;
mac[macpos+ 8] = (this.h[4] >>> 0) & 0xff;
mac[macpos+ 9] = (this.h[4] >>> 8) & 0xff;
mac[macpos+10] = (this.h[5] >>> 0) & 0xff;
mac[macpos+11] = (this.h[5] >>> 8) & 0xff;
mac[macpos+12] = (this.h[6] >>> 0) & 0xff;
mac[macpos+13] = (this.h[6] >>> 8) & 0xff;
mac[macpos+14] = (this.h[7] >>> 0) & 0xff;
mac[macpos+15] = (this.h[7] >>> 8) & 0xff;
};
poly1305.prototype.update = function(m, mpos, bytes) {
var i, want;
if (this.leftover) {
want = (16 - this.leftover);
if (want > bytes)
want = bytes;
for (i = 0; i < want; i++)
this.buffer[this.leftover + i] = m[mpos+i];
bytes -= want;
mpos += want;
this.leftover += want;
if (this.leftover < 16)
return;
this.blocks(this.buffer, 0, 16);
this.leftover = 0;
}
if (bytes >= 16) {
want = bytes - (bytes % 16);
this.blocks(m, mpos, want);
mpos += want;
bytes -= want;
}
if (bytes) {
for (i = 0; i < bytes; i++)
this.buffer[this.leftover + i] = m[mpos+i];
this.leftover += bytes;
}
};
module.exports = poly1305

View File

@ -1,5 +1,13 @@
var assert = require('nanoassert')
const {
crypto_stream_chacha20_ietf,
crypto_stream_chacha20_ietf_KEYBYTES,
crypto_stream_chacha20_ietf_NONCEBYTES
} = require('./crypto_stream_chacha20')
const randombytes_SEEDBYTES = 32
var randombytes = (function () {
var QUOTA = 65536 // limit for QuotaExceededException
var crypto = globalThis.crypto || globalThis.msCrypto
@ -34,7 +42,21 @@ Object.defineProperty(module.exports, 'randombytes', {
value: randombytes
})
module.exports.randombytes_buf = function (out) {
function randombytes_buf (out) {
assert(out, 'out must be given')
randombytes(out, out.byteLength)
}
function randombytes_buf_deterministic (buf, seed) {
const nonce = Buffer.alloc(crypto_stream_chacha20_ietf_NONCEBYTES)
nonce.write('LibsodiumDRG')
assert(randombytes_SEEDBYTES === crypto_stream_chacha20_ietf_KEYBYTES)
crypto_stream_chacha20_ietf(buf, nonce, seed)
}
module.exports = {
randombytes_buf,
randombytes_buf_deterministic,
randombytes_SEEDBYTES
}

226
test/crypto_pwhash.js Normal file
View File

@ -0,0 +1,226 @@
const test = require('brittle')
const sodium = require('..')
test('constants', function (t) {
t.ok(sodium.crypto_pwhash_ALG_ARGON2I13 != null, 'crypto_pwhash_ALG_ARGON2I13 is defined')
t.ok(sodium.crypto_pwhash_ALG_ARGON2ID13 != null, 'crypto_pwhash_ALG_ARGON2ID13 is defined')
t.ok(sodium.crypto_pwhash_ALG_DEFAULT === sodium.crypto_pwhash_ALG_ARGON2ID13, 'crypto_pwhash_ALG_DEFAULT is crypto_pwhash_ALG_ARGON2ID13')
t.ok(sodium.crypto_pwhash_BYTES_MIN != null, 'crypto_pwhash_BYTES_MIN is defined')
t.ok(sodium.crypto_pwhash_BYTES_MAX != null, 'crypto_pwhash_BYTES_MAX is defined')
t.ok(sodium.crypto_pwhash_PASSWD_MIN != null, 'crypto_pwhash_PASSWD_MIN is defined')
t.ok(sodium.crypto_pwhash_PASSWD_MAX != null, 'crypto_pwhash_PASSWD_MAX is defined')
t.ok(sodium.crypto_pwhash_SALTBYTES != null, 'crypto_pwhash_SALTBYTES is defined')
t.ok(sodium.crypto_pwhash_STRBYTES != null, 'crypto_pwhash_STRBYTES is defined')
t.ok(sodium.crypto_pwhash_OPSLIMIT_MIN != null, 'crypto_pwhash_OPSLIMIT_MIN is defined')
t.ok(sodium.crypto_pwhash_OPSLIMIT_MAX != null, 'crypto_pwhash_OPSLIMIT_MAX is defined')
t.ok(sodium.crypto_pwhash_MEMLIMIT_MIN != null, 'crypto_pwhash_MEMLIMIT_MIN is defined')
t.ok(sodium.crypto_pwhash_MEMLIMIT_MAX != null, 'crypto_pwhash_MEMLIMIT_MAX is defined')
t.ok(sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE != null, 'crypto_pwhash_OPSLIMIT_INTERACTIVE is defined')
t.ok(sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE != null, 'crypto_pwhash_MEMLIMIT_INTERACTIVE is defined')
t.ok(sodium.crypto_pwhash_OPSLIMIT_MODERATE != null, 'crypto_pwhash_OPSLIMIT_MODERATE is defined')
t.ok(sodium.crypto_pwhash_MEMLIMIT_MODERATE != null, 'crypto_pwhash_MEMLIMIT_MODERATE is defined')
t.ok(sodium.crypto_pwhash_OPSLIMIT_SENSITIVE != null, 'crypto_pwhash_OPSLIMIT_SENSITIVE is defined')
t.ok(sodium.crypto_pwhash_MEMLIMIT_SENSITIVE != null, 'crypto_pwhash_MEMLIMIT_SENSITIVE is defined')
})
test('crypto_pwhash', function (t) {
const output = Buffer.alloc(32) // can be any size
const passwd = Buffer.from('Hej, Verden!')
const salt = Buffer.alloc(sodium.crypto_pwhash_SALTBYTES, 'lo')
const opslimit = sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE
const memlimit = sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE
const algo = sodium.crypto_pwhash_ALG_DEFAULT
sodium.crypto_pwhash(output, passwd, salt, opslimit, memlimit, algo)
t.alike(output.toString('hex'), 'f0236e17ec70050fc989f19d8ce640301e8f912154b4f0afc1552cdf246e659f', 'hashes password')
salt[0] = 0
sodium.crypto_pwhash(output, passwd, salt, opslimit, memlimit, algo)
t.alike(output.toString('hex'), 'df73f15d217196311d4b1aa6fba339905ffe581dee4bd3a95ec2bb7c52991d65', 'diff salt -> diff hash')
})
test('crypto_pwhash_str', function (t) {
const output = Buffer.alloc(sodium.crypto_pwhash_STRBYTES)
const passwd = Buffer.from('Hej, Verden!')
const opslimit = sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE
const memlimit = sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE
t.exception.all(function () {
sodium.crypto_pwhash_str(output, passwd)
}, 'should throw on missing args')
sodium.crypto_pwhash_str(output, passwd, opslimit, memlimit)
t.not(output, Buffer.alloc(output.length), 'not blank')
t.absent(sodium.crypto_pwhash_str_verify(Buffer.alloc(output.length), passwd), 'does not verify')
t.ok(sodium.crypto_pwhash_str_verify(output, passwd), 'verifies')
})
test('crypto_pwhash_str_needs_rehash', function (t) {
const passwd = Buffer.from('secret')
const weakMem = Buffer.alloc(sodium.crypto_pwhash_STRBYTES)
const weakOps = Buffer.alloc(sodium.crypto_pwhash_STRBYTES)
const malformed = Buffer.alloc(sodium.crypto_pwhash_STRBYTES)
const good = Buffer.alloc(sodium.crypto_pwhash_STRBYTES)
const weakAlg = Buffer.alloc(sodium.crypto_pwhash_STRBYTES)
weakAlg.set(Buffer.from('$argon2id$v=19$m=8,t=1,p=1$DF4Tce8BK5di0gKeMBb2Fw$uNE4oyvyA0z68RPUom2NXu/KyGvpFppyUoN6pwFBtRU'))
sodium.crypto_pwhash_str(weakMem, passwd, sodium.crypto_pwhash_OPSLIMIT_MODERATE, sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE)
sodium.crypto_pwhash_str(weakOps, passwd, sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE, sodium.crypto_pwhash_MEMLIMIT_MODERATE)
sodium.crypto_pwhash_str(malformed, passwd, sodium.crypto_pwhash_OPSLIMIT_MODERATE, sodium.crypto_pwhash_MEMLIMIT_MODERATE)
sodium.crypto_pwhash_str(good, passwd, sodium.crypto_pwhash_OPSLIMIT_MODERATE, sodium.crypto_pwhash_MEMLIMIT_MODERATE)
const first$ = malformed.indexOf('$')
const second$ = malformed.indexOf('$', first$ + 1)
malformed.fill('p=,m=,', first$, second$, 'ascii')
t.ok(sodium.crypto_pwhash_str_needs_rehash(weakMem, sodium.crypto_pwhash_OPSLIMIT_MODERATE, sodium.crypto_pwhash_MEMLIMIT_MODERATE))
t.ok(sodium.crypto_pwhash_str_needs_rehash(weakOps, sodium.crypto_pwhash_OPSLIMIT_MODERATE, sodium.crypto_pwhash_MEMLIMIT_MODERATE))
t.ok(sodium.crypto_pwhash_str_needs_rehash(weakAlg, sodium.crypto_pwhash_OPSLIMIT_MODERATE, sodium.crypto_pwhash_MEMLIMIT_MODERATE))
t.absent(sodium.crypto_pwhash_str_needs_rehash(good, sodium.crypto_pwhash_OPSLIMIT_MODERATE, sodium.crypto_pwhash_MEMLIMIT_MODERATE))
t.ok(sodium.crypto_pwhash_str_needs_rehash(
, sodium.crypto_pwhash_OPSLIMIT_MODERATE, sodium.crypto_pwhash_MEMLIMIT_MODERATE))
})
test('crypto_pwhash_async', function (t) {
t.plan(4)
const output = Buffer.alloc(32) // can be any size
const passwd = Buffer.from('Hej, Verden!')
const salt = Buffer.alloc(sodium.crypto_pwhash_SALTBYTES, 'lo')
const opslimit = sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE
const memlimit = sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE
const algo = sodium.crypto_pwhash_ALG_DEFAULT
sodium.crypto_pwhash_async(output, passwd, salt, opslimit, memlimit, algo, function (err) {
t.absent(err)
t.alike(output.toString('hex'), 'f0236e17ec70050fc989f19d8ce640301e8f912154b4f0afc1552cdf246e659f', 'hashes password')
salt[0] = 0
sodium.crypto_pwhash_async(output, passwd, salt, opslimit, memlimit, algo, function (err) {
t.absent(err)
t.alike(output.toString('hex'), 'df73f15d217196311d4b1aa6fba339905ffe581dee4bd3a95ec2bb7c52991d65', 'diff salt -> diff hash')
})
})
})
test('crypto_pwhash_str_async', function (t) {
t.plan(7)
const output = Buffer.alloc(sodium.crypto_pwhash_STRBYTES)
const passwd = Buffer.from('Hej, Verden!')
const opslimit = sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE
const memlimit = sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE
t.exception.all(function () {
sodium.crypto_pwhash_str_async(output, passwd)
}, 'should throw on missing args')
sodium.crypto_pwhash_str_async(output, passwd, opslimit, memlimit, function (err) {
t.absent(err)
t.not(output, Buffer.alloc(output.length), 'not blank')
sodium.crypto_pwhash_str_verify_async(Buffer.alloc(output.length), passwd, function (err, bool) {
t.absent(err)
t.ok(bool === false, 'does not verify')
sodium.crypto_pwhash_str_verify_async(output, passwd, function (err, bool) {
t.absent(err)
t.ok(bool === true, 'verifies')
})
})
})
})
test('crypto_pwhash limits', function (t) {
const output = Buffer.alloc(sodium.crypto_pwhash_STRBYTES)
const passwd = Buffer.from('Hej, Verden!')
const opslimit = Number.MAX_SAFE_INTEGER
const memlimit = Number.MAX_SAFE_INTEGER
t.exception.all(function () {
sodium.crypto_pwhash_str(output, passwd, opslimit, memlimit)
}, 'should throw on large limits')
t.exception.all(function () {
sodium.crypto_pwhash_str(output, passwd, -1, -1)
}, 'should throw on negative limits')
})
test('crypto_pwhash_async uncaughtException', function (t) {
t.plan(1)
const output = Buffer.alloc(32) // can be any size
const passwd = Buffer.from('Hej, Verden!')
const salt = Buffer.alloc(sodium.crypto_pwhash_SALTBYTES, 'lo')
const opslimit = sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE
const memlimit = sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE
const algo = sodium.crypto_pwhash_ALG_DEFAULT
process.once('uncaughtException', listener)
sodium.crypto_pwhash_async(output, passwd, salt, opslimit, memlimit, algo, exception)
function exception () {
throw new Error('caught')
}
function listener (err) {
if (err.message !== 'caught') {
t.fail()
} else {
t.pass()
}
}
})
test('crypto_pwhash_str_async uncaughtException', function (t) {
t.plan(1)
const output = Buffer.alloc(sodium.crypto_pwhash_STRBYTES) // can be any size
const passwd = Buffer.from('Hej, Verden!')
const opslimit = sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE
const memlimit = sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE
process.once('uncaughtException', listener)
sodium.crypto_pwhash_str_async(output, passwd, opslimit, memlimit, exception)
function exception () {
throw new Error('caught')
}
function listener (err) {
if (err.message === 'caught') {
t.pass()
} else {
t.fail()
}
}
})
test('crypto_pwhash_str_verify_async uncaughtException', function (t) {
t.plan(1)
const output = Buffer.alloc(sodium.crypto_pwhash_STRBYTES) // can be any size
const passwd = Buffer.from('Hej, Verden!')
process.once('uncaughtException', listener)
sodium.crypto_pwhash_str_verify_async(output, passwd, exception)
function exception () {
throw new Error('caught')
}
function listener (err) {
if (err.message === 'caught') {
t.pass()
} else {
t.fail()
}
}
})

View File

@ -0,0 +1,113 @@
const test = require('brittle')
const sodium = require('..')
const fixtures = require('./fixtures/crypto_tweak_ed25519_sign.js')
test('crypto_tweak', function (t) {
const pk = Buffer.alloc(sodium.crypto_sign_PUBLICKEYBYTES)
const sk = Buffer.alloc(sodium.crypto_sign_SECRETKEYBYTES)
sodium.crypto_sign_keypair(pk, sk)
const tpk = Buffer.alloc(sodium.crypto_tweak_ed25519_BYTES)
const tsk = Buffer.alloc(sodium.crypto_tweak_ed25519_SCALARBYTES)
const tkpk = Buffer.alloc(sodium.crypto_tweak_ed25519_BYTES)
const tksk = Buffer.alloc(sodium.crypto_tweak_ed25519_SCALARBYTES)
const point = Buffer.alloc(sodium.crypto_tweak_ed25519_BYTES)
const tweak = Buffer.alloc(sodium.crypto_tweak_ed25519_SCALARBYTES)
const ns = Buffer.alloc(32)
sodium.crypto_generichash(ns, Buffer.from('namespace'))
t.exception.all(function () {
sodium.crypto_tweak_ed25519_base()
}, 'should validate input')
t.exception.all(function () {
sodium.crypto_tweak_ed25519_base(Buffer.alloc(0), Buffer.alloc(0), ns)
}, 'should validate input length')
sodium.crypto_tweak_ed25519_base(tweak, point, ns)
const _sk = sk.subarray(0, 32)
sodium.crypto_tweak_ed25519_sk_to_scalar(_sk, sk)
sodium.crypto_tweak_ed25519_pk(tpk, pk, ns)
sodium.crypto_tweak_ed25519_scalar(tsk, _sk, ns)
sodium.crypto_tweak_ed25519_keypair(tkpk, tksk, _sk, ns)
sodium.crypto_tweak_ed25519_pk_add(pk, pk, point)
sodium.crypto_tweak_ed25519_scalar_add(_sk, _sk, tweak)
t.alike(pk, tpk, 'tweak public key')
t.alike(_sk, tsk, 'tweak secret key')
t.alike(pk, tkpk, 'tweak keypair public key')
t.alike(_sk, tksk, 'tweak keypair secret key')
})
test('crypto_tweak_sign', function (t) {
const pk = Buffer.alloc(sodium.crypto_sign_PUBLICKEYBYTES)
const sk = Buffer.alloc(sodium.crypto_sign_SECRETKEYBYTES)
sodium.crypto_sign_keypair(pk, sk)
const tpk = Buffer.alloc(sodium.crypto_tweak_ed25519_BYTES)
const tsk = Buffer.alloc(sodium.crypto_tweak_ed25519_SCALARBYTES)
const point = Buffer.alloc(sodium.crypto_tweak_ed25519_BYTES)
const tweak = Buffer.alloc(sodium.crypto_tweak_ed25519_SCALARBYTES)
const ns = Buffer.alloc(32)
sodium.crypto_generichash(ns, Buffer.from('namespace'))
sodium.crypto_tweak_ed25519_base(tweak, point, ns)
sodium.crypto_tweak_ed25519_pk(tpk, pk, ns)
sodium.crypto_tweak_ed25519_sk_to_scalar(tsk, sk)
sodium.crypto_tweak_ed25519_scalar(tsk, tsk, ns)
sodium.crypto_tweak_ed25519_pk_add(pk, pk, point)
const _sk = sk.subarray(0, 32)
sodium.crypto_tweak_ed25519_sk_to_scalar(_sk, sk)
sodium.crypto_tweak_ed25519_scalar_add(_sk, _sk, tweak)
const m = Buffer.from('test message')
const sig = Buffer.alloc(sodium.crypto_sign_BYTES)
sodium.crypto_tweak_ed25519_sign_detached(sig, m, _sk)
t.ok(sodium.crypto_sign_verify_detached(sig, m, pk))
t.ok(sodium.crypto_sign_verify_detached(sig, m, tpk))
sodium.crypto_tweak_ed25519_sign_detached(sig, m, tsk)
t.ok(sodium.crypto_sign_verify_detached(sig, m, pk))
t.ok(sodium.crypto_sign_verify_detached(sig, m, tpk))
})
test('crypto_tweak sign fixtures', t => {
for (const f of fixtures) {
const [sk, n, m, sig, tweak, tpk, tn] = f.map(Buffer.from)
const signature = Buffer.alloc(64)
const scalar = Buffer.alloc(32)
const pk = Buffer.alloc(32)
sodium.crypto_tweak_ed25519_sk_to_scalar(scalar, sk)
t.alike(scalar, n)
sodium.crypto_tweak_ed25519_sign_detached(signature, m, n)
t.alike(signature, sig)
sodium.randombytes_buf(signature)
sodium.crypto_sign_ed25519_sk_to_pk(pk, sk)
sodium.crypto_tweak_ed25519_sign_detached(signature, m, n, pk)
t.alike(signature, sig)
sodium.crypto_tweak_ed25519_keypair(pk, scalar, n, tweak)
t.alike(pk, tpk)
t.alike(scalar, tn)
}
})