mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-01-11 16:00:57 +00:00
refactor(crypto): extract Cardano derivations to separate file
Changes the API: all Cardano derivations will now produce a 96-byte secret in the format of private_key + private_key_ext + chain_code. This can then be trivially converted to a HDNode.
This commit is contained in:
parent
05cbda4a7a
commit
1174648777
@ -100,6 +100,7 @@ SRCS += schnorr.c
|
|||||||
SRCS += zkp_context.c
|
SRCS += zkp_context.c
|
||||||
SRCS += zkp_ecdsa.c
|
SRCS += zkp_ecdsa.c
|
||||||
SRCS += zkp_bip340.c
|
SRCS += zkp_bip340.c
|
||||||
|
SRCS += cardano.c
|
||||||
|
|
||||||
OBJS = $(SRCS:.c=.o)
|
OBJS = $(SRCS:.c=.o)
|
||||||
OBJS += secp256k1-zkp.o
|
OBJS += secp256k1-zkp.o
|
||||||
|
184
crypto/bip32.c
184
crypto/bip32.c
@ -30,6 +30,7 @@
|
|||||||
#include "base58.h"
|
#include "base58.h"
|
||||||
#include "bignum.h"
|
#include "bignum.h"
|
||||||
#include "bip32.h"
|
#include "bip32.h"
|
||||||
|
#include "cardano.h"
|
||||||
#include "curves.h"
|
#include "curves.h"
|
||||||
#include "ecdsa.h"
|
#include "ecdsa.h"
|
||||||
#include "ed25519-donna/ed25519-sha3.h"
|
#include "ed25519-donna/ed25519-sha3.h"
|
||||||
@ -45,13 +46,8 @@
|
|||||||
#if USE_NEM
|
#if USE_NEM
|
||||||
#include "nem.h"
|
#include "nem.h"
|
||||||
#endif
|
#endif
|
||||||
#if USE_CARDANO
|
|
||||||
#include "pbkdf2.h"
|
|
||||||
#endif
|
|
||||||
#include "memzero.h"
|
#include "memzero.h"
|
||||||
|
|
||||||
#define CARDANO_MAX_NODE_DEPTH 1048576
|
|
||||||
|
|
||||||
const curve_info ed25519_info = {
|
const curve_info ed25519_info = {
|
||||||
.bip32_name = "ed25519 seed",
|
.bip32_name = "ed25519 seed",
|
||||||
.params = NULL,
|
.params = NULL,
|
||||||
@ -61,15 +57,6 @@ const curve_info ed25519_info = {
|
|||||||
.hasher_script = HASHER_SHA2,
|
.hasher_script = HASHER_SHA2,
|
||||||
};
|
};
|
||||||
|
|
||||||
const curve_info ed25519_cardano_info = {
|
|
||||||
.bip32_name = "ed25519 cardano seed",
|
|
||||||
.params = NULL,
|
|
||||||
.hasher_base58 = HASHER_SHA2D,
|
|
||||||
.hasher_sign = HASHER_SHA2D,
|
|
||||||
.hasher_pubkey = HASHER_SHA2_RIPEMD,
|
|
||||||
.hasher_script = HASHER_SHA2,
|
|
||||||
};
|
|
||||||
|
|
||||||
const curve_info ed25519_sha3_info = {
|
const curve_info ed25519_sha3_info = {
|
||||||
.bip32_name = "ed25519-sha3 seed",
|
.bip32_name = "ed25519-sha3 seed",
|
||||||
.params = NULL,
|
.params = NULL,
|
||||||
@ -203,11 +190,17 @@ uint32_t hdnode_fingerprint(HDNode *node) {
|
|||||||
return fingerprint;
|
return fingerprint;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hdnode_private_ckd(HDNode *inout, uint32_t i) {
|
int hdnode_private_ckd_bip32(HDNode *inout, uint32_t i) {
|
||||||
static CONFIDENTIAL uint8_t data[1 + 32 + 4];
|
static CONFIDENTIAL uint8_t data[1 + 32 + 4];
|
||||||
static CONFIDENTIAL uint8_t I[32 + 32];
|
static CONFIDENTIAL uint8_t I[32 + 32];
|
||||||
static CONFIDENTIAL bignum256 a, b;
|
static CONFIDENTIAL bignum256 a, b;
|
||||||
|
|
||||||
|
#if USE_CARDANO
|
||||||
|
if (inout->curve == &ed25519_cardano_info) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (i & 0x80000000) { // private derivation
|
if (i & 0x80000000) { // private derivation
|
||||||
data[0] = 0;
|
data[0] = 0;
|
||||||
memcpy(data + 1, inout->private_key, 32);
|
memcpy(data + 1, inout->private_key, 32);
|
||||||
@ -271,159 +264,16 @@ int hdnode_private_ckd(HDNode *inout, uint32_t i) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int hdnode_private_ckd(HDNode *inout, uint32_t i) {
|
||||||
#if USE_CARDANO
|
#if USE_CARDANO
|
||||||
static void scalar_multiply8(const uint8_t *src, int bytes, uint8_t *dst) {
|
if (inout->curve == &ed25519_cardano_info) {
|
||||||
uint8_t prev_acc = 0;
|
return hdnode_private_ckd_cardano(inout, i);
|
||||||
for (int i = 0; i < bytes; i++) {
|
} else
|
||||||
dst[i] = (src[i] << 3) + (prev_acc & 0x7);
|
|
||||||
prev_acc = src[i] >> 5;
|
|
||||||
}
|
|
||||||
dst[bytes] = src[bytes - 1] >> 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void scalar_add_256bits(const uint8_t *src1, const uint8_t *src2,
|
|
||||||
uint8_t *dst) {
|
|
||||||
uint16_t r = 0;
|
|
||||||
for (int i = 0; i < 32; i++) {
|
|
||||||
r = r + (uint16_t)src1[i] + (uint16_t)src2[i];
|
|
||||||
dst[i] = r & 0xff;
|
|
||||||
r >>= 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int hdnode_private_ckd_cardano(HDNode *inout, uint32_t index) {
|
|
||||||
if (inout->depth >= CARDANO_MAX_NODE_DEPTH) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// checks for hardened/non-hardened derivation, keysize 32 means we are
|
|
||||||
// dealing with public key and thus non-h, keysize 64 is for private key
|
|
||||||
int keysize = 32;
|
|
||||||
if (index & 0x80000000) {
|
|
||||||
keysize = 64;
|
|
||||||
}
|
|
||||||
|
|
||||||
static CONFIDENTIAL uint8_t data[1 + 64 + 4];
|
|
||||||
static CONFIDENTIAL uint8_t z[32 + 32];
|
|
||||||
static CONFIDENTIAL uint8_t priv_key[64];
|
|
||||||
static CONFIDENTIAL uint8_t res_key[64];
|
|
||||||
|
|
||||||
write_le(data + keysize + 1, index);
|
|
||||||
|
|
||||||
memcpy(priv_key, inout->private_key, 32);
|
|
||||||
memcpy(priv_key + 32, inout->private_key_extension, 32);
|
|
||||||
|
|
||||||
if (keysize == 64) { // private derivation
|
|
||||||
data[0] = 0;
|
|
||||||
memcpy(data + 1, inout->private_key, 32);
|
|
||||||
memcpy(data + 1 + 32, inout->private_key_extension, 32);
|
|
||||||
} else { // public derivation
|
|
||||||
if (hdnode_fill_public_key(inout) != 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
data[0] = 2;
|
|
||||||
memcpy(data + 1, inout->public_key + 1, 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
static CONFIDENTIAL HMAC_SHA512_CTX ctx;
|
|
||||||
hmac_sha512_Init(&ctx, inout->chain_code, 32);
|
|
||||||
hmac_sha512_Update(&ctx, data, 1 + keysize + 4);
|
|
||||||
hmac_sha512_Final(&ctx, z);
|
|
||||||
|
|
||||||
static CONFIDENTIAL uint8_t zl8[32];
|
|
||||||
memzero(zl8, 32);
|
|
||||||
|
|
||||||
/* get 8 * Zl */
|
|
||||||
scalar_multiply8(z, 28, zl8);
|
|
||||||
/* Kl = 8*Zl + parent(K)l */
|
|
||||||
scalar_add_256bits(zl8, priv_key, res_key);
|
|
||||||
|
|
||||||
/* Kr = Zr + parent(K)r */
|
|
||||||
scalar_add_256bits(z + 32, priv_key + 32, res_key + 32);
|
|
||||||
|
|
||||||
memcpy(inout->private_key, res_key, 32);
|
|
||||||
memcpy(inout->private_key_extension, res_key + 32, 32);
|
|
||||||
|
|
||||||
if (keysize == 64) {
|
|
||||||
data[0] = 1;
|
|
||||||
} else {
|
|
||||||
data[0] = 3;
|
|
||||||
}
|
|
||||||
hmac_sha512_Init(&ctx, inout->chain_code, 32);
|
|
||||||
hmac_sha512_Update(&ctx, data, 1 + keysize + 4);
|
|
||||||
hmac_sha512_Final(&ctx, z);
|
|
||||||
|
|
||||||
memcpy(inout->chain_code, z + 32, 32);
|
|
||||||
inout->depth++;
|
|
||||||
inout->child_num = index;
|
|
||||||
memzero(inout->public_key, sizeof(inout->public_key));
|
|
||||||
|
|
||||||
// making sure to wipe our memory
|
|
||||||
memzero(z, sizeof(z));
|
|
||||||
memzero(data, sizeof(data));
|
|
||||||
memzero(priv_key, sizeof(priv_key));
|
|
||||||
memzero(res_key, sizeof(res_key));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int hdnode_from_secret_cardano(const uint8_t *k,
|
|
||||||
const uint8_t *chain_code, HDNode *out) {
|
|
||||||
memzero(out, sizeof(HDNode));
|
|
||||||
out->depth = 0;
|
|
||||||
out->child_num = 0;
|
|
||||||
out->curve = &ed25519_cardano_info;
|
|
||||||
memcpy(out->private_key, k, 32);
|
|
||||||
memcpy(out->private_key_extension, k + 32, 32);
|
|
||||||
memcpy(out->chain_code, chain_code, 32);
|
|
||||||
|
|
||||||
out->private_key[0] &= 0xf8;
|
|
||||||
out->private_key[31] &= 0x1f;
|
|
||||||
out->private_key[31] |= 0x40;
|
|
||||||
|
|
||||||
out->public_key[0] = 0;
|
|
||||||
if (hdnode_fill_public_key(out) != 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Derives the root Cardano HDNode from a master secret, aka seed, as defined in
|
|
||||||
// SLIP-0023.
|
|
||||||
int hdnode_from_seed_cardano(const uint8_t *seed, int seed_len, HDNode *out) {
|
|
||||||
static CONFIDENTIAL uint8_t I[SHA512_DIGEST_LENGTH];
|
|
||||||
static CONFIDENTIAL uint8_t k[SHA512_DIGEST_LENGTH];
|
|
||||||
static CONFIDENTIAL HMAC_SHA512_CTX ctx;
|
|
||||||
|
|
||||||
hmac_sha512_Init(&ctx, (const uint8_t *)ED25519_CARDANO_NAME,
|
|
||||||
strlen(ED25519_CARDANO_NAME));
|
|
||||||
hmac_sha512_Update(&ctx, seed, seed_len);
|
|
||||||
hmac_sha512_Final(&ctx, I);
|
|
||||||
|
|
||||||
sha512_Raw(I, 32, k);
|
|
||||||
|
|
||||||
int ret = hdnode_from_secret_cardano(k, I + 32, out);
|
|
||||||
|
|
||||||
memzero(I, sizeof(I));
|
|
||||||
memzero(k, sizeof(k));
|
|
||||||
memzero(&ctx, sizeof(ctx));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Derives the root Cardano HDNode from a passphrase and the entropy encoded in
|
|
||||||
// a BIP-0039 mnemonic using the Icarus derivation scheme, aka V2 derivation
|
|
||||||
// scheme.
|
|
||||||
int hdnode_from_entropy_cardano_icarus(const uint8_t *pass, int pass_len,
|
|
||||||
const uint8_t *entropy, int entropy_len,
|
|
||||||
HDNode *out) {
|
|
||||||
static CONFIDENTIAL uint8_t secret[96];
|
|
||||||
pbkdf2_hmac_sha512(pass, pass_len, entropy, entropy_len, 4096, secret, 96);
|
|
||||||
|
|
||||||
int ret = hdnode_from_secret_cardano(secret, secret + 64, out);
|
|
||||||
memzero(secret, sizeof(secret));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
|
return hdnode_private_ckd_bip32(inout, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int hdnode_public_ckd_cp(const ecdsa_curve *curve, const curve_point *parent,
|
int hdnode_public_ckd_cp(const ecdsa_curve *curve, const curve_point *parent,
|
||||||
const uint8_t *parent_chain_code, uint32_t i,
|
const uint8_t *parent_chain_code, uint32_t i,
|
||||||
@ -952,9 +802,11 @@ const curve_info *get_curve_by_name(const char *curve_name) {
|
|||||||
if (strcmp(curve_name, ED25519_NAME) == 0) {
|
if (strcmp(curve_name, ED25519_NAME) == 0) {
|
||||||
return &ed25519_info;
|
return &ed25519_info;
|
||||||
}
|
}
|
||||||
|
#if USE_CARDANO
|
||||||
if (strcmp(curve_name, ED25519_CARDANO_NAME) == 0) {
|
if (strcmp(curve_name, ED25519_CARDANO_NAME) == 0) {
|
||||||
return &ed25519_cardano_info;
|
return &ed25519_cardano_info;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (strcmp(curve_name, ED25519_SHA3_NAME) == 0) {
|
if (strcmp(curve_name, ED25519_SHA3_NAME) == 0) {
|
||||||
return &ed25519_sha3_info;
|
return &ed25519_sha3_info;
|
||||||
}
|
}
|
||||||
|
@ -75,14 +75,6 @@ int hdnode_from_seed(const uint8_t *seed, int seed_len, const char *curve,
|
|||||||
|
|
||||||
int hdnode_private_ckd(HDNode *inout, uint32_t i);
|
int hdnode_private_ckd(HDNode *inout, uint32_t i);
|
||||||
|
|
||||||
#if USE_CARDANO
|
|
||||||
int hdnode_private_ckd_cardano(HDNode *inout, uint32_t i);
|
|
||||||
int hdnode_from_seed_cardano(const uint8_t *seed, int seed_len, HDNode *out);
|
|
||||||
int hdnode_from_entropy_cardano_icarus(const uint8_t *pass, int pass_len,
|
|
||||||
const uint8_t *seed, int seed_len,
|
|
||||||
HDNode *out);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int hdnode_public_ckd_cp(const ecdsa_curve *curve, const curve_point *parent,
|
int hdnode_public_ckd_cp(const ecdsa_curve *curve, const curve_point *parent,
|
||||||
const uint8_t *parent_chain_code, uint32_t i,
|
const uint8_t *parent_chain_code, uint32_t i,
|
||||||
curve_point *child, uint8_t *child_chain_code);
|
curve_point *child, uint8_t *child_chain_code);
|
||||||
|
252
crypto/cardano.c
Normal file
252
crypto/cardano.c
Normal file
@ -0,0 +1,252 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2013-2021 SatoshiLabs
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "bignum.h"
|
||||||
|
#include "bip32.h"
|
||||||
|
#include "cardano.h"
|
||||||
|
#include "curves.h"
|
||||||
|
#include "hasher.h"
|
||||||
|
#include "hmac.h"
|
||||||
|
#include "memzero.h"
|
||||||
|
#include "options.h"
|
||||||
|
#include "pbkdf2.h"
|
||||||
|
#include "sha2.h"
|
||||||
|
|
||||||
|
#if USE_CARDANO
|
||||||
|
|
||||||
|
#define CARDANO_MAX_NODE_DEPTH 1048576
|
||||||
|
|
||||||
|
const curve_info ed25519_cardano_info = {
|
||||||
|
.bip32_name = "ed25519 cardano seed",
|
||||||
|
.params = NULL,
|
||||||
|
.hasher_base58 = HASHER_SHA2D,
|
||||||
|
.hasher_sign = HASHER_SHA2D,
|
||||||
|
.hasher_pubkey = HASHER_SHA2_RIPEMD,
|
||||||
|
.hasher_script = HASHER_SHA2,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void scalar_multiply8(const uint8_t *src, int bytes, uint8_t *dst) {
|
||||||
|
uint8_t prev_acc = 0;
|
||||||
|
for (int i = 0; i < bytes; i++) {
|
||||||
|
dst[i] = (src[i] << 3) + (prev_acc & 0x7);
|
||||||
|
prev_acc = src[i] >> 5;
|
||||||
|
}
|
||||||
|
dst[bytes] = src[bytes - 1] >> 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void scalar_add_256bits(const uint8_t *src1, const uint8_t *src2,
|
||||||
|
uint8_t *dst) {
|
||||||
|
uint16_t r = 0;
|
||||||
|
for (int i = 0; i < 32; i++) {
|
||||||
|
r = r + (uint16_t)src1[i] + (uint16_t)src2[i];
|
||||||
|
dst[i] = r & 0xff;
|
||||||
|
r >>= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cardano_ed25519_tweak_bits(uint8_t private_key[32]) {
|
||||||
|
private_key[0] &= 0xf8;
|
||||||
|
private_key[31] &= 0x1f;
|
||||||
|
private_key[31] |= 0x40;
|
||||||
|
}
|
||||||
|
|
||||||
|
int hdnode_private_ckd_cardano(HDNode *inout, uint32_t index) {
|
||||||
|
if (inout->curve != &ed25519_cardano_info) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inout->depth >= CARDANO_MAX_NODE_DEPTH) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// checks for hardened/non-hardened derivation, keysize 32 means we are
|
||||||
|
// dealing with public key and thus non-h, keysize 64 is for private key
|
||||||
|
int keysize = 32;
|
||||||
|
if (index & 0x80000000) {
|
||||||
|
keysize = 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CONFIDENTIAL uint8_t data[1 + 64 + 4];
|
||||||
|
static CONFIDENTIAL uint8_t z[32 + 32];
|
||||||
|
static CONFIDENTIAL uint8_t priv_key[64];
|
||||||
|
static CONFIDENTIAL uint8_t res_key[64];
|
||||||
|
|
||||||
|
write_le(data + keysize + 1, index);
|
||||||
|
|
||||||
|
memcpy(priv_key, inout->private_key, 32);
|
||||||
|
memcpy(priv_key + 32, inout->private_key_extension, 32);
|
||||||
|
|
||||||
|
if (keysize == 64) { // private derivation
|
||||||
|
data[0] = 0;
|
||||||
|
memcpy(data + 1, inout->private_key, 32);
|
||||||
|
memcpy(data + 1 + 32, inout->private_key_extension, 32);
|
||||||
|
} else { // public derivation
|
||||||
|
if (hdnode_fill_public_key(inout) != 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
data[0] = 2;
|
||||||
|
memcpy(data + 1, inout->public_key + 1, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
static CONFIDENTIAL HMAC_SHA512_CTX ctx;
|
||||||
|
hmac_sha512_Init(&ctx, inout->chain_code, 32);
|
||||||
|
hmac_sha512_Update(&ctx, data, 1 + keysize + 4);
|
||||||
|
hmac_sha512_Final(&ctx, z);
|
||||||
|
|
||||||
|
static CONFIDENTIAL uint8_t zl8[32];
|
||||||
|
memzero(zl8, 32);
|
||||||
|
|
||||||
|
/* get 8 * Zl */
|
||||||
|
scalar_multiply8(z, 28, zl8);
|
||||||
|
/* Kl = 8*Zl + parent(K)l */
|
||||||
|
scalar_add_256bits(zl8, priv_key, res_key);
|
||||||
|
|
||||||
|
/* Kr = Zr + parent(K)r */
|
||||||
|
scalar_add_256bits(z + 32, priv_key + 32, res_key + 32);
|
||||||
|
|
||||||
|
memcpy(inout->private_key, res_key, 32);
|
||||||
|
memcpy(inout->private_key_extension, res_key + 32, 32);
|
||||||
|
|
||||||
|
if (keysize == 64) {
|
||||||
|
data[0] = 1;
|
||||||
|
} else {
|
||||||
|
data[0] = 3;
|
||||||
|
}
|
||||||
|
hmac_sha512_Init(&ctx, inout->chain_code, 32);
|
||||||
|
hmac_sha512_Update(&ctx, data, 1 + keysize + 4);
|
||||||
|
hmac_sha512_Final(&ctx, z);
|
||||||
|
|
||||||
|
memcpy(inout->chain_code, z + 32, 32);
|
||||||
|
inout->depth++;
|
||||||
|
inout->child_num = index;
|
||||||
|
memzero(inout->public_key, sizeof(inout->public_key));
|
||||||
|
|
||||||
|
// making sure to wipe our memory
|
||||||
|
memzero(z, sizeof(z));
|
||||||
|
memzero(data, sizeof(data));
|
||||||
|
memzero(priv_key, sizeof(priv_key));
|
||||||
|
memzero(res_key, sizeof(res_key));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int hdnode_from_secret_cardano(const uint8_t secret[CARDANO_SECRET_LENGTH],
|
||||||
|
HDNode *out) {
|
||||||
|
memzero(out, sizeof(HDNode));
|
||||||
|
out->depth = 0;
|
||||||
|
out->child_num = 0;
|
||||||
|
out->curve = &ed25519_cardano_info;
|
||||||
|
memcpy(out->private_key, secret, 32);
|
||||||
|
memcpy(out->private_key_extension, secret + 32, 32);
|
||||||
|
memcpy(out->chain_code, secret + 64, 32);
|
||||||
|
|
||||||
|
cardano_ed25519_tweak_bits(out->private_key);
|
||||||
|
|
||||||
|
out->public_key[0] = 0;
|
||||||
|
if (hdnode_fill_public_key(out) != 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Derives the root Cardano secret from a master secret, aka seed, as defined in
|
||||||
|
// SLIP-0023.
|
||||||
|
int secret_from_seed_cardano_slip23(const uint8_t *seed, int seed_len,
|
||||||
|
uint8_t secret_out[CARDANO_SECRET_LENGTH]) {
|
||||||
|
static CONFIDENTIAL uint8_t I[SHA512_DIGEST_LENGTH];
|
||||||
|
static CONFIDENTIAL HMAC_SHA512_CTX ctx;
|
||||||
|
|
||||||
|
hmac_sha512_Init(&ctx, (const uint8_t *)ED25519_CARDANO_NAME,
|
||||||
|
strlen(ED25519_CARDANO_NAME));
|
||||||
|
hmac_sha512_Update(&ctx, seed, seed_len);
|
||||||
|
hmac_sha512_Final(&ctx, I);
|
||||||
|
|
||||||
|
sha512_Raw(I, 32, secret_out);
|
||||||
|
|
||||||
|
memcpy(secret_out + SHA512_DIGEST_LENGTH, I + 32, 32);
|
||||||
|
cardano_ed25519_tweak_bits(secret_out);
|
||||||
|
|
||||||
|
memzero(I, sizeof(I));
|
||||||
|
memzero(&ctx, sizeof(ctx));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CARDANO_ICARUS_STEPS 32
|
||||||
|
#define CARDANO_ICARUS_ROUNDS_PER_STEP \
|
||||||
|
(CARDANO_ICARUS_PBKDF2_ROUNDS / CARDANO_ICARUS_STEPS)
|
||||||
|
|
||||||
|
// Derives the root Cardano HDNode from a passphrase and the entropy encoded in
|
||||||
|
// a BIP-0039 mnemonic using the Icarus derivation scheme, aka V2 derivation
|
||||||
|
// scheme.
|
||||||
|
int secret_from_entropy_cardano_icarus(
|
||||||
|
const uint8_t *pass, int pass_len, const uint8_t *entropy, int entropy_len,
|
||||||
|
uint8_t secret_out[CARDANO_SECRET_LENGTH],
|
||||||
|
void (*progress_callback)(uint32_t, uint32_t)) {
|
||||||
|
static CONFIDENTIAL PBKDF2_HMAC_SHA512_CTX pctx;
|
||||||
|
static CONFIDENTIAL uint8_t digest[SHA512_DIGEST_LENGTH];
|
||||||
|
uint32_t progress = 0;
|
||||||
|
|
||||||
|
// PASS 1: first 64 bytes
|
||||||
|
pbkdf2_hmac_sha512_Init(&pctx, pass, pass_len, entropy, entropy_len, 1);
|
||||||
|
if (progress_callback) {
|
||||||
|
progress_callback(progress, CARDANO_ICARUS_PBKDF2_ROUNDS * 2);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < CARDANO_ICARUS_STEPS; i++) {
|
||||||
|
pbkdf2_hmac_sha512_Update(&pctx, CARDANO_ICARUS_ROUNDS_PER_STEP);
|
||||||
|
if (progress_callback) {
|
||||||
|
progress += CARDANO_ICARUS_ROUNDS_PER_STEP;
|
||||||
|
progress_callback(progress, CARDANO_ICARUS_PBKDF2_ROUNDS * 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pbkdf2_hmac_sha512_Final(&pctx, digest);
|
||||||
|
|
||||||
|
memcpy(secret_out, digest, SHA512_DIGEST_LENGTH);
|
||||||
|
|
||||||
|
// PASS 2: remaining 32 bytes
|
||||||
|
pbkdf2_hmac_sha512_Init(&pctx, pass, pass_len, entropy, entropy_len, 2);
|
||||||
|
if (progress_callback) {
|
||||||
|
progress_callback(progress, CARDANO_ICARUS_PBKDF2_ROUNDS * 2);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < CARDANO_ICARUS_STEPS; i++) {
|
||||||
|
pbkdf2_hmac_sha512_Update(&pctx, CARDANO_ICARUS_ROUNDS_PER_STEP);
|
||||||
|
if (progress_callback) {
|
||||||
|
progress += CARDANO_ICARUS_ROUNDS_PER_STEP;
|
||||||
|
progress_callback(progress, CARDANO_ICARUS_PBKDF2_ROUNDS * 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pbkdf2_hmac_sha512_Final(&pctx, digest);
|
||||||
|
|
||||||
|
memcpy(secret_out + SHA512_DIGEST_LENGTH, digest,
|
||||||
|
CARDANO_SECRET_LENGTH - SHA512_DIGEST_LENGTH);
|
||||||
|
|
||||||
|
cardano_ed25519_tweak_bits(secret_out);
|
||||||
|
|
||||||
|
memzero(&pctx, sizeof(pctx));
|
||||||
|
memzero(digest, sizeof(digest));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // USE_CARDANO
|
54
crypto/cardano.h
Normal file
54
crypto/cardano.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2013-2021 SatoshiLabs
|
||||||
|
*
|
||||||
|
* 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 __CARDANO_H__
|
||||||
|
#define __CARDANO_H__
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "bip32.h"
|
||||||
|
#include "options.h"
|
||||||
|
|
||||||
|
#if USE_CARDANO
|
||||||
|
|
||||||
|
#define CARDANO_SECRET_LENGTH 96
|
||||||
|
#define CARDANO_ICARUS_PBKDF2_ROUNDS 4096
|
||||||
|
|
||||||
|
extern const curve_info ed25519_cardano_info;
|
||||||
|
|
||||||
|
int hdnode_private_ckd_cardano(HDNode *inout, uint32_t i);
|
||||||
|
|
||||||
|
int secret_from_entropy_cardano_icarus(
|
||||||
|
const uint8_t *pass, int pass_len, const uint8_t *entropy, int entropy_len,
|
||||||
|
uint8_t secret_out[CARDANO_SECRET_LENGTH],
|
||||||
|
void (*progress_callback)(uint32_t current, uint32_t total));
|
||||||
|
int secret_from_seed_cardano_ledger(const uint8_t *seed, int seed_len,
|
||||||
|
uint8_t secret_out[CARDANO_SECRET_LENGTH]);
|
||||||
|
int secret_from_seed_cardano_slip23(const uint8_t *seed, int seed_len,
|
||||||
|
uint8_t secret_out[CARDANO_SECRET_LENGTH]);
|
||||||
|
|
||||||
|
int hdnode_from_secret_cardano(const uint8_t secret[CARDANO_SECRET_LENGTH],
|
||||||
|
HDNode *out);
|
||||||
|
|
||||||
|
#endif // USE_CARDANO
|
||||||
|
|
||||||
|
#endif // __CARDANO_H__
|
@ -48,6 +48,7 @@
|
|||||||
#include "blake256.h"
|
#include "blake256.h"
|
||||||
#include "blake2b.h"
|
#include "blake2b.h"
|
||||||
#include "blake2s.h"
|
#include "blake2s.h"
|
||||||
|
#include "cardano.h"
|
||||||
#include "chacha_drbg.h"
|
#include "chacha_drbg.h"
|
||||||
#include "curves.h"
|
#include "curves.h"
|
||||||
#include "ecdsa.h"
|
#include "ecdsa.h"
|
||||||
|
@ -113,14 +113,24 @@ START_TEST(test_bip32_cardano_hdnode_vector_1) {
|
|||||||
HDNode node;
|
HDNode node;
|
||||||
|
|
||||||
uint8_t mnemonic_bits[66];
|
uint8_t mnemonic_bits[66];
|
||||||
|
uint8_t cardano_secret[CARDANO_SECRET_LENGTH];
|
||||||
int mnemonic_bits_len = mnemonic_to_bits(
|
int mnemonic_bits_len = mnemonic_to_bits(
|
||||||
"ring crime symptom enough erupt lady behave ramp apart settle citizen "
|
"ring crime symptom enough erupt lady behave ramp apart settle citizen "
|
||||||
"junk",
|
"junk",
|
||||||
mnemonic_bits);
|
mnemonic_bits);
|
||||||
ck_assert_int_eq(mnemonic_bits_len, 132);
|
ck_assert_int_eq(mnemonic_bits_len, 132);
|
||||||
hdnode_from_entropy_cardano_icarus((const uint8_t *)"", 0, mnemonic_bits,
|
secret_from_entropy_cardano_icarus((const uint8_t *)"", 0, mnemonic_bits,
|
||||||
mnemonic_bits_len / 8, &node);
|
mnemonic_bits_len / 8, cardano_secret,
|
||||||
|
NULL);
|
||||||
|
hdnode_from_secret_cardano(cardano_secret, &node);
|
||||||
|
|
||||||
|
ck_assert_mem_eq(
|
||||||
|
cardano_secret,
|
||||||
|
fromhex(
|
||||||
|
"08a14df748e477a69d21c97c56db151fc19e2521f31dd0ac5360f269e5b6ea46"
|
||||||
|
"daeb991f2d2128e2525415c56a07f4366baa26c1e48572a5e073934b6de35fbc"
|
||||||
|
"affbc325d9027c0f2d9f925b1dcf6c12bf5c1dd08904474066a4f2c00db56173"),
|
||||||
|
96);
|
||||||
ck_assert_mem_eq(
|
ck_assert_mem_eq(
|
||||||
node.chain_code,
|
node.chain_code,
|
||||||
fromhex(
|
fromhex(
|
||||||
@ -149,15 +159,18 @@ START_TEST(test_bip32_cardano_hdnode_vector_2) {
|
|||||||
HDNode node;
|
HDNode node;
|
||||||
|
|
||||||
uint8_t mnemonic_bits[66];
|
uint8_t mnemonic_bits[66];
|
||||||
|
uint8_t cardano_secret[CARDANO_SECRET_LENGTH];
|
||||||
int mnemonic_bits_len = mnemonic_to_bits(
|
int mnemonic_bits_len = mnemonic_to_bits(
|
||||||
"ring crime symptom enough erupt lady behave ramp apart settle citizen "
|
"ring crime symptom enough erupt lady behave ramp apart settle citizen "
|
||||||
"junk",
|
"junk",
|
||||||
mnemonic_bits);
|
mnemonic_bits);
|
||||||
ck_assert_int_eq(mnemonic_bits_len, 132);
|
ck_assert_int_eq(mnemonic_bits_len, 132);
|
||||||
hdnode_from_entropy_cardano_icarus((const uint8_t *)"", 0, mnemonic_bits,
|
secret_from_entropy_cardano_icarus((const uint8_t *)"", 0, mnemonic_bits,
|
||||||
mnemonic_bits_len / 8, &node);
|
mnemonic_bits_len / 8, cardano_secret,
|
||||||
|
NULL);
|
||||||
|
hdnode_from_secret_cardano(cardano_secret, &node);
|
||||||
|
|
||||||
hdnode_private_ckd_cardano(&node, 0x80000000);
|
hdnode_private_ckd(&node, 0x80000000);
|
||||||
|
|
||||||
ck_assert_mem_eq(
|
ck_assert_mem_eq(
|
||||||
node.chain_code,
|
node.chain_code,
|
||||||
@ -187,15 +200,18 @@ START_TEST(test_bip32_cardano_hdnode_vector_3) {
|
|||||||
HDNode node;
|
HDNode node;
|
||||||
|
|
||||||
uint8_t mnemonic_bits[66];
|
uint8_t mnemonic_bits[66];
|
||||||
|
uint8_t cardano_secret[CARDANO_SECRET_LENGTH];
|
||||||
int mnemonic_bits_len = mnemonic_to_bits(
|
int mnemonic_bits_len = mnemonic_to_bits(
|
||||||
"ring crime symptom enough erupt lady behave ramp apart settle citizen "
|
"ring crime symptom enough erupt lady behave ramp apart settle citizen "
|
||||||
"junk",
|
"junk",
|
||||||
mnemonic_bits);
|
mnemonic_bits);
|
||||||
ck_assert_int_eq(mnemonic_bits_len, 132);
|
ck_assert_int_eq(mnemonic_bits_len, 132);
|
||||||
hdnode_from_entropy_cardano_icarus((const uint8_t *)"", 0, mnemonic_bits,
|
secret_from_entropy_cardano_icarus((const uint8_t *)"", 0, mnemonic_bits,
|
||||||
mnemonic_bits_len / 8, &node);
|
mnemonic_bits_len / 8, cardano_secret,
|
||||||
|
NULL);
|
||||||
|
hdnode_from_secret_cardano(cardano_secret, &node);
|
||||||
|
|
||||||
hdnode_private_ckd_cardano(&node, 0x80000001);
|
hdnode_private_ckd(&node, 0x80000001);
|
||||||
|
|
||||||
ck_assert_mem_eq(
|
ck_assert_mem_eq(
|
||||||
node.chain_code,
|
node.chain_code,
|
||||||
@ -225,16 +241,19 @@ START_TEST(test_bip32_cardano_hdnode_vector_4) {
|
|||||||
HDNode node;
|
HDNode node;
|
||||||
|
|
||||||
uint8_t mnemonic_bits[66];
|
uint8_t mnemonic_bits[66];
|
||||||
|
uint8_t cardano_secret[CARDANO_SECRET_LENGTH];
|
||||||
int mnemonic_bits_len = mnemonic_to_bits(
|
int mnemonic_bits_len = mnemonic_to_bits(
|
||||||
"ring crime symptom enough erupt lady behave ramp apart settle citizen "
|
"ring crime symptom enough erupt lady behave ramp apart settle citizen "
|
||||||
"junk",
|
"junk",
|
||||||
mnemonic_bits);
|
mnemonic_bits);
|
||||||
ck_assert_int_eq(mnemonic_bits_len, 132);
|
ck_assert_int_eq(mnemonic_bits_len, 132);
|
||||||
hdnode_from_entropy_cardano_icarus((const uint8_t *)"", 0, mnemonic_bits,
|
secret_from_entropy_cardano_icarus((const uint8_t *)"", 0, mnemonic_bits,
|
||||||
mnemonic_bits_len / 8, &node);
|
mnemonic_bits_len / 8, cardano_secret,
|
||||||
|
NULL);
|
||||||
|
hdnode_from_secret_cardano(cardano_secret, &node);
|
||||||
|
|
||||||
hdnode_private_ckd_cardano(&node, 0x80000000);
|
hdnode_private_ckd(&node, 0x80000000);
|
||||||
hdnode_private_ckd_cardano(&node, 0x80000001);
|
hdnode_private_ckd(&node, 0x80000001);
|
||||||
|
|
||||||
ck_assert_mem_eq(
|
ck_assert_mem_eq(
|
||||||
node.chain_code,
|
node.chain_code,
|
||||||
@ -264,17 +283,20 @@ START_TEST(test_bip32_cardano_hdnode_vector_5) {
|
|||||||
HDNode node;
|
HDNode node;
|
||||||
|
|
||||||
uint8_t mnemonic_bits[66];
|
uint8_t mnemonic_bits[66];
|
||||||
|
uint8_t cardano_secret[CARDANO_SECRET_LENGTH];
|
||||||
int mnemonic_bits_len = mnemonic_to_bits(
|
int mnemonic_bits_len = mnemonic_to_bits(
|
||||||
"ring crime symptom enough erupt lady behave ramp apart settle citizen "
|
"ring crime symptom enough erupt lady behave ramp apart settle citizen "
|
||||||
"junk",
|
"junk",
|
||||||
mnemonic_bits);
|
mnemonic_bits);
|
||||||
ck_assert_int_eq(mnemonic_bits_len, 132);
|
ck_assert_int_eq(mnemonic_bits_len, 132);
|
||||||
hdnode_from_entropy_cardano_icarus((const uint8_t *)"", 0, mnemonic_bits,
|
secret_from_entropy_cardano_icarus((const uint8_t *)"", 0, mnemonic_bits,
|
||||||
mnemonic_bits_len / 8, &node);
|
mnemonic_bits_len / 8, cardano_secret,
|
||||||
|
NULL);
|
||||||
|
hdnode_from_secret_cardano(cardano_secret, &node);
|
||||||
|
|
||||||
hdnode_private_ckd_cardano(&node, 0x80000000);
|
hdnode_private_ckd(&node, 0x80000000);
|
||||||
hdnode_private_ckd_cardano(&node, 0x80000001);
|
hdnode_private_ckd(&node, 0x80000001);
|
||||||
hdnode_private_ckd_cardano(&node, 0x80000002);
|
hdnode_private_ckd(&node, 0x80000002);
|
||||||
|
|
||||||
ck_assert_mem_eq(
|
ck_assert_mem_eq(
|
||||||
node.chain_code,
|
node.chain_code,
|
||||||
@ -304,18 +326,21 @@ START_TEST(test_bip32_cardano_hdnode_vector_6) {
|
|||||||
HDNode node;
|
HDNode node;
|
||||||
|
|
||||||
uint8_t mnemonic_bits[66];
|
uint8_t mnemonic_bits[66];
|
||||||
|
uint8_t cardano_secret[CARDANO_SECRET_LENGTH];
|
||||||
int mnemonic_bits_len = mnemonic_to_bits(
|
int mnemonic_bits_len = mnemonic_to_bits(
|
||||||
"ring crime symptom enough erupt lady behave ramp apart settle citizen "
|
"ring crime symptom enough erupt lady behave ramp apart settle citizen "
|
||||||
"junk",
|
"junk",
|
||||||
mnemonic_bits);
|
mnemonic_bits);
|
||||||
ck_assert_int_eq(mnemonic_bits_len, 132);
|
ck_assert_int_eq(mnemonic_bits_len, 132);
|
||||||
hdnode_from_entropy_cardano_icarus((const uint8_t *)"", 0, mnemonic_bits,
|
secret_from_entropy_cardano_icarus((const uint8_t *)"", 0, mnemonic_bits,
|
||||||
mnemonic_bits_len / 8, &node);
|
mnemonic_bits_len / 8, cardano_secret,
|
||||||
|
NULL);
|
||||||
|
hdnode_from_secret_cardano(cardano_secret, &node);
|
||||||
|
|
||||||
hdnode_private_ckd_cardano(&node, 0x80000000);
|
hdnode_private_ckd(&node, 0x80000000);
|
||||||
hdnode_private_ckd_cardano(&node, 0x80000001);
|
hdnode_private_ckd(&node, 0x80000001);
|
||||||
hdnode_private_ckd_cardano(&node, 0x80000002);
|
hdnode_private_ckd(&node, 0x80000002);
|
||||||
hdnode_private_ckd_cardano(&node, 0x80000002);
|
hdnode_private_ckd(&node, 0x80000002);
|
||||||
|
|
||||||
ck_assert_mem_eq(
|
ck_assert_mem_eq(
|
||||||
node.chain_code,
|
node.chain_code,
|
||||||
@ -345,19 +370,22 @@ START_TEST(test_bip32_cardano_hdnode_vector_7) {
|
|||||||
HDNode node;
|
HDNode node;
|
||||||
|
|
||||||
uint8_t mnemonic_bits[66];
|
uint8_t mnemonic_bits[66];
|
||||||
|
uint8_t cardano_secret[CARDANO_SECRET_LENGTH];
|
||||||
int mnemonic_bits_len = mnemonic_to_bits(
|
int mnemonic_bits_len = mnemonic_to_bits(
|
||||||
"ring crime symptom enough erupt lady behave ramp apart settle citizen "
|
"ring crime symptom enough erupt lady behave ramp apart settle citizen "
|
||||||
"junk",
|
"junk",
|
||||||
mnemonic_bits);
|
mnemonic_bits);
|
||||||
ck_assert_int_eq(mnemonic_bits_len, 132);
|
ck_assert_int_eq(mnemonic_bits_len, 132);
|
||||||
hdnode_from_entropy_cardano_icarus((const uint8_t *)"", 0, mnemonic_bits,
|
secret_from_entropy_cardano_icarus((const uint8_t *)"", 0, mnemonic_bits,
|
||||||
mnemonic_bits_len / 8, &node);
|
mnemonic_bits_len / 8, cardano_secret,
|
||||||
|
NULL);
|
||||||
|
hdnode_from_secret_cardano(cardano_secret, &node);
|
||||||
|
|
||||||
hdnode_private_ckd_cardano(&node, 0x80000000);
|
hdnode_private_ckd(&node, 0x80000000);
|
||||||
hdnode_private_ckd_cardano(&node, 0x80000001);
|
hdnode_private_ckd(&node, 0x80000001);
|
||||||
hdnode_private_ckd_cardano(&node, 0x80000002);
|
hdnode_private_ckd(&node, 0x80000002);
|
||||||
hdnode_private_ckd_cardano(&node, 0x80000002);
|
hdnode_private_ckd(&node, 0x80000002);
|
||||||
hdnode_private_ckd_cardano(&node, 0xBB9ACA00);
|
hdnode_private_ckd(&node, 0xBB9ACA00);
|
||||||
|
|
||||||
ck_assert_mem_eq(
|
ck_assert_mem_eq(
|
||||||
node.chain_code,
|
node.chain_code,
|
||||||
@ -387,19 +415,22 @@ START_TEST(test_bip32_cardano_hdnode_vector_8) {
|
|||||||
HDNode node;
|
HDNode node;
|
||||||
|
|
||||||
uint8_t mnemonic_bits[66];
|
uint8_t mnemonic_bits[66];
|
||||||
|
uint8_t cardano_secret[CARDANO_SECRET_LENGTH];
|
||||||
int mnemonic_bits_len = mnemonic_to_bits(
|
int mnemonic_bits_len = mnemonic_to_bits(
|
||||||
"found differ bulb shadow wrist blue bind vessel deposit tip pelican "
|
"found differ bulb shadow wrist blue bind vessel deposit tip pelican "
|
||||||
"action surprise weapon check fiction muscle this",
|
"action surprise weapon check fiction muscle this",
|
||||||
mnemonic_bits);
|
mnemonic_bits);
|
||||||
ck_assert_int_eq(mnemonic_bits_len, 198);
|
ck_assert_int_eq(mnemonic_bits_len, 198);
|
||||||
hdnode_from_entropy_cardano_icarus((const uint8_t *)"", 0, mnemonic_bits,
|
secret_from_entropy_cardano_icarus((const uint8_t *)"", 0, mnemonic_bits,
|
||||||
mnemonic_bits_len / 8, &node);
|
mnemonic_bits_len / 8, cardano_secret,
|
||||||
|
NULL);
|
||||||
|
hdnode_from_secret_cardano(cardano_secret, &node);
|
||||||
|
|
||||||
hdnode_private_ckd_cardano(&node, 0x80000000);
|
hdnode_private_ckd(&node, 0x80000000);
|
||||||
hdnode_private_ckd_cardano(&node, 0x80000001);
|
hdnode_private_ckd(&node, 0x80000001);
|
||||||
hdnode_private_ckd_cardano(&node, 0x80000002);
|
hdnode_private_ckd(&node, 0x80000002);
|
||||||
hdnode_private_ckd_cardano(&node, 0x80000002);
|
hdnode_private_ckd(&node, 0x80000002);
|
||||||
hdnode_private_ckd_cardano(&node, 0xBB9ACA00);
|
hdnode_private_ckd(&node, 0xBB9ACA00);
|
||||||
|
|
||||||
ck_assert_mem_eq(
|
ck_assert_mem_eq(
|
||||||
node.chain_code,
|
node.chain_code,
|
||||||
@ -429,20 +460,23 @@ START_TEST(test_bip32_cardano_hdnode_vector_9) {
|
|||||||
HDNode node;
|
HDNode node;
|
||||||
|
|
||||||
uint8_t mnemonic_bits[66];
|
uint8_t mnemonic_bits[66];
|
||||||
|
uint8_t cardano_secret[CARDANO_SECRET_LENGTH];
|
||||||
int mnemonic_bits_len = mnemonic_to_bits(
|
int mnemonic_bits_len = mnemonic_to_bits(
|
||||||
"balance exotic ranch knife glory slow tape favorite yard gym awake "
|
"balance exotic ranch knife glory slow tape favorite yard gym awake "
|
||||||
"ill exist useless parent aim pig stay effort into square gasp credit "
|
"ill exist useless parent aim pig stay effort into square gasp credit "
|
||||||
"butter",
|
"butter",
|
||||||
mnemonic_bits);
|
mnemonic_bits);
|
||||||
ck_assert_int_eq(mnemonic_bits_len, 264);
|
ck_assert_int_eq(mnemonic_bits_len, 264);
|
||||||
hdnode_from_entropy_cardano_icarus((const uint8_t *)"", 0, mnemonic_bits,
|
secret_from_entropy_cardano_icarus((const uint8_t *)"", 0, mnemonic_bits,
|
||||||
mnemonic_bits_len / 8, &node);
|
mnemonic_bits_len / 8, cardano_secret,
|
||||||
|
NULL);
|
||||||
|
hdnode_from_secret_cardano(cardano_secret, &node);
|
||||||
|
|
||||||
hdnode_private_ckd_cardano(&node, 0x80000000);
|
hdnode_private_ckd(&node, 0x80000000);
|
||||||
hdnode_private_ckd_cardano(&node, 0x80000001);
|
hdnode_private_ckd(&node, 0x80000001);
|
||||||
hdnode_private_ckd_cardano(&node, 0x80000002);
|
hdnode_private_ckd(&node, 0x80000002);
|
||||||
hdnode_private_ckd_cardano(&node, 0x80000002);
|
hdnode_private_ckd(&node, 0x80000002);
|
||||||
hdnode_private_ckd_cardano(&node, 0xBB9ACA00);
|
hdnode_private_ckd(&node, 0xBB9ACA00);
|
||||||
|
|
||||||
ck_assert_mem_eq(
|
ck_assert_mem_eq(
|
||||||
node.chain_code,
|
node.chain_code,
|
||||||
|
Loading…
Reference in New Issue
Block a user