diff --git a/packages/cmds/src/main.cairo b/packages/cmds/src/main.cairo index ff11139e..eb6e2654 100644 --- a/packages/cmds/src/main.cairo +++ b/packages/cmds/src/main.cairo @@ -1,7 +1,8 @@ use shinigami_compiler::compiler::CompilerImpl; use shinigami_engine::engine::{EngineImpl, EngineInternalImpl}; -use shinigami_engine::utxo::{UTXO}; -use shinigami_engine::transaction::{EngineInternalTransactionImpl, EngineInternalTransactionTrait}; +use shinigami_engine::transaction::{ + EngineInternalTransactionImpl, EngineInternalTransactionTrait, UTXO, +}; use shinigami_engine::flags; use shinigami_engine::witness; use shinigami_engine::hash_cache::HashCacheImpl; diff --git a/packages/engine/src/lib.cairo b/packages/engine/src/lib.cairo index 0dbe353f..2a70ac14 100644 --- a/packages/engine/src/lib.cairo +++ b/packages/engine/src/lib.cairo @@ -32,7 +32,6 @@ pub mod signature { pub mod schnorr; } pub mod transaction; -pub mod utxo; #[cfg(test)] mod tests { diff --git a/packages/engine/src/signature/sighash.cairo b/packages/engine/src/signature/sighash.cairo index 18c36580..e6e86c31 100644 --- a/packages/engine/src/signature/sighash.cairo +++ b/packages/engine/src/signature/sighash.cairo @@ -221,6 +221,10 @@ pub impl TaprootSighashOptionsImpl of TaprootSighashOptionsTrait { } } + fn set_annex(ref self: TaprootSighashOptions, annex: @ByteArray) { + self.annex_hash = @sha256_byte_array(annex); + } + // Write in msg the sihash message extension defined by the current active flag. fn write_digest_extensions(ref self: TaprootSighashOptions, ref msg: ByteArray) { // Base extension doesn'nt modify the digest at all. diff --git a/packages/engine/src/signature/taproot_signature.cairo b/packages/engine/src/signature/taproot_signature.cairo index 94b5ad53..2f486a2d 100644 --- a/packages/engine/src/signature/taproot_signature.cairo +++ b/packages/engine/src/signature/taproot_signature.cairo @@ -4,7 +4,9 @@ use crate::transaction::{ EngineTransactionTrait, }; use crate::flags::ScriptFlags; -use crate::signature::{constants, schnorr, sighash, sighash::{TaprootSighashOptionsTrait}}; +use crate::signature::{ + constants, schnorr, sighash, sighash::{TaprootSighashOptionsTrait, TaprootSighashOptions}, +}; use crate::hash_cache::{TxSigHashes, SigHashMidstateTrait}; use crate::errors::Error; @@ -54,6 +56,13 @@ pub fn parse_taproot_sig_and_pk< return Result::Ok((pk, sig, sighash_type)); } +// TODO: remplace sig result by VerifyResult ? +// #[derive(Clone, Copy, Drop, Default)] +// pub struct VerifyResult { +// sigValid: bool, +// sigMatch: bool, +// } + #[derive(Drop)] pub struct TaprootSigVerifier { // public key as a point on the secp256k1 curve, used to verify the signature @@ -96,7 +105,7 @@ pub trait TaprootSigVerifierTrait< sig_bytes: @ByteArray, pk_bytes: @ByteArray, ref engine: Engine, ) -> Result, felt252>; fn verify(self: TaprootSigVerifier) -> Result<(), felt252>; - fn verify_base(self: TaprootSigVerifier) -> Result<(), felt252>; + fn verify_base(self: TaprootSigVerifier, ref engine: Engine) -> Result<(), felt252>; } pub impl TaprootSigVerifierImpl< @@ -179,16 +188,42 @@ pub impl TaprootSigVerifierImpl< let mut opts = TaprootSighashOptionsTrait::new_with_annex(self.annex); let sig_hash = sighash::calc_taproot_signature_hash::< T, - >(self.hashCache, self.hash_type, self.tx, self.inputIndex, self.prevOuts, ref opts)?; + >( + self.hashCache, self.hash_type, self.tx, self.inputIndex, self.prevOuts, ref opts, + )?; // on error should return error or false ? if !schnorr::verify_schnorr(self.sig, @sig_hash.into(), self.pk_bytes)? { - return Result::Err(Error::TAPROOT_INVALID_SIG); + return Result::Err( + Error::TAPROOT_INVALID_SIG, + ); // should not return error ? VerifyResult ? } Result::Ok(()) } - fn verify_base(self: TaprootSigVerifier) -> Result<(), felt252> { - // TODO: implement taproot verification + fn verify_base(self: TaprootSigVerifier, ref engine: Engine) -> Result<(), felt252> { + if (self.pub_key.is_none()) { + return Result::Ok(()); + } + + let mut opts = TaprootSighashOptionsTrait::new_with_tapscript_version( + engine.taproot_context.code_sep, @engine.taproot_context.tapleaf_hash.into(), + ); + + if engine.taproot_context.annex.len() > 0 { + opts.set_annex(engine.taproot_context.annex); + } + + let sig_hash = sighash::calc_taproot_signature_hash::< + T, + >( + self.hashCache, self.hash_type, self.tx, self.inputIndex, self.prevOuts, ref opts, + )?; // on error should return error or false ? + + if !schnorr::verify_schnorr(self.sig, @sig_hash.into(), self.pk_bytes)? { + return Result::Err( + Error::TAPROOT_INVALID_SIG, + ); // should not return error ? VerifyResult ? + } Result::Ok(()) } } diff --git a/packages/engine/src/tests/test_taproot_hash.cairo b/packages/engine/src/tests/test_taproot_hash.cairo index 4b09888a..2c73776a 100644 --- a/packages/engine/src/tests/test_taproot_hash.cairo +++ b/packages/engine/src/tests/test_taproot_hash.cairo @@ -3,10 +3,10 @@ use crate::signature::sighash::{ TAPSCRIPT_SIGHASH_EXT_FLAG, }; use crate::transaction::{ - EngineTransactionOutput, EngineTransaction, EngineTransactionInput, EngineOutPoint, + EngineTransactionOutput, EngineTransaction, EngineTransactionInput, EngineOutPoint, UTXO, }; use crate::hash_cache::{TxSigHashes, SigHashMidstateTrait}; -use shinigami_engine::utxo::{UTXO}; +use shinigami_engine::utxo::{}; use shinigami_utils::bytecode::hex_to_bytecode; use shinigami_utils::byte_array::{U256IntoByteArray}; diff --git a/packages/engine/src/transaction.cairo b/packages/engine/src/transaction.cairo index cfb2fc34..5e254be0 100644 --- a/packages/engine/src/transaction.cairo +++ b/packages/engine/src/transaction.cairo @@ -3,7 +3,14 @@ use shinigami_utils::byte_array::{byte_array_value_at_le, byte_array_value_at_be use shinigami_utils::bytecode::{bytecode_to_hex, read_var_int, write_var_int}; use shinigami_utils::bit_shifts::shr; use shinigami_utils::hash::double_sha256; -use shinigami_engine::utxo::{UTXO}; + +#[derive(Debug, Drop, Clone, Default)] +pub struct UTXO { + pub amount: i64, + pub pubkey_script: ByteArray, + pub block_height: u32, + // TODO: flags? +} // Tracks previous transaction outputs #[derive(Drop, Copy, Default)] diff --git a/packages/engine/src/utxo.cairo b/packages/engine/src/utxo.cairo deleted file mode 100644 index bd3d84a8..00000000 --- a/packages/engine/src/utxo.cairo +++ /dev/null @@ -1,7 +0,0 @@ -#[derive(Debug, Drop, Clone, Default)] -pub struct UTXO { - pub amount: i64, - pub pubkey_script: ByteArray, - pub block_height: u32, - // TODO: flags? -} diff --git a/packages/tests/src/tests/test_coinbase.cairo b/packages/tests/src/tests/test_coinbase.cairo index 12d223d7..8bf28eef 100644 --- a/packages/tests/src/tests/test_coinbase.cairo +++ b/packages/tests/src/tests/test_coinbase.cairo @@ -113,7 +113,6 @@ fn test_validate_coinbase_block_481823() { } #[test] -#[ignore] fn test_validate_coinbase_block_481824() { // Test the first block after BIP141 segwit let raw_transaction_hex = @@ -127,7 +126,6 @@ fn test_validate_coinbase_block_481824() { } #[test] -#[ignore] fn test_validate_coinbase_block_538403() { // Test random block from learnmebitcoin let raw_transaction_hex = diff --git a/packages/tests/src/tests/test_p2ms.cairo b/packages/tests/src/tests/test_p2ms.cairo index a24817b5..0357bd9d 100644 --- a/packages/tests/src/tests/test_p2ms.cairo +++ b/packages/tests/src/tests/test_p2ms.cairo @@ -1,8 +1,6 @@ -use shinigami_engine::transaction::EngineInternalTransactionTrait; -use shinigami_engine::utxo::{UTXO}; - -use crate::validate; +use shinigami_engine::transaction::{UTXO, EngineInternalTransactionTrait}; use shinigami_utils::bytecode::hex_to_bytecode; +use crate::validate; #[test] fn test_p2ms_1_of_2() { diff --git a/packages/tests/src/tests/test_p2pk.cairo b/packages/tests/src/tests/test_p2pk.cairo index 28067885..10334351 100644 --- a/packages/tests/src/tests/test_p2pk.cairo +++ b/packages/tests/src/tests/test_p2pk.cairo @@ -1,7 +1,6 @@ use shinigami_engine::engine::{EngineImpl}; -use shinigami_engine::transaction::EngineInternalTransactionTrait; +use shinigami_engine::transaction::{UTXO, EngineInternalTransactionTrait}; use crate::validate; -use shinigami_engine::utxo::{UTXO}; use shinigami_utils::bytecode::hex_to_bytecode; // https://learnmeabitcoin.com/explorer/tx/cda1f7d88232ff7e4fc1fcbf8a66b2cc3b8e19b5bc0ad22618453b8b75156740 diff --git a/packages/tests/src/tests/test_p2pkh.cairo b/packages/tests/src/tests/test_p2pkh.cairo index b6debae0..baf697ef 100644 --- a/packages/tests/src/tests/test_p2pkh.cairo +++ b/packages/tests/src/tests/test_p2pkh.cairo @@ -1,7 +1,6 @@ -use shinigami_engine::transaction::EngineInternalTransactionTrait; -use shinigami_engine::utxo::{UTXO}; -use crate::validate; +use shinigami_engine::transaction::{UTXO, EngineInternalTransactionTrait}; use shinigami_utils::bytecode::hex_to_bytecode; +use crate::validate; #[test] fn test_p2pkh_transaction() { diff --git a/packages/tests/src/tests/test_p2sh.cairo b/packages/tests/src/tests/test_p2sh.cairo index 4df8a688..7b1aee13 100644 --- a/packages/tests/src/tests/test_p2sh.cairo +++ b/packages/tests/src/tests/test_p2sh.cairo @@ -1,7 +1,6 @@ -use shinigami_engine::transaction::EngineInternalTransactionTrait; +use shinigami_engine::transaction::{UTXO, EngineInternalTransactionTrait}; use shinigami_engine::engine::EngineImpl; use shinigami_engine::hash_cache::HashCacheImpl; -use shinigami_engine::utxo::{UTXO}; use shinigami_engine::flags::ScriptFlags; use crate::validate; use shinigami_utils::bytecode::hex_to_bytecode; diff --git a/packages/tests/src/tests/test_p2wpkh.cairo b/packages/tests/src/tests/test_p2wpkh.cairo index 9c219f23..13f89db0 100644 --- a/packages/tests/src/tests/test_p2wpkh.cairo +++ b/packages/tests/src/tests/test_p2wpkh.cairo @@ -1,5 +1,4 @@ -use shinigami_engine::transaction::EngineInternalTransactionTrait; -use shinigami_engine::utxo::{UTXO}; +use shinigami_engine::transaction::{UTXO, EngineInternalTransactionTrait}; use crate::validate; use shinigami_utils::bytecode::hex_to_bytecode; use shinigami_engine::flags::ScriptFlags; diff --git a/packages/tests/src/tests/test_p2wsh.cairo b/packages/tests/src/tests/test_p2wsh.cairo index 94f5f51a..7d9d3ab4 100644 --- a/packages/tests/src/tests/test_p2wsh.cairo +++ b/packages/tests/src/tests/test_p2wsh.cairo @@ -1,9 +1,8 @@ -use shinigami_engine::transaction::EngineInternalTransactionTrait; +use shinigami_engine::transaction::{UTXO, EngineInternalTransactionTrait}; use shinigami_engine::flags::ScriptFlags; use shinigami_engine::errors::Error; use crate::validate; -use shinigami_engine::utxo::{UTXO}; use shinigami_utils::bytecode::hex_to_bytecode; // P2WSH with P2MS diff --git a/packages/tests/src/tests/test_transactions.cairo b/packages/tests/src/tests/test_transactions.cairo index 36000db1..14fda14f 100644 --- a/packages/tests/src/tests/test_transactions.cairo +++ b/packages/tests/src/tests/test_transactions.cairo @@ -1,5 +1,4 @@ -use shinigami_engine::transaction::EngineInternalTransactionTrait; -use shinigami_engine::utxo::{UTXO}; +use shinigami_engine::transaction::{UTXO, EngineInternalTransactionTrait}; use crate::validate; use shinigami_utils::byte_array::u256_from_byte_array_with_offset; diff --git a/packages/tests/src/validate.cairo b/packages/tests/src/validate.cairo index dcdc05df..4c665313 100644 --- a/packages/tests/src/validate.cairo +++ b/packages/tests/src/validate.cairo @@ -1,8 +1,7 @@ use shinigami_engine::engine::EngineImpl; use shinigami_engine::hash_cache::HashCacheImpl; -use shinigami_engine::transaction::EngineTransaction; +use shinigami_engine::transaction::{EngineTransaction, UTXO}; use shinigami_engine::opcodes::Opcode; -use shinigami_engine::utxo::{UTXO}; // TODO: Move validate coinbase here