diff --git a/bip32.c b/bip32.c index 1dadc9aa5..e58755071 100644 --- a/bip32.c +++ b/bip32.c @@ -456,6 +456,26 @@ int hdnode_get_nem_address(HDNode *node, uint8_t version, char *address) { hdnode_fill_public_key(node); return nem_get_address(&node->public_key[1], version, address); } + +int hdnode_get_nem_shared_key(const HDNode *node, const ed25519_public_key peer_public_key, const uint8_t *salt, ed25519_public_key mul, uint8_t *shared_key) { + if (node->curve != &ed25519_keccak_info) { + return 0; + } + + // sizeof(ed25519_public_key) == SHA3_256_DIGEST_LENGTH + if (mul == NULL) mul = shared_key; + + if (ed25519_scalarmult_keccak(mul, node->private_key, peer_public_key)) { + return 0; + } + + for (size_t i = 0; i < 32; i++) { + shared_key[i] = mul[i] ^ salt[i]; + } + + keccak_256(shared_key, 32, shared_key); + return 1; +} #endif // msg is a data to be signed diff --git a/bip32.h b/bip32.h index 83a285cff..3499fdc75 100644 --- a/bip32.h +++ b/bip32.h @@ -28,6 +28,7 @@ #include #include #include "ecdsa.h" +#include "ed25519.h" #include "options.h" typedef struct { @@ -74,6 +75,7 @@ int hdnode_get_ethereum_pubkeyhash(const HDNode *node, uint8_t *pubkeyhash); #if USE_NEM int hdnode_get_nem_address(HDNode *node, uint8_t version, char *address); +int hdnode_get_nem_shared_key(const HDNode *node, const ed25519_public_key peer_public_key, const uint8_t *salt, ed25519_public_key mul, uint8_t *shared_key); #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]));