mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-07-23 23:18:16 +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
|
||||
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.
|
||||
#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_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 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_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 {
|
||||
ECDSA_TWEAK_PUBKEY_SUCCESS = 0,
|
||||
|
Loading…
Reference in New Issue
Block a user