mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-07-25 07:58:12 +00:00
feat(crypto): Add ECDSA private key masking functions.
This commit is contained in:
parent
ff4ff75f61
commit
1ff04d10c6
@ -1377,3 +1377,84 @@ ecdsa_tweak_pubkey_result ecdsa_tweak_pubkey(const ecdsa_curve *curve,
|
|||||||
#endif
|
#endif
|
||||||
return tc_ecdsa_tweak_pubkey(curve, pub_key, tweak, tweaked_pub_key);
|
return tc_ecdsa_tweak_pubkey(curve, pub_key, tweak, tweaked_pub_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ecdsa_mask_scalar(const ecdsa_curve *curve,
|
||||||
|
const uint8_t masking_key[ECDSA_PRIVATE_KEY_SIZE],
|
||||||
|
const uint8_t scalar[ECDSA_PRIVATE_KEY_SIZE],
|
||||||
|
uint8_t masked_scalar[ECDSA_PRIVATE_KEY_SIZE]) {
|
||||||
|
bignum256 k = {0};
|
||||||
|
bn_read_be(masking_key, &k);
|
||||||
|
if (bn_is_zero(&k) || !bn_is_less(&k, &curve->order)) {
|
||||||
|
// Invalid masking key.
|
||||||
|
memzero(&k, sizeof(k));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bignum256 s = {0};
|
||||||
|
bn_read_be(scalar, &s);
|
||||||
|
bn_multiply(&k, &s, &curve->order); // s = s * k
|
||||||
|
bn_mod(&s, &curve->order);
|
||||||
|
bn_write_be(&s, masked_scalar);
|
||||||
|
memzero(&k, sizeof(k));
|
||||||
|
memzero(&s, sizeof(s));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ecdsa_unmask_scalar(const ecdsa_curve *curve,
|
||||||
|
const uint8_t masking_key[ECDSA_PRIVATE_KEY_SIZE],
|
||||||
|
const uint8_t masked_scalar[ECDSA_PRIVATE_KEY_SIZE],
|
||||||
|
uint8_t scalar[ECDSA_PRIVATE_KEY_SIZE]) {
|
||||||
|
bignum256 k = {0};
|
||||||
|
bn_read_be(masking_key, &k);
|
||||||
|
if (bn_is_zero(&k) || !bn_is_less(&k, &curve->order)) {
|
||||||
|
// Invalid masking key.
|
||||||
|
memzero(&k, sizeof(k));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bignum256 s = {0};
|
||||||
|
bn_read_be(masked_scalar, &s);
|
||||||
|
bn_inverse(&k, &curve->order); // k = k^-1
|
||||||
|
bn_multiply(&k, &s, &curve->order); // s = s * k
|
||||||
|
bn_mod(&s, &curve->order);
|
||||||
|
bn_write_be(&s, scalar);
|
||||||
|
memzero(&k, sizeof(k));
|
||||||
|
memzero(&s, sizeof(s));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// masked_pub_key may be compressed or uncompressed
|
||||||
|
int ecdsa_unmask_public_key(const ecdsa_curve *curve,
|
||||||
|
const uint8_t masking_key[ECDSA_PRIVATE_KEY_SIZE],
|
||||||
|
const uint8_t *masked_pub_key,
|
||||||
|
uint8_t pub_key[ECDSA_PUBLIC_KEY_SIZE]) {
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
curve_point point = {0};
|
||||||
|
if (!ecdsa_read_pubkey(curve, masked_pub_key, &point)) {
|
||||||
|
// Invalid public key.
|
||||||
|
ret = 1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
bignum256 k = {0};
|
||||||
|
bn_read_be(masking_key, &k);
|
||||||
|
if (bn_is_zero(&k) || !bn_is_less(&k, &curve->order)) {
|
||||||
|
// Invalid masking key.
|
||||||
|
ret = 2;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
bn_inverse(&k, &curve->order);
|
||||||
|
bn_mod(&k, &curve->order);
|
||||||
|
point_multiply(curve, &k, &point, &point);
|
||||||
|
|
||||||
|
pub_key[0] = 0x04;
|
||||||
|
bn_write_be(&point.x, pub_key + 1);
|
||||||
|
bn_write_be(&point.y, pub_key + 33);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
memzero(&point, sizeof(point));
|
||||||
|
memzero(&k, sizeof(k));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
@ -61,7 +61,15 @@ typedef struct {
|
|||||||
// (4 + 32 + 1 + 4 [checksum]) * 8 / log2(58) plus NUL.
|
// (4 + 32 + 1 + 4 [checksum]) * 8 / log2(58) plus NUL.
|
||||||
#define MAX_WIF_SIZE (57)
|
#define MAX_WIF_SIZE (57)
|
||||||
|
|
||||||
#define ECDSA_PRIVATE_KEY_SIZE 32
|
// Maximum length of a DER-encoded secp256k1 or secp256p1 signature.
|
||||||
|
#define MAX_DER_SIGNATURE_SIZE 72
|
||||||
|
|
||||||
|
#define ECDSA_SCALAR_SIZE 32
|
||||||
|
#define ECDSA_COORDINATE_SIZE 32
|
||||||
|
#define ECDSA_PRIVATE_KEY_SIZE ECDSA_SCALAR_SIZE
|
||||||
|
#define ECDSA_PUBLIC_KEY_SIZE (1 + 2 * ECDSA_COORDINATE_SIZE)
|
||||||
|
#define ECDSA_PUBLIC_KEY_COMPRESSED_SIZE (1 + ECDSA_COORDINATE_SIZE)
|
||||||
|
#define ECDSA_RAW_SIGNATURE_SIZE (2 * ECDSA_SCALAR_SIZE)
|
||||||
|
|
||||||
void point_copy(const curve_point *cp1, curve_point *cp2);
|
void point_copy(const curve_point *cp1, curve_point *cp2);
|
||||||
void point_add(const ecdsa_curve *curve, const curve_point *cp1,
|
void point_add(const ecdsa_curve *curve, const curve_point *cp1,
|
||||||
@ -126,6 +134,18 @@ int ecdsa_recover_pub_from_sig(const ecdsa_curve *curve, uint8_t *pub_key,
|
|||||||
int recid);
|
int recid);
|
||||||
int ecdsa_sig_to_der(const uint8_t *sig, uint8_t *der);
|
int ecdsa_sig_to_der(const uint8_t *sig, uint8_t *der);
|
||||||
int ecdsa_sig_from_der(const uint8_t *der, size_t der_len, uint8_t sig[64]);
|
int ecdsa_sig_from_der(const uint8_t *der, size_t der_len, uint8_t sig[64]);
|
||||||
|
int ecdsa_mask_scalar(const ecdsa_curve *curve,
|
||||||
|
const uint8_t masking_key[ECDSA_PRIVATE_KEY_SIZE],
|
||||||
|
const uint8_t scalar[ECDSA_SCALAR_SIZE],
|
||||||
|
uint8_t masked_scalar[ECDSA_SCALAR_SIZE]);
|
||||||
|
int ecdsa_unmask_scalar(const ecdsa_curve *curve,
|
||||||
|
const uint8_t masking_key[ECDSA_PRIVATE_KEY_SIZE],
|
||||||
|
const uint8_t masked_scalar[ECDSA_SCALAR_SIZE],
|
||||||
|
uint8_t scalar[ECDSA_SCALAR_SIZE]);
|
||||||
|
int ecdsa_unmask_public_key(const ecdsa_curve *curve,
|
||||||
|
const uint8_t masking_key[ECDSA_PRIVATE_KEY_SIZE],
|
||||||
|
const uint8_t *masked_pub_key,
|
||||||
|
uint8_t pub_key[ECDSA_PUBLIC_KEY_SIZE]);
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ECDSA_TWEAK_PUBKEY_SUCCESS = 0,
|
ECDSA_TWEAK_PUBKEY_SUCCESS = 0,
|
||||||
|
Loading…
Reference in New Issue
Block a user