From d10ec230c0523e0a27c5e470e84f005035e5fb5c Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Sat, 8 Oct 2016 17:56:12 +0200 Subject: [PATCH] add support for multibyte address versions --- bip32.c | 4 +-- bip32.h | 4 +-- ecdsa.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++----------- ecdsa.h | 6 ++--- 4 files changed, 69 insertions(+), 21 deletions(-) diff --git a/bip32.c b/bip32.c index de82996a39..ce617150bc 100644 --- a/bip32.c +++ b/bip32.c @@ -266,7 +266,7 @@ int hdnode_public_ckd(HDNode *inout, uint32_t i) return 1; } -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) +int hdnode_public_ckd_address_optimized(const curve_point *pub, const uint8_t *public_key, const uint8_t *chain_code, uint32_t i, uint32_t version, char *addr, int addrsize) { uint8_t data[1 + 32 + 4]; uint8_t I[32 + 32]; @@ -374,7 +374,7 @@ int hdnode_private_ckd_cached(HDNode *inout, const uint32_t *i, size_t i_count) #endif -void hdnode_get_address_raw(HDNode *node, uint8_t version, uint8_t *addr_raw) +void hdnode_get_address_raw(HDNode *node, uint32_t version, uint8_t *addr_raw) { hdnode_fill_public_key(node); ecdsa_get_address_raw(node->public_key, version, addr_raw); diff --git a/bip32.h b/bip32.h index 83e76797be..4095deb815 100644 --- a/bip32.h +++ b/bip32.h @@ -55,7 +55,7 @@ int hdnode_private_ckd(HDNode *inout, uint32_t i); int hdnode_public_ckd(HDNode *inout, uint32_t i); -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); +int hdnode_public_ckd_address_optimized(const curve_point *pub, const uint8_t *public_key, const uint8_t *chain_code, uint32_t i, uint32_t version, char *addr, int addrsize); #if USE_BIP32_CACHE @@ -83,7 +83,7 @@ int hdnode_deserialize(const char *str, HDNode *node); // Private int hdnode_serialize(const HDNode *node, uint32_t fingerprint, uint32_t version, char use_public, char *str, int strsize); -void hdnode_get_address_raw(HDNode *node, uint8_t version, uint8_t *addr_raw); +void hdnode_get_address_raw(HDNode *node, uint32_t version, uint8_t *addr_raw); const curve_info *get_curve_by_name(const char *curve_name); diff --git a/ecdsa.c b/ecdsa.c index 2462f1c27e..e166ff8f07 100644 --- a/ecdsa.c +++ b/ecdsa.c @@ -854,32 +854,80 @@ void ecdsa_get_pubkeyhash(const uint8_t *pub_key, uint8_t *pubkeyhash) MEMSET_BZERO(h, sizeof(h)); } -void ecdsa_get_address_raw(const uint8_t *pub_key, uint8_t version, uint8_t *addr_raw) +void ecdsa_get_address_raw(const uint8_t *pub_key, uint32_t version, uint8_t *addr_raw) { - addr_raw[0] = version; - ecdsa_get_pubkeyhash(pub_key, addr_raw + 1); + if (version <= 0xFF) { + addr_raw[0] = version; + ecdsa_get_pubkeyhash(pub_key, addr_raw + 1); + } else if (version <= 0xFFFF) { + addr_raw[0] = version >> 8; + addr_raw[1] = version & 0xFF; + ecdsa_get_pubkeyhash(pub_key, addr_raw + 2); + } else if (version <= 0xFFFFFF) { + addr_raw[0] = version >> 16; + addr_raw[1] = (version >> 8) & 0xFF; + addr_raw[2] = version & 0xFF; + ecdsa_get_pubkeyhash(pub_key, addr_raw + 3); + } else { + addr_raw[0] = version >> 24; + addr_raw[1] = (version >> 16) & 0xFF; + addr_raw[2] = (version >> 8) & 0xFF; + addr_raw[3] = version & 0xFF; + ecdsa_get_pubkeyhash(pub_key, addr_raw + 4); + } } -void ecdsa_get_address(const uint8_t *pub_key, uint8_t version, char *addr, int addrsize) +void ecdsa_get_address(const uint8_t *pub_key, uint32_t version, char *addr, int addrsize) { - uint8_t raw[21]; + uint8_t raw[20+4]; ecdsa_get_address_raw(pub_key, version, raw); - base58_encode_check(raw, 21, addr, addrsize); - + if (version <= 0xFF) { + base58_encode_check(raw, 21, addr, addrsize); + } else if (version <= 0xFFFF) { + base58_encode_check(raw, 22, addr, addrsize); + } else if (version <= 0xFFFFFF) { + base58_encode_check(raw, 23, addr, addrsize); + } else { + base58_encode_check(raw, 24, addr, addrsize); + } // not as important to clear this one, but we might as well MEMSET_BZERO(raw, sizeof(raw)); } -void ecdsa_get_wif(const uint8_t *priv_key, uint8_t version, char *wif, int wifsize) +void ecdsa_get_wif(const uint8_t *priv_key, uint32_t version, char *wif, int wifsize) { - uint8_t data[34]; - data[0] = version; - memcpy(data + 1, priv_key, 32); - data[33] = 0x01; - base58_encode_check(data, 34, wif, wifsize); + uint8_t wif_raw[4 + 32 + 1]; + + if (version <= 0xFF) { + wif_raw[0] = version; + memcpy(wif_raw + 1, priv_key, 32); + wif_raw[33] = 0x01; + base58_encode_check(wif_raw, 1 + 32 + 1, wif, wifsize); + } else if (version <= 0xFFFF) { + wif_raw[0] = version >> 8; + wif_raw[1] = version & 0xFF; + memcpy(wif_raw + 2, priv_key, 32); + wif_raw[34] = 0x01; + base58_encode_check(wif_raw, 2 + 32 + 1, wif, wifsize); + } else if (version <= 0xFFFFFF) { + wif_raw[0] = version >> 16; + wif_raw[1] = (version >> 8) & 0xFF; + wif_raw[2] = version & 0xFF; + memcpy(wif_raw + 3, priv_key, 32); + wif_raw[35] = 0x01; + base58_encode_check(wif_raw, 3 + 32 + 1, wif, wifsize); + } else { + wif_raw[0] = version >> 24; + wif_raw[1] = (version >> 16) & 0xFF; + wif_raw[2] = (version >> 8) & 0xFF; + wif_raw[3] = version & 0xFF; + memcpy(wif_raw + 4, priv_key, 32); + wif_raw[36] = 0x01; + base58_encode_check(wif_raw, 4 + 32 + 1, wif, wifsize); + } // private keys running around our stack can cause trouble - MEMSET_BZERO(data, sizeof(data)); + MEMSET_BZERO(wif_raw, sizeof(wif_raw)); } int ecdsa_address_decode(const char *addr, uint8_t *out) diff --git a/ecdsa.h b/ecdsa.h index c0629d5d5f..a07e418cae 100644 --- a/ecdsa.h +++ b/ecdsa.h @@ -71,9 +71,9 @@ int ecdsa_sign_digest(const ecdsa_curve *curve, const uint8_t *priv_key, const u void ecdsa_get_public_key33(const ecdsa_curve *curve, const uint8_t *priv_key, uint8_t *pub_key); void ecdsa_get_public_key65(const ecdsa_curve *curve, const uint8_t *priv_key, uint8_t *pub_key); void ecdsa_get_pubkeyhash(const uint8_t *pub_key, uint8_t *pubkeyhash); -void ecdsa_get_address_raw(const uint8_t *pub_key, uint8_t version, uint8_t *addr_raw); -void ecdsa_get_address(const uint8_t *pub_key, uint8_t version, char *addr, int addrsize); -void ecdsa_get_wif(const uint8_t *priv_key, uint8_t version, char *wif, int wifsize); +void ecdsa_get_address_raw(const uint8_t *pub_key, uint32_t version, uint8_t *addr_raw); +void ecdsa_get_address(const uint8_t *pub_key, uint32_t version, char *addr, int addrsize); +void ecdsa_get_wif(const uint8_t *priv_key, uint32_t version, char *wif, int wifsize); int ecdsa_address_decode(const char *addr, uint8_t *out); int ecdsa_read_pubkey(const ecdsa_curve *curve, const uint8_t *pub_key, curve_point *pub);