1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-20 05:18:08 +00:00

feat(rust/ethereum): remove primitive-types dependency, make chain ID optional

This commit is contained in:
DaniPopes 2024-01-05 21:57:24 +01:00 committed by matejcik
parent 37fde954b4
commit 74c1129445
4 changed files with 40 additions and 84 deletions

View File

@ -92,12 +92,6 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "crunchy"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
[[package]] [[package]]
name = "dashmap" name = "dashmap"
version = "5.5.3" version = "5.5.3"
@ -133,15 +127,6 @@ version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
[[package]]
name = "fixed-hash"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534"
dependencies = [
"static_assertions",
]
[[package]] [[package]]
name = "futures" name = "futures"
version = "0.3.29" version = "0.3.29"
@ -383,16 +368,6 @@ version = "0.3.27"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
[[package]]
name = "primitive-types"
version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2"
dependencies = [
"fixed-hash",
"uint",
]
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.69" version = "1.0.69"
@ -597,12 +572,6 @@ version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.39" version = "2.0.39"
@ -736,7 +705,6 @@ dependencies = [
"bitcoin", "bitcoin",
"byteorder", "byteorder",
"hex", "hex",
"primitive-types",
"protobuf", "protobuf",
"rusb", "rusb",
"serial_test", "serial_test",
@ -753,18 +721,6 @@ dependencies = [
"protobuf-codegen", "protobuf-codegen",
] ]
[[package]]
name = "uint"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52"
dependencies = [
"byteorder",
"crunchy",
"hex",
"static_assertions",
]
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.12" version = "1.0.12"

View File

@ -44,9 +44,6 @@ tracing = "0.1"
bitcoin = { version = "0.31", optional = true } bitcoin = { version = "0.31", optional = true }
unicode-normalization = { version = "0.1.22", optional = true } unicode-normalization = { version = "0.1.22", optional = true }
# ethereum
primitive-types = { version = "0.12", default-features = false, optional = true }
[dev-dependencies] [dev-dependencies]
tracing-subscriber = "0.3" tracing-subscriber = "0.3"
serial_test = "2.0.0" serial_test = "2.0.0"
@ -56,7 +53,7 @@ default = ["bitcoin", "ethereum"]
# Client implementations # Client implementations
bitcoin = ["dep:bitcoin", "unicode-normalization"] bitcoin = ["dep:bitcoin", "unicode-normalization"]
ethereum = ["primitive-types"] ethereum = []
# Just bindings to the Trezor protobufs # Just bindings to the Trezor protobufs
binance = [] binance = []

View File

