1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-05-25 18:28:47 +00:00

core/secp256k1_zkp: refactor API into a Context class

In order to prevent frequent memory allocations, the user can create a single
Context object and re-use it between subsequent cryptographic operations.
This commit is contained in:
Roman Zeyde 2019-05-28 11:46:14 +03:00 committed by Pavol Rusnak
parent 91b23f3ea2
commit b538eb3375
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D
3 changed files with 213 additions and 141 deletions

View File

@ -37,79 +37,115 @@ void secp256k1_default_error_callback_fn(const char *str, void *data) {
return; return;
} }
static secp256k1_context *secp256k1_ctx = NULL;
static void *secp256k1_ctx_buf = NULL;
static size_t secp256k1_ctx_size = 0;
static const secp256k1_context *mod_trezorcrypto_secp256k1_context_create(
void) {
if (secp256k1_ctx == NULL) {
secp256k1_ctx_size = secp256k1_context_preallocated_size(
SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
secp256k1_ctx_buf = m_new_maybe(uint8_t, secp256k1_ctx_size);
if (!secp256k1_ctx_buf) {
mp_raise_ValueError("secp256k1_zkp context is too large");
}
secp256k1_ctx = secp256k1_context_preallocated_create(
secp256k1_ctx_buf, SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
uint8_t rand[32];
random_buffer(rand, 32);
int ret = secp256k1_context_randomize(secp256k1_ctx, rand);
if (ret != 1) {
mp_raise_msg(&mp_type_RuntimeError, "secp256k1_context_randomize failed");
}
}
return secp256k1_ctx;
}
STATIC void mod_trezorcrypto_secp256k1_context_delete(void) {
secp256k1_context_preallocated_destroy(secp256k1_ctx);
m_del(uint8_t, secp256k1_ctx_buf, secp256k1_ctx_size);
secp256k1_ctx_buf = NULL;
secp256k1_ctx = NULL;
}
/// package: trezorcrypto.secp256k1_zkp /// package: trezorcrypto.secp256k1_zkp
/// def generate_secret() -> bytes: /// class Context:
/// """
/// Owns a secp256k1 context.
/// Can be allocated once and re-used between subsequent operations.
/// """
///
typedef struct _mp_obj_secp256k1_context_t {
mp_obj_base_t base;
secp256k1_context *secp256k1_ctx;
size_t secp256k1_ctx_size;
uint8_t secp256k1_ctx_buf[0]; // to be allocate via m_new_obj_var_maybe().
} mp_obj_secp256k1_context_t;
/// def __init__(self):
/// """
/// Allocate and initialize secp256k1_context.
/// """
STATIC mp_obj_t mod_trezorcrypto_secp256k1_context_make_new(
const mp_obj_type_t *type, size_t n_args, size_t n_kw,
const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 0, false);
const size_t secp256k1_ctx_size = secp256k1_context_preallocated_size(
SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
mp_obj_secp256k1_context_t *o = m_new_obj_var_maybe(
mp_obj_secp256k1_context_t, uint8_t, secp256k1_ctx_size);
if (!o) {
mp_raise_ValueError("secp256k1_zkp context is too large");
}
o->base.type = type;
o->secp256k1_ctx_size = secp256k1_ctx_size;
o->secp256k1_ctx = secp256k1_context_preallocated_create(
o->secp256k1_ctx_buf, SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
uint8_t rand[32] = {0};
random_buffer(rand, 32);
int ret = secp256k1_context_randomize(o->secp256k1_ctx, rand);
if (ret != 1) {
mp_raise_msg(&mp_type_RuntimeError, "secp256k1_context_randomize failed");
}
return MP_OBJ_FROM_PTR(o);
}
/// def __del__(self):
/// """
/// Destructor.
/// """
STATIC mp_obj_t mod_trezorcrypto_secp256k1_context___del__(mp_obj_t self) {
mp_obj_secp256k1_context_t *o = MP_OBJ_TO_PTR(self);
secp256k1_context_preallocated_destroy(o->secp256k1_ctx);
memzero(o->secp256k1_ctx_buf, o->secp256k1_ctx_size);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_secp256k1_context___del___obj,
mod_trezorcrypto_secp256k1_context___del__);
/// def size(self):
/// """
/// Return the size in bytes of the internal secp256k1_ctx_buf buffer.
/// """
STATIC mp_obj_t mod_trezorcrypto_secp256k1_context_size(mp_obj_t self) {
mp_obj_secp256k1_context_t *o = MP_OBJ_TO_PTR(self);
return mp_obj_new_int_from_uint(o->secp256k1_ctx_size);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_secp256k1_context_size_obj,
mod_trezorcrypto_secp256k1_context_size);
static const secp256k1_context *mod_trezorcrypto_get_secp256k1_context(
mp_obj_t self) {
mp_obj_secp256k1_context_t *o = MP_OBJ_TO_PTR(self);
return o->secp256k1_ctx;
}
/// def generate_secret(self) -> bytes:
/// """ /// """
/// Generate secret key. /// Generate secret key.
/// """ /// """
STATIC mp_obj_t mod_trezorcrypto_secp256k1_zkp_generate_secret() { STATIC mp_obj_t mod_trezorcrypto_secp256k1_zkp_generate_secret(mp_obj_t self) {
uint8_t out[32]; const secp256k1_context *ctx = mod_trezorcrypto_get_secp256k1_context(self);
uint8_t out[32] = {0};
for (;;) { for (;;) {
random_buffer(out, 32); random_buffer(out, 32);
// check whether secret > 0 && secret < curve_order // check whether secret > 0 && secret < curve_order
if (0 == memcmp(out, if (secp256k1_ec_seckey_verify(ctx, out) == 1) {
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" break;
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }
"\x00\x00\x00\x00\x00\x00",
32))
continue;
if (0 <= memcmp(out,
"\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_bytes(out, sizeof(out)); return mp_obj_new_bytes(out, sizeof(out));
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_0( STATIC MP_DEFINE_CONST_FUN_OBJ_1(
mod_trezorcrypto_secp256k1_zkp_generate_secret_obj, mod_trezorcrypto_secp256k1_zkp_generate_secret_obj,
mod_trezorcrypto_secp256k1_zkp_generate_secret); mod_trezorcrypto_secp256k1_zkp_generate_secret);
/// def publickey(secret_key: bytes, compressed: bool = True) -> bytes: /// def publickey(self, secret_key: bytes, compressed: bool = True) -> bytes:
/// """ /// """
/// Computes public key from secret key. /// Computes public key from secret key.
/// """ /// """
STATIC mp_obj_t mod_trezorcrypto_secp256k1_zkp_publickey(size_t n_args, STATIC mp_obj_t mod_trezorcrypto_secp256k1_context_publickey(
const mp_obj_t *args) { size_t n_args, const mp_obj_t *args) {
const secp256k1_context *ctx = mod_trezorcrypto_secp256k1_context_create(); const secp256k1_context *ctx =
mod_trezorcrypto_get_secp256k1_context(args[0]);
mp_buffer_info_t sk; mp_buffer_info_t sk;
mp_get_buffer_raise(args[0], &sk, MP_BUFFER_READ); mp_get_buffer_raise(args[1], &sk, MP_BUFFER_READ);
secp256k1_pubkey pk; secp256k1_pubkey pk;
if (sk.len != 32) { if (sk.len != 32) {
mp_raise_ValueError("Invalid length of secret key"); mp_raise_ValueError("Invalid length of secret key");
@ -118,32 +154,32 @@ STATIC mp_obj_t mod_trezorcrypto_secp256k1_zkp_publickey(size_t n_args,
mp_raise_ValueError("Invalid secret key"); mp_raise_ValueError("Invalid secret key");
} }
bool compressed = n_args < 2 || args[1] == mp_const_true; bool compressed = n_args < 3 || args[2] == mp_const_true;
uint8_t out[65]; uint8_t out[65];
size_t outlen = sizeof(out); size_t outlen = sizeof(out);
secp256k1_ec_pubkey_serialize( secp256k1_ec_pubkey_serialize(
ctx, out, &outlen, &pk, ctx, out, &outlen, &pk,
compressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED); compressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED);
mod_trezorcrypto_secp256k1_context_delete();
return mp_obj_new_bytes(out, outlen); return mp_obj_new_bytes(out, outlen);
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN( STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(
mod_trezorcrypto_secp256k1_zkp_publickey_obj, 1, 2, mod_trezorcrypto_secp256k1_context_publickey_obj, 2, 3,
mod_trezorcrypto_secp256k1_zkp_publickey); mod_trezorcrypto_secp256k1_context_publickey);
/// def sign( /// def sign(
/// secret_key: bytes, digest: bytes, compressed: bool = True /// self, secret_key: bytes, digest: bytes, compressed: bool = True
/// ) -> bytes: /// ) -> bytes:
/// """ /// """
/// Uses secret key to produce the signature of the digest. /// Uses secret key to produce the signature of the digest.
/// """ /// """
STATIC mp_obj_t mod_trezorcrypto_secp256k1_zkp_sign(size_t n_args, STATIC mp_obj_t mod_trezorcrypto_secp256k1_context_sign(size_t n_args,
const mp_obj_t *args) { const mp_obj_t *args) {
const secp256k1_context *ctx = mod_trezorcrypto_secp256k1_context_create(); const secp256k1_context *ctx =
mod_trezorcrypto_get_secp256k1_context(args[0]);
mp_buffer_info_t sk, dig; mp_buffer_info_t sk, dig;
mp_get_buffer_raise(args[0], &sk, MP_BUFFER_READ); mp_get_buffer_raise(args[1], &sk, MP_BUFFER_READ);
mp_get_buffer_raise(args[1], &dig, MP_BUFFER_READ); mp_get_buffer_raise(args[2], &dig, MP_BUFFER_READ);
bool compressed = n_args < 3 || args[2] == mp_const_true; bool compressed = n_args < 4 || args[3] == mp_const_true;
if (sk.len != 32) { if (sk.len != 32) {
mp_raise_ValueError("Invalid length of secret key"); mp_raise_ValueError("Invalid length of secret key");
} }
@ -159,27 +195,28 @@ STATIC mp_obj_t mod_trezorcrypto_secp256k1_zkp_sign(size_t n_args,
} }
secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx, &out[1], &pby, secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx, &out[1], &pby,
&sig); &sig);
mod_trezorcrypto_secp256k1_context_delete();
out[0] = 27 + pby + compressed * 4; out[0] = 27 + pby + compressed * 4;
return mp_obj_new_bytes(out, sizeof(out)); return mp_obj_new_bytes(out, sizeof(out));
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN( STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(
mod_trezorcrypto_secp256k1_zkp_sign_obj, 2, 3, mod_trezorcrypto_secp256k1_context_sign_obj, 3, 4,
mod_trezorcrypto_secp256k1_zkp_sign); mod_trezorcrypto_secp256k1_context_sign);
/// def verify(public_key: bytes, signature: bytes, digest: bytes) -> bool: /// def verify(
/// self, public_key: bytes, signature: bytes, digest: bytes
/// ) -> bool:
/// """ /// """
/// Uses public key to verify the signature of the digest. /// Uses public key to verify the signature of the digest.
/// Returns True on success. /// Returns True on success.
/// """ /// """
STATIC mp_obj_t mod_trezorcrypto_secp256k1_zkp_verify(mp_obj_t public_key, STATIC mp_obj_t
mp_obj_t signature, mod_trezorcrypto_secp256k1_context_verify(size_t n_args, const mp_obj_t *args) {
mp_obj_t digest) { const secp256k1_context *ctx =
const secp256k1_context *ctx = mod_trezorcrypto_secp256k1_context_create(); mod_trezorcrypto_get_secp256k1_context(args[0]);
mp_buffer_info_t pk, sig, dig; mp_buffer_info_t pk, sig, dig;
mp_get_buffer_raise(public_key, &pk, MP_BUFFER_READ); mp_get_buffer_raise(args[1], &pk, MP_BUFFER_READ);
mp_get_buffer_raise(signature, &sig, MP_BUFFER_READ); mp_get_buffer_raise(args[2], &sig, MP_BUFFER_READ);
mp_get_buffer_raise(digest, &dig, MP_BUFFER_READ); mp_get_buffer_raise(args[3], &dig, MP_BUFFER_READ);
if (pk.len != 33 && pk.len != 65) { if (pk.len != 33 && pk.len != 65) {
return mp_const_false; return mp_const_false;
} }
@ -202,20 +239,20 @@ STATIC mp_obj_t mod_trezorcrypto_secp256k1_zkp_verify(mp_obj_t public_key,
} }
bool ret = (1 == secp256k1_ecdsa_verify(ctx, &ec_sig, bool ret = (1 == secp256k1_ecdsa_verify(ctx, &ec_sig,
(const uint8_t *)dig.buf, &ec_pk)); (const uint8_t *)dig.buf, &ec_pk));
mod_trezorcrypto_secp256k1_context_delete();
return mp_obj_new_bool(ret); return mp_obj_new_bool(ret);
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_trezorcrypto_secp256k1_zkp_verify_obj, STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(
mod_trezorcrypto_secp256k1_zkp_verify); mod_trezorcrypto_secp256k1_context_verify_obj, 4, 4,
mod_trezorcrypto_secp256k1_context_verify);
/// def verify_recover(signature: bytes, digest: bytes) -> bytes: /// def verify_recover(self, signature: bytes, digest: bytes) -> bytes:
/// """ /// """
/// Uses signature of the digest to verify the digest and recover the public /// Uses signature of the digest to verify the digest and recover the public
/// key. Returns public key on success, None if the signature is invalid. /// key. Returns public key on success, None if the signature is invalid.
/// """ /// """
STATIC mp_obj_t mod_trezorcrypto_secp256k1_zkp_verify_recover( STATIC mp_obj_t mod_trezorcrypto_secp256k1_context_verify_recover(
mp_obj_t signature, mp_obj_t digest) { mp_obj_t self, mp_obj_t signature, mp_obj_t digest) {
const secp256k1_context *ctx = mod_trezorcrypto_secp256k1_context_create(); const secp256k1_context *ctx = mod_trezorcrypto_get_secp256k1_context(self);
mp_buffer_info_t sig, dig; mp_buffer_info_t sig, dig;
mp_get_buffer_raise(signature, &sig, MP_BUFFER_READ); mp_get_buffer_raise(signature, &sig, MP_BUFFER_READ);
mp_get_buffer_raise(digest, &dig, MP_BUFFER_READ); mp_get_buffer_raise(digest, &dig, MP_BUFFER_READ);
@ -246,12 +283,11 @@ STATIC mp_obj_t mod_trezorcrypto_secp256k1_zkp_verify_recover(
secp256k1_ec_pubkey_serialize( secp256k1_ec_pubkey_serialize(
ctx, out, &pklen, &pk, ctx, out, &pklen, &pk,
compressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED); compressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED);
mod_trezorcrypto_secp256k1_context_delete();
return mp_obj_new_bytes(out, pklen); return mp_obj_new_bytes(out, pklen);
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_2( STATIC MP_DEFINE_CONST_FUN_OBJ_3(
mod_trezorcrypto_secp256k1_zkp_verify_recover_obj, mod_trezorcrypto_secp256k1_context_verify_recover_obj,
mod_trezorcrypto_secp256k1_zkp_verify_recover); mod_trezorcrypto_secp256k1_context_verify_recover);
static int secp256k1_ecdh_hash_passthrough(uint8_t *output, const uint8_t *x, static int secp256k1_ecdh_hash_passthrough(uint8_t *output, const uint8_t *x,
const uint8_t *y, void *data) { const uint8_t *y, void *data) {
@ -262,14 +298,14 @@ static int secp256k1_ecdh_hash_passthrough(uint8_t *output, const uint8_t *x,
return 1; return 1;
} }
/// def multiply(secret_key: bytes, public_key: bytes) -> bytes: /// def multiply(self, secret_key: bytes, public_key: bytes) -> bytes:
/// """ /// """
/// Multiplies point defined by public_key with scalar defined by /// Multiplies point defined by public_key with scalar defined by
/// secret_key. Useful for ECDH. /// secret_key. Useful for ECDH.
/// """ /// """
STATIC mp_obj_t mod_trezorcrypto_secp256k1_zkp_multiply(mp_obj_t secret_key, STATIC mp_obj_t mod_trezorcrypto_secp256k1_context_multiply(
mp_obj_t public_key) { mp_obj_t self, mp_obj_t secret_key, mp_obj_t public_key) {
const secp256k1_context *ctx = mod_trezorcrypto_secp256k1_context_create(); const secp256k1_context *ctx = mod_trezorcrypto_get_secp256k1_context(self);
mp_buffer_info_t sk, pk; mp_buffer_info_t sk, pk;
mp_get_buffer_raise(secret_key, &sk, MP_BUFFER_READ); mp_get_buffer_raise(secret_key, &sk, MP_BUFFER_READ);
mp_get_buffer_raise(public_key, &pk, MP_BUFFER_READ); mp_get_buffer_raise(public_key, &pk, MP_BUFFER_READ);
@ -289,27 +325,50 @@ STATIC mp_obj_t mod_trezorcrypto_secp256k1_zkp_multiply(mp_obj_t secret_key,
secp256k1_ecdh_hash_passthrough, NULL)) { secp256k1_ecdh_hash_passthrough, NULL)) {
mp_raise_ValueError("Multiply failed"); mp_raise_ValueError("Multiply failed");
} }
mod_trezorcrypto_secp256k1_context_delete();
return mp_obj_new_bytes(out, sizeof(out)); return mp_obj_new_bytes(out, sizeof(out));
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_secp256k1_zkp_multiply_obj, STATIC MP_DEFINE_CONST_FUN_OBJ_3(
mod_trezorcrypto_secp256k1_zkp_multiply); mod_trezorcrypto_secp256k1_context_multiply_obj,
mod_trezorcrypto_secp256k1_context_multiply);
//////////////////////////////////////////////////////////////////////////////
STATIC const mp_rom_map_elem_t
mod_trezorcrypto_secp256k1_context_locals_dict_table[] = {
{MP_ROM_QSTR(MP_QSTR___del__),
MP_ROM_PTR(&mod_trezorcrypto_secp256k1_context___del___obj)},
{MP_ROM_QSTR(MP_QSTR_size),
MP_ROM_PTR(&mod_trezorcrypto_secp256k1_context_size_obj)},
{MP_ROM_QSTR(MP_QSTR_generate_secret),
MP_ROM_PTR(&mod_trezorcrypto_secp256k1_zkp_generate_secret_obj)},
{MP_ROM_QSTR(MP_QSTR_publickey),
MP_ROM_PTR(&mod_trezorcrypto_secp256k1_context_publickey_obj)},
{MP_ROM_QSTR(MP_QSTR_sign),
MP_ROM_PTR(&mod_trezorcrypto_secp256k1_context_sign_obj)},
{MP_ROM_QSTR(MP_QSTR_verify),
MP_ROM_PTR(&mod_trezorcrypto_secp256k1_context_verify_obj)},
{MP_ROM_QSTR(MP_QSTR_verify_recover),
MP_ROM_PTR(&mod_trezorcrypto_secp256k1_context_verify_recover_obj)},
{MP_ROM_QSTR(MP_QSTR_multiply),
MP_ROM_PTR(&mod_trezorcrypto_secp256k1_context_multiply_obj)},
};
STATIC MP_DEFINE_CONST_DICT(
mod_trezorcrypto_secp256k1_context_locals_dict,
mod_trezorcrypto_secp256k1_context_locals_dict_table);
STATIC const mp_obj_type_t mod_trezorcrypto_secp256k1_context_type = {
{&mp_type_type},
.name = MP_QSTR_Context,
.make_new = mod_trezorcrypto_secp256k1_context_make_new,
.locals_dict = (void *)&mod_trezorcrypto_secp256k1_context_locals_dict,
};
STATIC const mp_rom_map_elem_t STATIC const mp_rom_map_elem_t
mod_trezorcrypto_secp256k1_zkp_globals_table[] = { mod_trezorcrypto_secp256k1_zkp_globals_table[] = {
{MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_secp256k1_zkp)}, {MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_secp256k1_zkp)},
{MP_ROM_QSTR(MP_QSTR_generate_secret), {MP_ROM_QSTR(MP_QSTR_Context),
MP_ROM_PTR(&mod_trezorcrypto_secp256k1_zkp_generate_secret_obj)}, MP_ROM_PTR(&mod_trezorcrypto_secp256k1_context_type)},
{MP_ROM_QSTR(MP_QSTR_publickey),
MP_ROM_PTR(&mod_trezorcrypto_secp256k1_zkp_publickey_obj)},
{MP_ROM_QSTR(MP_QSTR_sign),
MP_ROM_PTR(&mod_trezorcrypto_secp256k1_zkp_sign_obj)},
{MP_ROM_QSTR(MP_QSTR_verify),
MP_ROM_PTR(&mod_trezorcrypto_secp256k1_zkp_verify_obj)},
{MP_ROM_QSTR(MP_QSTR_verify_recover),
MP_ROM_PTR(&mod_trezorcrypto_secp256k1_zkp_verify_recover_obj)},
{MP_ROM_QSTR(MP_QSTR_multiply),
MP_ROM_PTR(&mod_trezorcrypto_secp256k1_zkp_multiply_obj)},
}; };
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_secp256k1_zkp_globals, STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_secp256k1_zkp_globals,
mod_trezorcrypto_secp256k1_zkp_globals_table); mod_trezorcrypto_secp256k1_zkp_globals_table);

View File

@ -2,47 +2,60 @@ from typing import *
# extmod/modtrezorcrypto/modtrezorcrypto-secp256k1_zkp.h # extmod/modtrezorcrypto/modtrezorcrypto-secp256k1_zkp.h
def generate_secret() -> bytes: class Context:
""" """
Generate secret key. Owns a secp256k1 context.
Can be allocated once and re-used between subsequent operations.
""" """
def __init__(self):
"""
Allocate and initialize secp256k1_context.
"""
# extmod/modtrezorcrypto/modtrezorcrypto-secp256k1_zkp.h def __del__(self):
def publickey(secret_key: bytes, compressed: bool = True) -> bytes: """
""" Destructor.
Computes public key from secret key. """
"""
def size(self):
"""
Return the size in bytes of the internal secp256k1_ctx_buf buffer.
"""
# extmod/modtrezorcrypto/modtrezorcrypto-secp256k1_zkp.h def generate_secret(self) -> bytes:
def sign( """
secret_key: bytes, digest: bytes, compressed: bool = True Generate secret key.
) -> bytes: """
"""
Uses secret key to produce the signature of the digest.
"""
def publickey(self, secret_key: bytes, compressed: bool = True) -> bytes:
"""
Computes public key from secret key.
"""
# extmod/modtrezorcrypto/modtrezorcrypto-secp256k1_zkp.h def sign(
def verify(public_key: bytes, signature: bytes, digest: bytes) -> bool: self, secret_key: bytes, digest: bytes, compressed: bool = True
""" ) -> bytes:
Uses public key to verify the signature of the digest. """
Returns True on success. Uses secret key to produce the signature of the digest.
""" """
def verify(
self, public_key: bytes, signature: bytes, digest: bytes
) -> bool:
"""
Uses public key to verify the signature of the digest.
Returns True on success.
"""
# extmod/modtrezorcrypto/modtrezorcrypto-secp256k1_zkp.h def verify_recover(self, signature: bytes, digest: bytes) -> bytes:
def verify_recover(signature: bytes, digest: bytes) -> bytes: """
""" Uses signature of the digest to verify the digest and recover the public
Uses signature of the digest to verify the digest and recover the public key. Returns public key on success, None if the signature is invalid.
key. Returns public key on success, None if the signature is invalid. """
"""
def multiply(self, secret_key: bytes, public_key: bytes) -> bytes:
# extmod/modtrezorcrypto/modtrezorcrypto-secp256k1_zkp.h """
def multiply(secret_key: bytes, public_key: bytes) -> bytes: Multiplies point defined by public_key with scalar defined by
""" secret_key. Useful for ECDH.
Multiplies point defined by public_key with scalar defined by """
secret_key. Useful for ECDH.
"""

View File

@ -139,7 +139,7 @@ class TestCryptoSecp256k1(Secp256k1Common, unittest.TestCase):
class TestCryptoSecp256k1Zkp(Secp256k1Common, unittest.TestCase): class TestCryptoSecp256k1Zkp(Secp256k1Common, unittest.TestCase):
def __init__(self): def __init__(self):
self.impl = secp256k1_zkp self.impl = secp256k1_zkp.Context()
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()