first attempt at wassm scalarmult

This commit is contained in:
Christophe Diederichs 2020-10-16 01:10:52 +02:00
parent a02899bfe2
commit bafe8f8fac
12 changed files with 1339 additions and 1287 deletions

View File

@ -6,6 +6,7 @@ module.exports = {
crypto_scalarmult_ed25519,
crypto_scalarmult_ed25519_base,
crypto_scalarmult_curve25519,
crypto_scalarmult_curve25519_1,
crypto_scalarmult_curve25519_base
}
@ -294,6 +295,44 @@ function crypto_scalarmult_curve25519 (q, n, p) {
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
if (has_small_order(p)) {
return -1;
}
for (i = 0; i < 32; i++) {
t[i] = n[i]
}
t[0] &= 248
t[31] &= 127
t[31] |= 64
ec.fe25519_frombytes(x1, p)
ec.fe25519_1(x2)
ec.fe25519_0(z2)
ec.fe25519_copy(x3, x1)
ec.fe25519_1(z3)
swap = ec.scalarmult_curve25519_inner_loop(x1, x2, x3, z2, z3, t)
ec.fe25519_cswap(x2, x3, swap)
ec.fe25519_cswap(z2, z3, swap)
ec.fe25519_invert(z2, z2)
ec.fe25519_mul(x2, x2, z2)
ec.fe25519_tobytes(q, x2)
return 0
}
function edwards_to_montgomery(montgomeryX, edwardsY, edwardsZ) {
var tempX = ec.fe25519()
var tempZ = ec.fe25519()

View File

@ -1,5 +1,5 @@
const sodium = require('./')
const { crypto_scalarmult_ed25519, crypto_scalarmult_ed25519_base, crypto_scalarmult_curve25519, crypto_scalarmult_curve25519_base } = require('./crypto_scalarmult_ed25519')
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 } = require('./crypto_sign_ed25519')
console.log(crypto_scalarmult_ed25519)
@ -102,13 +102,24 @@ 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.log(res.toString('hex'))
console.log(res1.toString('hex'))
// console.log(sm.toString('hex'))
// pass &= smlen === sodium.crypto_sign_BYTES + test.m.byteLength

View File

@ -165,14 +165,14 @@ console.log('tess :', res.toString('hex'))
console.time('standard')
for (let i = 0; i < 10000; i++) ec.fe25519_pow22523(b, a)
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++) wasm_pow(b, a)
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'))

View File

