1
0
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:
Pavol Rusnak 2016-11-08 23:10:31 +01:00
parent a31dba225e
commit c8eb2bf17b
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D
4 changed files with 17 additions and 11 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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()