diff --git a/emscripten/Makefile b/emscripten/Makefile new file mode 100644 index 0000000000..81bf4fa72c --- /dev/null +++ b/emscripten/Makefile @@ -0,0 +1,17 @@ +EMFLAGS = \ + -O2 --closure 1 \ + --memory-init-file 0 \ + --pre-js pre.js --post-js post.js \ + -s EXPORTED_FUNCTIONS='["_hdnode_public_ckd", "_ecdsa_get_address"]' \ + +SRC = ../bignum.c ../ecdsa.c ../secp256k1.c ../hmac.c ../bip32.c \ + ../base58.c ../ripemd160.c ../sha2.c ../rand.c + +test: trezor-crypto.js + node test.js + +trezor-crypto.js: $(SRC) + emcc $(EMFLAGS) -o $@ $^ + +clean: + rm -f trezor-crypto.js diff --git a/emscripten/post.js b/emscripten/post.js new file mode 100644 index 0000000000..d5b37bd2f4 --- /dev/null +++ b/emscripten/post.js @@ -0,0 +1 @@ +module.exports = Module; diff --git a/emscripten/pre.js b/emscripten/pre.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/emscripten/test.js b/emscripten/test.js new file mode 100644 index 0000000000..0bc809c9a3 --- /dev/null +++ b/emscripten/test.js @@ -0,0 +1,67 @@ +var crypto = require('./trezor-crypto'); + +/* typedef struct { + uint32_t depth; + uint32_t fingerprint; + uint32_t child_num; + uint8_t chain_code[32]; + uint8_t private_key[32]; + uint8_t public_key[33]; + } HDNode; +*/ + +var HDNODE_SIZE = 4 + 4 + 4 + 32 + 32 + 33; +var hdnode = crypto._malloc(HDNODE_SIZE); + +var ADDRESS_SIZE = 40; // maximum size +var address = crypto._malloc(ADDRESS_SIZE); + +function prepareNode(n) { + var b = new ArrayBuffer(HDNODE_SIZE); + var u8 = new Uint8Array(b, 0, HDNODE_SIZE); + var u32 = new Uint32Array(b, 0, 12); + + u32[0] = n.depth; + u32[1] = n.parentFingerprint; + u32[2] = n.index; + u8.set(n.chainCode, 12); + u8.set(n.pubKey.toBuffer(), 12 + 32 + 32); + + return u8; +} + +function deriveAddress(pn, i, version) { + crypto.HEAPU8.set(pn, hdnode); + crypto._hdnode_public_ckd(hdnode, i); + crypto._ecdsa_get_address(hdnode + 12 + 32 + 32, version, address, ADDRESS_SIZE); + return crypto.Pointer_stringify(address); +} + +// benching code + +var bitcoin = require('bitcoinjs-lib'); + +var node = bitcoin.HDNode.fromBase58( + 'xpub6AHA9hZDN11k2ijHMeS5QqHx2KP9aMBRhTDqANMnwVtdyw2TDYRm' + + 'F8PjpvwUFcL1Et8Hj59S3gTSMcUQ5gAqTz3Wd8EsMTmF3DChhqPQBnU' +).derive(0); + +timeBitcoinjs(node); +timeTrezorCrypto(node); + +function timeBitcoinjs(n) { + console.time('bitcoinjs') + for (var i = 0; i < 1000; i++) { + n.derive(i).getAddress() + } + console.timeEnd('bitcoinjs') +} + +function timeTrezorCrypto(n) { + var nP = prepareNode(n); + console.time('trezor-crypto') + for (var i = 0; i < 1000; i++) { + deriveAddress(nP, i, 0); + } + console.timeEnd('trezor-crypto') +}