From 21812665d18544d09e1eab426dc60870431afb25 Mon Sep 17 00:00:00 2001 From: ZhenQian Date: Tue, 8 Oct 2024 18:06:16 +0800 Subject: [PATCH 01/16] feat: add ada usb sign tx support --- src/ui/gui_chain/gui_chain.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ui/gui_chain/gui_chain.c b/src/ui/gui_chain/gui_chain.c index 4456d561d..e4ee51bc5 100644 --- a/src/ui/gui_chain/gui_chain.c +++ b/src/ui/gui_chain/gui_chain.c @@ -15,6 +15,10 @@ bool CheckViewTypeIsAllow(uint8_t viewType) case REMAPVIEW_SUI_SIGN_MESSAGE_HASH: case REMAPVIEW_ADA_SIGN_TX_HASH: return true; + case REMAPVIEW_ADA: + case REMAPVIEW_ADA_SIGN_DATA: + case REMAPVIEW_ADA_CATALYST: + return true; default: return false; } @@ -129,7 +133,6 @@ GuiChainCoinType ViewTypeToChainTypeSwitch(uint8_t ViewType) } return CHAIN_BUTT; } - #ifndef BTC_ONLY bool IsMessageType(uint8_t type) { From 98ea0640d405341fc31334bc6dfcd66b2e3c8c59 Mon Sep 17 00:00:00 2001 From: ZhenQian Date: Wed, 9 Oct 2024 11:20:38 +0800 Subject: [PATCH 02/16] feat: add ada sign tx unlimited support --- rust/rust_c/src/cardano/src/lib.rs | 80 +++++++++++++++++++++++++++--- src/tasks/data_parser_task.c | 2 +- src/ui/gui_chain/gui_chain.c | 2 +- src/ui/gui_chain/others/gui_ada.c | 31 ++++++++++++ src/ui/gui_chain/others/gui_ada.h | 1 + 5 files changed, 107 insertions(+), 9 deletions(-) diff --git a/rust/rust_c/src/cardano/src/lib.rs b/rust/rust_c/src/cardano/src/lib.rs index 85f15025a..77f2384d6 100644 --- a/rust/rust_c/src/cardano/src/lib.rs +++ b/rust/rust_c/src/cardano/src/lib.rs @@ -35,7 +35,7 @@ use common_rust_c::errors::{RustCError, R}; use common_rust_c::extract_ptr_with_type; use common_rust_c::structs::{SimpleResponse, TransactionCheckResult, TransactionParseResult}; use common_rust_c::types::{Ptr, PtrBytes, PtrString, PtrT, PtrUR}; -use common_rust_c::ur::{UREncodeResult, FRAGMENT_MAX_LENGTH_DEFAULT}; +use common_rust_c::ur::{UREncodeResult, FRAGMENT_MAX_LENGTH_DEFAULT, FRAGMENT_UNLIMITED_LENGTH}; use common_rust_c::utils::{convert_c_char, recover_c_char}; use ur_registry::registry_types::{ CARDANO_CATALYST_VOTING_REGISTRATION_SIGNATURE, CARDANO_SIGNATURE, CARDANO_SIGN_DATA_SIGNATURE, @@ -505,7 +505,29 @@ pub extern "C" fn cardano_sign_tx_with_ledger_bitbox02( Err(e) => UREncodeResult::from(e).c_ptr(), } } +#[no_mangle] +pub extern "C" fn cardano_sign_tx_with_ledger_bitbox02_unlimited( + ptr: PtrUR, + master_fingerprint: PtrBytes, + cardano_xpub: PtrString, + mnemonic: PtrString, + passphrase: PtrString, +) -> PtrT { + let mnemonic = recover_c_char(mnemonic); + let passphrase = recover_c_char(passphrase); + let master_key = + keystore::algorithms::ed25519::bip32_ed25519::get_ledger_bitbox02_master_key_by_mnemonic( + passphrase.as_bytes(), + mnemonic, + ); + match master_key { + Ok(master_key) => { + cardano_sign_tx_by_icarus_unlimited(ptr, master_fingerprint, cardano_xpub, master_key) + } + Err(e) => UREncodeResult::from(e).c_ptr(), + } +} #[no_mangle] pub extern "C" fn cardano_sign_tx( ptr: PtrUR, @@ -542,11 +564,57 @@ fn cardano_sign_tx_hash_by_icarus(ptr: PtrUR, icarus_master_key: XPrv) -> PtrT PtrT { + let entropy = unsafe { alloc::slice::from_raw_parts(entropy, entropy_len as usize) }; + let passphrase = recover_c_char(passphrase); + let icarus_master_key = calc_icarus_master_key(entropy, passphrase.as_bytes()); + cardano_sign_tx_by_icarus_unlimited(ptr, master_fingerprint, cardano_xpub, icarus_master_key) +} + fn cardano_sign_tx_by_icarus( ptr: PtrUR, master_fingerprint: PtrBytes, cardano_xpub: PtrString, icarus_master_key: XPrv, +) -> PtrT { + cardano_sign_tx_by_icarus_dynamic( + ptr, + master_fingerprint, + cardano_xpub, + icarus_master_key, + FRAGMENT_MAX_LENGTH_DEFAULT.clone(), + ) +} + +fn cardano_sign_tx_by_icarus_unlimited( + ptr: PtrUR, + master_fingerprint: PtrBytes, + cardano_xpub: PtrString, + icarus_master_key: XPrv, +) -> PtrT { + cardano_sign_tx_by_icarus_dynamic( + ptr, + master_fingerprint, + cardano_xpub, + icarus_master_key, + FRAGMENT_UNLIMITED_LENGTH.clone(), + ) +} + +fn cardano_sign_tx_by_icarus_dynamic( + ptr: PtrUR, + master_fingerprint: PtrBytes, + cardano_xpub: PtrString, + icarus_master_key: XPrv, + fragment_length: usize, ) -> PtrT { let cardano_sign_reqeust = extract_ptr_with_type!(ptr, CardanoSignRequest); let tx_hex = cardano_sign_reqeust.get_sign_data(); @@ -561,12 +629,10 @@ fn cardano_sign_tx_by_icarus( ); match sign_result { Ok(d) => match d { - Ok(data) => UREncodeResult::encode( - data, - CARDANO_SIGNATURE.get_type(), - FRAGMENT_MAX_LENGTH_DEFAULT.clone(), - ) - .c_ptr(), + Ok(data) => { + UREncodeResult::encode(data, CARDANO_SIGNATURE.get_type(), fragment_length) + .c_ptr() + } Err(e) => UREncodeResult::from(e).c_ptr(), }, Err(e) => UREncodeResult::from(e).c_ptr(), diff --git a/src/tasks/data_parser_task.c b/src/tasks/data_parser_task.c index 105e96cae..a89edd1b5 100644 --- a/src/tasks/data_parser_task.c +++ b/src/tasks/data_parser_task.c @@ -92,7 +92,7 @@ void CreateDataParserTask(void) { const osThreadAttr_t dataParserTask_attributes = { .name = "data_parser_task", - .stack_size = 1024 * 8, + .stack_size = 1024 * 16, .priority = (osPriority_t)osPriorityHigh, }; g_dataParserHandle = osThreadNew(DataParserTask, NULL, &dataParserTask_attributes); diff --git a/src/ui/gui_chain/gui_chain.c b/src/ui/gui_chain/gui_chain.c index e4ee51bc5..37f7b50e3 100644 --- a/src/ui/gui_chain/gui_chain.c +++ b/src/ui/gui_chain/gui_chain.c @@ -202,7 +202,7 @@ static GenerateUR UrGenerator(ViewType viewType, bool isMulti) func = GuiGetAdaSignCatalystVotingRegistrationQrCodeData; break; case CardanoTx: - func = GuiGetAdaSignQrCodeData; + func = isMulti ? GuiGetAdaSignQrCodeData : GuiGetAdaSignUrDataUnlimited; break; case XRPTx: func = GuiGetXrpSignQrCodeData; diff --git a/src/ui/gui_chain/others/gui_ada.c b/src/ui/gui_chain/others/gui_ada.c index b2f5f1c11..75ebb0d1a 100644 --- a/src/ui/gui_chain/others/gui_ada.c +++ b/src/ui/gui_chain/others/gui_ada.c @@ -903,6 +903,37 @@ void GuiShowAdaSignTxHashDetails(lv_obj_t *parent, void *totalData) } + +UREncodeResult *GuiGetAdaSignUrDataUnlimited(void) +{ + bool enable = IsPreviousLockScreenEnable(); + SetLockScreen(false); + UREncodeResult *encodeResult; + uint8_t mfp[4]; + GetMasterFingerPrint(mfp); + + void *data = g_isMulti ? g_urMultiResult->data : g_urResult->data; + do { + uint8_t entropy[64]; + uint8_t len = 0; + GetAccountEntropy(GetCurrentAccountIndex(), entropy, &len, SecretCacheGetPassword()); + if (GetAdaXPubType() == LEDGER_ADA) { + char *mnemonic = NULL; + bip39_mnemonic_from_bytes(NULL, entropy, len, &mnemonic); + encodeResult = cardano_sign_tx_with_ledger_bitbox02_unlimited(data, mfp, xpub, mnemonic, GetPassphrase(GetCurrentAccountIndex())); + } else { + encodeResult = cardano_sign_tx_unlimited(data, mfp, xpub, entropy, len, GetPassphrase(GetCurrentAccountIndex())); + } + ClearSecretCache(); + CHECK_CHAIN_BREAK(encodeResult); + } while (0); + SetLockScreen(enable); + return encodeResult; +} + + + + ChainType GetAdaXPubTypeByIndexAndDerivationType(AdaXPubType type, uint16_t index) { switch (index) { diff --git a/src/ui/gui_chain/others/gui_ada.h b/src/ui/gui_chain/others/gui_ada.h index 17b9a0912..17f6dc5d8 100644 --- a/src/ui/gui_chain/others/gui_ada.h +++ b/src/ui/gui_chain/others/gui_ada.h @@ -59,6 +59,7 @@ void FreeAdaCatalystMemory(void); void FreeAdaSignTxHashMemory(void); char *GuiGetADABaseAddressByXPub(char *xPub); UREncodeResult *GuiGetAdaSignQrCodeData(void); +UREncodeResult *GuiGetAdaSignUrDataUnlimited(void); UREncodeResult *GuiGetAdaSignSignDataQrCodeData(void); UREncodeResult *GuiGetAdaSignCatalystVotingRegistrationQrCodeData(void); From 0046484449e3a2a761239fe85d2cccb528c034dd Mon Sep 17 00:00:00 2001 From: ZhenQian Date: Tue, 15 Oct 2024 18:38:02 +0800 Subject: [PATCH 03/16] chore: add cardano sign cip8 data unit test case --- rust/rust_c/src/cardano/src/lib.rs | 59 ++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/rust/rust_c/src/cardano/src/lib.rs b/rust/rust_c/src/cardano/src/lib.rs index 77f2384d6..781cf9dfc 100644 --- a/rust/rust_c/src/cardano/src/lib.rs +++ b/rust/rust_c/src/cardano/src/lib.rs @@ -714,7 +714,12 @@ fn get_cardano_derivation_path(path: CryptoKeyPath) -> R { #[cfg(test)] mod tests { use super::*; + use address::cardano_get_base_address; use alloc::vec; + use app_cardano::address::AddressType; + use keystore::algorithms::ed25519::bip32_ed25519::derive_extended_privkey_by_xprv; + use bitcoin::bip32::Xpriv ; + use ur_registry::crypto_key_path::PathComponent; use ur_registry::crypto_key_path::PathComponent; #[test] @@ -735,4 +740,58 @@ mod tests { assert_eq!(result.unwrap().get_path().unwrap(), "2/0"); } + + #[test] + fn test_sign_data() { + let payload = hex::encode("hello world"); + let expected_message_hash = "42d1854b7d69e3b57c64fcc7b4f64171b47dff43fba6ac0499ff437f"; + let message_hash = hex::encode(cryptoxide::hashing::blake2b_224( + hex::decode(&payload).unwrap().as_slice(), + )); + assert_eq!(expected_message_hash, message_hash); + let master_key_expected = "402b03cd9c8bed9ba9f9bd6cd9c315ce9fcc59c7c25d37c85a36096617e69d418e35cb4a3b737afd007f0688618f21a8831643c0e6c77fc33c06026d2a0fc93832596435e70647d7d98ef102a32ea40319ca8fb6c851d7346d3bd8f9d1492658"; + let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"; + let passphrase = ""; + let master_key = + keystore::algorithms::ed25519::bip32_ed25519::get_ledger_bitbox02_master_key_by_mnemonic( + passphrase.as_bytes(), + mnemonic.to_string(), + ).unwrap(); + assert_eq!(master_key_expected, hex::encode(master_key.as_ref())); + let bip32_signing_key = + keystore::algorithms::ed25519::bip32_ed25519::derive_extended_privkey_by_icarus_master_key( + &master_key.as_ref(), + &"m/1852'/1815'/0'".to_string(), + ) + .unwrap(); + // assert_eq!( + // hex::encode(bip32_signing_key.public().public_key().to_vec()), + // "cd2b047d1a803eee059769cffb3dfd0a4b9327e55bc78aa962d9bd4f720db0b2" + // ); + // assert_eq!( + // hex::encode(bip32_signing_key.chain_code()), + // "914ba07fb381f23c5c09bce26587bdf359aab7ea8f4192adbf93a38fd893ccea" + // ); + // 5840cd2b047d1a803eee059769cffb3dfd0a4b9327e55bc78aa962d9bd4f720db0b2914ba07fb381f23c5c09bce26587bdf359aab7ea8f4192adbf93a38fd893ccea + // cd2b047d1a803eee059769cffb3dfd0a4b9327e55bc78aa962d9bd4f720db0b2914ba07fb381f23c5c09bce26587bdf359aab7ea8f4192adbf93a38fd893ccea + let xpub = bip32_signing_key.public(); + let real_testnet_xpub = "0d94fa4489745249e9cd999c907f2692e0e5c7ac868a960312ed5d480c59f2dc231adc1ee85703f714abe70c6d95f027e76ee947f361cbb72a155ac8cad6d23f".to_string(); + assert_eq!(real_testnet_xpub, hex::encode(xpub.as_ref())); + let address = + app_cardano::address::derive_address(real_testnet_xpub, 0, 0, 0, AddressType::Base, 0) + .unwrap(); + assert_eq!("addr_test1qq2vzmtlgvjrhkq50rngh8d482zj3l20kyrc6kx4ffl3zfqayfawlf9hwv2fzuygt2km5v92kvf8e3s3mk7ynxw77cwq2glhm4", address); + + let private_key = + derive_extended_privkey_by_xprv(&bip32_signing_key, &"0/0".to_string()).unwrap(); + assert_eq!("00e931ab7c17c922c5e905d46991cb590818f49eb39922a15018fc2124e69d41b3c7dfec8d2c21667419404ce6fe0fe6bc9e8e2b361487a59313bb9a0b2322cd", hex::encode(private_key.extended_secret_key_bytes())); + let result = app_cardano::transaction::sign_data( + &"m/1852'/1815'/0'/0/0".to_string(), + &message_hash, + master_key, + ) + .unwrap(); + let signature = hex::encode(result.get_signature()); + assert_eq!(signature,"56ebf5bbea63aafbf1440cd63c5fbcbe3de799de401d48165a366e10f36c17b490c261ea8a00cf464cf7140732369cc4e333eb6714cabe625abddac1cd9dd20b"); + } } From 1e55ce52966a3cdca9370efb60f7b81da0f4a691 Mon Sep 17 00:00:00 2001 From: ZhenQian Date: Fri, 18 Oct 2024 16:07:31 +0800 Subject: [PATCH 04/16] feat: add cardano sign cip8 data support --- rust/apps/cardano/src/structs.rs | 48 ++++ rust/apps/cardano/src/transaction.rs | 14 +- .../src/cardano/src/cip8_cbor_data_ledger.rs | 70 ++++++ rust/rust_c/src/cardano/src/lib.rs | 238 ++++++++++++++++-- rust/rust_c/src/cardano/src/structs.rs | 15 +- rust/rust_c/src/common/src/ur.rs | 22 ++ rust/rust_c/src/common/src/ur_ext.rs | 9 + src/ui/gui_analyze/gui_analyze.c | 1 + src/ui/gui_chain/gui_chain.c | 6 +- src/ui/gui_chain/others/gui_ada.c | 29 +++ src/ui/gui_chain/others/gui_ada.h | 1 + 11 files changed, 434 insertions(+), 19 deletions(-) create mode 100644 rust/rust_c/src/cardano/src/cip8_cbor_data_ledger.rs diff --git a/rust/apps/cardano/src/structs.rs b/rust/apps/cardano/src/structs.rs index 03408dadd..6308e4a40 100644 --- a/rust/apps/cardano/src/structs.rs +++ b/rust/apps/cardano/src/structs.rs @@ -1,9 +1,12 @@ use crate::address::{derive_address, derive_pubkey_hash, AddressType}; use crate::errors::{CardanoError, R}; use alloc::collections::BTreeMap; +use alloc::format; use alloc::string::{String, ToString}; use alloc::vec; use alloc::vec::Vec; +use core::ops::Div; + use app_utils::{impl_internal_struct, impl_public_struct}; use cardano_serialization_lib::protocol_types::{ self, Address, BaseAddress, EnterpriseAddress, RewardAddress, @@ -55,6 +58,14 @@ impl_public_struct!(ParsedCardanoSignData { xpub: String }); +impl_public_struct!(ParsedCardanoSignCip8Data { + payload: String, + derivation_path: String, + message_hash: String, + xpub: String, + hash_payload: bool +}); + impl_public_struct!(VotingProcedure { voter: String, transaction_id: String, @@ -200,6 +211,43 @@ impl ParsedCardanoSignData { } } +impl ParsedCardanoSignCip8Data { + pub fn build( + sign_data: Vec, + derivation_path: String, + xpub: String, + hash_payload: bool, + ) -> R { + let sign_structure = CardanoSignStructure::from_cbor(sign_data.clone()); + match sign_structure { + Ok(sign_structure) => { + let raw_payload = sign_structure.get_payload(); + let mut payload = String::from_utf8(hex::decode(raw_payload.clone()).unwrap()) + .unwrap_or_else(|_| raw_payload.clone()); + let mut message_hash = hex::encode(raw_payload); + if hash_payload { + let hash = blake2b_224(payload.as_bytes()); + message_hash = hex::encode(hash); + } + Ok(Self { + payload, + derivation_path, + message_hash, + xpub, + hash_payload, + }) + } + Err(e) => Ok(Self { + payload: hex::encode(sign_data.clone()), + derivation_path, + message_hash: hex::encode(sign_data), + xpub, + hash_payload, + }), + } + } +} + impl ParsedCardanoTx { pub fn from_cardano_tx(tx: Transaction, context: ParseContext) -> R { let network_id = Self::judge_network_id(&tx); diff --git a/rust/apps/cardano/src/transaction.rs b/rust/apps/cardano/src/transaction.rs index c5970141c..c25ae7ab4 100644 --- a/rust/apps/cardano/src/transaction.rs +++ b/rust/apps/cardano/src/transaction.rs @@ -1,5 +1,8 @@ -use crate::errors::{CardanoError, R}; use crate::structs::{ParseContext, ParsedCardanoSignData, ParsedCardanoTx, SignDataResult}; +use crate::{ + errors::{CardanoError, R}, + structs::ParsedCardanoSignCip8Data, +}; use alloc::collections::BTreeMap; use alloc::string::{String, ToString}; use alloc::vec::Vec; @@ -23,6 +26,15 @@ pub fn parse_sign_data( ParsedCardanoSignData::build(sign_data, derviation_path, xpub) } +pub fn parse_sign_cip8_data( + sign_data: Vec, + derviation_path: String, + xpub: String, + hash_payload: bool, +) -> R { + ParsedCardanoSignCip8Data::build(sign_data, derviation_path, xpub, hash_payload) +} + pub fn check_tx(tx: Vec, context: ParseContext) -> R<()> { let cardano_tx = cardano_serialization_lib::protocol_types::FixedTransaction::from_bytes(tx)?; ParsedCardanoTx::verify(cardano_tx, context) diff --git a/rust/rust_c/src/cardano/src/cip8_cbor_data_ledger.rs b/rust/rust_c/src/cardano/src/cip8_cbor_data_ledger.rs new file mode 100644 index 000000000..4cc54fafb --- /dev/null +++ b/rust/rust_c/src/cardano/src/cip8_cbor_data_ledger.rs @@ -0,0 +1,70 @@ +use alloc::vec::Vec; +// follow the ledger signMessage logic +// https://github.com/LedgerHQ/app-cardano/blob/develop/src/signMsg.c#L328 +use minicbor::encode::Write; +use minicbor::Encoder; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct CardanoCip8SigStructureLedgerType { + pub address_field: Vec, + pub payload: Vec, +} +// protectedHeader = { +// 1 : -8, // set algorithm to EdDSA +// “address” : address_bytes // raw address given by the user, or key hash +// } +fn create_protected_header(address_field_bytes: &[u8]) -> Vec { + let mut buffer = Vec::new(); + let mut e = Encoder::new(&mut buffer); + e.map(2).unwrap(); + e.i8(1).unwrap(); + e.i8(-8).unwrap(); + e.str("address").unwrap(); + e.bytes(address_field_bytes).unwrap(); + buffer +} + +// Sig_structure = [ +// context : “Signature1”, +// body_protected : CBOR_encode(protectedHeader), +// external_aad : bstr, // empty buffer here +// payload : bstr // message or its hash as bytes +// ] +impl minicbor::Encode for CardanoCip8SigStructureLedgerType { + fn encode( + &self, + e: &mut Encoder, + _ctx: &mut C, + ) -> Result<(), minicbor::encode::Error> { + e.array(4)?; + e.str("Signature1")?; + let protected_header = create_protected_header(&self.address_field); + e.bytes(&protected_header)?; + e.bytes(&[])?; + e.bytes(&self.payload)?; + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use third_party::hex; + #[test] + fn test1() { + // Signature1 + // A20127676164647265737358390014C16D7F43243BD81478E68B9DB53A8528FD4FB1078D58D54A7F11241D227AEFA4B773149170885AADBA30AAB3127CC611DDBC4999DEF61C + // [] + // 42D1854B7D69E3B57C64FCC7B4F64171B47DFF43FBA6AC0499FF437F + let cardano_address_hex = hex::decode("0014c16d7f43243bd81478e68b9db53a8528fd4fb1078d58d54a7f11241d227aefa4b773149170885aadba30aab3127cc611ddbc4999def61c".to_uppercase()).unwrap(); + // payload = blake2b(messageHex) + let data = CardanoCip8SigStructureLedgerType { + address_field: cardano_address_hex, + payload: hex::decode("42D1854B7D69E3B57C64FCC7B4F64171B47DFF43FBA6AC0499FF437F") + .unwrap(), + }; + let encoded = minicbor::to_vec(data).unwrap(); + let encoded_hex = hex::encode(encoded).to_uppercase(); + assert_eq!("846A5369676E6174757265315846A20127676164647265737358390014C16D7F43243BD81478E68B9DB53A8528FD4FB1078D58D54A7F11241D227AEFA4B773149170885AADBA30AAB3127CC611DDBC4999DEF61C40581C42D1854B7D69E3B57C64FCC7B4F64171B47DFF43FBA6AC0499FF437F", encoded_hex); + } +} diff --git a/rust/rust_c/src/cardano/src/lib.rs b/rust/rust_c/src/cardano/src/lib.rs index 781cf9dfc..950ddcacd 100644 --- a/rust/rust_c/src/cardano/src/lib.rs +++ b/rust/rust_c/src/cardano/src/lib.rs @@ -9,6 +9,8 @@ use alloc::{ }; use alloc::vec::Vec; +use core::str::FromStr; + use app_cardano::address::derive_xpub_from_xpub; use app_cardano::errors::CardanoError; use app_cardano::governance; @@ -30,20 +32,20 @@ use ur_registry::cardano::cardano_sign_tx_hash_request::CardanoSignTxHashRequest use ur_registry::cardano::cardano_signature::CardanoSignature; use ur_registry::crypto_key_path::CryptoKeyPath; -use crate::structs::{DisplayCardanoCatalyst, DisplayCardanoSignData, DisplayCardanoTx}; -use common_rust_c::errors::{RustCError, R}; +use cip8_cbor_data_ledger::CardanoCip8SigStructureLedgerType; +use common_rust_c::errors::{R, RustCError}; use common_rust_c::extract_ptr_with_type; use common_rust_c::structs::{SimpleResponse, TransactionCheckResult, TransactionParseResult}; use common_rust_c::types::{Ptr, PtrBytes, PtrString, PtrT, PtrUR}; -use common_rust_c::ur::{UREncodeResult, FRAGMENT_MAX_LENGTH_DEFAULT, FRAGMENT_UNLIMITED_LENGTH}; +use common_rust_c::ur::{FRAGMENT_MAX_LENGTH_DEFAULT, FRAGMENT_UNLIMITED_LENGTH, UREncodeResult}; use common_rust_c::utils::{convert_c_char, recover_c_char}; use ur_registry::registry_types::{ CARDANO_CATALYST_VOTING_REGISTRATION_SIGNATURE, CARDANO_SIGNATURE, CARDANO_SIGN_DATA_SIGNATURE, }; pub mod address; +pub mod cip8_cbor_data_ledger; pub mod structs; - #[no_mangle] pub extern "C" fn cardano_catalyst_xpub(ptr: PtrUR) -> Ptr> { let cardano_catalyst_request = @@ -132,6 +134,20 @@ pub extern "C" fn cardano_get_sign_data_root_index(ptr: PtrUR) -> Ptr Ptr> { + let cardano_sign_data_reqeust = extract_ptr_with_type!(ptr, CardanoSignCip8DataRequest); + let derviation_path: CryptoKeyPath = cardano_sign_data_reqeust.get_derivation_path(); + match derviation_path.get_components().get(2) { + Some(_data) => { + let index = _data.get_index().unwrap(); + SimpleResponse::success(convert_c_char(index.to_string())).simple_c_ptr() + } + None => SimpleResponse::from(CardanoError::InvalidTransaction(format!("invalid path"))) + .simple_c_ptr(), + } +} + #[no_mangle] pub extern "C" fn cardano_check_sign_data_path_type( ptr: PtrUR, @@ -161,6 +177,35 @@ pub extern "C" fn cardano_check_sign_data_path_type( } } +#[no_mangle] +pub extern "C" fn cardano_check_sign_cip8_data_path_type( + ptr: PtrUR, + cardano_xpub: PtrString, +) -> PtrT { + let cardano_sign_cip8_data_reqeust = extract_ptr_with_type!(ptr, CardanoSignCip8DataRequest); + let cardano_xpub = recover_c_char(cardano_xpub); + let xpub = cardano_sign_cip8_data_reqeust.get_xpub(); + let xpub = hex::encode(xpub); + let derivation_path = + get_cardano_derivation_path(cardano_sign_cip8_data_reqeust.get_derivation_path()); + match derivation_path { + Ok(derivation_path) => match derive_xpub_from_xpub(cardano_xpub, derivation_path) { + Ok(_xpub) => { + if _xpub == xpub { + TransactionCheckResult::new().c_ptr() + } else { + TransactionCheckResult::from(RustCError::InvalidData( + "invalid xpub".to_string(), + )) + .c_ptr() + } + } + Err(e) => TransactionCheckResult::from(e).c_ptr(), + }, + Err(e) => TransactionCheckResult::from(e).c_ptr(), + } +} + #[no_mangle] pub extern "C" fn cardano_check_sign_data( ptr: PtrUR, @@ -182,6 +227,27 @@ pub extern "C" fn cardano_check_sign_data( TransactionCheckResult::new().c_ptr() } +#[no_mangle] +pub extern "C" fn cardano_check_sign_cip8_data( + ptr: PtrUR, + master_fingerprint: PtrBytes, +) -> PtrT { + let cardano_sign_cip8_data_reqeust = extract_ptr_with_type!(ptr, CardanoSignCip8DataRequest); + let mfp = unsafe { slice::from_raw_parts(master_fingerprint, 4) }; + let ur_mfp = cardano_sign_cip8_data_reqeust + .get_derivation_path() + .get_source_fingerprint() + .ok_or(RustCError::InvalidMasterFingerprint); + + if let Ok(mfp) = mfp.try_into() as Result<[u8; 4], _> { + if hex::encode(mfp) != hex::encode(ur_mfp.unwrap()) { + return TransactionCheckResult::from(RustCError::MasterFingerprintMismatch).c_ptr(); + } + } + + TransactionCheckResult::new().c_ptr() +} + #[no_mangle] pub extern "C" fn cardano_check_tx( ptr: PtrUR, @@ -303,6 +369,29 @@ pub extern "C" fn cardano_parse_sign_data( } } +#[no_mangle] +pub extern "C" fn cardano_parse_sign_cip8_data( + ptr: PtrUR, +) -> PtrT> { + let cardano_sign_cip8_data_reqeust = extract_ptr_with_type!(ptr, CardanoSignCip8DataRequest); + let sign_data = cardano_sign_cip8_data_reqeust.get_sign_data(); + let derviation_path = cardano_sign_cip8_data_reqeust + .get_derivation_path() + .get_path() + .unwrap(); + let xpub = cardano_sign_cip8_data_reqeust.get_xpub(); + let parsed_data = app_cardano::transaction::parse_sign_cip8_data( + sign_data, + derviation_path, + hex::encode(xpub), + cardano_sign_cip8_data_reqeust.get_hash_payload(), + ); + match parsed_data { + Ok(v) => TransactionParseResult::success(DisplayCardanoSignData::from(v).c_ptr()).c_ptr(), + Err(e) => TransactionParseResult::from(e).c_ptr(), + } +} + #[no_mangle] pub extern "C" fn cardano_parse_catalyst( ptr: PtrUR, @@ -425,6 +514,26 @@ pub extern "C" fn cardano_sign_sign_data_with_ledger_bitbox02( } } +#[no_mangle] +pub extern "C" fn cardano_sign_sign_cip8_data_with_ledger_bitbox02( + ptr: PtrUR, + mnemonic: PtrString, + passphrase: PtrString, +) -> PtrT { + let mnemonic = recover_c_char(mnemonic); + let passphrase = recover_c_char(passphrase); + let master_key = + keystore::algorithms::ed25519::bip32_ed25519::get_ledger_bitbox02_master_key_by_mnemonic( + passphrase.as_bytes(), + mnemonic, + ); + + match master_key { + Ok(master_key) => cardano_sign_sign_cip8_data_by_icarus(ptr, master_key), + Err(e) => UREncodeResult::from(e).c_ptr(), + } +} + #[no_mangle] pub extern "C" fn cardano_sign_sign_data( ptr: PtrUR, @@ -438,10 +547,22 @@ pub extern "C" fn cardano_sign_sign_data( cardano_sign_sign_data_by_icarus(ptr, icarus_master_key) } +#[no_mangle] +pub extern "C" fn cardano_sign_sign_cip8_data( + ptr: PtrUR, + entropy: PtrBytes, + entropy_len: u32, + passphrase: PtrString, +) -> PtrT { + let entropy = unsafe { alloc::slice::from_raw_parts(entropy, entropy_len as usize) }; + let passphrase = recover_c_char(passphrase); + let icarus_master_key = calc_icarus_master_key(entropy, passphrase.as_bytes()); + cardano_sign_sign_cip8_data_by_icarus(ptr, icarus_master_key) +} + fn cardano_sign_sign_data_by_icarus(ptr: PtrUR, icarus_master_key: XPrv) -> PtrT { let cardano_sign_data_reqeust = extract_ptr_with_type!(ptr, CardanoSignDataRequest); let sign_data = cardano_sign_data_reqeust.get_sign_data(); - let result = app_cardano::transaction::sign_data( &cardano_sign_data_reqeust .get_derivation_path() @@ -478,6 +599,87 @@ fn cardano_sign_sign_data_by_icarus(ptr: PtrUR, icarus_master_key: XPrv) -> PtrT return result; } +fn cardano_sign_sign_cip8_data_by_icarus( + ptr: PtrUR, + icarus_master_key: XPrv, +) -> PtrT { + let cardano_sign_data_reqeust = extract_ptr_with_type!(ptr, CardanoSignCip8DataRequest); + let mut sign_data = cardano_sign_data_reqeust.get_sign_data(); + // Signature1 + // A20127676164647265737358390014C16D7F43243BD81478E68B9DB53A8528FD4FB1078D58D54A7F11241D227AEFA4B773149170885AADBA30AAB3127CC611DDBC4999DEF61C40581C42D1854B7D69E3B57C64FCC7B4F64171B47DFF43FBA6AC0499FF437F + // [] + // 42D1854B7D69E3B57C64FCC7B4F64171B47DFF43FBA6AC0499FF437F + // construct cardano cip8 data using ledger style + if cardano_sign_data_reqeust.get_hash_payload() { + sign_data = blake2b_224(&sign_data).to_vec(); + } + let mut address_field = vec![]; + let address_type = cardano_sign_data_reqeust.get_address_type(); + if address_type.as_str() == "ADDRESS" { + address_field = decode( + &cardano_sign_data_reqeust + .get_address_bench32() + .unwrap() + .as_str(), + ) + .unwrap() + .1; + } else { + rust_tools::debug!(format!("address type: {}", address_type.as_str())); + let public_key = cardano_sign_data_reqeust.get_xpub(); + address_field = blake2b_224(&public_key).to_vec(); + } + + let cip8_data = CardanoCip8SigStructureLedgerType { + address_field: address_field.clone(), + payload: sign_data, + }; + let cip8_cbor_data_ledger_type = + hex::encode(minicbor::to_vec(&cip8_data).unwrap()).to_uppercase(); + let result = app_cardano::transaction::sign_data( + &cardano_sign_data_reqeust + .get_derivation_path() + .get_path() + .unwrap(), + cip8_cbor_data_ledger_type.as_str(), + icarus_master_key, + ) + .map(|v| { + rust_tools::debug!(format!("sign data success")); + rust_tools::debug!(format!("signature: {}", hex::encode(v.get_signature()))); + rust_tools::debug!(format!("pub key: {}", hex::encode(v.get_pub_key()))); + rust_tools::debug!(format!( + "address field: {}", + hex::encode(address_field.clone()) + )); + CardanoSignCip8DataSignature::new( + cardano_sign_data_reqeust.get_request_id(), + v.get_signature(), + v.get_pub_key(), + address_field.clone(), + ) + .try_into() + }) + .map_or_else( + |e| UREncodeResult::from(e).c_ptr(), + |v| { + v.map_or_else( + |e| UREncodeResult::from(e).c_ptr(), + |data| { + UREncodeResult::encode( + data, + CARDANO_SIGN_CIP8_DATA_SIGNATURE.get_type(), + FRAGMENT_MAX_LENGTH_DEFAULT.clone(), + ) + .c_ptr() + }, + ) + }, + ); + + return result; +} + #[no_mangle] pub extern "C" fn cardano_sign_tx_with_ledger_bitbox02( ptr: PtrUR, @@ -713,9 +915,8 @@ fn get_cardano_derivation_path(path: CryptoKeyPath) -> R { #[cfg(test)] mod tests { - use super::*; - use address::cardano_get_base_address; use alloc::vec; + use app_cardano::address::AddressType; use keystore::algorithms::ed25519::bip32_ed25519::derive_extended_privkey_by_xprv; use bitcoin::bip32::Xpriv ; @@ -785,13 +986,20 @@ mod tests { let private_key = derive_extended_privkey_by_xprv(&bip32_signing_key, &"0/0".to_string()).unwrap(); assert_eq!("00e931ab7c17c922c5e905d46991cb590818f49eb39922a15018fc2124e69d41b3c7dfec8d2c21667419404ce6fe0fe6bc9e8e2b361487a59313bb9a0b2322cd", hex::encode(private_key.extended_secret_key_bytes())); - let result = app_cardano::transaction::sign_data( - &"m/1852'/1815'/0'/0/0".to_string(), - &message_hash, - master_key, - ) - .unwrap(); - let signature = hex::encode(result.get_signature()); - assert_eq!(signature,"56ebf5bbea63aafbf1440cd63c5fbcbe3de799de401d48165a366e10f36c17b490c261ea8a00cf464cf7140732369cc4e333eb6714cabe625abddac1cd9dd20b"); + + let address_field = decode(address.as_str()).unwrap().1; + assert_eq!( + "0014c16d7f43243bd81478e68b9db53a8528fd4fb1078d58d54a7f11241d227aefa4b773149170885aadba30aab3127cc611ddbc4999def61c", + hex::encode(address_field.as_slice()) + ); + + // let result = app_cardano::transaction::sign_data( + // &"m/1852'/1815'/0'/0/0".to_string(), + // &message_hash, + // master_key, + // ) + // .unwrap(); + // let signature = hex::encode(result.get_signature()); + // assert_eq!(signature,"56ebf5bbea63aafbf1440cd63c5fbcbe3de799de401d48165a366e10f36c17b490c261ea8a00cf464cf7140732369cc4e333eb6714cabe625abddac1cd9dd20b"); } } diff --git a/rust/rust_c/src/cardano/src/structs.rs b/rust/rust_c/src/cardano/src/structs.rs index 70538b53b..2a5b50dce 100644 --- a/rust/rust_c/src/cardano/src/structs.rs +++ b/rust/rust_c/src/cardano/src/structs.rs @@ -2,8 +2,8 @@ use alloc::string::ToString; use alloc::vec::Vec; use alloc::{boxed::Box, string::String}; use app_cardano::structs::{ - CardanoCertificate, CardanoFrom, CardanoTo, CardanoWithdrawal, ParsedCardanoSignData, - ParsedCardanoTx, VotingProcedure, VotingProposal, + CardanoCertificate, CardanoFrom, CardanoTo, CardanoWithdrawal, ParsedCardanoSignCip8Data, + ParsedCardanoSignData, ParsedCardanoTx, VotingProcedure, VotingProposal, }; use core::ptr::null_mut; use hex; @@ -222,6 +222,17 @@ impl From for DisplayCardanoSignData { } } +impl From for DisplayCardanoSignData { + fn from(value: ParsedCardanoSignCip8Data) -> Self { + Self { + payload: convert_c_char(value.get_payload()), + derivation_path: convert_c_char(value.get_derivation_path()), + message_hash: convert_c_char(value.get_message_hash()), + xpub: convert_c_char(value.get_xpub()), + } + } +} + impl From for DisplayCardanoTx { fn from(value: ParsedCardanoTx) -> Self { Self { diff --git a/rust/rust_c/src/common/src/ur.rs b/rust/rust_c/src/common/src/ur.rs index f53c9b0f8..25dc20055 100644 --- a/rust/rust_c/src/common/src/ur.rs +++ b/rust/rust_c/src/common/src/ur.rs @@ -25,6 +25,7 @@ use ur_registry::bytes::Bytes; #[cfg(feature = "multi-coins")] use ur_registry::cardano::{ cardano_catalyst_voting_registration::CardanoCatalystVotingRegistrationRequest, + cardano_sign_cip8_data_request::CardanoSignCip8DataRequest, cardano_sign_data_request::CardanoSignDataRequest, cardano_sign_request::CardanoSignRequest, }; #[cfg(feature = "multi-coins")] @@ -213,6 +214,8 @@ pub enum ViewType { #[cfg(feature = "multi-coins")] CardanoSignData, #[cfg(feature = "multi-coins")] + CardanoSignCip8Data, + #[cfg(feature = "multi-coins")] CardanoCatalystVotingRegistration, #[cfg(feature = "multi-coins")] CardanoSignTxHash, @@ -281,6 +284,8 @@ pub enum QRCodeType { #[cfg(feature = "multi-coins")] CardanoSignDataRequest, #[cfg(feature = "multi-coins")] + CardanoSignCip8DataRequest, + #[cfg(feature = "multi-coins")] CardanoCatalystVotingRegistrationRequest, #[cfg(feature = "multi-coins")] CosmosSignRequest, @@ -338,6 +343,10 @@ impl QRCodeType { #[cfg(feature = "multi-coins")] InnerURType::CardanoSignTxHashRequest(_) => Ok(QRCodeType::CardanoSignTxHashRequest), #[cfg(feature = "multi-coins")] + InnerURType::CardanoSignCip8DataRequest(_) => { + Ok(QRCodeType::CardanoSignCip8DataRequest) + } + #[cfg(feature = "multi-coins")] InnerURType::CardanoSignDataRequest(_) => Ok(QRCodeType::CardanoSignDataRequest), #[cfg(feature = "multi-coins")] InnerURType::CardanoCatalystVotingRegistrationRequest(_) => { @@ -492,6 +501,10 @@ fn free_ur(ur_type: &QRCodeType, data: PtrUR) { free_ptr_with_type!(data, CardanoSignTxHashRequest); } + #[cfg(feature = "multi-coins")] + QRCodeType::CardanoSignCip8DataRequest => { + free_ptr_with_type!(data, CardanoSignCip8DataRequest); + } #[cfg(feature = "multi-coins")] QRCodeType::CardanoCatalystVotingRegistrationRequest => { free_ptr_with_type!(data, CardanoCatalystVotingRegistrationRequest); @@ -636,6 +649,11 @@ pub fn decode_ur(ur: String) -> URParseResult { QRCodeType::CardanoSignTxHashRequest => _decode_ur::(ur, ur_type), #[cfg(feature = "multi-coins")] QRCodeType::CardanoSignDataRequest => _decode_ur::(ur, ur_type), + #[cfg(feature = "multi-coins")] + QRCodeType::CardanoSignCip8DataRequest => { + _decode_ur::(ur, ur_type) + } + #[cfg(feature = "multi-coins")] QRCodeType::CardanoCatalystVotingRegistrationRequest => { _decode_ur::(ur, ur_type) @@ -722,6 +740,10 @@ fn receive_ur(ur: String, decoder: &mut KeystoneURDecoder) -> URParseMultiResult _receive_ur::(ur, ur_type, decoder) } + #[cfg(feature = "multi-coins")] + QRCodeType::CardanoSignCip8DataRequest => { + _receive_ur::(ur, ur_type, decoder) + } #[cfg(feature = "multi-coins")] QRCodeType::CardanoSignDataRequest => { _receive_ur::(ur, ur_type, decoder) diff --git a/rust/rust_c/src/common/src/ur_ext.rs b/rust/rust_c/src/common/src/ur_ext.rs index d4729816a..adfb8a7e8 100644 --- a/rust/rust_c/src/common/src/ur_ext.rs +++ b/rust/rust_c/src/common/src/ur_ext.rs @@ -4,6 +4,8 @@ use alloc::vec::Vec; use serde_json::{from_slice, from_value, Value}; #[cfg(feature = "multi-coins")] +ur_registry::cardano::cardano_sign_cip8_data_request::CardanoSignCip8DataRequest; +#[cfg(feature = "multi-coins")] use ur_registry::aptos::aptos_sign_request::AptosSignRequest; #[cfg(feature = "multi-coins")] use ur_registry::arweave::arweave_sign_request::{ArweaveSignRequest, SignType}; @@ -292,6 +294,13 @@ impl InferViewType for CardanoSignDataRequest { } } +#[cfg(feature = "multi-coins")] +impl InferViewType for CardanoSignCip8DataRequest { + fn infer(&self) -> Result { + Ok(ViewType::CardanoSignCip8Data) + } +} + #[cfg(feature = "multi-coins")] impl InferViewType for CardanoCatalystVotingRegistrationRequest { fn infer(&self) -> Result { diff --git a/src/ui/gui_analyze/gui_analyze.c b/src/ui/gui_analyze/gui_analyze.c index 9e60b5890..2199ab5da 100644 --- a/src/ui/gui_analyze/gui_analyze.c +++ b/src/ui/gui_analyze/gui_analyze.c @@ -1756,6 +1756,7 @@ GuiRemapViewType ViewTypeReMap(uint8_t viewType) case CardanoTx: return REMAPVIEW_ADA; case CardanoSignData: + case CardanoSignCip8Data: return REMAPVIEW_ADA_SIGN_DATA; case CardanoCatalystVotingRegistration: return REMAPVIEW_ADA_CATALYST; diff --git a/src/ui/gui_chain/gui_chain.c b/src/ui/gui_chain/gui_chain.c index 37f7b50e3..98d81b27c 100644 --- a/src/ui/gui_chain/gui_chain.c +++ b/src/ui/gui_chain/gui_chain.c @@ -114,6 +114,7 @@ GuiChainCoinType ViewTypeToChainTypeSwitch(uint8_t ViewType) case CardanoTx: case CardanoSignData: case CardanoCatalystVotingRegistration: + case CardanoSignCip8Data: return CHAIN_ADA; case XRPTx: return CHAIN_XRP; @@ -136,7 +137,7 @@ GuiChainCoinType ViewTypeToChainTypeSwitch(uint8_t ViewType) #ifndef BTC_ONLY bool IsMessageType(uint8_t type) { - return type == EthPersonalMessage || type == EthTypedData || IsCosmosMsg(type) || type == SolanaMessage || IsAptosMsg(type) || type == BtcMsg || type == ArweaveMessage || type == CardanoSignData; + return type == EthPersonalMessage || type == EthTypedData || IsCosmosMsg(type) || type == SolanaMessage || IsAptosMsg(type) || type == BtcMsg || type == ArweaveMessage || type == CardanoSignData || type == CardanoSignCip8Data; } bool isTonSignProof(uint8_t type) @@ -198,6 +199,9 @@ static GenerateUR UrGenerator(ViewType viewType, bool isMulti) case CardanoSignData: func = GuiGetAdaSignSignDataQrCodeData; break; + case CardanoSignCip8Data: + func = GuiGetAdaSignSignCip8DataQrCodeData; + break; case CardanoCatalystVotingRegistration: func = GuiGetAdaSignCatalystVotingRegistrationQrCodeData; break; diff --git a/src/ui/gui_chain/others/gui_ada.c b/src/ui/gui_chain/others/gui_ada.c index 75ebb0d1a..bf149906c 100644 --- a/src/ui/gui_chain/others/gui_ada.c +++ b/src/ui/gui_chain/others/gui_ada.c @@ -671,6 +671,35 @@ UREncodeResult *GuiGetAdaSignSignDataQrCodeData(void) return encodeResult; } +UREncodeResult *GuiGetAdaSignSignCip8DataQrCodeData(void) +{ + bool enable = IsPreviousLockScreenEnable(); + SetLockScreen(false); + UREncodeResult *encodeResult; + uint8_t mfp[4]; + GetMasterFingerPrint(mfp); + + void *data = g_isMulti ? g_urMultiResult->data : g_urResult->data; + do { + uint8_t entropy[64]; + uint8_t len = 0; + GetAccountEntropy(GetCurrentAccountIndex(), entropy, &len, SecretCacheGetPassword()); + if (GetAdaXPubType() == LEDGER_ADA) { + char *mnemonic = NULL; + bip39_mnemonic_from_bytes(NULL, entropy, len, &mnemonic); + encodeResult = cardano_sign_sign_cip8_data_with_ledger_bitbox02(data, mnemonic, GetPassphrase(GetCurrentAccountIndex())); + } else { + encodeResult = cardano_sign_sign_cip8_data(data, entropy, len, GetPassphrase(GetCurrentAccountIndex())); + } + ClearSecretCache(); + CHECK_CHAIN_BREAK(encodeResult); + } while (0); + SetLockScreen(enable); + return encodeResult; +} + + + UREncodeResult *GuiGetAdaSignQrCodeData(void) { diff --git a/src/ui/gui_chain/others/gui_ada.h b/src/ui/gui_chain/others/gui_ada.h index 17f6dc5d8..54f77bbbe 100644 --- a/src/ui/gui_chain/others/gui_ada.h +++ b/src/ui/gui_chain/others/gui_ada.h @@ -61,6 +61,7 @@ char *GuiGetADABaseAddressByXPub(char *xPub); UREncodeResult *GuiGetAdaSignQrCodeData(void); UREncodeResult *GuiGetAdaSignUrDataUnlimited(void); UREncodeResult *GuiGetAdaSignSignDataQrCodeData(void); +UREncodeResult *GuiGetAdaSignSignCip8DataQrCodeData(void); UREncodeResult *GuiGetAdaSignCatalystVotingRegistrationQrCodeData(void); void GetCatalystNonce(void *indata, void *param, uint32_t maxLen); From 06b42084a537c9df04afffeb704380c7cb50793c Mon Sep 17 00:00:00 2001 From: ZhenQian Date: Fri, 18 Oct 2024 16:12:13 +0800 Subject: [PATCH 05/16] chore: add cardano sign cip8 data deps --- rust/rust_c/src/cardano/Cargo.toml | 2 +- rust/third_party/Cargo.toml | 0 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 rust/third_party/Cargo.toml diff --git a/rust/rust_c/src/cardano/Cargo.toml b/rust/rust_c/src/cardano/Cargo.toml index 95fe47c17..1b743f8ef 100644 --- a/rust/rust_c/src/cardano/Cargo.toml +++ b/rust/rust_c/src/cardano/Cargo.toml @@ -17,7 +17,7 @@ hex = { workspace = true } ur-registry = { workspace = true } bitcoin = { workspace = true } ed25519-bip32-core = { workspace = true } - +minicbor = { version = "0.19", features = ["alloc"] } common_rust_c = { path = "../common" } [features] diff --git a/rust/third_party/Cargo.toml b/rust/third_party/Cargo.toml new file mode 100644 index 000000000..e69de29bb From a9d99f9d91c288a107d8600fa4bb552b2fdaadda Mon Sep 17 00:00:00 2001 From: ZhenQian Date: Thu, 24 Oct 2024 09:51:25 +0800 Subject: [PATCH 06/16] chore: run cargo fmt --- rust/rust_c/src/cardano/src/lib.rs | 12 ++++++++---- rust/rust_c/src/common/src/ur_ext.rs | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/rust/rust_c/src/cardano/src/lib.rs b/rust/rust_c/src/cardano/src/lib.rs index 950ddcacd..8333cca80 100644 --- a/rust/rust_c/src/cardano/src/lib.rs +++ b/rust/rust_c/src/cardano/src/lib.rs @@ -2,6 +2,7 @@ extern crate alloc; +use alloc::vec::Vec; use alloc::{format, slice}; use alloc::{ string::{String, ToString}, @@ -25,22 +26,24 @@ use structs::DisplayCardanoSignTxHash; use ur_registry::cardano::cardano_catalyst_signature::CardanoCatalystSignature; use ur_registry::cardano::cardano_catalyst_voting_registration::CardanoCatalystVotingRegistrationRequest; +use ur_registry::cardano::cardano_sign_cip8_data_request::CardanoSignCip8DataRequest; + use ur_registry::cardano::cardano_sign_data_request::CardanoSignDataRequest; use ur_registry::cardano::cardano_sign_data_signature::CardanoSignDataSignature; use ur_registry::cardano::cardano_sign_request::CardanoSignRequest; use ur_registry::cardano::cardano_sign_tx_hash_request::CardanoSignTxHashRequest; use ur_registry::cardano::cardano_signature::CardanoSignature; use ur_registry::crypto_key_path::CryptoKeyPath; - +use ur_registry::cardano::cardano_sign_cip8_data_signature::CardanoSignCip8DataSignature; use cip8_cbor_data_ledger::CardanoCip8SigStructureLedgerType; -use common_rust_c::errors::{R, RustCError}; +use common_rust_c::errors::{RustCError, R}; use common_rust_c::extract_ptr_with_type; use common_rust_c::structs::{SimpleResponse, TransactionCheckResult, TransactionParseResult}; use common_rust_c::types::{Ptr, PtrBytes, PtrString, PtrT, PtrUR}; -use common_rust_c::ur::{FRAGMENT_MAX_LENGTH_DEFAULT, FRAGMENT_UNLIMITED_LENGTH, UREncodeResult}; +use common_rust_c::ur::{UREncodeResult, FRAGMENT_MAX_LENGTH_DEFAULT, FRAGMENT_UNLIMITED_LENGTH}; use common_rust_c::utils::{convert_c_char, recover_c_char}; use ur_registry::registry_types::{ - CARDANO_CATALYST_VOTING_REGISTRATION_SIGNATURE, CARDANO_SIGNATURE, CARDANO_SIGN_DATA_SIGNATURE, + CARDANO_CATALYST_VOTING_REGISTRATION_SIGNATURE, CARDANO_SIGNATURE,CARDANO_SIGN_CIP8_DATA_SIGNATURE, CARDANO_SIGN_DATA_SIGNATURE, }; pub mod address; @@ -922,6 +925,7 @@ mod tests { use bitcoin::bip32::Xpriv ; use ur_registry::crypto_key_path::PathComponent; use ur_registry::crypto_key_path::PathComponent; + use bench32::decode; #[test] fn test_get_cardano_derivation_path() { diff --git a/rust/rust_c/src/common/src/ur_ext.rs b/rust/rust_c/src/common/src/ur_ext.rs index adfb8a7e8..51c86be85 100644 --- a/rust/rust_c/src/common/src/ur_ext.rs +++ b/rust/rust_c/src/common/src/ur_ext.rs @@ -49,6 +49,7 @@ use ur_registry::ton::ton_sign_request::{DataType, TonSignRequest}; use ur_registry::{ bitcoin::btc_sign_request::BtcSignRequest, sui::sui_sign_hash_request::SuiSignHashRequest, }; +use ur_registry::cardano::cardano_sign_cip8_data_request::CardanoSignCip8DataRequest; use crate::ur::ViewType; From 5a95e80260b46ab0cdf8ef971380236727bef9dc Mon Sep 17 00:00:00 2001 From: ZhenQian Date: Thu, 24 Oct 2024 10:09:48 +0800 Subject: [PATCH 07/16] chore: remove cardano sign cip8 unused printf --- rust/rust_c/src/cardano/src/lib.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/rust/rust_c/src/cardano/src/lib.rs b/rust/rust_c/src/cardano/src/lib.rs index 8333cca80..ed3e59962 100644 --- a/rust/rust_c/src/cardano/src/lib.rs +++ b/rust/rust_c/src/cardano/src/lib.rs @@ -648,13 +648,6 @@ fn cardano_sign_sign_cip8_data_by_icarus( icarus_master_key, ) .map(|v| { - rust_tools::debug!(format!("sign data success")); - rust_tools::debug!(format!("signature: {}", hex::encode(v.get_signature()))); - rust_tools::debug!(format!("pub key: {}", hex::encode(v.get_pub_key()))); - rust_tools::debug!(format!( - "address field: {}", - hex::encode(address_field.clone()) - )); CardanoSignCip8DataSignature::new( cardano_sign_data_reqeust.get_request_id(), v.get_signature(), From ceff9419d2ea311a712d68ffd043d1789673dc08 Mon Sep 17 00:00:00 2001 From: ZhenQian Date: Thu, 24 Oct 2024 13:31:22 +0800 Subject: [PATCH 08/16] fix: use ledger derivation type when using cardano usb --- .../gui_widgets/general/gui_key_derivation_request_widgets.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ui/gui_widgets/general/gui_key_derivation_request_widgets.c b/src/ui/gui_widgets/general/gui_key_derivation_request_widgets.c index 4aedff715..17205e301 100644 --- a/src/ui/gui_widgets/general/gui_key_derivation_request_widgets.c +++ b/src/ui/gui_widgets/general/gui_key_derivation_request_widgets.c @@ -530,14 +530,14 @@ static UREncodeResult *ModelGenerateSyncUR(void) pubkey = get_ed25519_pubkey_by_seed(seed, seedLen, path); break; case BIP32_ED25519: - if (selected_ada_derivation_algo == HD_STANDARD_ADA) { + if (selected_ada_derivation_algo == HD_STANDARD_ADA && !g_isUsb) { uint8_t entropyLen = 0; uint8_t entropy[64]; GetAccountEntropy(GetCurrentAccountIndex(), entropy, &entropyLen, password); SimpleResponse_c_char* cip3_response = get_icarus_master_key(entropy, entropyLen, GetPassphrase(GetCurrentAccountIndex())); char* icarusMasterKey = cip3_response->data; pubkey = derive_bip32_ed25519_extended_pubkey(icarusMasterKey, path); - } else if (selected_ada_derivation_algo == HD_LEDGER_BITBOX_ADA) { + } else if (selected_ada_derivation_algo == HD_LEDGER_BITBOX_ADA || g_isUsb) { // seed -> mnemonic --> master key(m) -> derive key uint8_t entropyLen = 0; uint8_t entropy[64]; From 49e17b320e220bf9ec540b3eafa36c1f9b798964 Mon Sep 17 00:00:00 2001 From: ZhenQian Date: Wed, 30 Oct 2024 17:53:23 +0800 Subject: [PATCH 09/16] feat: add sign cardano opcert support --- src/ui/gui_chain/others/gui_ada.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/ui/gui_chain/others/gui_ada.c b/src/ui/gui_chain/others/gui_ada.c index bf149906c..42e77d941 100644 --- a/src/ui/gui_chain/others/gui_ada.c +++ b/src/ui/gui_chain/others/gui_ada.c @@ -297,6 +297,21 @@ PtrT_TransactionCheckResult GuiGetAdaSignDataCheckResult(void) void *data = g_isMulti ? g_urMultiResult->data : g_urResult->data; uint8_t mfp[4]; GetMasterFingerPrint(mfp); + // first check is sign opcert and then check sign cip8 or cip36 data + PtrT_TransactionCheckResult checkCardanoCip1853SignOpcertResult = cardano_check_sign_data_is_sign_opcert(data); + if (checkCardanoCip1853SignOpcertResult->error_code != 0) { + Try2FixAdaPathType(); + checkCardanoCip1853SignOpcertResult = cardano_check_sign_data_is_sign_opcert(data); + if (checkCardanoCip1853SignOpcertResult->error_code == 0) { + free_TransactionCheckResult(checkCardanoCip1853SignOpcertResult); + PtrT_TransactionCheckResult result = cardano_check_sign_data(data, mfp); + return result; + } + } else { + free_TransactionCheckResult(checkCardanoCip1853SignOpcertResult); + PtrT_TransactionCheckResult result = cardano_check_sign_data(data, mfp); + return result; + } Ptr_SimpleResponse_c_char master_key_index = cardano_get_sign_data_root_index(data); if (master_key_index->error_code != 0) { return NULL; From 8192b3ed4b4c6b0170a76c7b6262831fe3df2a8e Mon Sep 17 00:00:00 2001 From: ZhenQian Date: Wed, 30 Oct 2024 17:54:00 +0800 Subject: [PATCH 10/16] fix: fix rebase master bugs and run astyle --- rust/Cargo.lock | 2 + rust/apps/cardano/src/structs.rs | 12 +-- rust/rust_c/src/cardano/Cargo.toml | 6 +- .../src/cardano/src/cip8_cbor_data_ledger.rs | 2 +- rust/rust_c/src/cardano/src/lib.rs | 94 +++++++++++++++---- src/ui/gui_frame/gui_obj.h | 2 +- 6 files changed, 86 insertions(+), 32 deletions(-) diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 1347260a5..587cefd2f 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -799,12 +799,14 @@ dependencies = [ "app_utils", "bitcoin", "common_rust_c", + "cryptoxide", "cstr_core", "cty", "ed25519-bip32-core", "hex", "itertools", "keystore", + "minicbor", "rust_tools", "ur-registry", ] diff --git a/rust/apps/cardano/src/structs.rs b/rust/apps/cardano/src/structs.rs index 6308e4a40..dfb309e06 100644 --- a/rust/apps/cardano/src/structs.rs +++ b/rust/apps/cardano/src/structs.rs @@ -19,11 +19,7 @@ use cardano_serialization_lib::{ protocol_types::FixedTransaction as Transaction, protocol_types::VoteKind, Certificate, CertificateKind, NetworkId, NetworkIdKind, }; - -use alloc::format; -use bitcoin::bip32::ChildNumber::{Hardened, Normal}; -use bitcoin::bip32::DerivationPath; -use core::ops::Div; +use cryptoxide::hashing::blake2b_224; use ur_registry::cardano::cardano_sign_structure::CardanoSignStructure; use ur_registry::traits::From; @@ -1167,12 +1163,6 @@ impl ParsedCardanoTx { None => {} } } - - if !pubkey_hash_paired { - return Err(CardanoError::InvalidTransaction( - "invalid address".to_string(), - )); - } parsed_inputs.push(ParsedCardanoInput { transaction_hash: utxo.transaction_hash.clone(), index: utxo.index, diff --git a/rust/rust_c/src/cardano/Cargo.toml b/rust/rust_c/src/cardano/Cargo.toml index 1b743f8ef..e689e8dbd 100644 --- a/rust/rust_c/src/cardano/Cargo.toml +++ b/rust/rust_c/src/cardano/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -keystore = { workspace = true} +keystore = { workspace = true } app_cardano = { workspace = true } app_utils = { workspace = true } rust_tools = { workspace = true } @@ -19,6 +19,6 @@ bitcoin = { workspace = true } ed25519-bip32-core = { workspace = true } minicbor = { version = "0.19", features = ["alloc"] } common_rust_c = { path = "../common" } - +cryptoxide = { workspace = true } [features] -debug-memory = [] \ No newline at end of file +debug-memory = [] diff --git a/rust/rust_c/src/cardano/src/cip8_cbor_data_ledger.rs b/rust/rust_c/src/cardano/src/cip8_cbor_data_ledger.rs index 4cc54fafb..288889f16 100644 --- a/rust/rust_c/src/cardano/src/cip8_cbor_data_ledger.rs +++ b/rust/rust_c/src/cardano/src/cip8_cbor_data_ledger.rs @@ -49,7 +49,7 @@ impl minicbor::Encode for CardanoCip8SigStructureLedgerType { #[cfg(test)] mod tests { use super::*; - use third_party::hex; + use hex; #[test] fn test1() { // Signature1 diff --git a/rust/rust_c/src/cardano/src/lib.rs b/rust/rust_c/src/cardano/src/lib.rs index ed3e59962..4ae0aa675 100644 --- a/rust/rust_c/src/cardano/src/lib.rs +++ b/rust/rust_c/src/cardano/src/lib.rs @@ -2,6 +2,8 @@ extern crate alloc; +use crate::alloc::string::ToString; +use crate::structs::DisplayCardanoTx; use alloc::vec::Vec; use alloc::{format, slice}; use alloc::{ @@ -12,6 +14,7 @@ use alloc::{ use alloc::vec::Vec; use core::str::FromStr; +use alloc::{string::String, vec}; use app_cardano::address::derive_xpub_from_xpub; use app_cardano::errors::CardanoError; use app_cardano::governance; @@ -20,30 +23,36 @@ use app_cardano::transaction::calc_icarus_master_key; use bitcoin::bip32::DerivationPath; use core::str::FromStr; use cty::c_char; +use bitcoin::bip32::DerivationPath; +use cip8_cbor_data_ledger::CardanoCip8SigStructureLedgerType; +use common_rust_c::errors::{RustCError, R}; +use common_rust_c::extract_ptr_with_type; +use common_rust_c::structs::{SimpleResponse, TransactionCheckResult, TransactionParseResult}; +use common_rust_c::types::{Ptr, PtrBytes, PtrString, PtrT, PtrUR}; +use common_rust_c::ur::{UREncodeResult, FRAGMENT_MAX_LENGTH_DEFAULT, FRAGMENT_UNLIMITED_LENGTH}; +use common_rust_c::utils::{convert_c_char, recover_c_char}; +use core::str::FromStr; +use cryptoxide::hashing::blake2b_224; +use cty::c_char; use ed25519_bip32_core::XPrv; use hex; use structs::DisplayCardanoSignTxHash; +use hex::decode; +use structs::{DisplayCardanoCatalyst, DisplayCardanoSignData}; use ur_registry::cardano::cardano_catalyst_signature::CardanoCatalystSignature; use ur_registry::cardano::cardano_catalyst_voting_registration::CardanoCatalystVotingRegistrationRequest; use ur_registry::cardano::cardano_sign_cip8_data_request::CardanoSignCip8DataRequest; - +use ur_registry::cardano::cardano_sign_cip8_data_signature::CardanoSignCip8DataSignature; use ur_registry::cardano::cardano_sign_data_request::CardanoSignDataRequest; use ur_registry::cardano::cardano_sign_data_signature::CardanoSignDataSignature; use ur_registry::cardano::cardano_sign_request::CardanoSignRequest; use ur_registry::cardano::cardano_sign_tx_hash_request::CardanoSignTxHashRequest; use ur_registry::cardano::cardano_signature::CardanoSignature; use ur_registry::crypto_key_path::CryptoKeyPath; -use ur_registry::cardano::cardano_sign_cip8_data_signature::CardanoSignCip8DataSignature; -use cip8_cbor_data_ledger::CardanoCip8SigStructureLedgerType; -use common_rust_c::errors::{RustCError, R}; -use common_rust_c::extract_ptr_with_type; -use common_rust_c::structs::{SimpleResponse, TransactionCheckResult, TransactionParseResult}; -use common_rust_c::types::{Ptr, PtrBytes, PtrString, PtrT, PtrUR}; -use common_rust_c::ur::{UREncodeResult, FRAGMENT_MAX_LENGTH_DEFAULT, FRAGMENT_UNLIMITED_LENGTH}; -use common_rust_c::utils::{convert_c_char, recover_c_char}; use ur_registry::registry_types::{ - CARDANO_CATALYST_VOTING_REGISTRATION_SIGNATURE, CARDANO_SIGNATURE,CARDANO_SIGN_CIP8_DATA_SIGNATURE, CARDANO_SIGN_DATA_SIGNATURE, + CARDANO_CATALYST_VOTING_REGISTRATION_SIGNATURE, CARDANO_SIGNATURE, + CARDANO_SIGN_CIP8_DATA_SIGNATURE, CARDANO_SIGN_DATA_SIGNATURE, }; pub mod address; @@ -127,6 +136,7 @@ pub extern "C" fn cardano_get_catalyst_root_index(ptr: PtrUR) -> Ptr Ptr> { let cardano_sign_data_reqeust = extract_ptr_with_type!(ptr, CardanoSignDataRequest); let derviation_path: CryptoKeyPath = cardano_sign_data_reqeust.get_derivation_path(); + rust_tools::debug!(format!("=-=========derviation_path: {:?}", derviation_path)); match derviation_path.get_components().get(2) { Some(_data) => { let index = _data.get_index().unwrap(); @@ -160,11 +170,14 @@ pub extern "C" fn cardano_check_sign_data_path_type( let cardano_xpub = recover_c_char(cardano_xpub); let xpub = cardano_sign_data_reqeust.get_xpub(); let xpub = hex::encode(xpub); + rust_tools::debug!(format!("xpub: {}", xpub)); let derivation_path = get_cardano_derivation_path(cardano_sign_data_reqeust.get_derivation_path()); + rust_tools::debug!(format!("derivation_path: {:?}", derivation_path)); match derivation_path { Ok(derivation_path) => match derive_xpub_from_xpub(cardano_xpub, derivation_path) { Ok(_xpub) => { + rust_tools::debug!(format!("derived xpub: {}", _xpub)); if _xpub == xpub { TransactionCheckResult::new().c_ptr() } else { @@ -180,6 +193,22 @@ pub extern "C" fn cardano_check_sign_data_path_type( } } +#[no_mangle] +pub extern "C" fn cardano_check_sign_data_is_sign_opcert( + ptr: PtrUR, +) -> PtrT { + let cardano_sign_data_reqeust = extract_ptr_with_type!(ptr, CardanoSignDataRequest); + let derviation_path: CryptoKeyPath = cardano_sign_data_reqeust.get_derivation_path(); + // if path first element is 1853 and path length is 4, that means it is a valid cardano cip1853 path + if derviation_path.get_components().len() == 4 + && derviation_path.get_components()[0].get_index() == Some(1853) + { + TransactionCheckResult::new().c_ptr() + } else { + TransactionCheckResult::from(RustCError::InvalidData("not opcert".to_string())).c_ptr() + } +} + #[no_mangle] pub extern "C" fn cardano_check_sign_cip8_data_path_type( ptr: PtrUR, @@ -619,7 +648,7 @@ fn cardano_sign_sign_cip8_data_by_icarus( let mut address_field = vec![]; let address_type = cardano_sign_data_reqeust.get_address_type(); if address_type.as_str() == "ADDRESS" { - address_field = decode( + address_field = bitcoin::bech32::decode( &cardano_sign_data_reqeust .get_address_bench32() .unwrap() @@ -912,14 +941,13 @@ fn get_cardano_derivation_path(path: CryptoKeyPath) -> R { #[cfg(test)] mod tests { use alloc::vec; + use bitcoin::bech32::decode; + use crate::alloc::string::ToString; + use crate::get_cardano_derivation_path; use app_cardano::address::AddressType; use keystore::algorithms::ed25519::bip32_ed25519::derive_extended_privkey_by_xprv; - use bitcoin::bip32::Xpriv ; - use ur_registry::crypto_key_path::PathComponent; - use ur_registry::crypto_key_path::PathComponent; - use bench32::decode; - + use ur_registry::crypto_key_path::{CryptoKeyPath, PathComponent}; #[test] fn test_get_cardano_derivation_path() { let path = CryptoKeyPath::new( @@ -999,4 +1027,38 @@ mod tests { // let signature = hex::encode(result.get_signature()); // assert_eq!(signature,"56ebf5bbea63aafbf1440cd63c5fbcbe3de799de401d48165a366e10f36c17b490c261ea8a00cf464cf7140732369cc4e333eb6714cabe625abddac1cd9dd20b"); } + + #[test] + fn test_sign_op_cert() { + // op_cert_hash = Buffer.concat([dkesPublicKeyHex,issueCounter,kesPeriod) + // op_cert_hash length must be 48 + let message_hash = "f70601c4de155e67797e057c07fb768b5590b2241b05ec30235a85b71e2ae858000000000000000100000000000000fb"; + let master_key_expected = "402b03cd9c8bed9ba9f9bd6cd9c315ce9fcc59c7c25d37c85a36096617e69d418e35cb4a3b737afd007f0688618f21a8831643c0e6c77fc33c06026d2a0fc93832596435e70647d7d98ef102a32ea40319ca8fb6c851d7346d3bd8f9d1492658"; + let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"; + let passphrase = ""; + let master_key = + keystore::algorithms::ed25519::bip32_ed25519::get_ledger_bitbox02_master_key_by_mnemonic( + passphrase.as_bytes(), + mnemonic.to_string(), + ).unwrap(); + assert_eq!(master_key_expected, hex::encode(master_key.as_ref())); + + let bip32_signing_key = + keystore::algorithms::ed25519::bip32_ed25519::derive_extended_privkey_by_icarus_master_key( + &master_key.as_ref(), + &"m/1853'/1815'/0'".to_string(), + ) + .unwrap(); + let xpub = bip32_signing_key.public(); + assert_eq!("", hex::encode(xpub.as_ref())); + + let result = app_cardano::transaction::sign_data( + &"m/1853'/1815'/0'/0'".to_string(), + &message_hash, + master_key, + ) + .unwrap(); + let signature = hex::encode(result.get_signature()); + assert_eq!(signature,"b44fcc4505aee4c93a716014ec709d17b28e0c95637384b78d2f8a4cebb92d1e01b54ce952e11771bbeaceda0eaf7a660e5c416f357bdec94e4ce2977997d204") + } } diff --git a/src/ui/gui_frame/gui_obj.h b/src/ui/gui_frame/gui_obj.h index 0b4ea7ae7..adbd1ab4d 100644 --- a/src/ui/gui_frame/gui_obj.h +++ b/src/ui/gui_frame/gui_obj.h @@ -6,7 +6,7 @@ typedef int32_t(*GuiEventProcessFunc)(void *self, uint16_t usEvent, void *param, uint16_t usLen); #define ITEM_ENUM(x) x, -#define ITEM_STR(x) #x, + #define ITEM_STR(x) #x, #define SCREEN_LIST(add) \ add(SCREEN_INIT) \ From 8bb1cbd540ab1f86cce09d570fe2705dda85b6d2 Mon Sep 17 00:00:00 2001 From: ZhenQian Date: Wed, 30 Oct 2024 17:57:05 +0800 Subject: [PATCH 11/16] fix: fix rebase master bugs and run astyle --- rust/rust_c/src/common/src/ur_ext.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rust/rust_c/src/common/src/ur_ext.rs b/rust/rust_c/src/common/src/ur_ext.rs index 51c86be85..53baf7d7c 100644 --- a/rust/rust_c/src/common/src/ur_ext.rs +++ b/rust/rust_c/src/common/src/ur_ext.rs @@ -4,8 +4,6 @@ use alloc::vec::Vec; use serde_json::{from_slice, from_value, Value}; #[cfg(feature = "multi-coins")] -ur_registry::cardano::cardano_sign_cip8_data_request::CardanoSignCip8DataRequest; -#[cfg(feature = "multi-coins")] use ur_registry::aptos::aptos_sign_request::AptosSignRequest; #[cfg(feature = "multi-coins")] use ur_registry::arweave::arweave_sign_request::{ArweaveSignRequest, SignType}; @@ -13,6 +11,8 @@ use ur_registry::bytes::Bytes; #[cfg(feature = "multi-coins")] use ur_registry::cardano::cardano_catalyst_voting_registration::CardanoCatalystVotingRegistrationRequest; #[cfg(feature = "multi-coins")] +use ur_registry::cardano::cardano_sign_cip8_data_request::CardanoSignCip8DataRequest; +#[cfg(feature = "multi-coins")] use ur_registry::cardano::cardano_sign_data_request::CardanoSignDataRequest; #[cfg(feature = "multi-coins")] use ur_registry::cardano::cardano_sign_request::CardanoSignRequest; From ecfcf7aed7ed7f41645a6654685f9f814b25e7dd Mon Sep 17 00:00:00 2001 From: ZhenQian Date: Wed, 20 Nov 2024 15:49:35 +0800 Subject: [PATCH 12/16] chore: rebase master --- rust/rust_c/src/cardano/src/lib.rs | 3 --- rust/rust_c/src/common/src/ur_ext.rs | 1 - 2 files changed, 4 deletions(-) diff --git a/rust/rust_c/src/cardano/src/lib.rs b/rust/rust_c/src/cardano/src/lib.rs index 4ae0aa675..2696088bd 100644 --- a/rust/rust_c/src/cardano/src/lib.rs +++ b/rust/rust_c/src/cardano/src/lib.rs @@ -23,7 +23,6 @@ use app_cardano::transaction::calc_icarus_master_key; use bitcoin::bip32::DerivationPath; use core::str::FromStr; use cty::c_char; -use bitcoin::bip32::DerivationPath; use cip8_cbor_data_ledger::CardanoCip8SigStructureLedgerType; use common_rust_c::errors::{RustCError, R}; use common_rust_c::extract_ptr_with_type; @@ -31,9 +30,7 @@ use common_rust_c::structs::{SimpleResponse, TransactionCheckResult, Transaction use common_rust_c::types::{Ptr, PtrBytes, PtrString, PtrT, PtrUR}; use common_rust_c::ur::{UREncodeResult, FRAGMENT_MAX_LENGTH_DEFAULT, FRAGMENT_UNLIMITED_LENGTH}; use common_rust_c::utils::{convert_c_char, recover_c_char}; -use core::str::FromStr; use cryptoxide::hashing::blake2b_224; -use cty::c_char; use ed25519_bip32_core::XPrv; use hex; use structs::DisplayCardanoSignTxHash; diff --git a/rust/rust_c/src/common/src/ur_ext.rs b/rust/rust_c/src/common/src/ur_ext.rs index 53baf7d7c..f3da10c45 100644 --- a/rust/rust_c/src/common/src/ur_ext.rs +++ b/rust/rust_c/src/common/src/ur_ext.rs @@ -49,7 +49,6 @@ use ur_registry::ton::ton_sign_request::{DataType, TonSignRequest}; use ur_registry::{ bitcoin::btc_sign_request::BtcSignRequest, sui::sui_sign_hash_request::SuiSignHashRequest, }; -use ur_registry::cardano::cardano_sign_cip8_data_request::CardanoSignCip8DataRequest; use crate::ur::ViewType; From 2ff269deeed551e6737abc2c13af04eb74443179 Mon Sep 17 00:00:00 2001 From: ZhenQian Date: Wed, 27 Nov 2024 18:12:29 +0800 Subject: [PATCH 13/16] chore: rebase master --- rust/apps/cardano/src/structs.rs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/rust/apps/cardano/src/structs.rs b/rust/apps/cardano/src/structs.rs index dfb309e06..8103b967f 100644 --- a/rust/apps/cardano/src/structs.rs +++ b/rust/apps/cardano/src/structs.rs @@ -1,30 +1,28 @@ -use crate::address::{derive_address, derive_pubkey_hash, AddressType}; +use crate::address::derive_pubkey_hash; use crate::errors::{CardanoError, R}; use alloc::collections::BTreeMap; use alloc::format; use alloc::string::{String, ToString}; use alloc::vec; use alloc::vec::Vec; +use bitcoin::bip32::DerivationPath; use core::ops::Div; use app_utils::{impl_internal_struct, impl_public_struct}; use cardano_serialization_lib::protocol_types::{ - self, Address, BaseAddress, EnterpriseAddress, RewardAddress, + Address, BaseAddress, EnterpriseAddress, RewardAddress, }; -use cardano_serialization_lib::protocol_types::numeric::BigNum; -use cardano_serialization_lib::protocol_types::{Anchor, DRepKind}; -use cardano_serialization_lib::protocol_types::{Ed25519KeyHash, ScriptHash}; +use bitcoin::bip32::ChildNumber::{Hardened, Normal}; +use cardano_serialization_lib::protocol_types::DRepKind; use cardano_serialization_lib::{ - protocol_types::FixedTransaction as Transaction, protocol_types::VoteKind, Certificate, - CertificateKind, NetworkId, NetworkIdKind, + protocol_types::FixedTransaction as Transaction, protocol_types::VoteKind, NetworkIdKind, }; use cryptoxide::hashing::blake2b_224; +use hex; use ur_registry::cardano::cardano_sign_structure::CardanoSignStructure; use ur_registry::traits::From; -use hex; - impl_public_struct!(ParseContext { utxos: Vec, cert_keys: Vec, From 96c9d9c13dd27f6d4e524d6503d1c52c743a71c0 Mon Sep 17 00:00:00 2001 From: ZhenQian Date: Mon, 9 Dec 2024 15:28:22 +0800 Subject: [PATCH 14/16] fix: fix conway tx crash --- rust/rust_c/src/cardano/src/lib.rs | 11 ++--------- src/tasks/background_task.c | 2 +- src/tasks/data_parser_task.c | 2 +- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/rust/rust_c/src/cardano/src/lib.rs b/rust/rust_c/src/cardano/src/lib.rs index 2696088bd..b331b0a90 100644 --- a/rust/rust_c/src/cardano/src/lib.rs +++ b/rust/rust_c/src/cardano/src/lib.rs @@ -6,13 +6,6 @@ use crate::alloc::string::ToString; use crate::structs::DisplayCardanoTx; use alloc::vec::Vec; use alloc::{format, slice}; -use alloc::{ - string::{String, ToString}, - vec, -}; - -use alloc::vec::Vec; -use core::str::FromStr; use alloc::{string::String, vec}; use app_cardano::address::derive_xpub_from_xpub; @@ -21,8 +14,6 @@ use app_cardano::governance; use app_cardano::structs::{CardanoCertKey, CardanoUtxo, ParseContext}; use app_cardano::transaction::calc_icarus_master_key; use bitcoin::bip32::DerivationPath; -use core::str::FromStr; -use cty::c_char; use cip8_cbor_data_ledger::CardanoCip8SigStructureLedgerType; use common_rust_c::errors::{RustCError, R}; use common_rust_c::extract_ptr_with_type; @@ -30,7 +21,9 @@ use common_rust_c::structs::{SimpleResponse, TransactionCheckResult, Transaction use common_rust_c::types::{Ptr, PtrBytes, PtrString, PtrT, PtrUR}; use common_rust_c::ur::{UREncodeResult, FRAGMENT_MAX_LENGTH_DEFAULT, FRAGMENT_UNLIMITED_LENGTH}; use common_rust_c::utils::{convert_c_char, recover_c_char}; +use core::str::FromStr; use cryptoxide::hashing::blake2b_224; +use cty::c_char; use ed25519_bip32_core::XPrv; use hex; use structs::DisplayCardanoSignTxHash; diff --git a/src/tasks/background_task.c b/src/tasks/background_task.c index 8bc1dc875..37b36bf4e 100644 --- a/src/tasks/background_task.c +++ b/src/tasks/background_task.c @@ -28,7 +28,7 @@ void CreateBackgroundTask(void) { const osThreadAttr_t backgroundTask_attributes = { .name = "BackgroundTask", - .stack_size = 1024 * 8, + .stack_size = 1024 * 4, .priority = (osPriority_t)osPriorityBelowNormal, }; g_backgroundTaskHandle = osThreadNew(BackgroundTask, NULL, &backgroundTask_attributes); diff --git a/src/tasks/data_parser_task.c b/src/tasks/data_parser_task.c index a89edd1b5..da626ff72 100644 --- a/src/tasks/data_parser_task.c +++ b/src/tasks/data_parser_task.c @@ -92,7 +92,7 @@ void CreateDataParserTask(void) { const osThreadAttr_t dataParserTask_attributes = { .name = "data_parser_task", - .stack_size = 1024 * 16, + .stack_size = 1024 * 28, .priority = (osPriority_t)osPriorityHigh, }; g_dataParserHandle = osThreadNew(DataParserTask, NULL, &dataParserTask_attributes); From 404f9cc6c82f1bcfc485d07f22ffd3a34f5acaeb Mon Sep 17 00:00:00 2001 From: ZhenQian Date: Mon, 9 Dec 2024 17:51:36 +0800 Subject: [PATCH 15/16] fix: fix conway tx crash --- rust/Cargo.lock | 2 +- rust/apps/cardano/Cargo.toml | 2 +- rust/apps/cardano/src/transaction.rs | 12 ++++++------ src/tasks/data_parser_task.c | 2 +- src/ui/gui_chain/others/gui_ada.c | 1 - 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 587cefd2f..bf861a1b3 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -762,7 +762,7 @@ dependencies = [ [[package]] name = "cardano-serialization-lib" version = "13.2.0" -source = "git+https://git@github.com/KeystoneHQ/cardano-serialization-lib.git?tag=keystone-0.1.6#584d9aff8548704b12bc78e78fbd6cdc0b5d1b8a" +source = "git+https://git@github.com/KeystoneHQ/cardano-serialization-lib.git?tag=keystone-0.1.7#1822d2223a105aaea5feee6ec888ff3cc74c999d" dependencies = [ "bech32 0.9.1", "cbor_event", diff --git a/rust/apps/cardano/Cargo.toml b/rust/apps/cardano/Cargo.toml index b4aa3676f..57689607b 100644 --- a/rust/apps/cardano/Cargo.toml +++ b/rust/apps/cardano/Cargo.toml @@ -22,4 +22,4 @@ bech32 = { workspace = true } [dependencies.cardano-serialization-lib] git = "https://git@github.com/KeystoneHQ/cardano-serialization-lib.git" -tag = "keystone-0.1.6" +tag = "keystone-0.1.7" diff --git a/rust/apps/cardano/src/transaction.rs b/rust/apps/cardano/src/transaction.rs index c25ae7ab4..d744421db 100644 --- a/rust/apps/cardano/src/transaction.rs +++ b/rust/apps/cardano/src/transaction.rs @@ -88,15 +88,15 @@ pub fn sign_tx_hash( .map_err(|e| CardanoError::SigningFailed(e.to_string()))?; // construct vkeywitness vkeys.add(&Vkeywitness::new( - &Vkey::new(&PublicKey::from_bytes(&pubkey).unwrap()), - &Ed25519Signature::from_bytes(signature.to_vec()) + Vkey::new(&PublicKey::from_bytes(&pubkey).unwrap()), + Ed25519Signature::from_bytes(signature.to_vec()) .map_err(|e| CardanoError::SigningFailed(e.to_string()))?, )); } Err(e) => return Err(e), } } - witness_set.set_vkeys(&vkeys); + witness_set.set_vkeys(vkeys); Ok(witness_set.to_bytes()) } @@ -179,16 +179,16 @@ pub fn sign_tx(tx: Vec, context: ParseContext, icarus_master_key: XPrv) -> R } for (pubkey, signature) in signatures { let v = Vkeywitness::new( - &Vkey::new( + Vkey::new( &PublicKey::from_bytes(&pubkey) .map_err(|e| CardanoError::SigningFailed(e.to_string()))?, ), - &Ed25519Signature::from_bytes(signature.to_vec()) + Ed25519Signature::from_bytes(signature.to_vec()) .map_err(|e| CardanoError::SigningFailed(e.to_string()))?, ); vkeys.add(&v); } - witness_set.set_vkeys(&vkeys); + witness_set.set_vkeys(vkeys); Ok(witness_set.to_bytes()) } diff --git a/src/tasks/data_parser_task.c b/src/tasks/data_parser_task.c index da626ff72..a62b0f4f2 100644 --- a/src/tasks/data_parser_task.c +++ b/src/tasks/data_parser_task.c @@ -92,7 +92,7 @@ void CreateDataParserTask(void) { const osThreadAttr_t dataParserTask_attributes = { .name = "data_parser_task", - .stack_size = 1024 * 28, + .stack_size = 1024 * 32, .priority = (osPriority_t)osPriorityHigh, }; g_dataParserHandle = osThreadNew(DataParserTask, NULL, &dataParserTask_attributes); diff --git a/src/ui/gui_chain/others/gui_ada.c b/src/ui/gui_chain/others/gui_ada.c index 42e77d941..2d3c00e40 100644 --- a/src/ui/gui_chain/others/gui_ada.c +++ b/src/ui/gui_chain/others/gui_ada.c @@ -117,7 +117,6 @@ void *GuiGetAdaCatalyst(void) void *GuiGetAdaSignTxHashData(void) { - printf("=========== GuiGetAdaSignTxHashData\r\n"); CHECK_FREE_PARSE_RESULT(g_parseResult); void *data = g_isMulti ? g_urMultiResult->data : g_urResult->data; do { From 1f9bcbd2301914eecba3ca23a8ce3af7370c6ab8 Mon Sep 17 00:00:00 2001 From: ZhenQian Date: Mon, 9 Dec 2024 18:30:53 +0800 Subject: [PATCH 16/16] fix: fix sign tx crash --- src/tasks/background_task.c | 2 +- src/tasks/data_parser_task.c | 2 +- src/tasks/ui_display_task.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tasks/background_task.c b/src/tasks/background_task.c index 37b36bf4e..8bc1dc875 100644 --- a/src/tasks/background_task.c +++ b/src/tasks/background_task.c @@ -28,7 +28,7 @@ void CreateBackgroundTask(void) { const osThreadAttr_t backgroundTask_attributes = { .name = "BackgroundTask", - .stack_size = 1024 * 4, + .stack_size = 1024 * 8, .priority = (osPriority_t)osPriorityBelowNormal, }; g_backgroundTaskHandle = osThreadNew(BackgroundTask, NULL, &backgroundTask_attributes); diff --git a/src/tasks/data_parser_task.c b/src/tasks/data_parser_task.c index a62b0f4f2..d7773006e 100644 --- a/src/tasks/data_parser_task.c +++ b/src/tasks/data_parser_task.c @@ -92,7 +92,7 @@ void CreateDataParserTask(void) { const osThreadAttr_t dataParserTask_attributes = { .name = "data_parser_task", - .stack_size = 1024 * 32, + .stack_size = 1024 * 36, .priority = (osPriority_t)osPriorityHigh, }; g_dataParserHandle = osThreadNew(DataParserTask, NULL, &dataParserTask_attributes); diff --git a/src/tasks/ui_display_task.c b/src/tasks/ui_display_task.c index 132acd92b..d4cf4b7c4 100644 --- a/src/tasks/ui_display_task.c +++ b/src/tasks/ui_display_task.c @@ -51,7 +51,7 @@ void CreateUiDisplayTask(void) { const osThreadAttr_t testtTask_attributes = { .name = "UiDisplayTask", - .stack_size = 1024 * 16, + .stack_size = 1024 * 24, .priority = (osPriority_t) osPriorityHigh, }; g_uiDisplayTaskHandle = osThreadNew(UiDisplayTask, NULL, &testtTask_attributes);