@ -11,50 +11,26 @@ const debug = {
}
}
const wasm_mul = require('./fe25519_25/fe25519_mul')({
imports: { debug }
})
const wasm_sq = require('./fe25519_25/fe25519_sq')({
imports: { debug }
})
const wasm_invert = require('./fe25519_25/fe25519_invert')({
imports: { debug }
})
const wasm_pow = require('./fe25519_25/fe25519_pow22523')({
imports: { debug }
})
const tbl = new WebAssembly.Table({ initial: 2, element: "anyfunc" })
const wasm_sc_red = require('./fe25519_25/sc_reduce')({
const importObject = {
imports: {
debug,
js: {
table: tbl
table: new WebAssembly.Table({ initial: 3, element: "anyfunc" })
},
debug
}
}
})
const wasm_sc_mul = require('./fe25519_25/sc25519_mul')({
imports: {
debug,
js: {
table: tbl
}
}
})
const wasm_sc_muladd = require('./fe25519_25/sc25519_muladd')({
imports: {
debug,
js: {
table: tbl
}
}
})
const wasm_mul = require('./fe25519_25/fe25519_mul')(importObject)
const wasm_sq = require('./fe25519_25/fe25519_sq')(importObject)
const wasm_invert = require('./fe25519_25/fe25519_invert')()
const wasm_pow = require('./fe25519_25/fe25519_pow22523')()
const wasm_sc_red = require('./fe25519_25/sc_reduce')(importObject)
const wasm_sc_mul = require('./fe25519_25/sc25519_mul')(importObject)
const wasm_sc_muladd = require('./fe25519_25/sc25519_muladd')(importObject)
const wasm_scalaramult_internal = require('./fe25519_25/scalarmult_curve25519')(importObject)
function fe25519_invert (h, f) {
var buf = Buffer.from(f.buffer)
var buf = new Uint8Array(f.buffer)
wasm_invert.memory.set(buf)
wasm_invert.exports.fe25519_invert(40, 0)
@ -63,10 +39,13 @@ function fe25519_invert (h, f) {
for (let i = 0; i < 10; i++) {
h[i] = buf.readUInt32LE(4 * i)
}
for (let i = 0; i < 10; i++) {
h[i] = buf.readUInt32LE(4 * i)
}
}
function fe25519_pow22523 (h, f) {
var buf = Buffer.from(f.buffer)
var buf = new Uint8Array(f.buffer)
wasm_pow.memory.set(buf)
wasm_pow.exports.fe25519_pow22523(40, 0)
@ -75,6 +54,9 @@ function fe25519_pow22523 (h, f) {
for (let i = 0; i < 10; i++) {
h[i] = buf.readUInt32LE(4 * i)
}
for (let i = 0; i < 10; i++) {
h[i] = buf.readUInt32LE(4 * i)
}
}
const base = require('./fe25519_25/base.json').map(a => a.map(b => ge2(b)))
@ -104,9 +86,10 @@ module.exports = {
fe25519_sq,
fe25519_sqmul,
fe25519_sq2,
fe25519_invert: fe25519_invert,
fe25519_pow22523: fe25519_pow22523,
fe25519_unchecked_sqrt,
fe25519_invert,
fe25519_invert_1,
fe25519_pow22523,
fe25519_pow22523_1,
fe25519_sqrt,
ge25519_has_small_order,
ge25519_frombytes,
@ -132,6 +115,7 @@ module.exports = {
ge25519_elligator2,
ge25519_from_uniform,
ge25519_from_hash,
scalarmult_curve25519_inner_loop,
ristretto255_sqrt_ratio_m1,
ristretto255_is_canonical,
ristretto255_frombytes,
@ -778,8 +762,8 @@ function fe25519_mul (h, f, g) {
// printFe(f, 'f')
// printFe(g, 'g')
var fbuf = Buffer.from(f.buffer)
var gbuf = Buffer.from(g.buffer)
var fbuf = new Uint8Array(f.buffer)
var gbuf = new Uint8Array(g.buffer)
wasm_mul.memory.set(fbuf)
wasm_mul.memory.set(gbuf, 40)
@ -806,7 +790,7 @@ function fe25519_sq (h, f, log) {
check_fe(h)
check_fe(f)
var buf = Buffer.from(f.buffer)
var buf = new Uint8Array(f.buffer)
wasm_sq.memory.set(buf)
wasm_sq.exports.sq(40, 0, 0)
@ -832,7 +816,7 @@ function fe25519_sq2 (h, f) {
check_fe(h)
check_fe(f)
var buf = Buffer.from(f.buffer)
var buf = new Uint8Array(f.buffer)
wasm_sq.memory.set(buf)
wasm_sq.exports.sq(40, 0, 1)
@ -998,7 +982,6 @@ function fe25519_sqrt (x, x2) {
fe25519_copy(x2_copy, x2)
fe25519_unchecked_sqrt(x, x2)
console.log(x, 'sqrt')
fe25519_sq(check, x)
fe25519_sub(check, check, x2_copy)
@ -2309,7 +2292,7 @@ function sc25519_reduce (s) {
_s[22] = 2097151 & (load_4(s, 57) >>> 6)
_s[23] = load_4(s, 60) >>> 3
var sbuf = Buffer.from(_s.buffer)
var sbuf = new Uint8Array(_s.buffer)
wasm_sc_red.memory.set(sbuf, 0)
wasm_sc_red.exports.sc25519_reduce(0)
@ -2835,6 +2818,48 @@ function ristretto255_from_hash (s, h) {
ristretto255_p3_tobytes(s, p)
}
function scalarmult_curve25519_inner_loop (x1, x2, x3, z2, z3, t) {
check_fe(x1)
check_fe(x2)
check_fe(x3)
check_fe(z2)
check_fe(z3)
assert(t instanceof Uint8Array && t.byteLength === 32)
// printFe(f, 'f')
// printFe(g, 'g')
const x1buf = new Uint8Array(x1.buffer)
const x2buf = new Uint8Array(x2.buffer)
const x3buf = new Uint8Array(x3.buffer)
const z2buf = new Uint8Array(z2.buffer)
const z3buf = new Uint8Array(z3.buffer)
const tbuf = new Uint8Array(t.buffer)
wasm_scalaramult_internal.memory.set(x1buf, 0)
wasm_scalaramult_internal.memory.set(x2buf, 40)
wasm_scalaramult_internal.memory.set(x3buf, 80)
wasm_scalaramult_internal.memory.set(z2buf, 120)
wasm_scalaramult_internal.memory.set(z3buf, 160)
wasm_scalaramult_internal.memory.set(tbuf, 200)
const swap = wasm_scalaramult_internal.exports.scalarmult(0, 40, 80, 120, 160, 200, 240, 280, 320, 360)
buf = Buffer.from(wasm_scalaramult_internal.memory.slice(240, 400))
for (let i = 0; i < 10; i++) {
x2[i] = buf.readInt32LE(4 * i)
}
for (let i = 10; i < 20; i++) {
x3[i % 10] = buf.readInt32LE(4 * i)
}
for (let i = 20; i < 30; i++) {
z2[i % 10] = buf.readInt32LE(4 * i)
}
for (let i = 30; i < 40; i++) {
z3[i % 10] = buf.readInt32LE(4 * i)
}
return swap
}
function check_fe (h) {
assert(h instanceof Int32Array)
assert(h.length === 10)

File diff suppressed because one or more lines are too long

View File

@ -1,35 +1,7 @@
(module
(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))
(memory $0 1)
(export "memory" (memory $0))
;; 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)))
(global $tmp0 (mut i64) (i64.const 0))
(global $tmp1 (mut i64) (i64.const 0))
(global $tmp2 (mut i64) (i64.const 0))

View File

@ -6,7 +6,7 @@ loadWebAssembly.supported = typeof WebAssembly !== 'undefined'
function loadWebAssembly (opts) {
if (!loadWebAssembly.supported) return null
var imp = opts && opts.imports
var imp = opts && opts.imports || { imports: {} }
var wasm = toUint8Array('AGFzbQEAAAABHwJgFX5+fn5+fn5+fn5+fn5+fn5+fn5+fwBgA39/fwACDgECanMFdGFibGUBcAABAwMCAAEFAwEAAQcYAgZtZW1vcnkCAAtmZTI1NTE5X211bAABCQcBAEEBCwEACv4QApAQAYYBfiAAp6whACABp6whASACp6whAiADp6whAyAEp6whBCAFp6whBSAGp6whBiAHp6whByAIp6whCCAJp6whCSAKp6whCiALp6whCyAMp6whDCANp6whDSAOp6whDiAPp6whDyAQp6whECARp6whESASp6whEiATp6whE0ITIAt+IAtCgICAgAiDQgGGQhN+fSEpQhMgDH4gDEKAgICACINCAYZCE359ISpCEyANfiANQoCAgIAIg0IBhkITfn0hK0ITIA5+IA5CgICAgAiDQgGGQhN+fSEsQhMgD34gD0KAgICACINCAYZCE359IS1CEyAQfiAQQoCAgIAIg0IBhkITfn0hLkITIBF+IBFCgICAgAiDQgGGQhN+fSEvQhMgEn4gEkKAgICACINCAYZCE359ITBCEyATfiATQoCAgIAIg0IBhkITfn0hMUICIAF+IAFCgICAgAiDQgGGQgJ+fSEyQgIgA34gA0KAgICACINCAYZCAn59ITNCAiAFfiAFQoCAgIAIg0IBhkICfn0hNEICIAd+IAdCgICAgAiDQgGGQgJ+fSE1QgIgCX4gCUKAgICACINCAYZCAn59ITYgKaesISkgKqesISogK6esISsgLKesISwgLaesIS0gLqesIS4gL6esIS8gMKesITAgMaesITEgMqesITIgM6esITMgNKesITQgNaesITUgNqesITYgACAKfiE3IAAgC34hOCAAIAx+ITkgACANfiE6IAAgDn4hOyAAIA9+ITwgACAQfiE9IAAgEX4hPiAAIBJ+IT8gACATfiFAIAEgCn4hQSAyIAt+IUIgASAMfiFDIDIgDX4hRCABIA5+IUUgMiAPfiFGIAEgEH4hRyAyIBF+IUggASASfiFJIDIgMX4hSiACIAp+IUsgAiALfiFMIAIgDH4hTSACIA1+IU4gAiAOfiFPIAIgD34hUCACIBB+IVEgAiARfiFSIAIgMH4hUyACIDF+IVQgAyAKfiFVIDMgC34hViADIAx+IVcgMyANfiFYIAMgDn4hWSAzIA9+IVogAyAQfiFbIDMgL34hXCADIDB+IV0gMyAxfiFeIAQgCn4hXyAEIAt+IWAgBCAMfiFhIAQgDX4hYiAEIA5+IWMgBCAPfiFkIAQgLn4hZSAEIC9+IWYgBCAwfiFnIAQgMX4haCAFIAp+IWkgNCALfiFqIAUgDH4hayA0IA1+IWwgBSAOfiFtIDQgLX4hbiAFIC5+IW8gNCAvfiFwIAUgMH4hcSA0IDF+IXIgBiAKfiFzIAYgC34hdCAGIAx+IXUgBiANfiF2IAYgLH4hdyAGIC1+IXggBiAufiF5IAYgL34heiAGIDB+IXsgBiAxfiF8IAcgCn4hfSA1IAt+IX4gByAMfiF/IDUgK34hgAEgByAsfiGBASA1IC1+IYIBIAcgLn4hgwEgNSAvfiGEASAHIDB+IYUBIDUgMX4hhgEgCCAKfiGHASAIIAt+IYgBIAggKn4hiQEgCCArfiGKASAIICx+IYsBIAggLX4hjAEgCCAufiGNASAIIC9+IY4BIAggMH4hjwEgCCAxfiGQASAJIAp+IZEBIDYgKX4hkgEgCSAqfiGTASA2ICt+IZQBIAkgLH4hlQEgNiAtfiGWASAJIC5+IZcBIDYgL34hmAEgCSAwfiGZASA2IDF+IZoBIDcgSiBTIFwgZSBuIHcggAEgiQEgkgF8fHx8fHx8fHwhFSA4IEEgVCBdIGYgbyB4IIEBIIoBIJMBfHx8fHx8fHx8IRYgOSBCIEsgXiBnIHAgeSCCASCLASCUAXx8fHx8fHx8fCEXIDogQyBMIFUgaCBxIHoggwEgjAEglQF8fHx8fHx8fHwhGCA7IEQgTSBWIF8gciB7IIQBII0BIJYBfHx8fHx8fHx8IRkgPCBFIE4gVyBgIGkgfCCFASCOASCXAXx8fHx8fHx8fCEaID0gRiBPIFggYSBqIHMghgEgjwEgmAF8fHx8fHx8fHwhGyA+IEcgUCBZIGIgayB0IH0gkAEgmQF8fHx8fHx8fHwhHCA/IEggUSBaIGMgbCB1IH4ghwEgmgF8fHx8fHx8fHwhHSBAIEkgUiBbIGQgbSB2IH8giAEgkQF8fHx8fHx8fHwhHiAVQgFCGYZ8QhqHIR8gFiAffCEWIBUgH0IBQhqGfn0hFSAZQgFCGYZ8QhqHISMgGiAjfCEaIBkgI0IBQhqGfn0hGSAWQgFCGIZ8QhmHISAgFyAgfCEXIBYgIEIBQhmGfn0hFiAaQgFCGIZ8QhmHISQgGyAkfCEbIBogJEIBQhmGfn0hGiAXQgFCGYZ8QhqHISEgGCAhfCEYIBcgIUIBQhqGfn0hFyAbQgFCGYZ8QhqHISUgHCAlfCEcIBsgJUIBQhqGfn0hGyAYQgFCGIZ8QhmHISIgGSAifCEZIBggIkIBQhmGfn0hGCAcQgFCGIZ8QhmHISYgHSAmfCEdIBwgJkIBQhmGfn0hHCAZQgFCGYZ8QhqHISMgGiAjfCEaIBkgI0IBQhqGfn0hGSAdQgFCGYZ8QhqHIScgHiAnfCEeIB0gJ0IBQhqGfn0hHSAeQgFCGIZ8QhmHISggFSAoQhN+fCEVIB4gKEIBQhmGfn0hHiAVQgFCGYZ8QhqHIR8gFiAffCEWIBUgH0IBQhqGfn0hFSAUIBU+AgAgFCAWPgIEIBQgFz4CCCAUIBg+AgwgFCAZPgIQIBQgGj4CFCAUIBs+AhggFCAcPgIcIBQgHT4CICAUIB4+AiQLagAgATUCACABNQIEIAE1AgggATUCDCABNQIQIAE1AhQgATUCGCABNQIcIAE1AiAgATUCJCACNQIAIAI1AgQgAjUCCCACNQIMIAI1AhAgAjUCFCACNQIYIAI1AhwgAjUCICACNQIkIAAQAAs=')
var ready = null
@ -39,6 +39,7 @@ function loadWebAssembly (opts) {
if (opts && opts.async) throw new Error('async')
setup({instance: new WebAssembly.Instance(new WebAssembly.Module(wasm), imp)})
} catch (err) {
console.log(err)
ready = WebAssembly.instantiate(wasm, imp).then(setup)
}

File diff suppressed because one or more lines are too long

View File

@ -1,35 +1,7 @@
(module
(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))
(memory $0 1)
(export "memory" (memory $0))
;; 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)))
(global $tmp0 (mut i64) (i64.const 0))
(global $tmp1 (mut i64) (i64.const 0))
(global $tmp2 (mut i64) (i64.const 0))

View File

@ -39,6 +39,7 @@ function loadWebAssembly (opts) {
if (opts && opts.async) throw new Error('async')
setup({instance: new WebAssembly.Instance(new WebAssembly.Module(wasm), imp)})
} catch (err) {
console.log(err)
ready = WebAssembly.instantiate(wasm, imp).then(setup)
}

View File

@ -7,7 +7,7 @@ function loadWebAssembly (opts) {
if (!loadWebAssembly.supported) return null
var imp = opts && opts.imports
var wasm = toUint8Array('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DCFWIBA1AhAhVyAQNQIUIVggEDUCGCFZIBA1AhwhWiAQNQIgIVsgEDUCJCFcID8gK3whNSBAICx8ITYgQSAtfCE3IEIgLnwhOCBDIC98ITkgRCAwfCE6IEUgMXwhOyBGIDJ8ITwgRyAzfCE9IEggNHwhPiA/ICt9ISsgQCAsfSEsIEEgLX0hLSBCIC59IS4gQyAvfSEvIEQgMH0hMCBFIDF9ITEgRiAyfSEyIEcgM30hMyBIIDR9ITQgUyBUIFUgViBXIFggWSBaIFsgXCBJIEogSyBMIE0gTiBPIFAgUSBSIA5BAxEAACBTIEl9IVMgVCBKfSFUIFUgS30hVSBWIEx9IVYgVyBNfSFXIFggTn0hWCBZIE99IVkgWiBQfSFaIFsgUX0hWyBcIFJ9IVwgKyAsIC0gLiAvIDAgMSAyIDMgNCANQQBBAEECEQEAQsK2B0IAQgBCAEIAQgBCAEIAQgBCACBTIFQgVSBWIFcgWCBZIFogWyBcIA5BAREAACA1IDYgNyA4IDkgOiA7IDwgPSA+IA9BAEEAQQIRAQAgDTUCACErIA01AgQhLCANNQIIIS0gDTUCDCEuIA01AhAhLyANNQIUITAgDTUCGCExIA01AhwhMiANNQIgITMgDTUCJCE0IA41AgAhPyAONQIEIUAgDjUCCCFBIA41AgwhQiAONQIQIUMgDjUCFCFEIA41AhghRSAONQIcIUYgDjUCICFHIA41AiQhSCAPNQIAITUgDzUCBCE2IA81AgghNyAPNQIMITggDzUCECE5IA81AhQhOiAPNQIYITsgDzUCHCE8IA81AiAhPSAPNQIkIT4gSSA/fCFJIEogQHwhSiBLIEF8IUsgTCBCfCFMIE0gQ3whTSBOIER8IU4gTyBFfCFPIFAgRnwhUCBRIEd8IVEgUiBIfCFSIBcgGCAZIBogGyAcIB0gHiAfICAgKyAsIC0gLiAvIDAgMSAyIDMgNCAOQQERAAAgSSBKIEsgTCBNIE4gTyBQIFEgUiBTIFQgVSBWIFcgWCBZIFogWyBcIA1BAREAACANNQIAISsgDTUCBCEsIA01AgghLSANNQIMIS4gDTUCECEvIA01AhQhMCANNQIYITEgDTUCHCEyIA01AiAhMyANNQIkITQgDjUCACE/IA41AgQhQCAONQIIIUEgDjUCDCFCIA41AhAhQyAONQIUIUQgDjUCGCFFIA41AhwhRiAONQIgIUcgDjUCJCFIIAxBAWshDAwACyAGICE+AgAgBiAiPgIEIAYgIz4CCCAGICQ+AgwgBiAlPgIQIAYgJj4CFCAGICc+AhggBiAoPgIcIAYgKT4CICAGICo+AiQgByA1PgIAIAcgNj4CBCAHIDc+AgggByA4PgIMIAcgOT4CECAHIDo+AhQgByA7PgIYIAcgPD4CHCAHID0+AiAgByA+PgIkIAggKz4CACAIICw+AgQgCCAtPgIIIAggLj4CDCAIIC8+AhAgCCAwPgIUIAggMT4CGCAIIDI+AhwgCCAzPgIgIAggND4CJCAJID8+AgAgCSBAPgIEIAkgQT4CCCAJIEI+AgwgCSBDPgIQIAkgRD4CFCAJIEU+AhggCSBGPgIcIAkgRz4CICAJIEg+AiQgCgs=')
var wasm = toUint8Array('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')
var ready = null
var mod = {

View File

@ -1,5 +1,5 @@
(module
(import "js" "table" (table 1 anyfunc))
(import "js" "table" (table 3 anyfunc))
(type $fe_mul (func
(param $f_0 i64)
(param $f_1 i64)
@ -38,6 +38,34 @@
(param $repeat i32)
(param $res i32)))
(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))
@ -214,11 +242,12 @@
(i32.const 254)
(set_local $pos)
(block $end
(loop $start
(i32.const 0)
(get_local $pos)
(i32.const 0)
(i32.lt_s)
(br_if $start)
(br_if $end)
;; choose which limb of t
(block $break
@ -1108,7 +1137,7 @@
(get_local $tmp0_8)
(get_local $tmp0_9)
(get_local $ptr1)
(i32.const 3)
(i32.const 1)
(call_indirect (type $fe_mul))
;; tmp1 = tmp1 - tmp0
@ -1385,7 +1414,9 @@
(i32.const 1)
(i32.sub)
(set_local $pos)
(br $start))
(br $start)))
;; (call $i32.log (get_local $res_x2))
(i64.store32 offset=0 (get_local $res_x2) (get_local $x2_0))
(i64.store32 offset=4 (get_local $res_x2) (get_local $x2_1))