mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-06-27 10:22:34 +00:00
feat(core): support ethereum transaction signing anti-exfil protocol
This commit is contained in:
parent
ba06f21a0e
commit
af4434b334
@ -102,7 +102,7 @@ async def sign_tx(
|
|||||||
rlp.write(sha, 0)
|
rlp.write(sha, 0)
|
||||||
|
|
||||||
digest = sha.get_digest()
|
digest = sha.get_digest()
|
||||||
result = _sign_digest(msg, keychain, digest)
|
result = await _sign_digest(msg, keychain, digest)
|
||||||
|
|
||||||
progress_obj.stop()
|
progress_obj.stop()
|
||||||
|
|
||||||
@ -253,25 +253,53 @@ async def send_request_chunk(data_left: int) -> bytes:
|
|||||||
return resp.data_chunk
|
return resp.data_chunk
|
||||||
|
|
||||||
|
|
||||||
def _sign_digest(
|
async def send_request_entropy(nonce_commitment: bytes) -> bytes:
|
||||||
|
from trezor.messages import EthereumTxAck
|
||||||
|
from trezor.wire.context import call
|
||||||
|
|
||||||
|
req = EthereumTxRequest()
|
||||||
|
req.nonce_commitment = nonce_commitment
|
||||||
|
resp = await call(req, EthereumTxAck)
|
||||||
|
assert resp.entropy is not None
|
||||||
|
return resp.entropy
|
||||||
|
|
||||||
|
|
||||||
|
async def _sign_digest(
|
||||||
msg: EthereumSignTx, keychain: Keychain, digest: bytes
|
msg: EthereumSignTx, keychain: Keychain, digest: bytes
|
||||||
) -> EthereumTxRequest:
|
) -> EthereumTxRequest:
|
||||||
from trezor.crypto.curve import secp256k1
|
from trezor.crypto.curve import secp256k1
|
||||||
|
|
||||||
node = keychain.derive(msg.address_n)
|
node = keychain.derive(msg.address_n)
|
||||||
signature = secp256k1.sign_recoverable(
|
private_key = node.private_key()
|
||||||
node.private_key(), digest, secp256k1.CANONICAL_SIG_ETHEREUM
|
|
||||||
)
|
if msg.entropy_commitment is not None:
|
||||||
|
# use anti-exfil protocol
|
||||||
|
nonce_commitment = secp256k1.anti_exfil_commit_nonce(
|
||||||
|
private_key, digest, msg.entropy_commitment
|
||||||
|
)
|
||||||
|
entropy = await send_request_entropy(nonce_commitment)
|
||||||
|
|
||||||
|
signature = secp256k1.anti_exfil_sign(private_key, digest, entropy)
|
||||||
|
else:
|
||||||
|
signature = secp256k1.sign_recoverable(
|
||||||
|
private_key, digest, secp256k1.CANONICAL_SIG_ETHEREUM
|
||||||
|
)
|
||||||
|
|
||||||
req = EthereumTxRequest()
|
req = EthereumTxRequest()
|
||||||
if msg.chain_id <= MAX_CHAIN_ID:
|
|
||||||
req.signature_v = signature[0] + 35 + 2 * msg.chain_id
|
|
||||||
else:
|
|
||||||
# https://github.com/trezor/trezor-core/pull/311
|
|
||||||
req.signature_v = signature[0]
|
|
||||||
|
|
||||||
req.signature_r = signature[1:33]
|
if msg.entropy_commitment is not None:
|
||||||
req.signature_s = signature[33:]
|
# use anti-exfil protocol
|
||||||
|
req.signature_v = None
|
||||||
|
req.signature_r = signature[:32]
|
||||||
|
req.signature_s = signature[32:]
|
||||||
|
else:
|
||||||
|
if msg.chain_id <= MAX_CHAIN_ID:
|
||||||
|
req.signature_v = 35 + 2 * msg.chain_id + signature[0]
|
||||||
|
else:
|
||||||
|
# https://github.com/trezor/trezor-core/pull/311
|
||||||
|
req.signature_v = signature[0]
|
||||||
|
req.signature_r = signature[1:33]
|
||||||
|
req.signature_s = signature[33:]
|
||||||
|
|
||||||
return req
|
return req
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ async def sign_tx_eip1559(
|
|||||||
rlp.write(sha, item.storage_keys)
|
rlp.write(sha, item.storage_keys)
|
||||||
|
|
||||||
digest = sha.get_digest()
|
digest = sha.get_digest()
|
||||||
result = _sign_digest(msg, keychain, digest)
|
result = await _sign_digest(msg, keychain, digest)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@ -151,20 +151,40 @@ def _get_total_length(msg: EthereumSignTxEIP1559, data_total: int) -> int:
|
|||||||
return length
|
return length
|
||||||
|
|
||||||
|
|
||||||
def _sign_digest(
|
async def _sign_digest(
|
||||||
msg: EthereumSignTxEIP1559, keychain: Keychain, digest: bytes
|
msg: EthereumSignTxEIP1559, keychain: Keychain, digest: bytes
|
||||||
) -> EthereumTxRequest:
|
) -> EthereumTxRequest:
|
||||||
from trezor.crypto.curve import secp256k1
|
from trezor.crypto.curve import secp256k1
|
||||||
from trezor.messages import EthereumTxRequest
|
from trezor.messages import EthereumTxRequest
|
||||||
|
|
||||||
|
from .sign_tx import send_request_entropy
|
||||||
|
|
||||||
node = keychain.derive(msg.address_n)
|
node = keychain.derive(msg.address_n)
|
||||||
signature = secp256k1.sign_recoverable(
|
private_key = node.private_key()
|
||||||
node.private_key(), digest, secp256k1.CANONICAL_SIG_ETHEREUM
|
|
||||||
)
|
if msg.entropy_commitment is not None:
|
||||||
|
# use anti-exfil protocol
|
||||||
|
nonce_commitment = secp256k1.anti_exfil_commit_nonce(
|
||||||
|
private_key, digest, msg.entropy_commitment
|
||||||
|
)
|
||||||
|
entropy = await send_request_entropy(nonce_commitment)
|
||||||
|
|
||||||
|
signature = secp256k1.anti_exfil_sign(private_key, digest, entropy)
|
||||||
|
else:
|
||||||
|
signature = secp256k1.sign_recoverable(
|
||||||
|
private_key, digest, secp256k1.CANONICAL_SIG_ETHEREUM
|
||||||
|
)
|
||||||
|
|
||||||
req = EthereumTxRequest()
|
req = EthereumTxRequest()
|
||||||
req.signature_v = signature[0]
|
|
||||||
req.signature_r = signature[1:33]
|
if msg.entropy_commitment is not None:
|
||||||
req.signature_s = signature[33:]
|
# use anti-exfil protocol
|
||||||
|
req.signature_v = None
|
||||||
|
req.signature_r = signature[:32]
|
||||||
|
req.signature_s = signature[32:]
|
||||||
|
else:
|
||||||
|
req.signature_v = signature[0]
|
||||||
|
req.signature_r = signature[1:33]
|
||||||
|
req.signature_s = signature[33:]
|
||||||
|
|
||||||
return req
|
return req
|
||||||
|
Loading…
Reference in New Issue
Block a user