mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-23 06:48:16 +00:00
Implement ECDH with Curve25519 at BIP32 module
This commit is contained in:
parent
0ad8a7c627
commit
906c543ebc
51
bip32.c
51
bip32.c
@ -37,6 +37,7 @@
|
|||||||
#include "secp256k1.h"
|
#include "secp256k1.h"
|
||||||
#include "nist256p1.h"
|
#include "nist256p1.h"
|
||||||
#include "ed25519.h"
|
#include "ed25519.h"
|
||||||
|
#include "curve25519-donna.h"
|
||||||
#if USE_ETHEREUM
|
#if USE_ETHEREUM
|
||||||
#include "sha3.h"
|
#include "sha3.h"
|
||||||
#endif
|
#endif
|
||||||
@ -47,6 +48,12 @@ const curve_info ed25519_info = {
|
|||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const curve_info curve25519_info = {
|
||||||
|
/* bip32_name */
|
||||||
|
"curve25519 seed",
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
int hdnode_from_xpub(uint32_t depth, uint32_t child_num, const uint8_t *chain_code, const uint8_t *public_key, const char* curve, HDNode *out)
|
int hdnode_from_xpub(uint32_t depth, uint32_t child_num, const uint8_t *chain_code, const uint8_t *public_key, const char* curve, HDNode *out)
|
||||||
{
|
{
|
||||||
const curve_info *info = get_curve_by_name(curve);
|
const curve_info *info = get_curve_by_name(curve);
|
||||||
@ -393,6 +400,9 @@ void hdnode_fill_public_key(HDNode *node)
|
|||||||
if (node->curve == &ed25519_info) {
|
if (node->curve == &ed25519_info) {
|
||||||
node->public_key[0] = 1;
|
node->public_key[0] = 1;
|
||||||
ed25519_publickey(node->private_key, node->public_key + 1);
|
ed25519_publickey(node->private_key, node->public_key + 1);
|
||||||
|
} else if (node->curve == &curve25519_info) {
|
||||||
|
node->public_key[0] = 1;
|
||||||
|
curve25519_publickey(node->public_key + 1, node->private_key);
|
||||||
} else {
|
} else {
|
||||||
ecdsa_get_public_key33(node->curve->params, node->private_key, node->public_key);
|
ecdsa_get_public_key33(node->curve->params, node->private_key, node->public_key);
|
||||||
}
|
}
|
||||||
@ -427,6 +437,8 @@ int hdnode_sign(HDNode *node, const uint8_t *msg, uint32_t msg_len, uint8_t *sig
|
|||||||
hdnode_fill_public_key(node);
|
hdnode_fill_public_key(node);
|
||||||
ed25519_sign(msg, msg_len, node->private_key, node->public_key + 1, sig);
|
ed25519_sign(msg, msg_len, node->private_key, node->public_key + 1, sig);
|
||||||
return 0;
|
return 0;
|
||||||
|
} else if (node->curve == &curve25519_info) {
|
||||||
|
return 1; // signatures are not supported
|
||||||
} else {
|
} else {
|
||||||
return ecdsa_sign(node->curve->params, node->private_key, msg, msg_len, sig, pby, is_canonical);
|
return ecdsa_sign(node->curve->params, node->private_key, msg, msg_len, sig, pby, is_canonical);
|
||||||
}
|
}
|
||||||
@ -438,11 +450,47 @@ int hdnode_sign_digest(HDNode *node, const uint8_t *digest, uint8_t *sig, uint8_
|
|||||||
hdnode_fill_public_key(node);
|
hdnode_fill_public_key(node);
|
||||||
ed25519_sign(digest, 32, node->private_key, node->public_key + 1, sig);
|
ed25519_sign(digest, 32, node->private_key, node->public_key + 1, sig);
|
||||||
return 0;
|
return 0;
|
||||||
|
} else if (node->curve == &curve25519_info) {
|
||||||
|
return 1; // signatures are not supported
|
||||||
} else {
|
} else {
|
||||||
return ecdsa_sign_digest(node->curve->params, node->private_key, digest, sig, pby, is_canonical);
|
return ecdsa_sign_digest(node->curve->params, node->private_key, digest, sig, pby, is_canonical);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int hdnode_get_shared_key(const HDNode *node, const uint8_t *peer_public_key, uint8_t *session_key, int *result_size)
|
||||||
|
{
|
||||||
|
// Use elliptic curve Diffie-Helman to compute shared session key
|
||||||
|
if (node->curve == &ed25519_info) {
|
||||||
|
*result_size = 0;
|
||||||
|
return 1; // ECDH is not supported
|
||||||
|
} else if (node->curve == &curve25519_info) {
|
||||||
|
session_key[0] = 0x04;
|
||||||
|
if (peer_public_key[0] != 0x40) {
|
||||||
|
return 1; // Curve25519 public key should start with 0x40 byte.
|
||||||
|
}
|
||||||
|
curve25519_scalarmult(session_key + 1, node->private_key, peer_public_key + 1);
|
||||||
|
*result_size = 33;
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
curve_point point;
|
||||||
|
const ecdsa_curve *curve = node->curve->params;
|
||||||
|
if (!ecdsa_read_pubkey(curve, peer_public_key, &point)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
bignum256 k;
|
||||||
|
bn_read_be(node->private_key, &k);
|
||||||
|
point_multiply(curve, &k, &point, &point);
|
||||||
|
MEMSET_BZERO(&k, sizeof(k));
|
||||||
|
|
||||||
|
session_key[0] = 0x04;
|
||||||
|
bn_write_be(&point.x, session_key + 1);
|
||||||
|
bn_write_be(&point.y, session_key + 33);
|
||||||
|
MEMSET_BZERO(&point, sizeof(point));
|
||||||
|
*result_size = 65;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int hdnode_serialize(const HDNode *node, uint32_t fingerprint, uint32_t version, char use_public, char *str, int strsize)
|
int hdnode_serialize(const HDNode *node, uint32_t fingerprint, uint32_t version, char use_public, char *str, int strsize)
|
||||||
{
|
{
|
||||||
@ -514,5 +562,8 @@ 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 (strcmp(curve_name, CURVE25519_NAME) == 0) {
|
||||||
|
return &curve25519_info;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
2
bip32.h
2
bip32.h
@ -74,6 +74,8 @@ int hdnode_get_ethereum_pubkeyhash(const HDNode *node, uint8_t *pubkeyhash);
|
|||||||
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(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]));
|
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]));
|
||||||
|
|
||||||
|
int hdnode_get_shared_key(const HDNode *node, const uint8_t *peer_public_key, uint8_t *session_key, int *result_size);
|
||||||
|
|
||||||
int hdnode_serialize_public(const HDNode *node, uint32_t fingerprint, char *str, int strsize);
|
int hdnode_serialize_public(const HDNode *node, uint32_t fingerprint, char *str, int strsize);
|
||||||
|
|
||||||
int hdnode_serialize_private(const HDNode *node, uint32_t fingerprint, char *str, int strsize);
|
int hdnode_serialize_private(const HDNode *node, uint32_t fingerprint, char *str, int strsize);
|
||||||
|
1
curves.c
1
curves.c
@ -23,3 +23,4 @@
|
|||||||
const char SECP256K1_NAME[] = "secp256k1";
|
const char SECP256K1_NAME[] = "secp256k1";
|
||||||
const char NIST256P1_NAME[] = "nist256p1";
|
const char NIST256P1_NAME[] = "nist256p1";
|
||||||
const char ED25519_NAME[] = "ed25519";
|
const char ED25519_NAME[] = "ed25519";
|
||||||
|
const char CURVE25519_NAME[] = "curve25519";
|
||||||
|
1
curves.h
1
curves.h
@ -26,5 +26,6 @@
|
|||||||
extern const char SECP256K1_NAME[];
|
extern const char SECP256K1_NAME[];
|
||||||
extern const char NIST256P1_NAME[];
|
extern const char NIST256P1_NAME[];
|
||||||
extern const char ED25519_NAME[];
|
extern const char ED25519_NAME[];
|
||||||
|
extern const char CURVE25519_NAME[];
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user