mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-22 14:28:07 +00:00
further optimize emscripten
This commit is contained in:
parent
6dd9ed0756
commit
110965f31d
20
bip32.c
20
bip32.c
@ -264,42 +264,42 @@ int hdnode_public_ckd(HDNode *inout, uint32_t i)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hdnode_public_ckd_address_optimized(const HDNode *in, const curve_point *pub, uint32_t i, uint8_t version, char *addr, int addrsize)
|
int hdnode_public_ckd_address_optimized(const curve_point *pub, const uint8_t *public_key, const uint8_t *chain_code, uint32_t i, uint8_t version, char *addr, int addrsize)
|
||||||
{
|
{
|
||||||
uint8_t data[1 + 32 + 4];
|
uint8_t data[1 + 32 + 4];
|
||||||
uint8_t I[32 + 32];
|
uint8_t I[32 + 32];
|
||||||
uint8_t public_key[33];
|
uint8_t child_pubkey[33];
|
||||||
curve_point b;
|
curve_point b;
|
||||||
bignum256 c;
|
bignum256 c;
|
||||||
|
|
||||||
if (i & 0x80000000) { // private derivation
|
if (i & 0x80000000) { // private derivation
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
memcpy(data, in->public_key, 33);
|
memcpy(data, public_key, 33);
|
||||||
write_be(data + 33, i);
|
write_be(data + 33, i);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
bool failed = false;
|
bool failed = false;
|
||||||
hmac_sha512(in->chain_code, 32, data, sizeof(data), I);
|
hmac_sha512(chain_code, 32, data, sizeof(data), I);
|
||||||
bn_read_be(I, &c);
|
bn_read_be(I, &c);
|
||||||
if (!bn_is_less(&c, &in->curve->params->order)) { // >= order
|
if (!bn_is_less(&c, &secp256k1.order)) { // >= order
|
||||||
failed = true;
|
failed = true;
|
||||||
} else {
|
} else {
|
||||||
scalar_multiply(in->curve->params, &c, &b); // b = c * G
|
scalar_multiply(&secp256k1, &c, &b); // b = c * G
|
||||||
point_add(in->curve->params, pub, &b); // b = a + b
|
point_add(&secp256k1, pub, &b); // b = a + b
|
||||||
if (point_is_infinity(&b)) {
|
if (point_is_infinity(&b)) {
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!failed) {
|
if (!failed) {
|
||||||
public_key[0] = 0x02 | (b.y.val[0] & 0x01);
|
child_pubkey[0] = 0x02 | (b.y.val[0] & 0x01);
|
||||||
bn_write_be(&b.x, public_key + 1);
|
bn_write_be(&b.x, child_pubkey + 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
data[0] = 1;
|
data[0] = 1;
|
||||||
memcpy(data + 1, I + 32, 32);
|
memcpy(data + 1, I + 32, 32);
|
||||||
}
|
}
|
||||||
ecdsa_get_address(public_key, version, addr, addrsize);
|
ecdsa_get_address(child_pubkey, version, addr, addrsize);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
bip32.h
2
bip32.h
@ -56,7 +56,7 @@ int hdnode_private_ckd(HDNode *inout, uint32_t i);
|
|||||||
|
|
||||||
int hdnode_public_ckd(HDNode *inout, uint32_t i);
|
int hdnode_public_ckd(HDNode *inout, uint32_t i);
|
||||||
|
|
||||||
int hdnode_public_ckd_address_optimized(const HDNode *in, const curve_point *pub, uint32_t i, uint8_t version, char *addr, int addrsize);
|
int hdnode_public_ckd_address_optimized(const curve_point *pub, const uint8_t *public_key, const uint8_t *chain_code, uint32_t i, uint8_t version, char *addr, int addrsize);
|
||||||
|
|
||||||
#if USE_BIP32_CACHE
|
#if USE_BIP32_CACHE
|
||||||
|
|
||||||
|
4
ecdsa.c
4
ecdsa.c
@ -35,6 +35,7 @@
|
|||||||
#include "ecdsa.h"
|
#include "ecdsa.h"
|
||||||
#include "base58.h"
|
#include "base58.h"
|
||||||
#include "macros.h"
|
#include "macros.h"
|
||||||
|
#include "secp256k1.h"
|
||||||
|
|
||||||
// Set cp2 = cp1
|
// Set cp2 = cp1
|
||||||
void point_copy(const curve_point *cp1, curve_point *cp2)
|
void point_copy(const curve_point *cp1, curve_point *cp2)
|
||||||
@ -878,6 +879,9 @@ void uncompress_coords(const ecdsa_curve *curve, uint8_t odd, const bignum256 *x
|
|||||||
|
|
||||||
int ecdsa_read_pubkey(const ecdsa_curve *curve, const uint8_t *pub_key, curve_point *pub)
|
int ecdsa_read_pubkey(const ecdsa_curve *curve, const uint8_t *pub_key, curve_point *pub)
|
||||||
{
|
{
|
||||||
|
if (!curve) {
|
||||||
|
curve = &secp256k1;
|
||||||
|
}
|
||||||
if (pub_key[0] == 0x04) {
|
if (pub_key[0] == 0x04) {
|
||||||
bn_read_be(pub_key + 1, &(pub->x));
|
bn_read_be(pub_key + 1, &(pub->x));
|
||||||
bn_read_be(pub_key + 33, &(pub->y));
|
bn_read_be(pub_key + 33, &(pub->y));
|
||||||
|
@ -2,7 +2,8 @@ EMFLAGS = \
|
|||||||
-Os --closure 1 \
|
-Os --closure 1 \
|
||||||
--memory-init-file 0 \
|
--memory-init-file 0 \
|
||||||
--pre-js pre.js --post-js post.js \
|
--pre-js pre.js --post-js post.js \
|
||||||
-s EXPORTED_FUNCTIONS='["_hdnode_public_ckd", "_ecdsa_get_address"]'
|
-I ../ed25519-donna \
|
||||||
|
-s EXPORTED_FUNCTIONS='["_hdnode_public_ckd_address_optimized", "_ecdsa_read_pubkey"]'
|
||||||
|
|
||||||
SRC = ../bignum.c ../ecdsa.c ../secp256k1.c ../hmac.c ../bip32.c \
|
SRC = ../bignum.c ../ecdsa.c ../secp256k1.c ../hmac.c ../bip32.c \
|
||||||
../base58.c ../ripemd160.c ../sha2.c ../rand.c
|
../base58.c ../ripemd160.c ../sha2.c ../rand.c
|
||||||
@ -22,3 +23,6 @@ node_modules:
|
|||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f trezor-crypto.js test-browserify.js
|
rm -f trezor-crypto.js test-browserify.js
|
||||||
|
|
||||||
|
docker:
|
||||||
|
docker run --rm -i -v $(shell pwd)/..:/src -t apiaryio/emcc /bin/bash
|
||||||
|
@ -11,13 +11,17 @@
|
|||||||
|
|
||||||
var HEAPU8 = Module['HEAPU8'];
|
var HEAPU8 = Module['HEAPU8'];
|
||||||
var _malloc = Module['_malloc'];
|
var _malloc = Module['_malloc'];
|
||||||
var _hdnode_public_ckd = Module['_hdnode_public_ckd'];
|
var _hdnode_public_ckd_address_optimized = Module['_hdnode_public_ckd_address_optimized'];
|
||||||
var _ecdsa_get_address = Module['_ecdsa_get_address'];
|
var _ecdsa_read_pubkey = Module['_ecdsa_read_pubkey'];
|
||||||
var Pointer_stringify = Module['Pointer_stringify'];
|
var Pointer_stringify = Module['Pointer_stringify'];
|
||||||
|
|
||||||
// HDNode struct global
|
// HDNode structs global
|
||||||
var HDNODE_SIZE = 4 + 4 + 4 + 32 + 32 + 33;
|
var PUBPOINT_SIZE = 2 * 9 * 4; // (2 * bignum256 (= 9 * uint32_t))
|
||||||
var _hdnode = _malloc(HDNODE_SIZE);
|
var _pubpoint = _malloc(PUBPOINT_SIZE);
|
||||||
|
var PUBKEY_SIZE = 33;
|
||||||
|
var _pubkey = _malloc(PUBKEY_SIZE);
|
||||||
|
var CHAINCODE_SIZE = 32;
|
||||||
|
var _chaincode = _malloc(CHAINCODE_SIZE);
|
||||||
|
|
||||||
// address string global
|
// address string global
|
||||||
var ADDRESS_SIZE = 40; // maximum size
|
var ADDRESS_SIZE = 40; // maximum size
|
||||||
@ -29,33 +33,26 @@ var _address = _malloc(ADDRESS_SIZE);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {HDNode} node HDNode struct, see the definition above
|
* @param {HDNode} node HDNode struct, see the definition above
|
||||||
* @return {Uint8Array}
|
|
||||||
*/
|
*/
|
||||||
function serializeNode(node) {
|
function serializeNode(node) {
|
||||||
var b = new ArrayBuffer(HDNODE_SIZE);
|
var u8_pubkey = new Uint8Array(33);
|
||||||
|
u8_pubkey.set(node['public_key'], 0);
|
||||||
|
HEAPU8.set(u8_pubkey, _pubkey);
|
||||||
|
|
||||||
var u32 = new Uint32Array(b, 0, 12);
|
var u8_chaincode = new Uint8Array(32);
|
||||||
u32[0] = node['depth'];
|
u8_chaincode.set(node['chain_code'], 0);
|
||||||
u32[1] = node['fingerprint'];
|
HEAPU8.set(u8_chaincode, _chaincode);
|
||||||
u32[2] = node['child_num'];
|
|
||||||
|
|
||||||
var u8 = new Uint8Array(b, 0, HDNODE_SIZE);
|
_ecdsa_read_pubkey(0, _pubkey, _pubpoint);
|
||||||
u8.set(node['chain_code'], 12);
|
|
||||||
u8.set(node['public_key'], 12 + 32 + 32);
|
|
||||||
|
|
||||||
return u8;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Uint8Array} sn serialized node, see `serializeNode`
|
|
||||||
* @param {Number} index BIP32 index of the address
|
* @param {Number} index BIP32 index of the address
|
||||||
* @param {Number} version address version byte
|
* @param {Number} version address version byte
|
||||||
* @return {String}
|
* @return {String}
|
||||||
*/
|
*/
|
||||||
function deriveAddress(sn, index, version) {
|
function deriveAddress(index, version) {
|
||||||
HEAPU8.set(sn, _hdnode);
|
_hdnode_public_ckd_address_optimized(_pubpoint, _pubkey, _chaincode, index, version, _address, ADDRESS_SIZE);
|
||||||
_hdnode_public_ckd(_hdnode, index);
|
|
||||||
_ecdsa_get_address(_hdnode + 12 + 32 + 32, version, _address, ADDRESS_SIZE);
|
|
||||||
return Pointer_stringify(_address);
|
return Pointer_stringify(_address);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,10 +65,10 @@ function deriveAddress(sn, index, version) {
|
|||||||
*/
|
*/
|
||||||
function deriveAddressRange(node, firstIndex, lastIndex, version) {
|
function deriveAddressRange(node, firstIndex, lastIndex, version) {
|
||||||
var addresses = [];
|
var addresses = [];
|
||||||
var sn = serializeNode(node);
|
serializeNode(node);
|
||||||
var i;
|
var i;
|
||||||
for (i = firstIndex; i <= lastIndex; i++) {
|
for (i = firstIndex; i <= lastIndex; i++) {
|
||||||
addresses.push(deriveAddress(sn, i, version));
|
addresses.push(deriveAddress(i, version));
|
||||||
}
|
}
|
||||||
return addresses;
|
return addresses;
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,6 @@ var nodeStruct = {
|
|||||||
chain_code: node.chainCode,
|
chain_code: node.chainCode,
|
||||||
public_key: node.keyPair.getPublicKeyBuffer()
|
public_key: node.keyPair.getPublicKeyBuffer()
|
||||||
};
|
};
|
||||||
var nodeSerialized = crypto.serializeNode(nodeStruct);
|
|
||||||
|
|
||||||
var suite;
|
var suite;
|
||||||
var worker;
|
var worker;
|
||||||
@ -60,8 +59,9 @@ function benchBitcoinJS(ops, fn) {
|
|||||||
|
|
||||||
function benchBrowserify(ops, fn) {
|
function benchBrowserify(ops, fn) {
|
||||||
var i;
|
var i;
|
||||||
|
crypto.serializeNode(nodeStruct);
|
||||||
for (i = 0; i < ops; i++) {
|
for (i = 0; i < ops; i++) {
|
||||||
crypto.deriveAddress(nodeSerialized, i, 0);
|
crypto.deriveAddress(i, 0);
|
||||||
}
|
}
|
||||||
fn();
|
fn();
|
||||||
}
|
}
|
||||||
|
@ -100,10 +100,10 @@ void bench_ckd_normal(void) {
|
|||||||
void bench_ckd_optimized(void) {
|
void bench_ckd_optimized(void) {
|
||||||
char addr[40];
|
char addr[40];
|
||||||
curve_point pub;
|
curve_point pub;
|
||||||
ecdsa_read_pubkey(root.curve->params, root.public_key, &pub);
|
ecdsa_read_pubkey(0, root.public_key, &pub);
|
||||||
clock_t t = clock();
|
clock_t t = clock();
|
||||||
for (int i = 0; i < 1000; i++) {
|
for (int i = 0; i < 1000; i++) {
|
||||||
hdnode_public_ckd_address_optimized(&root, &pub, i, 0, addr, 40);
|
hdnode_public_ckd_address_optimized(&pub, root.public_key, root.chain_code, i, 0, addr, 40);
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
printf("address = %s\n", addr);
|
printf("address = %s\n", addr);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user