Skip to content

Instantly share code, notes, and snippets.

@btchip
Created April 5, 2017 12:34
Show Gist options
  • Save btchip/ec28fb50dcfaf90136d58b10cc009d92 to your computer and use it in GitHub Desktop.
Save btchip/ec28fb50dcfaf90136d58b10cc009d92 to your computer and use it in GitHub Desktop.
derive BIP 32
void derive(cx_curve_t curve, unsigned int *path, unsigned int pathLength,
unsigned char *privateKey, unsigned char *chain) {
unsigned char tmpPrivateChain[64];
unsigned int i;
cx_ecfp_private_key_t tmpEcdsaPrivate;
cx_curve_domain_t *domain = cx_ecfp_get_domain(curve);
os_memmove(tmpPrivateChain, privateKey, 32);
os_memmove(tmpPrivateChain + 32, chain, 32);
for (i = 0; i < pathLength; i++) {
unsigned char tmp[65];
if (((path[i] >> 24) & 0x80) != 0) {
tmp[0] = 0;
os_memmove(tmp + 1, tmpPrivateChain, 32);
} else {
if (curve == CX_CURVE_Ed25519) {
THROW(EXCEPTION);
}
cx_ecfp_public_key_t tmpEcdsaPublic;
cx_ecdsa_init_private_key(curve, tmpPrivateChain, 32,
&tmpEcdsaPrivate);
cx_ecfp_generate_pair(curve, &tmpEcdsaPublic, &tmpEcdsaPrivate, 1);
tmpEcdsaPublic.W[0] = ((tmpEcdsaPublic.W[64] & 1) ? 0x03 : 0x02);
os_memmove(tmp, tmpEcdsaPublic.W, 33);
}
for (;;) {
unsigned char failed = 0;
tmp[33] = ((path[i] >> 24) & 0xff);
tmp[34] = ((path[i] >> 16) & 0xff);
tmp[35] = ((path[i] >> 8) & 0xff);
tmp[36] = (path[i] & 0xff);
cx_hmac_sha512(tmpPrivateChain + 32, 32, tmp, 37, tmp);
if (curve != CX_CURVE_Ed25519) {
if (cx_math_cmp(tmp, domain->n, 32) >= 0) {
failed = 1;
} else {
cx_math_addm(tmp, tmp, tmpPrivateChain, domain->n, 32);
failed = cx_math_is_zero(tmp, 32);
}
}
if (!failed) {
break;
}
tmp[0] = 1;
os_memmove(tmp + 1, tmp + 32, 32);
}
os_memmove(tmpPrivateChain, tmp, 32);
os_memmove(tmpPrivateChain + 32, tmp + 32, 32);
}
os_memmove(privateKey, tmpPrivateChain, 32);
os_memmove(chain, tmpPrivateChain + 32, 32);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment