From 8edc0c58d3c4bd01b19ccb2b63e36804220b560c Mon Sep 17 00:00:00 2001 From: Saleem Rashid Date: Fri, 19 May 2017 18:17:24 +0100 Subject: [PATCH] bip32: Add hdnode_get_nem_address --- CMakeLists.txt | 1 + Makefile | 1 + bip32.c | 14 +++++++++++ bip32.h | 4 ++++ nem.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++ nem.h | 39 ++++++++++++++++++++++++++++++ 6 files changed, 123 insertions(+) create mode 100644 nem.c create mode 100644 nem.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e977f725a..83397e656 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,7 @@ set(SOURCES blake2b.c blake2s.c chacha20poly1305/chacha20poly1305.c chacha20poly1305/chacha_merged.c chacha20poly1305/poly1305-donna.c chacha20poly1305/rfc7539.c rc4.c + nem.c ) add_library(TrezorCrypto STATIC ${SOURCES}) diff --git a/Makefile b/Makefile index 0b00418ab..a42b9c18e 100644 --- a/Makefile +++ b/Makefile @@ -49,6 +49,7 @@ SRCS += ed25519-donna/ed25519.c ed25519-donna/curve25519-donna-scalarmult-base. SRCS += blake2b.c blake2s.c SRCS += chacha20poly1305/chacha20poly1305.c chacha20poly1305/chacha_merged.c chacha20poly1305/poly1305-donna.c chacha20poly1305/rfc7539.c SRCS += rc4.c +SRCS += nem.c OBJS = $(SRCS:.c=.o) diff --git a/bip32.c b/bip32.c index 58ee61273..1dadc9aa5 100644 --- a/bip32.c +++ b/bip32.c @@ -43,6 +43,9 @@ #if USE_KECCAK #include "ed25519-keccak.h" #endif +#if USE_NEM +#include "nem.h" +#endif const curve_info ed25519_info = { /* bip32_name */ @@ -444,6 +447,17 @@ int hdnode_get_ethereum_pubkeyhash(const HDNode *node, uint8_t *pubkeyhash) } #endif +#if USE_NEM +int hdnode_get_nem_address(HDNode *node, uint8_t version, char *address) { + if (node->curve != &ed25519_keccak_info) { + return 0; + } + + hdnode_fill_public_key(node); + return nem_get_address(&node->public_key[1], version, address); +} +#endif + // msg is a data to be signed // msg_len is the message length int hdnode_sign(HDNode *node, const uint8_t *msg, uint32_t msg_len, uint8_t *sig, uint8_t *pby, int (*is_canonical)(uint8_t by, uint8_t sig[64])) diff --git a/bip32.h b/bip32.h index 71d9b8ed7..83a285cff 100644 --- a/bip32.h +++ b/bip32.h @@ -72,6 +72,10 @@ void hdnode_fill_public_key(HDNode *node); int hdnode_get_ethereum_pubkeyhash(const HDNode *node, uint8_t *pubkeyhash); #endif +#if USE_NEM +int hdnode_get_nem_address(HDNode *node, uint8_t version, char *address); +#endif + int hdnode_sign(HDNode *node, const uint8_t *msg, uint32_t msg_len, uint8_t *sig, uint8_t *pby, int (*is_canonical)(uint8_t by, uint8_t sig[64])); int hdnode_sign_digest(HDNode *node, const uint8_t *digest, uint8_t *sig, uint8_t *pby, int (*is_canonical)(uint8_t by, uint8_t sig[64])); diff --git a/nem.c b/nem.c new file mode 100644 index 000000000..c8c6ab002 --- /dev/null +++ b/nem.c @@ -0,0 +1,64 @@ +/** + * Copyright (c) 2017 Saleem Rashid + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, E1PRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "nem.h" + +#include +#include + +#include "base32.h" +#include "macros.h" +#include "ripemd160.h" +#include "sha3.h" + +void nem_get_address_raw(const ed25519_public_key public_key, uint8_t version, uint8_t *address) { + uint8_t hash[SHA3_256_DIGEST_LENGTH]; + + /* 1. Perform 256-bit Sha3 on the public key */ + keccak_256(public_key, sizeof(ed25519_public_key), hash); + + /* 2. Perform 160-bit Ripemd of hash resulting from step 1. */ + ripemd160(hash, SHA3_256_DIGEST_LENGTH, &address[1]); + + /* 3. Prepend version byte to Ripemd hash (either 0x68 or 0x98) */ + address[0] = version; + + /* 4. Perform 256-bit Sha3 on the result, take the first four bytes as a checksum */ + keccak_256(address, 1 + RIPEMD160_DIGEST_LENGTH, hash); + + /* 5. Concatenate output of step 3 and the checksum from step 4 */ + memcpy(&address[1 + RIPEMD160_DIGEST_LENGTH], hash, 4); + + MEMSET_BZERO(hash, sizeof(hash)); +} + +bool nem_get_address(const ed25519_public_key public_key, uint8_t version, char *address) { + uint8_t pubkeyhash[NEM_ADDRESS_SIZE_RAW]; + + nem_get_address_raw(public_key, version, pubkeyhash); + + char *ret = base32_encode(pubkeyhash, sizeof(pubkeyhash), address, NEM_ADDRESS_SIZE + 1, BASE32_ALPHABET_RFC4648); + + MEMSET_BZERO(pubkeyhash, sizeof(pubkeyhash)); + + return (ret != NULL); +} diff --git a/nem.h b/nem.h new file mode 100644 index 000000000..294ba71a8 --- /dev/null +++ b/nem.h @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2017 Saleem Rashid + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef __NEM_H__ +#define __NEM_H__ + +#include +#include + +#define NEM_NETWORK_MAINNET 0x68 +#define NEM_NETWORK_TESTNET 0x98 +#define NEM_NETWORK_MIJIN 0x60 + +#define NEM_ADDRESS_SIZE 40 +#define NEM_ADDRESS_SIZE_RAW 25 + +void nem_get_address_raw(const ed25519_public_key public_key, uint8_t version, uint8_t *address); +bool nem_get_address(const ed25519_public_key public_key, uint8_t version, char *address); + +#endif