mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-23 06:48:16 +00:00
modtrezorcrypto: add generate_secret methods to curves
This commit is contained in:
parent
3c5c685b8c
commit
9c921c073f
@ -9,6 +9,8 @@
|
||||
|
||||
#include "trezor-crypto/curve25519-donna/curve25519-donna.h"
|
||||
|
||||
#include "rand.h"
|
||||
|
||||
typedef struct _mp_obj_Curve25519_t {
|
||||
mp_obj_base_t base;
|
||||
} mp_obj_Curve25519_t;
|
||||
@ -20,6 +22,22 @@ STATIC mp_obj_t mod_TrezorCrypto_Curve25519_make_new(const mp_obj_type_t *type,
|
||||
return MP_OBJ_FROM_PTR(o);
|
||||
}
|
||||
|
||||
/// def trezor.crypto.curve.curve25519.generate_secret() -> bytes:
|
||||
/// '''
|
||||
/// Generate secret key.
|
||||
/// '''
|
||||
STATIC mp_obj_t mod_TrezorCrypto_Curve25519_generate_secret(mp_obj_t self) {
|
||||
vstr_t vstr;
|
||||
vstr_init_len(&vstr, 32);
|
||||
random_buffer((uint8_t *)vstr.buf, 32);
|
||||
// taken from https://cr.yp.to/ecdh.html
|
||||
vstr.buf[0] &= 248;
|
||||
vstr.buf[31] &= 127;
|
||||
vstr.buf[31] |= 64;
|
||||
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_TrezorCrypto_Curve25519_generate_secret_obj, mod_TrezorCrypto_Curve25519_generate_secret);
|
||||
|
||||
/// def trezor.crypto.curve.curve25519.publickey(secret_key: bytes) -> bytes:
|
||||
/// '''
|
||||
/// Computes public key from secret key.
|
||||
@ -60,6 +78,7 @@ STATIC mp_obj_t mod_TrezorCrypto_Curve25519_multiply(mp_obj_t self, mp_obj_t sec
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_TrezorCrypto_Curve25519_multiply_obj, mod_TrezorCrypto_Curve25519_multiply);
|
||||
|
||||
STATIC const mp_rom_map_elem_t mod_TrezorCrypto_Curve25519_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_generate_secret), MP_ROM_PTR(&mod_TrezorCrypto_Curve25519_generate_secret_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_publickey), MP_ROM_PTR(&mod_TrezorCrypto_Curve25519_publickey_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_multiply), MP_ROM_PTR(&mod_TrezorCrypto_Curve25519_multiply_obj) },
|
||||
};
|
||||
|
@ -9,6 +9,8 @@
|
||||
|
||||
#include "trezor-crypto/ed25519-donna/ed25519.h"
|
||||
|
||||
#include "rand.h"
|
||||
|
||||
typedef struct _mp_obj_Ed25519_t {
|
||||
mp_obj_base_t base;
|
||||
} mp_obj_Ed25519_t;
|
||||
@ -20,6 +22,22 @@ STATIC mp_obj_t mod_TrezorCrypto_Ed25519_make_new(const mp_obj_type_t *type, siz
|
||||
return MP_OBJ_FROM_PTR(o);
|
||||
}
|
||||
|
||||
/// def trezor.crypto.curve.ed25519.generate_secret() -> bytes:
|
||||
/// '''
|
||||
/// Generate secret key.
|
||||
/// '''
|
||||
STATIC mp_obj_t mod_TrezorCrypto_Ed25519_generate_secret(mp_obj_t self) {
|
||||
vstr_t vstr;
|
||||
vstr_init_len(&vstr, 32);
|
||||
random_buffer((uint8_t *)vstr.buf, 32);
|
||||
// taken from https://cr.yp.to/ecdh.html
|
||||
vstr.buf[0] &= 248;
|
||||
vstr.buf[31] &= 127;
|
||||
vstr.buf[31] |= 64;
|
||||
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_TrezorCrypto_Ed25519_generate_secret_obj, mod_TrezorCrypto_Ed25519_generate_secret);
|
||||
|
||||
/// def trezor.crypto.curve.ed25519.publickey(secret_key: bytes) -> bytes:
|
||||
/// '''
|
||||
/// Computes public key from secret key.
|
||||
@ -84,6 +102,7 @@ STATIC mp_obj_t mod_TrezorCrypto_Ed25519_verify(size_t n_args, const mp_obj_t *a
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_TrezorCrypto_Ed25519_verify_obj, 4, 4, mod_TrezorCrypto_Ed25519_verify);
|
||||
|
||||
STATIC const mp_rom_map_elem_t mod_TrezorCrypto_Ed25519_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_generate_secret), MP_ROM_PTR(&mod_TrezorCrypto_Ed25519_generate_secret_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_publickey), MP_ROM_PTR(&mod_TrezorCrypto_Ed25519_publickey_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_sign), MP_ROM_PTR(&mod_TrezorCrypto_Ed25519_sign_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_verify), MP_ROM_PTR(&mod_TrezorCrypto_Ed25519_verify_obj) },
|
||||
|
@ -21,6 +21,24 @@ STATIC mp_obj_t mod_TrezorCrypto_Nist256p1_make_new(const mp_obj_type_t *type, s
|
||||
return MP_OBJ_FROM_PTR(o);
|
||||
}
|
||||
|
||||
/// def trezor.crypto.curve.nist256p1.generate_secret() -> bytes:
|
||||
/// '''
|
||||
/// Generate secret key.
|
||||
/// '''
|
||||
STATIC mp_obj_t mod_TrezorCrypto_Nist256p1_generate_secret(mp_obj_t self) {
|
||||
vstr_t vstr;
|
||||
vstr_init_len(&vstr, 32);
|
||||
for (;;) {
|
||||
random_buffer((uint8_t *)vstr.buf, 32);
|
||||
// check whether secret > 0 && secret < curve_order
|
||||
if (0 == memcmp(vstr.buf, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 32)) continue;
|
||||
if (0 <= memcmp(vstr.buf, "\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xBC\xE6\xFA\xAD\xA7\x17\x9E\x84\xF3\xB9\xCA\xC2\xFC\x63\x25\x51", 32)) continue;
|
||||
break;
|
||||
}
|
||||
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_TrezorCrypto_Nist256p1_generate_secret_obj, mod_TrezorCrypto_Nist256p1_generate_secret);
|
||||
|
||||
/// def trezor.crypto.curve.nist256p1.publickey(secret_key: bytes, compressed: bool=True) -> bytes:
|
||||
/// '''
|
||||
/// Computes public key from secret key.
|
||||
@ -117,6 +135,7 @@ STATIC mp_obj_t mod_TrezorCrypto_Nist256p1_multiply(mp_obj_t self, mp_obj_t secr
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_TrezorCrypto_Nist256p1_multiply_obj, mod_TrezorCrypto_Nist256p1_multiply);
|
||||
|
||||
STATIC const mp_rom_map_elem_t mod_TrezorCrypto_Nist256p1_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_generate_secret), MP_ROM_PTR(&mod_TrezorCrypto_Nist256p1_generate_secret_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_publickey), MP_ROM_PTR(&mod_TrezorCrypto_Nist256p1_publickey_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_sign), MP_ROM_PTR(&mod_TrezorCrypto_Nist256p1_sign_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_verify), MP_ROM_PTR(&mod_TrezorCrypto_Nist256p1_verify_obj) },
|
||||
|
@ -21,6 +21,24 @@ STATIC mp_obj_t mod_TrezorCrypto_Secp256k1_make_new(const mp_obj_type_t *type, s
|
||||
return MP_OBJ_FROM_PTR(o);
|
||||
}
|
||||
|
||||
/// def trezor.crypto.curve.secp256k1.generate_secret() -> bytes:
|
||||
/// '''
|
||||
/// Generate secret key.
|
||||
/// '''
|
||||
STATIC mp_obj_t mod_TrezorCrypto_Secp256k1_generate_secret(mp_obj_t self) {
|
||||
vstr_t vstr;
|
||||
vstr_init_len(&vstr, 32);
|
||||
for (;;) {
|
||||
random_buffer((uint8_t *)vstr.buf, 32);
|
||||
// check whether secret > 0 && secret < curve_order
|
||||
if (0 == memcmp(vstr.buf, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 32)) continue;
|
||||
if (0 <= memcmp(vstr.buf, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\xBA\xAE\xDC\xE6\xAF\x48\xA0\x3B\xBF\xD2\x5E\x8C\xD0\x36\x41\x41", 32)) continue;
|
||||
break;
|
||||
}
|
||||
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_TrezorCrypto_Secp256k1_generate_secret_obj, mod_TrezorCrypto_Secp256k1_generate_secret);
|
||||
|
||||
/// def trezor.crypto.curve.secp256k1.publickey(secret_key: bytes, compressed: bool=True) -> bytes:
|
||||
/// '''
|
||||
/// Computes public key from secret key.
|
||||
@ -117,6 +135,7 @@ STATIC mp_obj_t mod_TrezorCrypto_Secp256k1_multiply(mp_obj_t self, mp_obj_t secr
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_TrezorCrypto_Secp256k1_multiply_obj, mod_TrezorCrypto_Secp256k1_multiply);
|
||||
|
||||
STATIC const mp_rom_map_elem_t mod_TrezorCrypto_Secp256k1_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_generate_secret), MP_ROM_PTR(&mod_TrezorCrypto_Secp256k1_generate_secret_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_publickey), MP_ROM_PTR(&mod_TrezorCrypto_Secp256k1_publickey_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_sign), MP_ROM_PTR(&mod_TrezorCrypto_Secp256k1_sign_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_verify), MP_ROM_PTR(&mod_TrezorCrypto_Secp256k1_verify_obj) },
|
||||
|
@ -5,7 +5,6 @@ import unittest
|
||||
from ubinascii import unhexlify
|
||||
|
||||
from trezor.crypto.curve import curve25519
|
||||
from trezor.crypto import random
|
||||
|
||||
class TestCryptoCurve25519(unittest.TestCase):
|
||||
|
||||
@ -13,6 +12,12 @@ class TestCryptoCurve25519(unittest.TestCase):
|
||||
('38c9d9b17911de26ed812f5cc19c0029e8d016bcbc6078bc9db2af33f1761e4a', '311b6248af8dabec5cc81eac5bf229925f6d218a12e0547fb1856e015cc76f5d', 'a93dbdb23e5c99da743e203bd391af79f2b83fb8d0fd6ec813371c71f08f2d4d'),
|
||||
]
|
||||
|
||||
def test_generate_secret(self):
|
||||
for _ in range(100):
|
||||
sk = curve25519.generate_secret()
|
||||
self.assertTrue(len(sk) == 32)
|
||||
self.assertTrue(sk[0] & 7 == 0 and sk[31] & 128 == 0 and sk[31] & 64 == 64)
|
||||
|
||||
def test_multiply(self):
|
||||
for sk, pk, session in self.vectors:
|
||||
session2 = curve25519.multiply(unhexlify(sk), unhexlify(pk))
|
||||
@ -20,11 +25,8 @@ class TestCryptoCurve25519(unittest.TestCase):
|
||||
|
||||
def test_multiply_random(self):
|
||||
for _ in range(100):
|
||||
sk1 = bytearray(random.bytes(32))
|
||||
sk2 = bytearray(random.bytes(32))
|
||||
# taken from https://cr.yp.to/ecdh.html
|
||||
sk1[0] &= 248 ; sk1[31] &= 127 ; sk1[31] |= 64
|
||||
sk2[0] &= 248 ; sk2[31] &= 127 ; sk2[31] |= 64
|
||||
sk1 = curve25519.generate_secret()
|
||||
sk2 = curve25519.generate_secret()
|
||||
pk1 = curve25519.publickey(sk1)
|
||||
pk2 = curve25519.publickey(sk2)
|
||||
session1 = curve25519.multiply(sk1, pk2)
|
||||
|
@ -5,6 +5,7 @@ import unittest
|
||||
from ubinascii import unhexlify
|
||||
|
||||
from trezor.crypto.curve import ed25519
|
||||
from trezor.crypto import random
|
||||
|
||||
class TestCryptoEd25519(unittest.TestCase):
|
||||
|
||||
@ -36,5 +37,19 @@ class TestCryptoEd25519(unittest.TestCase):
|
||||
self.assertTrue(ed25519.verify(unhexlify(pk), unhexlify(sig), unhexlify(pk)))
|
||||
pass
|
||||
|
||||
def test_generate_secret(self):
|
||||
for _ in range(100):
|
||||
sk = ed25519.generate_secret()
|
||||
self.assertTrue(len(sk) == 32)
|
||||
self.assertTrue(sk[0] & 7 == 0 and sk[31] & 128 == 0 and sk[31] & 64 == 64)
|
||||
|
||||
def test_random(self):
|
||||
for l in range(1, 300):
|
||||
sk = ed25519.generate_secret()
|
||||
pk = ed25519.publickey(sk)
|
||||
msg = random.bytes(l)
|
||||
sig = ed25519.sign(sk, msg)
|
||||
self.assertTrue(ed25519.verify(pk, sig, msg))
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
@ -64,6 +64,13 @@ class TestCryptoNist256p1(unittest.TestCase):
|
||||
(115792089210356248762697446949407573529996955224135760342422259061068512044368, '6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296B01CBD1C01E58065711814B583F061E9D431CCA994CEA1313449BF97C840AE0A'),
|
||||
]
|
||||
|
||||
def test_generate_secret(self):
|
||||
for _ in range(100):
|
||||
sk = nist256p1.generate_secret()
|
||||
self.assertTrue(len(sk) == 32)
|
||||
self.assertTrue(sk != b'\x00' * 32)
|
||||
self.assertTrue(sk < b'\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xBC\xE6\xFA\xAD\xA7\x17\x9E\x84\xF3\xB9\xCA\xC2\xFC\x63\x25\x51')
|
||||
|
||||
def test_publickey(self):
|
||||
for sk, pk in self.vectors:
|
||||
sk = hex(sk)[2:]
|
||||
|
@ -57,6 +57,13 @@ class TestCryptoSecp256k1(unittest.TestCase):
|
||||
(115792089237316195423570985008687907852837564279074904382605163141518161494336, '79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798B7C52588D95C3B9AA25B0403F1EEF75702E84BB7597AABE663B82F6F04EF2777'),
|
||||
]
|
||||
|
||||
def test_generate_secret(self):
|
||||
for _ in range(100):
|
||||
sk = secp256k1.generate_secret()
|
||||
self.assertTrue(len(sk) == 32)
|
||||
self.assertTrue(sk != b'\x00' * 32)
|
||||
self.assertTrue(sk < b'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\xBA\xAE\xDC\xE6\xAF\x48\xA0\x3B\xBF\xD2\x5E\x8C\xD0\x36\x41\x41')
|
||||
|
||||
def test_publickey(self):
|
||||
for sk, pk in self.vectors:
|
||||
sk = hex(sk)[2:]
|
||||
|
Loading…
Reference in New Issue
Block a user