diff --git a/ragger_tests/test_get_app_version.py b/ragger_tests/test_get_app_version.py index 0ad8685b..c08e5fc8 100644 --- a/ragger_tests/test_get_app_version.py +++ b/ragger_tests/test_get_app_version.py @@ -3,4 +3,4 @@ def test_get_version(backend): - assert backend.exchange(cla=CLA, ins=INS).data.hex() == "00071d" + assert backend.exchange(cla=CLA, ins=INS).data.hex() == "00071e" diff --git a/sbor/src/instruction.rs b/sbor/src/instruction.rs index f0be053c..2bd40341 100644 --- a/sbor/src/instruction.rs +++ b/sbor/src/instruction.rs @@ -1,7 +1,6 @@ /// Instructions recognized by instruction extractor -// Keep in sync with -// https://raw.githubusercontent.com/radixdlt/radixdlt-scrypto/develop/transaction/src/model/instruction.rs - +/// Keep in sync with +/// https://raw.githubusercontent.com/radixdlt/radixdlt-scrypto/develop/transaction/src/model/instruction.rs #[repr(u8)] #[derive(Copy, Clone, Debug, PartialEq)] pub enum Instruction { diff --git a/sbor/src/instruction_extractor.rs b/sbor/src/instruction_extractor.rs index 3bd088be..7e78bdf0 100644 --- a/sbor/src/instruction_extractor.rs +++ b/sbor/src/instruction_extractor.rs @@ -1,7 +1,7 @@ -/// Process events received from SBOR decoder and extract data related to each instruction -/// and its parameters. -/// Implemented as a state machine which "walks" through the transaction intent and when it reaches -/// the instructions it starts emitting relevant events. +//! Process events received from SBOR decoder and extract data related to each instruction +//! and its parameters. +//! Implemented as a state machine which "walks" through the transaction intent and when it reaches +//! the instructions it starts emitting relevant events. use crate::instruction::{to_instruction, InstructionInfo}; use crate::sbor_decoder::SborEvent; use crate::type_info::{to_type_info, TypeInfo, TYPE_ENUM, TYPE_NONE, TYPE_TUPLE}; diff --git a/sbor/src/math/decimal.rs b/sbor/src/math/decimal.rs index caa17a40..63e76d7c 100644 --- a/sbor/src/math/decimal.rs +++ b/sbor/src/math/decimal.rs @@ -3,10 +3,10 @@ use simple_bigint::bigint::{BigInt, BigIntError}; use crate::math::format_big_int; use crate::static_vec::StaticVec; +/// Ledger app-specific counterpart of the Scrypto Decimal type #[derive(Copy, Clone, Debug)] pub struct Decimal(BigInt<192>); -/// Ledger app-specific counterpart of the Scrypto Decimal type impl Decimal { pub const SIZE_IN_BYTES: usize = BigInt::<192>::NUM_BYTES; pub const ZERO: Decimal = Decimal(BigInt::from_limbs([0, 0, 0, 0, 0, 0])); diff --git a/sbor/src/math/precise_decimal.rs b/sbor/src/math/precise_decimal.rs index 24fd4b96..2d1097ae 100644 --- a/sbor/src/math/precise_decimal.rs +++ b/sbor/src/math/precise_decimal.rs @@ -3,10 +3,10 @@ use simple_bigint::bigint::{BigInt, BigIntError}; use crate::math::format_big_int; use crate::static_vec::StaticVec; +/// Ledger app-specific counterpart of the Scrypto PreciseDecimal type #[derive(Copy, Clone)] pub struct PreciseDecimal(BigInt<256>); -/// Ledger app-specific counterpart of the Scrypto PreciseDecimal type impl PreciseDecimal { pub const SIZE_IN_BYTES: usize = BigInt::<256>::NUM_BYTES; pub const SCALE: usize = 36; diff --git a/sbor/src/print/state.rs b/sbor/src/print/state.rs index 803c1604..7833de94 100644 --- a/sbor/src/print/state.rs +++ b/sbor/src/print/state.rs @@ -60,11 +60,14 @@ pub const TITLE_SIZE: usize = 32; pub struct ParameterPrinterState { pub display: StaticVec, pub data: StaticVec, - pub title: StaticVec, // Intermediate buffer for formatting instruction titles (instruction number) + /// Intermediate buffer for formatting instruction titles (instruction number) + pub title: StaticVec, pub stack: StaticVec, - pub nesting_level: u8, // Active nesting level in the stack + /// Active nesting level in the stack + pub nesting_level: u8, pub network_id: NetworkId, - pub show_instructions: bool, // Whether to show instructions or not + /// Whether to show instructions or not + pub show_instructions: bool, tty: TTY, } diff --git a/sbor/src/print/tx_summary_detector.rs b/sbor/src/print/tx_summary_detector.rs index d86d9f47..c4fa7f4d 100644 --- a/sbor/src/print/tx_summary_detector.rs +++ b/sbor/src/print/tx_summary_detector.rs @@ -1,8 +1,8 @@ -/// Transaction summary detector is used to determine the type of the transaction intent and collect -/// information about fees. -/// Implementation consists of two independent state machines - one for detecting the intent type and -/// other to collect fee information. Both of them use information about decoded instructions -/// received from `InstructionExtractor`. +//! Transaction summary detector is used to determine the type of the transaction intent and collect +//! information about fees. +//! Implementation consists of two independent state machines - one for detecting the intent type and +//! other to collect fee information. Both of them use information about decoded instructions +//! received from `InstructionExtractor`. use crate::bech32::address::Address; use crate::instruction::{Instruction, InstructionInfo}; use crate::instruction_extractor::ExtractorEvent; @@ -52,10 +52,14 @@ pub enum DecodingPhase { #[derive(Copy, Clone, Debug)] pub struct TransferDetails { pub fee: Option, - pub src_address: Address, // From ... - pub dst_address: Address, // To ... - pub res_address: Address, // Resource ... - pub amount: Decimal, // Amount ... + /// From ... + pub src_address: Address, + /// To ... + pub dst_address: Address, + /// Resource ... + pub res_address: Address, + /// Amount ... + pub amount: Decimal, } #[derive(Copy, Clone, Debug)] diff --git a/sbor/src/sbor_decoder.rs b/sbor/src/sbor_decoder.rs index b25988d7..00e636c6 100644 --- a/sbor/src/sbor_decoder.rs +++ b/sbor/src/sbor_decoder.rs @@ -1,4 +1,4 @@ -/// Streaming decoder for SBOR format +//! Streaming decoder for SBOR format use crate::decoder_error::DecoderError; use crate::type_info::*; use core::option::Option::{None, Some}; @@ -8,7 +8,8 @@ use core::result::Result::{Err, Ok}; /// Maximal nesting depth of the SBOR-encoded data pub const STACK_DEPTH: u8 = 25; -pub const SBOR_LEADING_BYTE: u8 = 0x4d; // MANIFEST_SBOR_V1_PAYLOAD_PREFIX +/// See MANIFEST_SBOR_V1_PAYLOAD_PREFIX in Scrypto +pub const SBOR_LEADING_BYTE: u8 = 0x4d; /// Compact representation of the decoder flags /// - Skip start/end: Skip reporting start/end events for each element of the array diff --git a/simple-bigint/src/bcd.rs b/simple-bigint/src/bcd.rs index 5ae55a46..34361a89 100644 --- a/simple-bigint/src/bcd.rs +++ b/simple-bigint/src/bcd.rs @@ -2,8 +2,7 @@ use crate::ceil_div; /// Implementation of the simple BCD convertor/accumulator /// Algorithm is a quite straightforward implementation of the double-dabble algorithm. -/// https://en.wikipedia.org/wiki/Double_dabble - +/// /// N - corresponds to number of bits of the equivalent binary representation /// Actual storage is 4/3 of the N because BCD representation is less dense than binary. #[derive(Copy, Clone)] diff --git a/src/sign/sign_mode.rs b/src/sign/sign_mode.rs index dd53573b..fcd056bb 100644 --- a/src/sign/sign_mode.rs +++ b/src/sign/sign_mode.rs @@ -17,7 +17,33 @@ pub enum SignMode { PreAuthRawSecp256k1, } +#[repr(u8)] +#[derive(PartialEq, Copy, Clone)] +pub enum SignType { + None, + Verbose, + Summary, +} + +#[repr(u8)] +#[derive(PartialEq, Copy, Clone)] +pub enum ReviewType { + Transaction, + OwnershipProof, + PreAuthHash, + PreAuthRaw, +} + impl SignMode { + pub fn requires_blind_signing(&self) -> bool { + match self { + SignMode::PreAuthHashEd25519 + | SignMode::PreAuthRawEd25519 + | SignMode::PreAuthHashSecp256k1 + | SignMode::PreAuthRawSecp256k1 => true, + _ => false, + } + } pub fn curve(&self) -> Curve { match self { SignMode::TxEd25519Verbose @@ -33,6 +59,28 @@ impl SignMode { } } + pub fn sign_type(&self) -> SignType { + match self { + SignMode::TxEd25519Verbose | SignMode::TxSecp256k1Verbose => SignType::Verbose, + SignMode::TxEd25519Summary | SignMode::TxSecp256k1Summary => SignType::Summary, + _ => SignType::None, + } + } + + pub fn review_type(&self) -> ReviewType { + match self { + SignMode::TxEd25519Verbose + | SignMode::TxSecp256k1Verbose + | SignMode::TxEd25519Summary + | SignMode::TxSecp256k1Summary => ReviewType::Transaction, + SignMode::AuthEd25519 | SignMode::AuthSecp256k1 => ReviewType::OwnershipProof, + SignMode::PreAuthHashEd25519 | SignMode::PreAuthHashSecp256k1 => { + ReviewType::PreAuthHash + } + SignMode::PreAuthRawEd25519 | SignMode::PreAuthRawSecp256k1 => ReviewType::PreAuthRaw, + } + } + pub fn shows_instructions(&self) -> bool { match self { SignMode::TxSecp256k1Summary diff --git a/src/sign/tx_state.rs b/src/sign/tx_state.rs index d80bd2f2..8550e185 100644 --- a/src/sign/tx_state.rs +++ b/src/sign/tx_state.rs @@ -12,10 +12,11 @@ use crate::command_class::CommandClass; use crate::settings::Settings; use crate::sign::decoding_mode::DecodingMode; use crate::sign::instruction_processor::InstructionProcessor; -use crate::sign::sign_mode::SignMode; +use crate::sign::sign_mode::{SignMode, SignType}; use crate::sign::sign_outcome::SignOutcome; use crate::xui::{ - auth_details, fee, hash, introductory_screen, pre_auth_hash_details, signature, transfer, + auth_details, blind_signing, fee, hash, introductory_screen, pre_auth_hash_details, signature, + transfer, }; const AUTH_CHALLENGE_LENGTH: usize = 32; @@ -87,7 +88,13 @@ impl TxState { self.processor.process_sign(comm, class, sign_mode)?; self.processor.set_network()?; self.processor.set_show_instructions(); - introductory_screen::display(sign_mode)?; + + if sign_mode.requires_blind_signing() && !Settings::get().blind_signing { + blind_signing::error(); + return Err(AppError::BadTxSignHashSignState); + } + + introductory_screen::display(sign_mode.review_type())?; } else { self.processor.process_sign(comm, class, sign_mode)?; @@ -170,7 +177,7 @@ impl TxState { sign_mode: SignMode, ) -> Result { let digest = self.processor.finalize()?; - self.display_tx_info(sign_mode, &digest)?; + self.display_tx_info(sign_mode.sign_type(), &digest)?; let rc = signature::ask_user(signature::SignType::TX); @@ -251,16 +258,16 @@ impl TxState { } } - fn display_tx_info(&mut self, sign_mode: SignMode, digest: &Digest) -> Result<(), AppError> { + fn display_tx_info(&mut self, sign_type: SignType, digest: &Digest) -> Result<(), AppError> { let detected_type = self.processor.get_detected_tx_type(); - match sign_mode { - SignMode::TxEd25519Verbose | SignMode::TxSecp256k1Verbose => { + match sign_type { + SignType::Verbose => { self.display_transaction_fee(&detected_type); Ok(()) } - SignMode::TxEd25519Summary | SignMode::TxSecp256k1Summary => match detected_type { + SignType::Summary => match detected_type { DetectedTxType::Transfer(details) => { transfer::display(&details, &mut self.processor); @@ -272,18 +279,13 @@ impl TxState { Ok(()) } else { - hash::error(); + blind_signing::error(); Err(AppError::BadTxSignHashSignState) } } }, - SignMode::AuthEd25519 - | SignMode::AuthSecp256k1 - | SignMode::PreAuthHashEd25519 - | SignMode::PreAuthHashSecp256k1 - | SignMode::PreAuthRawEd25519 - | SignMode::PreAuthRawSecp256k1 => Ok(()), + _ => Ok(()), } } diff --git a/src/xui.rs b/src/xui.rs index 3701aafc..5f90037f 100644 --- a/src/xui.rs +++ b/src/xui.rs @@ -1,5 +1,6 @@ pub mod address; pub mod auth_details; +pub mod blind_signing; pub mod fee; pub mod hash; pub mod introductory_screen; diff --git a/src/xui/blind_signing.rs b/src/xui/blind_signing.rs new file mode 100644 index 00000000..795ae946 --- /dev/null +++ b/src/xui/blind_signing.rs @@ -0,0 +1,9 @@ +use crate::xui::titled_message; + +#[cfg(not(target_os = "stax"))] +pub fn error() { + titled_message::display_error("\nBlind signing must\nbe enabled in Settings"); +} + +#[cfg(target_os = "stax")] +pub fn error() {} diff --git a/src/xui/hash.rs b/src/xui/hash.rs index e7948f14..ae0d37e6 100644 --- a/src/xui/hash.rs +++ b/src/xui/hash.rs @@ -15,10 +15,6 @@ pub fn display( fee::display(fee, processor); } } -#[cfg(not(target_os = "stax"))] -pub fn error() { - titled_message::display_error("\nBlind signing must\nbe enabled in Settings"); -} #[cfg(target_os = "stax")] pub fn display( @@ -27,5 +23,3 @@ pub fn display( processor: &mut InstructionProcessor, ) { } -#[cfg(target_os = "stax")] -pub fn error() {} diff --git a/src/xui/introductory_screen.rs b/src/xui/introductory_screen.rs index 22c17c28..dd4443be 100644 --- a/src/xui/introductory_screen.rs +++ b/src/xui/introductory_screen.rs @@ -1,19 +1,14 @@ use crate::app_error::AppError; -use crate::sign::sign_mode::SignMode; +use crate::sign::sign_mode::{ReviewType, SignMode}; use crate::ui::single_message::SingleMessage; #[cfg(not(target_os = "stax"))] -pub fn display(sign_mode: SignMode) -> Result<(), AppError> { - let text = match sign_mode { - SignMode::TxEd25519Verbose - | SignMode::TxSecp256k1Verbose - | SignMode::TxEd25519Summary - | SignMode::TxSecp256k1Summary => "Review\n\nTransaction", - SignMode::AuthEd25519 | SignMode::AuthSecp256k1 => "Review\nOwnership\nProof", - SignMode::PreAuthHashEd25519 | SignMode::PreAuthHashSecp256k1 => { - "Review\nPre-authorization\nHash" - } - SignMode::PreAuthRawEd25519 | SignMode::PreAuthRawSecp256k1 => "Review\nPre-authorization", +pub fn display(review_type: ReviewType) -> Result<(), AppError> { + let text = match review_type { + ReviewType::Transaction => "Review\n\nTransaction", + ReviewType::OwnershipProof => "Review\nOwnership\nProof", + ReviewType::PreAuthHash => "Review\nPre-authorization\nHash", + ReviewType::PreAuthRaw => "Review\nPre-authorization", }; SingleMessage::with_right_arrow(text).show_and_wait(); diff --git a/test/test-get-application-version.py b/test/test-get-application-version.py index 5d18c583..396d7970 100755 --- a/test/test-get-application-version.py +++ b/test/test-get-application-version.py @@ -23,5 +23,5 @@ print("Testing", "GetAppVersion", instructionCode, end=" ") response = dongle.exchange(bytes.fromhex(instructionClass + instructionCode + p1 + p2 + dataLength)) -assert response.hex() == '00071d', "Invalid version\nReceived:" + response.hex() +assert response.hex() == '00071e', "Invalid version\nReceived:" + response.hex() print("Success")