mirror of
https://github.com/trezor/trezor-firmware.git
synced 2026-02-20 00:33:30 +01:00
Replace ecdsa with cryptography in legacy bootloader, debug signing, and test helper files
Co-authored-by: obrusvit <14001709+obrusvit@users.noreply.github.com>
This commit is contained in:
@@ -3,7 +3,13 @@ import argparse
|
||||
import hashlib
|
||||
import struct
|
||||
|
||||
import ecdsa
|
||||
from cryptography.hazmat.primitives import hashes, serialization
|
||||
from cryptography.hazmat.primitives.asymmetric import ec
|
||||
from cryptography.hazmat.primitives.asymmetric.utils import (
|
||||
decode_dss_signature,
|
||||
encode_dss_signature,
|
||||
)
|
||||
from cryptography.exceptions import InvalidSignature
|
||||
|
||||
SLOTS = 3
|
||||
|
||||
@@ -129,14 +135,16 @@ def check_signatures(data):
|
||||
print(f"Slot #{x + 1}", "is empty")
|
||||
else:
|
||||
pk = pubkeys[indexes[x]]
|
||||
verify = ecdsa.VerifyingKey.from_string(
|
||||
bytes.fromhex(pk)[1:],
|
||||
curve=ecdsa.curves.SECP256k1,
|
||||
hashfunc=hashlib.sha256,
|
||||
verify = ec.EllipticCurvePublicKey.from_encoded_point(
|
||||
ec.SECP256K1(),
|
||||
bytes.fromhex(pk),
|
||||
)
|
||||
|
||||
try:
|
||||
verify.verify(signature, to_sign, hashfunc=hashlib.sha256)
|
||||
r = int.from_bytes(signature[:32], "big")
|
||||
s = int.from_bytes(signature[32:], "big")
|
||||
der_sig = encode_dss_signature(r, s)
|
||||
verify.verify(der_sig, to_sign, ec.ECDSA(hashes.SHA256()))
|
||||
|
||||
if indexes[x] in used:
|
||||
print(f"Slot #{x + 1} signature: DUPLICATE", signature.hex())
|
||||
@@ -176,7 +184,7 @@ def sign(data, is_pem):
|
||||
if pem_key.strip() == "":
|
||||
# Blank key,let's remove existing signature from slot
|
||||
return modify(data, slot, 0, b"\x00" * 64)
|
||||
key = ecdsa.SigningKey.from_pem(pem_key)
|
||||
key = serialization.load_pem_private_key(pem_key.encode(), password=None)
|
||||
else:
|
||||
print("Paste SECEXP (in hex) and press Enter:")
|
||||
print("(blank private key removes the signature on given index)")
|
||||
@@ -184,16 +192,15 @@ def sign(data, is_pem):
|
||||
if secexp.strip() == "":
|
||||
# Blank key,let's remove existing signature from slot
|
||||
return modify(data, slot, 0, b"\x00" * 64)
|
||||
key = ecdsa.SigningKey.from_secret_exponent(
|
||||
secexp=int(secexp, 16),
|
||||
curve=ecdsa.curves.SECP256k1,
|
||||
hashfunc=hashlib.sha256,
|
||||
)
|
||||
key = ec.derive_private_key(int(secexp, 16), ec.SECP256K1())
|
||||
|
||||
to_sign = get_header(data, zero_signatures=True)
|
||||
|
||||
# Locate proper index of current signing key
|
||||
pubkey = "04" + key.get_verifying_key().to_string().hex()
|
||||
pubkey = key.public_key().public_bytes(
|
||||
serialization.Encoding.X962,
|
||||
serialization.PublicFormat.UncompressedPoint,
|
||||
).hex()
|
||||
index = None
|
||||
for i, pk in pubkeys.items():
|
||||
if pk == pubkey:
|
||||
@@ -203,26 +210,41 @@ def sign(data, is_pem):
|
||||
if index is None:
|
||||
raise Exception("Unable to find private key index. Unknown private key?")
|
||||
|
||||
signature = key.sign_deterministic(to_sign, hashfunc=hashlib.sha256)
|
||||
der_sig = key.sign(to_sign, ec.ECDSA(hashes.SHA256()))
|
||||
r, s = decode_dss_signature(der_sig)
|
||||
signature = r.to_bytes(32, "big") + s.to_bytes(32, "big")
|
||||
|
||||
return modify(data, slot, index, signature)
|
||||
|
||||
|
||||
def main(args):
|
||||
if args.generate:
|
||||
key = ecdsa.SigningKey.generate(
|
||||
curve=ecdsa.curves.SECP256k1, hashfunc=hashlib.sha256
|
||||
)
|
||||
key = ec.generate_private_key(ec.SECP256K1())
|
||||
|
||||
print("PRIVATE KEY (SECEXP):")
|
||||
print(key.to_string().hex())
|
||||
print(
|
||||
key.private_numbers().private_value.to_bytes(32, "big").hex()
|
||||
)
|
||||
print()
|
||||
|
||||
print("PRIVATE KEY (PEM):")
|
||||
print(key.to_pem())
|
||||
print(
|
||||
key.private_bytes(
|
||||
serialization.Encoding.PEM,
|
||||
serialization.PrivateFormat.TraditionalOpenSSL,
|
||||
serialization.NoEncryption(),
|
||||
).decode()
|
||||
)
|
||||
|
||||
print("PUBLIC KEY:")
|
||||
print("04" + key.get_verifying_key().to_string().hex())
|
||||
print(
|
||||
key.public_key()
|
||||
.public_bytes(
|
||||
serialization.Encoding.X962,
|
||||
serialization.PublicFormat.UncompressedPoint,
|
||||
)
|
||||
.hex()
|
||||
)
|
||||
return
|
||||
|
||||
if not args.path:
|
||||
|
||||
@@ -3,8 +3,13 @@ import argparse
|
||||
import hashlib
|
||||
import struct
|
||||
|
||||
import ecdsa
|
||||
from ecdsa import BadSignatureError
|
||||
from cryptography.hazmat.primitives import hashes, serialization
|
||||
from cryptography.hazmat.primitives.asymmetric import ec
|
||||
from cryptography.hazmat.primitives.asymmetric.utils import (
|
||||
decode_dss_signature,
|
||||
encode_dss_signature,
|
||||
)
|
||||
from cryptography.exceptions import InvalidSignature
|
||||
|
||||
SLOTS = 3
|
||||
|
||||
@@ -121,14 +126,16 @@ def check_signatures(data):
|
||||
else:
|
||||
pubkeys = pubkeys_dev
|
||||
pk = pubkeys[indexes[x]]
|
||||
verify = ecdsa.VerifyingKey.from_string(
|
||||
bytes.fromhex(pk)[1:],
|
||||
curve=ecdsa.curves.SECP256k1,
|
||||
hashfunc=hashlib.sha256,
|
||||
verify = ec.EllipticCurvePublicKey.from_encoded_point(
|
||||
ec.SECP256K1(),
|
||||
bytes.fromhex(pk),
|
||||
)
|
||||
|
||||
try:
|
||||
verify.verify(signature, to_sign, hashfunc=hashlib.sha256)
|
||||
r = int.from_bytes(signature[:32], "big")
|
||||
s = int.from_bytes(signature[32:], "big")
|
||||
der_sig = encode_dss_signature(r, s)
|
||||
verify.verify(der_sig, to_sign, ec.ECDSA(hashes.SHA256()))
|
||||
|
||||
if indexes[x] in used:
|
||||
print(f"Slot #{x + 1} signature: DUPLICATE", signature.hex())
|
||||
@@ -150,16 +157,15 @@ def modify(data, slot, index, signature):
|
||||
|
||||
|
||||
def sign(data, slot, secexp):
|
||||
key = ecdsa.SigningKey.from_secret_exponent(
|
||||
secexp=int(secexp, 16),
|
||||
curve=ecdsa.curves.SECP256k1,
|
||||
hashfunc=hashlib.sha256,
|
||||
)
|
||||
key = ec.derive_private_key(int(secexp, 16), ec.SECP256K1())
|
||||
|
||||
to_sign = get_header(data, zero_signatures=True)
|
||||
|
||||
# Locate proper index of current signing key
|
||||
pubkey = "04" + key.get_verifying_key().to_string().hex()
|
||||
pubkey = key.public_key().public_bytes(
|
||||
serialization.Encoding.X962,
|
||||
serialization.PublicFormat.UncompressedPoint,
|
||||
).hex()
|
||||
index = None
|
||||
|
||||
pubkeys = pubkeys_dev
|
||||
@@ -171,7 +177,9 @@ def sign(data, slot, secexp):
|
||||
if index is None:
|
||||
raise Exception("Unable to find private key index. Unknown private key?")
|
||||
|
||||
signature = key.sign_deterministic(to_sign, hashfunc=hashlib.sha256)
|
||||
der_sig = key.sign(to_sign, ec.ECDSA(hashes.SHA256()))
|
||||
r, s = decode_dss_signature(der_sig)
|
||||
signature = r.to_bytes(32, "big") + s.to_bytes(32, "big")
|
||||
|
||||
return modify(data, slot, index, signature)
|
||||
|
||||
@@ -223,14 +231,16 @@ def check_signatures_old(data):
|
||||
else:
|
||||
pubkeys = pubkeys_dev
|
||||
pk = pubkeys[indexes[x]]
|
||||
verify = ecdsa.VerifyingKey.from_string(
|
||||
bytes.fromhex(pk)[1:],
|
||||
curve=ecdsa.curves.SECP256k1,
|
||||
hashfunc=hashlib.sha256,
|
||||
verify = ec.EllipticCurvePublicKey.from_encoded_point(
|
||||
ec.SECP256K1(),
|
||||
bytes.fromhex(pk),
|
||||
)
|
||||
|
||||
try:
|
||||
verify.verify(signature, to_sign, hashfunc=hashlib.sha256)
|
||||
r = int.from_bytes(signature[:32], "big")
|
||||
s = int.from_bytes(signature[32:], "big")
|
||||
der_sig = encode_dss_signature(r, s)
|
||||
verify.verify(der_sig, to_sign, ec.ECDSA(hashes.SHA256()))
|
||||
|
||||
if indexes[x] in used:
|
||||
print("Slot #%d signature: DUPLICATE" % (x + 1), signature.hex())
|
||||
@@ -238,7 +248,7 @@ def check_signatures_old(data):
|
||||
used.append(indexes[x])
|
||||
print("Slot #%d signature: VALID" % (x + 1), signature.hex())
|
||||
|
||||
except BadSignatureError:
|
||||
except InvalidSignature:
|
||||
print("Slot #%d signature: INVALID" % (x + 1), signature.hex())
|
||||
|
||||
|
||||
@@ -261,16 +271,15 @@ def modify_old(data, slot, index, signature):
|
||||
|
||||
|
||||
def sign_old(data, slot, secexp):
|
||||
key = ecdsa.SigningKey.from_secret_exponent(
|
||||
secexp=int(secexp, 16),
|
||||
curve=ecdsa.curves.SECP256k1,
|
||||
hashfunc=hashlib.sha256,
|
||||
)
|
||||
key = ec.derive_private_key(int(secexp, 16), ec.SECP256K1())
|
||||
|
||||
to_sign = prepare_old(data)[256:] # without meta
|
||||
|
||||
# Locate proper index of current signing key
|
||||
pubkey = "04" + key.get_verifying_key().to_string().hex()
|
||||
pubkey = key.public_key().public_bytes(
|
||||
serialization.Encoding.X962,
|
||||
serialization.PublicFormat.UncompressedPoint,
|
||||
).hex()
|
||||
index = None
|
||||
|
||||
pubkeys = pubkeys_dev
|
||||
@@ -283,7 +292,9 @@ def sign_old(data, slot, secexp):
|
||||
if index is None:
|
||||
raise Exception("Unable to find private key index. Unknown private key?")
|
||||
|
||||
signature = key.sign_deterministic(to_sign, hashfunc=hashlib.sha256)
|
||||
der_sig = key.sign(to_sign, ec.ECDSA(hashes.SHA256()))
|
||||
r, s = decode_dss_signature(der_sig)
|
||||
signature = r.to_bytes(32, "big") + s.to_bytes(32, "big")
|
||||
|
||||
return modify_old(data, slot, index, signature)
|
||||
|
||||
|
||||
@@ -4,7 +4,9 @@ import os
|
||||
import subprocess
|
||||
from binascii import hexlify, unhexlify
|
||||
|
||||
import ecdsa
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
from cryptography.hazmat.primitives.asymmetric import ec
|
||||
from cryptography.hazmat.primitives.asymmetric.utils import decode_dss_signature
|
||||
|
||||
print("master secret:", end="")
|
||||
h = input()
|
||||
@@ -20,16 +22,25 @@ print()
|
||||
for i in range(1, 6):
|
||||
se = hashlib.sha256(h + chr(i).encode("ascii")).hexdigest()
|
||||
print("seckey", i, ":", se)
|
||||
sk = ecdsa.SigningKey.from_secret_exponent(
|
||||
secexp=int(se, 16), curve=ecdsa.curves.SECP256k1, hashfunc=hashlib.sha256
|
||||
sk = ec.derive_private_key(int(se, 16), ec.SECP256K1())
|
||||
pk = sk.public_key()
|
||||
pk_bytes = pk.public_bytes(
|
||||
serialization.Encoding.X962,
|
||||
serialization.PublicFormat.UncompressedPoint,
|
||||
)
|
||||
print(
|
||||
"pubkey",
|
||||
i,
|
||||
":",
|
||||
(b"04" + hexlify(sk.get_verifying_key().to_string())).decode("ascii"),
|
||||
hexlify(pk_bytes).decode("ascii"),
|
||||
)
|
||||
print(
|
||||
sk.private_bytes(
|
||||
serialization.Encoding.PEM,
|
||||
serialization.PrivateFormat.TraditionalOpenSSL,
|
||||
serialization.NoEncryption(),
|
||||
).decode("ascii")
|
||||
)
|
||||
print(sk.to_pem().decode("ascii"))
|
||||
|
||||
p = subprocess.Popen("ssss-split -t 3 -n 5 -x".split(" "), stdin=subprocess.PIPE)
|
||||
p.communicate(input=hexlify(h) + "\n")
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
import sys
|
||||
from hashlib import sha256
|
||||
|
||||
import ecdsa
|
||||
from cryptography.hazmat.primitives import hashes
|
||||
from cryptography.hazmat.primitives.asymmetric import ec
|
||||
from cryptography.hazmat.primitives.asymmetric.utils import Prehashed, encode_dss_signature
|
||||
|
||||
# arg 1 - hex digest of firmware header with zeroed sigslots
|
||||
# arg 2 - public key (compressed or uncompressed)
|
||||
@@ -17,6 +19,10 @@ prefix = b"\x18Bitcoin Signed Message:\n\x20"
|
||||
message_predigest = prefix + digest
|
||||
message = sha256(message_predigest).digest()
|
||||
|
||||
vk = ecdsa.VerifyingKey.from_string(public_key, curve=ecdsa.SECP256k1, hashfunc=sha256)
|
||||
result = vk.verify(sig, message)
|
||||
vk = ec.EllipticCurvePublicKey.from_encoded_point(ec.SECP256K1(), public_key)
|
||||
r = int.from_bytes(sig[:32], "big")
|
||||
s = int.from_bytes(sig[32:], "big")
|
||||
der_sig = encode_dss_signature(r, s)
|
||||
vk.verify(der_sig, message, ec.ECDSA(Prehashed(hashes.SHA256())))
|
||||
result = True
|
||||
print("Signature verification result", result)
|
||||
|
||||
@@ -5,7 +5,14 @@ import pprint
|
||||
import sys
|
||||
from hashlib import sha1, sha256
|
||||
|
||||
import ecdsa
|
||||
from cryptography.hazmat.primitives import hashes, serialization
|
||||
from cryptography.hazmat.primitives.asymmetric import ec
|
||||
from cryptography.hazmat.primitives.asymmetric.utils import (
|
||||
decode_dss_signature,
|
||||
encode_dss_signature,
|
||||
)
|
||||
from cryptography.exceptions import InvalidSignature
|
||||
|
||||
from fill_t1_fw_signatures import Signatures
|
||||
|
||||
secret_keys_hex = [
|
||||
@@ -17,13 +24,19 @@ secret_keys_hex = [
|
||||
]
|
||||
|
||||
secret_keys = [
|
||||
ecdsa.SigningKey.from_string(
|
||||
bytes.fromhex(sk), curve=ecdsa.SECP256k1, hashfunc=sha256
|
||||
ec.derive_private_key(
|
||||
int.from_bytes(bytes.fromhex(sk), "big"), ec.SECP256K1()
|
||||
)
|
||||
for sk in secret_keys_hex
|
||||
]
|
||||
public_keys = [sk.get_verifying_key() for sk in secret_keys]
|
||||
public_keys_hex = [pk.to_string("compressed").hex() for pk in public_keys]
|
||||
public_keys = [sk.public_key() for sk in secret_keys]
|
||||
public_keys_hex = [
|
||||
pk.public_bytes(
|
||||
serialization.Encoding.X962,
|
||||
serialization.PublicFormat.CompressedPoint,
|
||||
).hex()
|
||||
for pk in public_keys
|
||||
]
|
||||
|
||||
# arg1 is input trezor.bin filename to be signed
|
||||
# arg2 is output filename, if omitted, will use input file + ".signed"
|
||||
@@ -54,21 +67,21 @@ assert public_keys_hex == [
|
||||
|
||||
print("Sanity check")
|
||||
for sk, pk_hex in zip(secret_keys, public_keys_hex):
|
||||
pk = ecdsa.VerifyingKey.from_string(
|
||||
bytes.fromhex(pk_hex), curve=ecdsa.SECP256k1, hashfunc=sha256
|
||||
pk = ec.EllipticCurvePublicKey.from_encoded_point(
|
||||
ec.SECP256K1(), bytes.fromhex(pk_hex)
|
||||
)
|
||||
message = bytes(os.urandom(64))
|
||||
|
||||
# These should work
|
||||
sig = sk.sign_deterministic(message, hashfunc=sha256)
|
||||
pk.verify(sig, message, hashfunc=sha256) # throws exception if wrong
|
||||
der_sig = sk.sign(message, ec.ECDSA(hashes.SHA256()))
|
||||
pk.verify(der_sig, message, ec.ECDSA(hashes.SHA256())) # throws exception if wrong
|
||||
|
||||
# These should fail
|
||||
try:
|
||||
sig = sk.sign_deterministic(message, hashfunc=sha1)
|
||||
pk.verify(sig, message, hashfunc=sha256) # should throw
|
||||
der_sig = sk.sign(message, ec.ECDSA(hashes.SHA1()))
|
||||
pk.verify(der_sig, message, ec.ECDSA(hashes.SHA256())) # should throw
|
||||
raise RuntimeError("These should not have matched!")
|
||||
except ecdsa.keys.BadSignatureError:
|
||||
except InvalidSignature:
|
||||
# print("Bad sig check fail test ok")
|
||||
pass # fine, should have failed
|
||||
|
||||
@@ -87,13 +100,16 @@ for i in sig_indices:
|
||||
index = i - 1 # in FW indices are indexed from 1, 0 means none
|
||||
print(f"--- Key {index}, sigindex {i}")
|
||||
sk = secret_keys[index]
|
||||
sig_64bytes = sk.sign_deterministic(header, hashfunc=sha256)
|
||||
der_sig = sk.sign(header, ec.ECDSA(hashes.SHA256()))
|
||||
r, s = decode_dss_signature(der_sig)
|
||||
sig_64bytes = r.to_bytes(32, "big") + s.to_bytes(32, "big")
|
||||
assert len(sig_64bytes) == 64
|
||||
print("Signature:", sig_64bytes.hex())
|
||||
pk = ecdsa.VerifyingKey.from_string(
|
||||
bytes.fromhex(public_keys_hex[index]), curve=ecdsa.SECP256k1, hashfunc=sha256
|
||||
pk = ec.EllipticCurvePublicKey.from_encoded_point(
|
||||
ec.SECP256K1(), bytes.fromhex(public_keys_hex[index])
|
||||
)
|
||||
pk.verify(sig_64bytes, header, hashfunc=sha256) # throws exception if wrong
|
||||
der_sig_verify = encode_dss_signature(r, s)
|
||||
pk.verify(der_sig_verify, header, ec.ECDSA(hashes.SHA256())) # throws exception if wrong
|
||||
print(f"Public key {public_keys_hex[index]}")
|
||||
print("Verified created sig with public key")
|
||||
print("=================================")
|
||||
|
||||
@@ -5,13 +5,20 @@ from hashlib import sha256
|
||||
from pathlib import Path
|
||||
|
||||
import click
|
||||
import ecdsa
|
||||
from cryptography.hazmat.primitives import hashes, serialization
|
||||
from cryptography.hazmat.primitives.asymmetric import ec
|
||||
from cryptography.hazmat.primitives.asymmetric.utils import (
|
||||
Prehashed,
|
||||
decode_dss_signature,
|
||||
)
|
||||
|
||||
from trezorlib.firmware.legacy import LegacyV2Firmware
|
||||
from trezorlib.firmware.models import LEGACY_V3_DEV
|
||||
|
||||
SECRET_KEYS = [
|
||||
ecdsa.SigningKey.from_string(bytes.fromhex(sk), curve=ecdsa.SECP256k1)
|
||||
ec.derive_private_key(
|
||||
int.from_bytes(bytes.fromhex(sk), "big"), ec.SECP256K1()
|
||||
)
|
||||
for sk in (
|
||||
"ca8de06e1e93d101136fa6fbc41432c52b6530299dfe32808030ee8e679702f1",
|
||||
"dde47dd393f7d76f9b522bfa9760bc4543d2c3654491393774f54e066461fccb",
|
||||
@@ -19,17 +26,25 @@ SECRET_KEYS = [
|
||||
)
|
||||
]
|
||||
|
||||
PUBLIC_KEYS: list[ecdsa.VerifyingKey] = [sk.get_verifying_key() for sk in SECRET_KEYS]
|
||||
PUBLIC_KEYS = [sk.public_key() for sk in SECRET_KEYS]
|
||||
|
||||
# Should be these public keys
|
||||
assert [pk.to_string("compressed") for pk in PUBLIC_KEYS] == LEGACY_V3_DEV.firmware_keys
|
||||
assert [
|
||||
pk.public_bytes(
|
||||
serialization.Encoding.X962,
|
||||
serialization.PublicFormat.CompressedPoint,
|
||||
)
|
||||
for pk in PUBLIC_KEYS
|
||||
] == LEGACY_V3_DEV.firmware_keys
|
||||
|
||||
|
||||
def signmessage(digest: bytes, key: ecdsa.SigningKey) -> bytes:
|
||||
def signmessage(digest: bytes, key: ec.EllipticCurvePrivateKey) -> bytes:
|
||||
"""Sign via SignMessage"""
|
||||
btc_digest = b"\x18Bitcoin Signed Message:\n\x20" + digest
|
||||
final_digest = sha256(sha256(btc_digest).digest()).digest()
|
||||
return key.sign_digest_deterministic(final_digest, hashfunc=sha256)
|
||||
der_sig = key.sign(final_digest, ec.ECDSA(Prehashed(hashes.SHA256())))
|
||||
r, s = decode_dss_signature(der_sig)
|
||||
return r.to_bytes(32, "big") + s.to_bytes(32, "big")
|
||||
|
||||
|
||||
@click.command()
|
||||
|
||||
@@ -39,7 +39,7 @@ dependencies = [
|
||||
"requests~=2.32",
|
||||
"termcolor",
|
||||
"Pillow>=11",
|
||||
"ecdsa>=0.16,<0.17",
|
||||
|
||||
"pyasn1",
|
||||
"noiseprotocol>=0.3.1,<0.4",
|
||||
"west>=1.4.0,<2",
|
||||
|
||||
@@ -2,7 +2,9 @@ import os
|
||||
from hashlib import sha256
|
||||
from typing import List
|
||||
|
||||
from ecdsa import NIST256p, SigningKey
|
||||
from cryptography.hazmat.primitives import hashes, serialization
|
||||
from cryptography.hazmat.primitives.asymmetric import ec
|
||||
from cryptography.hazmat.primitives.asymmetric.utils import Prehashed, decode_dss_signature
|
||||
|
||||
from trezorlib import evolu
|
||||
from trezorlib.debuglink import DebugSession as Session
|
||||
@@ -19,7 +21,9 @@ TEST_host_static_public_key = curve25519.get_public_key(TEST_host_static_private
|
||||
|
||||
def get_proof(client: Client, header: bytes, arguments: List[bytes]) -> bytes:
|
||||
private_key = get_delegated_identity_key(client)
|
||||
signing_key = SigningKey.from_string(private_key, curve=NIST256p)
|
||||
signing_key = ec.derive_private_key(
|
||||
int.from_bytes(private_key, "big"), ec.SECP256R1()
|
||||
)
|
||||
|
||||
ctx = sha256()
|
||||
ctx.update(compact_size(len(header)))
|
||||
@@ -27,7 +31,9 @@ def get_proof(client: Client, header: bytes, arguments: List[bytes]) -> bytes:
|
||||
for arg in arguments:
|
||||
ctx.update(compact_size(len(arg)))
|
||||
ctx.update(arg)
|
||||
return signing_key.sign_digest(ctx.digest())
|
||||
der_sig = signing_key.sign(ctx.digest(), ec.ECDSA(Prehashed(hashes.SHA256())))
|
||||
r, s = decode_dss_signature(der_sig)
|
||||
return r.to_bytes(32, "big") + s.to_bytes(32, "big")
|
||||
|
||||
|
||||
def get_invalid_proof(client: Client, header: bytes, arguments: List[bytes]) -> bytes:
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import pytest
|
||||
from ecdsa import NIST256p, SigningKey, VerifyingKey
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
from cryptography.hazmat.primitives.asymmetric import ec
|
||||
|
||||
from trezorlib import evolu
|
||||
from trezorlib.debuglink import TrezorTestContext as Client
|
||||
@@ -13,10 +14,14 @@ pytestmark = pytest.mark.models("core")
|
||||
|
||||
|
||||
def signing_buffer(private_key: bytes, challenge: bytes, size: int) -> bytes:
|
||||
public_key: VerifyingKey = SigningKey.from_string(private_key, curve=NIST256p).get_verifying_key() # type: ignore
|
||||
sk = ec.derive_private_key(int.from_bytes(private_key, "big"), ec.SECP256R1())
|
||||
public_key_bytes = sk.public_key().public_bytes(
|
||||
serialization.Encoding.X962,
|
||||
serialization.PublicFormat.UncompressedPoint,
|
||||
)
|
||||
components = [
|
||||
b"EvoluSignRegistrationRequestV1:",
|
||||
public_key.to_string("uncompressed"),
|
||||
public_key_bytes,
|
||||
challenge,
|
||||
size.to_bytes(4, "big"),
|
||||
]
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
from dataclasses import dataclass
|
||||
from hashlib import sha256
|
||||
|
||||
from ecdsa import NIST256p, SigningKey
|
||||
from cryptography.hazmat.primitives.asymmetric import ec
|
||||
from cryptography.hazmat.primitives.asymmetric.utils import Prehashed, decode_dss_signature
|
||||
from cryptography.hazmat.primitives import hashes
|
||||
|
||||
from trezorlib import messages
|
||||
from trezorlib.client import Session
|
||||
@@ -37,9 +39,12 @@ class CoinPurchaseMemo:
|
||||
address_resp: messages.Address | messages.EthereumAddress | None = None
|
||||
|
||||
|
||||
payment_req_signer = SigningKey.from_string(
|
||||
b"\x05\x62\x35\xb0\x47\x6f\x05\x7f\x27\x65\x21\x97\x24\xf7\xf1\x80\x7d\x58\x80\x2b\x55\x0e\xd5\xbf\x6f\x73\x05\x0a\xf5\x45\x63\x00",
|
||||
curve=NIST256p,
|
||||
payment_req_signer = ec.derive_private_key(
|
||||
int.from_bytes(
|
||||
b"\x05\x62\x35\xb0\x47\x6f\x05\x7f\x27\x65\x21\x97\x24\xf7\xf1\x80\x7d\x58\x80\x2b\x55\x0e\xd5\xbf\x6f\x73\x05\x0a\xf5\x45\x63\x00",
|
||||
"big",
|
||||
),
|
||||
ec.SECP256R1(),
|
||||
)
|
||||
|
||||
|
||||
@@ -135,6 +140,13 @@ def make_payment_request(
|
||||
else None
|
||||
)
|
||||
|
||||
der_sig = payment_req_signer.sign(
|
||||
h_pr.digest(),
|
||||
ec.ECDSA(Prehashed(hashes.SHA256())),
|
||||
)
|
||||
r, s = decode_dss_signature(der_sig)
|
||||
raw_sig = r.to_bytes(32, "big") + s.to_bytes(32, "big")
|
||||
|
||||
return messages.PaymentRequest(
|
||||
recipient_name=recipient_name,
|
||||
amount=(
|
||||
@@ -142,5 +154,5 @@ def make_payment_request(
|
||||
),
|
||||
memos=msg_memos,
|
||||
nonce=nonce,
|
||||
signature=payment_req_signer.sign_digest_deterministic(h_pr.digest()),
|
||||
signature=raw_sig,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user