mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-26 01:18:28 +00:00
trezor.crypto: prepend recid to ecdsa signatures
This commit is contained in:
parent
a31dba225e
commit
c8eb2bf17b
@ -77,12 +77,12 @@ STATIC mp_obj_t mod_TrezorCrypto_Nist256p1_sign(mp_obj_t self, mp_obj_t secret_k
|
|||||||
mp_raise_ValueError("Invalid length of digest");
|
mp_raise_ValueError("Invalid length of digest");
|
||||||
}
|
}
|
||||||
vstr_t vstr;
|
vstr_t vstr;
|
||||||
vstr_init_len(&vstr, 64);
|
vstr_init_len(&vstr, 65);
|
||||||
uint8_t pby;
|
uint8_t pby;
|
||||||
if (0 != ecdsa_sign_digest(&nist256p1, (const uint8_t *)sk.buf, (const uint8_t *)dig.buf, (uint8_t *)vstr.buf, &pby, NULL)) { // TODO: is_canonical
|
if (0 != ecdsa_sign_digest(&nist256p1, (const uint8_t *)sk.buf, (const uint8_t *)dig.buf, (uint8_t *)vstr.buf + 1, &pby, NULL)) { // TODO: is_canonical
|
||||||
mp_raise_ValueError("Signing failed");
|
mp_raise_ValueError("Signing failed");
|
||||||
}
|
}
|
||||||
(void)pby;
|
vstr.buf[0] = 27 + pby + 4;
|
||||||
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_TrezorCrypto_Nist256p1_sign_obj, mod_TrezorCrypto_Nist256p1_sign);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_TrezorCrypto_Nist256p1_sign_obj, mod_TrezorCrypto_Nist256p1_sign);
|
||||||
@ -100,13 +100,14 @@ STATIC mp_obj_t mod_TrezorCrypto_Nist256p1_verify(size_t n_args, const mp_obj_t
|
|||||||
if (pk.len != 33 && pk.len != 65) {
|
if (pk.len != 33 && pk.len != 65) {
|
||||||
mp_raise_ValueError("Invalid length of public key");
|
mp_raise_ValueError("Invalid length of public key");
|
||||||
}
|
}
|
||||||
if (sig.len != 64) {
|
if (sig.len != 64 && sig.len != 65) {
|
||||||
mp_raise_ValueError("Invalid length of signature");
|
mp_raise_ValueError("Invalid length of signature");
|
||||||
}
|
}
|
||||||
|
int offset = sig.len - 64;
|
||||||
if (dig.len != 32) {
|
if (dig.len != 32) {
|
||||||
mp_raise_ValueError("Invalid length of digest");
|
mp_raise_ValueError("Invalid length of digest");
|
||||||
}
|
}
|
||||||
return mp_obj_new_bool(0 == ecdsa_verify_digest(&nist256p1, (const uint8_t *)pk.buf, (const uint8_t *)sig.buf, (const uint8_t *)dig.buf));
|
return mp_obj_new_bool(0 == ecdsa_verify_digest(&nist256p1, (const uint8_t *)pk.buf, (const uint8_t *)sig.buf + offset, (const uint8_t *)dig.buf));
|
||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_TrezorCrypto_Nist256p1_verify_obj, 4, 4, mod_TrezorCrypto_Nist256p1_verify);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_TrezorCrypto_Nist256p1_verify_obj, 4, 4, mod_TrezorCrypto_Nist256p1_verify);
|
||||||
|
|
||||||
|
@ -77,12 +77,12 @@ STATIC mp_obj_t mod_TrezorCrypto_Secp256k1_sign(mp_obj_t self, mp_obj_t secret_k
|
|||||||
mp_raise_ValueError("Invalid length of digest");
|
mp_raise_ValueError("Invalid length of digest");
|
||||||
}
|
}
|
||||||
vstr_t vstr;
|
vstr_t vstr;
|
||||||
vstr_init_len(&vstr, 64);
|
vstr_init_len(&vstr, 65);
|
||||||
uint8_t pby;
|
uint8_t pby;
|
||||||
if (0 != ecdsa_sign_digest(&secp256k1, (const uint8_t *)sk.buf, (const uint8_t *)dig.buf, (uint8_t *)vstr.buf, &pby, NULL)) { // TODO: is_canonical
|
if (0 != ecdsa_sign_digest(&secp256k1, (const uint8_t *)sk.buf, (const uint8_t *)dig.buf, (uint8_t *)vstr.buf + 1, &pby, NULL)) { // TODO: is_canonical
|
||||||
mp_raise_ValueError("Signing failed");
|
mp_raise_ValueError("Signing failed");
|
||||||
}
|
}
|
||||||
(void)pby;
|
vstr.buf[0] = 27 + pby + 4;
|
||||||
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_TrezorCrypto_Secp256k1_sign_obj, mod_TrezorCrypto_Secp256k1_sign);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_TrezorCrypto_Secp256k1_sign_obj, mod_TrezorCrypto_Secp256k1_sign);
|
||||||
@ -100,13 +100,14 @@ STATIC mp_obj_t mod_TrezorCrypto_Secp256k1_verify(size_t n_args, const mp_obj_t
|
|||||||
if (pk.len != 33 && pk.len != 65) {
|
if (pk.len != 33 && pk.len != 65) {
|
||||||
mp_raise_ValueError("Invalid length of public key");
|
mp_raise_ValueError("Invalid length of public key");
|
||||||
}
|
}
|
||||||
if (sig.len != 64) {
|
if (sig.len != 64 && sig.len != 65) {
|
||||||
mp_raise_ValueError("Invalid length of signature");
|
mp_raise_ValueError("Invalid length of signature");
|
||||||
}
|
}
|
||||||
|
int offset = sig.len - 64;
|
||||||
if (dig.len != 32) {
|
if (dig.len != 32) {
|
||||||
mp_raise_ValueError("Invalid length of digest");
|
mp_raise_ValueError("Invalid length of digest");
|
||||||
}
|
}
|
||||||
return mp_obj_new_bool(0 == ecdsa_verify_digest(&secp256k1, (const uint8_t *)pk.buf, (const uint8_t *)sig.buf, (const uint8_t *)dig.buf));
|
return mp_obj_new_bool(0 == ecdsa_verify_digest(&secp256k1, (const uint8_t *)pk.buf, (const uint8_t *)sig.buf + offset, (const uint8_t *)dig.buf));
|
||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_TrezorCrypto_Secp256k1_verify_obj, 4, 4, mod_TrezorCrypto_Secp256k1_verify);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_TrezorCrypto_Secp256k1_verify_obj, 4, 4, mod_TrezorCrypto_Secp256k1_verify);
|
||||||
|
|
||||||
|
@ -328,7 +328,7 @@ def ecdsa_hash_pubkey(pubkey: bytes) -> bytes:
|
|||||||
|
|
||||||
def ecdsa_sign(node, digest: bytes) -> bytes:
|
def ecdsa_sign(node, digest: bytes) -> bytes:
|
||||||
sig = secp256k1.sign(node.private_key(), digest)
|
sig = secp256k1.sign(node.private_key(), digest)
|
||||||
sigder = der.encode_seq((sig[:32], sig[32:]))
|
sigder = der.encode_seq((sig[1:33], sig[33:65]))
|
||||||
return sigder
|
return sigder
|
||||||
|
|
||||||
|
|
||||||
|
@ -90,14 +90,17 @@ class TestCryptoNist256p1(unittest.TestCase):
|
|||||||
dig = bytes([1] + [0]*31)
|
dig = bytes([1] + [0]*31)
|
||||||
sig = nist256p1.sign(sk, dig)
|
sig = nist256p1.sign(sk, dig)
|
||||||
self.assertTrue(nist256p1.verify(pk, sig, dig))
|
self.assertTrue(nist256p1.verify(pk, sig, dig))
|
||||||
|
self.assertTrue(nist256p1.verify(pk, sig[1:], dig))
|
||||||
|
|
||||||
dig = bytes([0]*31 + [1])
|
dig = bytes([0]*31 + [1])
|
||||||
sig = nist256p1.sign(sk, dig)
|
sig = nist256p1.sign(sk, dig)
|
||||||
self.assertTrue(nist256p1.verify(pk, sig, dig))
|
self.assertTrue(nist256p1.verify(pk, sig, dig))
|
||||||
|
self.assertTrue(nist256p1.verify(pk, sig[1:], dig))
|
||||||
|
|
||||||
dig = bytes([0xFF]*32)
|
dig = bytes([0xFF]*32)
|
||||||
sig = nist256p1.sign(sk, dig)
|
sig = nist256p1.sign(sk, dig)
|
||||||
self.assertTrue(nist256p1.verify(pk, sig, dig))
|
self.assertTrue(nist256p1.verify(pk, sig, dig))
|
||||||
|
self.assertTrue(nist256p1.verify(pk, sig[1:], dig))
|
||||||
|
|
||||||
def test_sign_verify_random(self):
|
def test_sign_verify_random(self):
|
||||||
for _ in range(100):
|
for _ in range(100):
|
||||||
@ -106,6 +109,7 @@ class TestCryptoNist256p1(unittest.TestCase):
|
|||||||
dig = random.bytes(32)
|
dig = random.bytes(32)
|
||||||
sig = nist256p1.sign(sk, dig)
|
sig = nist256p1.sign(sk, dig)
|
||||||
self.assertTrue(nist256p1.verify(pk, sig, dig))
|
self.assertTrue(nist256p1.verify(pk, sig, dig))
|
||||||
|
self.assertTrue(nist256p1.verify(pk, sig[1:], dig))
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
Loading…
Reference in New Issue
Block a user