From 0dfb491e9d3b5691adb49b40f932773c238f3d03 Mon Sep 17 00:00:00 2001 From: Jaco Date: Sat, 19 Mar 2022 08:02:52 +0100 Subject: [PATCH] Reproduction for secp256k1 asm.js failure (#310) * Reproduction for secp256k1 asm.js failure * Make test output more readable * Additional test cleanups * Bump build deps * Adjust output sizing flags * Bump wasm-bindgen * secp256k1 HACK * Update packages/wasm-crypto/src/bundle.ts * Update packages/wasm-crypto/src/bundle.ts * Update packages/wasm-crypto/test/all/index.cjs --- packages/wasm-crypto/Cargo.lock | 30 +++++++++++----------- packages/wasm-crypto/Cargo.toml | 2 +- packages/wasm-crypto/src/bridge.ts | 2 ++ packages/wasm-crypto/src/bundle.ts | 11 +++++++++ packages/wasm-crypto/src/init.ts | 1 + packages/wasm-crypto/test/all/index.cjs | 33 ++++++++++++++++--------- packages/wasm-crypto/test/asm.cjs | 2 +- packages/wasm-crypto/test/wasm.cjs | 2 +- scripts/build-wasm.sh | 10 +++----- scripts/install-build-deps.sh | 13 +++++----- 10 files changed, 64 insertions(+), 42 deletions(-) diff --git a/packages/wasm-crypto/Cargo.lock b/packages/wasm-crypto/Cargo.lock index e623207f..423d6632 100644 --- a/packages/wasm-crypto/Cargo.lock +++ b/packages/wasm-crypto/Cargo.lock @@ -568,9 +568,9 @@ checksum = "99c605b9a0adc77b7211c6b1f722dcb613d68d66859a44f3d485a6da332b0598" [[package]] name = "proc-macro2" -version = "1.0.19" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12" +checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" dependencies = [ "unicode-xid", ] @@ -781,9 +781,9 @@ checksum = "502d53007c02d7605a05df1c1a73ee436952781653da5d0bf57ad608f66932c1" [[package]] name = "syn" -version = "1.0.38" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e69abc24912995b3038597a7a593be5053eb0fb44f3cc5beec0deb421790c1f4" +checksum = "ea297be220d52398dcc07ce15a209fce436d361735ac1db700cab3b6cdfb9f54" dependencies = [ "proc-macro2", "quote", @@ -908,19 +908,19 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.65" +version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3edbcc9536ab7eababcc6d2374a0b7bfe13a2b6d562c5e07f370456b1a8f33d" +checksum = "25f1af7423d8588a3d840681122e72e6a24ddbcb3f0ec385cac0d12d24256c06" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.0", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.65" +version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ed2fb8c84bfad20ea66b26a3743f3e7ba8735a69fe7d95118c33ec8fc1244d" +checksum = "8b21c0df030f5a177f3cba22e9bc4322695ec43e7257d865302900290bcdedca" dependencies = [ "bumpalo", "lazy_static", @@ -933,9 +933,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.65" +version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb071268b031a64d92fc6cf691715ca5a40950694d8f683c5bb43db7c730929e" +checksum = "2f4203d69e40a52ee523b2529a773d5ffc1dc0071801c87b3d270b471b80ed01" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -943,9 +943,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.65" +version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf592c807080719d1ff2f245a687cbadb3ed28b2077ed7084b47aba8b691f2c6" +checksum = "bfa8a30d46208db204854cadbb5d4baf5fcf8071ba5bf48190c3e59937962ebc" dependencies = [ "proc-macro2", "quote", @@ -956,9 +956,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.65" +version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b6c0220ded549d63860c78c38f3bcc558d1ca3f4efa74942c536ddbbb55e87" +checksum = "3d958d035c4438e28c70e4321a2911302f10135ce78a9c7834c0cab4123d06a2" [[package]] name = "wee_alloc" diff --git a/packages/wasm-crypto/Cargo.toml b/packages/wasm-crypto/Cargo.toml index af5a818b..0304a0e4 100644 --- a/packages/wasm-crypto/Cargo.toml +++ b/packages/wasm-crypto/Cargo.toml @@ -32,7 +32,7 @@ sha2 = "0.8.1" tiny-bip39 = { version = "0.7", default-features = false } tiny-keccak = { version = "2.0.1", features = ["keccak"] } twox-hash = "1.5.0" -wasm-bindgen = "=0.2.65" +wasm-bindgen = "=0.2.79" wee_alloc = "0.4.3" [dev-dependencies] diff --git a/packages/wasm-crypto/src/bridge.ts b/packages/wasm-crypto/src/bridge.ts index 52b3fd29..22af7622 100644 --- a/packages/wasm-crypto/src/bridge.ts +++ b/packages/wasm-crypto/src/bridge.ts @@ -15,6 +15,7 @@ type PopFirst = interface Bridge { cachegetInt32: Int32Array | null; cachegetUint8: Uint8Array | null; + type: 'wasm' | 'asm'; wasm: WasmCryptoInstance | null; wasmPromise: Promise | null; } @@ -22,6 +23,7 @@ interface Bridge { export const __bridge: Bridge = { cachegetInt32: null, cachegetUint8: null, + type: 'wasm', wasm: null, wasmPromise: null }; diff --git a/packages/wasm-crypto/src/bundle.ts b/packages/wasm-crypto/src/bundle.ts index d39a11ef..8dd232a0 100644 --- a/packages/wasm-crypto/src/bundle.ts +++ b/packages/wasm-crypto/src/bundle.ts @@ -54,7 +54,18 @@ export const ed25519Verify = withWasm((wasm, signature: Uint8Array, message: Uin return ret !== 0; }); +let secpLazyInit = false; + export const secp256k1FromSeed = withWasm((wasm, seckey: Uint8Array): Uint8Array => { + // HACK In an asm.js environment, the static initialization seems to trip up the + // first usage of the keypair generation + // https://github.com/polkadot-js/wasm/issues/307 + if (!secpLazyInit && __bridge.type === 'asm') { + wasm.ext_secp_from_seed(8, ...allocU8a(seckey)); + resultU8a(); + } + + secpLazyInit = true; wasm.ext_secp_from_seed(8, ...allocU8a(seckey)); return resultU8a(); diff --git a/packages/wasm-crypto/src/init.ts b/packages/wasm-crypto/src/init.ts index c0b1dec5..abfb80c1 100644 --- a/packages/wasm-crypto/src/init.ts +++ b/packages/wasm-crypto/src/init.ts @@ -19,6 +19,7 @@ async function createPromise (wasmBytes: Uint8Array | null, asmFn: AsmCreator | } catch (error) { // if we have a valid supplied asm.js, return that if (asmFn) { + __bridge.type = 'asm'; __bridge.wasm = asmFn(imports); } else { console.error('FATAL: Unable to initialize @polkadot/wasm-crypto'); diff --git a/packages/wasm-crypto/test/all/index.cjs b/packages/wasm-crypto/test/all/index.cjs index 506bd795..ae3a8685 100644 --- a/packages/wasm-crypto/test/all/index.cjs +++ b/packages/wasm-crypto/test/all/index.cjs @@ -10,19 +10,22 @@ const sr25519 = require('./sr25519.cjs'); const vrf = require('./vrf.cjs'); const tests = { - ...bip39, - ...ed25519, - ...hashing, + // We place secp256k1 first, this allows the interaction with it in the + // hashing (specifically scrypt) test not be an issue (ASM.js only) + // https://github.com/polkadot-js/wasm/issues/307 ...secp256k1, + ...ed25519, ...sr25519, - ...vrf + ...vrf, + ...bip39, + ...hashing }; function beforeAll () { return wasm.waitReady(); } -function runAll () { +function runAll (name) { const failed = []; let count = 0; @@ -38,23 +41,29 @@ function runAll () { console.timeEnd(name); } catch (error) { + console.error(); console.error(error); + failed.push(name); } }); if (failed.length) { - throw new Error(`Failed: ${failed.length} of ${count}: ${failed.concat(', ')}`); + throw new Error(`\n*** ${name}: FAILED: ${failed.length} of ${count}: ${failed.join(', ')}`); } } -function runUnassisted () { - beforeAll() - .then(() => runAll()) - .then(() => process.exit(0)) - .catch((error) => { - console.error(error); +function runUnassisted (name) { + console.log(`\n*** ${name}: Running tests`); + beforeAll() + .then(() => runAll(name)) + .then(() => { + console.log(`\n*** ${name}: All passed`); + process.exit(0); + }) + .catch((error) => { + console.error(error.message, '\n'); process.exit(-1); }); } diff --git a/packages/wasm-crypto/test/asm.cjs b/packages/wasm-crypto/test/asm.cjs index 0a5224f0..04a8b0c5 100644 --- a/packages/wasm-crypto/test/asm.cjs +++ b/packages/wasm-crypto/test/asm.cjs @@ -6,4 +6,4 @@ require('@polkadot/wasm-crypto/initOnlyAsm.cjs'); const { runUnassisted } = require('./all/index.cjs'); -runUnassisted(); +runUnassisted('ASM'); diff --git a/packages/wasm-crypto/test/wasm.cjs b/packages/wasm-crypto/test/wasm.cjs index f11825ef..8acc53b1 100644 --- a/packages/wasm-crypto/test/wasm.cjs +++ b/packages/wasm-crypto/test/wasm.cjs @@ -5,4 +5,4 @@ require('./alias-imports.cjs'); const { runUnassisted } = require('./all/index.cjs'); -runUnassisted(); +runUnassisted('WASM'); diff --git a/scripts/build-wasm.sh b/scripts/build-wasm.sh index b5b49b7c..aa58139b 100755 --- a/scripts/build-wasm.sh +++ b/scripts/build-wasm.sh @@ -26,7 +26,7 @@ echo "*** Converting to WASM" # optimise echo "*** Optimising WASM output" -../binaryen/bin/wasm-opt $WSM -Os -o $OPT +../binaryen/bin/wasm-opt $WSM -Oz -o $OPT # convert wasm to base64 structure echo "*** Packing WASM into baseX" @@ -34,14 +34,12 @@ node ../scripts/pack-wasm-base.cjs # build asmjs version from the input (optimised) WASM echo "*** Building asm.js version" -../binaryen/bin/wasm2js --output $ASM $OPT +../binaryen/bin/wasm2js -Oz --output $ASM $OPT # cleanup the generated asm, converting to cjs sed -i -e '/import {/d' $ASM -sed -i -e '/export var /d' $ASM -sed -i -e 's/{abort.*},memasmFunc/wbg, memasmFunc/g' $ASM -sed -i -e 's/var retasmFunc = /const asmJsInit = (wbg) => /' $ASM -echo "module.exports = { asmJsInit };" >> $ASM +sed -i -e '1,/var retasmFunc = /!d' $ASM +sed -i -e 's/var retasmFunc = .*/const asmJsInit = (wbg) => asmFunc(wbg);\n\nmodule.exports = { asmJsInit };/g' $ASM # cleanups rm -rf wasm-crypto-asmjs/build/cjs/*-e diff --git a/scripts/install-build-deps.sh b/scripts/install-build-deps.sh index 02dee39b..c06fed18 100755 --- a/scripts/install-build-deps.sh +++ b/scripts/install-build-deps.sh @@ -7,16 +7,17 @@ set -e source ./scripts/rust-version.sh -BINARYEN_REPO=https://github.com/WebAssembly/binaryen -BINARYEN_VER=version_97 -BINARYEN_ZIP= - +# NOTE If this is bumped, bump the version in Cargo.toml as well BINDGEN_REPO=https://github.com/rustwasm/wasm-bindgen -BINDGEN_VER=0.2.65 +BINDGEN_VER=0.2.79 BINDGEN_ZIP= +BINARYEN_REPO=https://github.com/WebAssembly/binaryen +BINARYEN_VER=version_105 +BINARYEN_ZIP= + WABT_REPO=https://github.com/WebAssembly/wabt -WABT_VER=1.0.19 +WABT_VER=1.0.27 WABT_ZIP= unamestr=`uname`