@ -1,9 +1,9 @@
use super::{handle_interaction, Trezor}; use super::{handle_interaction, Trezor};
use crate::{ use crate::{
error::Result, error::Result,
protos::{self, ethereum_sign_tx_eip1559::EthereumAccessList}, protos::{self, ethereum_sign_tx_eip1559::EthereumAccessList, EthereumTxRequest},
Error,
}; };
use primitive_types::U256;
/// Access list item. /// Access list item.
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
@ -18,9 +18,9 @@ pub struct AccessListItem {
#[derive(Debug, Clone, PartialEq, Eq, Copy)] #[derive(Debug, Clone, PartialEq, Eq, Copy)]
pub struct Signature { pub struct Signature {
/// R value /// R value
pub r: U256, pub r: [u8; 32],
/// S Value /// S Value
pub s: U256, pub s: [u8; 32],
/// V value in 'Electrum' notation. /// V value in 'Electrum' notation.
pub v: u64, pub v: u64,
} }
@ -44,13 +44,13 @@ impl Trezor {
req, req,
Box::new(|_, m: protos::EthereumMessageSignature| { Box::new(|_, m: protos::EthereumMessageSignature| {
let signature = m.signature(); let signature = m.signature();
if signature.len() != 65 {
// why are you in the end return Err(Error::MalformedSignature);
}
let r = signature[0..32].try_into().unwrap();
let s = signature[32..64].try_into().unwrap();
let v = signature[64] as u64; let v = signature[64] as u64;
let r = U256::from_big_endian(&signature[0..32]); Ok(Signature { r, s, v })
let s = U256::from_big_endian(&signature[32..64]);
Ok(Signature { r, v, s })
}), }),
)?)?; )?)?;
@ -66,18 +66,20 @@ impl Trezor {
gas_limit: Vec<u8>, gas_limit: Vec<u8>,
to: String, to: String,
value: Vec<u8>, value: Vec<u8>,
_data: Vec<u8>, data: Vec<u8>,
chain_id: u64, chain_id: Option<u64>,
) -> Result<Signature> { ) -> Result<Signature> {
let mut req = protos::EthereumSignTx::new(); let mut req = protos::EthereumSignTx::new();
let mut data = _data; let mut data = data;
req.address_n = path; req.address_n = path;
req.set_nonce(nonce); req.set_nonce(nonce);
req.set_gas_price(gas_price); req.set_gas_price(gas_price);
req.set_gas_limit(gas_limit); req.set_gas_limit(gas_limit);
req.set_value(value); req.set_value(value);
if let Some(chain_id) = chain_id {
req.set_chain_id(chain_id); req.set_chain_id(chain_id);
}
req.set_to(to); req.set_to(to);
req.set_data_length(data.len() as u32); req.set_data_length(data.len() as u32);
@ -93,15 +95,7 @@ impl Trezor {
resp = self.call(ack, Box::new(|_, m: protos::EthereumTxRequest| Ok(m)))?.ok()?; resp = self.call(ack, Box::new(|_, m: protos::EthereumTxRequest| Ok(m)))?.ok()?;
} }
if resp.signature_v() <= 1 { convert_signature(&resp, chain_id)
resp.set_signature_v(resp.signature_v() + 2 * (chain_id as u32) + 35);
}
Ok(Signature {
r: resp.signature_r().into(),
v: resp.signature_v().into(),
s: resp.signature_s().into(),
})
} }
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
@ -112,14 +106,14 @@ impl Trezor {
gas_limit: Vec<u8>, gas_limit: Vec<u8>,
to: String, to: String,
value: Vec<u8>, value: Vec<u8>,
_data: Vec<u8>, data: Vec<u8>,
chain_id: u64, chain_id: Option<u64>,
max_gas_fee: Vec<u8>, max_gas_fee: Vec<u8>,
max_priority_fee: Vec<u8>, max_priority_fee: Vec<u8>,
access_list: Vec<AccessListItem>, access_list: Vec<AccessListItem>,
) -> Result<Signature> { ) -> Result<Signature> {
let mut req = protos::EthereumSignTxEIP1559::new(); let mut req = protos::EthereumSignTxEIP1559::new();
let mut data = _data; let mut data = data;
req.address_n = path; req.address_n = path;
req.set_nonce(nonce); req.set_nonce(nonce);
@ -127,7 +121,9 @@ impl Trezor {
req.set_max_priority_fee(max_priority_fee); req.set_max_priority_fee(max_priority_fee);
req.set_gas_limit(gas_limit); req.set_gas_limit(gas_limit);
req.set_value(value); req.set_value(value);
if let Some(chain_id) = chain_id {
req.set_chain_id(chain_id); req.set_chain_id(chain_id);
}
req.set_to(to); req.set_to(to);
if !access_list.is_empty() { if !access_list.is_empty() {
@ -154,14 +150,18 @@ impl Trezor {
resp = self.call(ack, Box::new(|_, m: protos::EthereumTxRequest| Ok(m)))?.ok()? resp = self.call(ack, Box::new(|_, m: protos::EthereumTxRequest| Ok(m)))?.ok()?
} }
if resp.signature_v() <= 1 { convert_signature(&resp, chain_id)
resp.set_signature_v(resp.signature_v() + 2 * (chain_id as u32) + 35);
}
Ok(Signature {
r: resp.signature_r().into(),
v: resp.signature_v().into(),
s: resp.signature_s().into(),
})
} }
} }
fn convert_signature(resp: &EthereumTxRequest, chain_id: Option<u64>) -> Result<Signature> {
let mut v = resp.signature_v() as u64;
if let Some(chain_id) = chain_id {
if v <= 1 {
v = v + 2 * chain_id + 35;
}
}
let r = resp.signature_r().try_into().map_err(|_| Error::MalformedSignature)?;
let s = resp.signature_r().try_into().map_err(|_| Error::MalformedSignature)?;
Ok(Signature { r, s, v })
}

View File

@ -15,6 +15,9 @@ pub enum Error {
/// More than one device was plugged in. /// More than one device was plugged in.
#[error("multiple Trezor devices found")] #[error("multiple Trezor devices found")]
DeviceNotUnique, DeviceNotUnique,
/// The device returned an invalid signature.
#[error("device returned invalid signature")]
MalformedSignature,
/// Transport error connecting to device. /// Transport error connecting to device.
#[error("transport connect: {0}")] #[error("transport connect: {0}")]
TransportConnect(#[source] TransportError), TransportConnect(#[source] TransportError),