Skip to content

Commit

Permalink
clean + add schnorrVerif in TaprootSigVerifier
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeanmichel7 committed Jan 16, 2025
1 parent 22b700a commit da91b8d
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 246 deletions.
30 changes: 15 additions & 15 deletions packages/engine/src/signature/schnorr.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,15 @@ pub fn parse_schnorr_signature(sig_bytes: @ByteArray) -> Result<Signature, felt2

let mut r: u256 = 0;
let mut s: u256 = 0;
for i in 0
..sig_bytes
.len() {
if i < 32 {
r *= 256;
r += sig_bytes[i].into();
} else {
s *= 256;
s += sig_bytes[i].into();
}
};
for i in 0..sig_bytes.len() {
if i < 32 {
r *= 256;
r += sig_bytes[i].into();
} else {
s *= 256;
s += sig_bytes[i].into();
}
};
if r >= constants::SECP256_FIELD_VAL {
return Result::Err(Error::SCHNORR_INVALID_SIG_R_FIELD);
}
Expand All @@ -59,12 +57,14 @@ pub fn parse_schnorr_signature(sig_bytes: @ByteArray) -> Result<Signature, felt2
// 8. Fail if not hash_even_y(R)
// 9. Fail is x(R) != r.
// 10. Return success if failure did not occur before reaching this point.
pub fn verify_schnorr(sig: Signature, hash: ByteArray, pubkey: ByteArray) -> Result<bool, felt252> {
pub fn verify_schnorr(
sig: Signature, hash: @ByteArray, pubkey: @ByteArray,
) -> Result<bool, felt252> {
if hash.len() != 32 {
return Result::Err(Error::SCHNORR_INVALID_MSG_SIZE);
}

let P = parse_schnorr_pub_key(@pubkey)?;
let P = parse_schnorr_pub_key(pubkey)?;

let n = Secp256Trait::<Secp256k1Point>::get_curve_size();
if sig.r >= p {
Expand All @@ -76,8 +76,8 @@ pub fn verify_schnorr(sig: Signature, hash: ByteArray, pubkey: ByteArray) -> Res
let mut msg: ByteArray = Default::default();
msg.append_word(sig.r.high.into(), 16);
msg.append_word(sig.r.low.into(), 16);
msg.append(@pubkey);
msg.append(@hash);
msg.append(pubkey);
msg.append(hash);
let e = tagged_hash(HashTag::Bip0340Challenge, @msg);

let G = Secp256Trait::<Secp256k1Point>::get_generator_point();
Expand Down
1 change: 0 additions & 1 deletion packages/engine/src/signature/sighash.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,6 @@ pub fn calc_tapscript_signature_hash() -> u256 {
0 // TODO
}


#[cfg(test)]
mod tests {
use super::{calc_taproot_signature_hash, TxSigHashes, TaprootSighashOptions};
Expand Down
160 changes: 0 additions & 160 deletions packages/engine/src/signature/signature.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -597,163 +597,3 @@ pub fn remove_signature(script: @ByteArray, sig_bytes: @ByteArray) -> @ByteArray

@processed_script
}
// // Parses the public key and signature for taproot spend.
// // Returning a tuple containing the parsed public key, signature, and hash type.
// pub fn parse_taproot_sig_and_pk<
// T,
// +Drop<T>,
// I,
// +Drop<I>,
// impl IEngineTransactionInputTrait: EngineTransactionInputTrait<I>,
// O,
// +Drop<O>,
// impl IEngineTransactionOutputTrait: EngineTransactionOutputTrait<O>,
// impl IEngineTransactionTrait: EngineTransactionTrait<
// T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait,
// >,
// >(
// ref vm: Engine<T>, pk_bytes: @ByteArray, sig_bytes: @ByteArray,
// ) -> Result<(Secp256k1Point, Signature, u32), felt252> {
// // Parse schnorr public key
// let pk = schnorr::parse_schnorr_pub_key(pk_bytes)?;

// // Check the size of the signature and if the `sighash byte` is set.
// let sig_len = sig_bytes.len();
// let (sig, sighash_type) = if sig_len == constants::SCHNORR_SIG_SIZE {
// // Parse signature, `sighash_type` has default value
// (schnorr::parse_schnorr_signature(sig_bytes)?, constants::SIG_HASH_DEFAULT)
// } else if sig_len == constants::SCHNORR_SIG_SIZE + 1 && sig_bytes[64] != 0 {
// // Extract `sighash_byte` and parse signature
// let sighash_type = sig_bytes[64];
// let mut sig_bytes_truncate: ByteArray = "";
// for i in 0..constants::SCHNORR_SIG_SIZE {
// sig_bytes_truncate.append_byte(sig_bytes[i]);
// };
// (schnorr::parse_schnorr_signature(@sig_bytes_truncate)?, sighash_type.into())
// } else {
// // Error on invalid signature size.
// return Result::Err(Error::SCHNORR_INVALID_SIG_SIZE);
// };

// return Result::Ok((pk, sig, sighash_type));
// }

// #[derive(Drop)]
// pub struct TaprootSigVerifier {
// // public key as a point on the secp256k1 curve, used to verify the signature
// pub_key: Secp256k1Point,
// // ECDSA signature
// sig: Signature,
// // raw byte array of the signature
// sig_bytes: @ByteArray,
// // raw byte array of the public key
// pk_bytes: @ByteArray,
// // specifies how the transaction was hashed for signing
// hash_type: u32,
// // annex data used for taproot verification
// annex: @ByteArray,
// }

// pub trait TaprootSigVerifierTrait<
// I,
// O,
// T,
// +EngineTransactionInputTrait<I>,
// +EngineTransactionOutputTrait<O>,
// +EngineTransactionTrait<T, I, O>,
// > {
// fn new(
// ref vm: Engine<T>, sig_bytes: @ByteArray, pk_bytes: @ByteArray, annex: @ByteArray,
// ) -> Result<TaprootSigVerifier, felt252>;
// fn new_base(
// ref vm: Engine<T>, sig_bytes: @ByteArray, pk_bytes: @ByteArray,
// ) -> Result<TaprootSigVerifier, felt252>;
// fn verify(ref self: TaprootSigVerifier) -> bool;
// fn verify_base(ref self: TaprootSigVerifier) -> bool;
// }

// pub impl TaprootSigVerifierImpl<
// I,
// O,
// T,
// impl IEngineTransactionInput: EngineTransactionInputTrait<I>,
// impl IEngineTransactionOutput: EngineTransactionOutputTrait<O>,
// impl IEngineTransaction: EngineTransactionTrait<
// T, I, O, IEngineTransactionInput, IEngineTransactionOutput,
// >,
// +Drop<O>,
// +Drop<I>,
// +Drop<T>,
// > of TaprootSigVerifierTrait<I, O, T> {
// fn new(
// ref vm: Engine<T>, sig_bytes: @ByteArray, pk_bytes: @ByteArray, annex: @ByteArray,
// ) -> Result<TaprootSigVerifier, felt252> {
// let (pub_key, sig, hash_type) = parse_taproot_sig_and_pk(ref vm, pk_bytes, sig_bytes)?;
// Result::Ok(
// TaprootSigVerifier {
// pub_key: pub_key, sig: sig, sig_bytes, pk_bytes, hash_type: hash_type, annex,
// },
// )
// }

// fn new_base(
// ref vm: Engine<T>, sig_bytes: @ByteArray, pk_bytes: @ByteArray,
// ) -> Result<TaprootSigVerifier, felt252> {
// let pk_len = pk_bytes.len();
// // Fail immediately if public key length is zero
// if pk_len == 0 {
// return Result::Err(Error::TAPROOT_EMPTY_PUBKEY);
// // If key is 32 byte, parse as normal
// } else if pk_len == 32 {
// let (pub_key, sig, hash_type) = parse_taproot_sig_and_pk(ref vm, pk_bytes,
// sig_bytes)?;
// return (Result::Ok(
// TaprootSigVerifier {
// pub_key: pub_key,
// sig: sig,
// sig_bytes,
// pk_bytes,
// hash_type: hash_type,
// annex: vm.taproot_context.annex,
// },
// ));
// // Otherwise, this is an unknown public key, assuming sig is valid
// } else {
// // However, return an error if the flags preventinf usage of unknown key type is set
// if vm.has_flag(ScriptFlags::ScriptVerifyDiscourageUpgradeablePubkeyType) {
// return Result::Err(Error::DISCOURAGE_UPGRADABLE_PUBKEY_TYPE);
// }

// let pub_key: u256 = u256_from_byte_array_with_offset(pk_bytes, 0, 32);
// let pk = Secp256Trait::<
// Secp256k1Point,
// >::secp256_ec_get_point_from_x_syscall(pub_key, false)
// .unwrap_syscall()
// .expect(Error::SECP256K1_INVALID_POINT);
// return (Result::Ok(
// TaprootSigVerifier {
// pub_key: pk,
// sig: Signature { r: 0, s: 0, y_parity: false },
// sig_bytes,
// pk_bytes,
// hash_type: constants::SIG_HASH_DEFAULT,
// annex: @"",
// },
// ));
// }
// }

// fn verify(ref self: TaprootSigVerifier) -> bool {
// // let sig_hash = sighash::calc_taproot_signature_hash(); // TODO
// // return schnorr::verify_schnorr();
// false
// }

// fn verify_base(ref self: TaprootSigVerifier) -> bool {
// // let sig_hash = sighash::calc_taproot_signature_hash(); // TODO
// // return schnorr::verify_schnorr();
// false
// }
// }


67 changes: 13 additions & 54 deletions packages/engine/src/signature/taproot_signature.cairo
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
use crate::engine::{Engine, EngineInternalImpl};
use crate::transaction::{
EngineTransactionInputTrait, EngineTransactionOutputTrait, EngineTransactionTrait,
EngineTransactionOutput, EngineTransactionInputTrait, EngineTransactionOutputTrait,
EngineTransactionTrait,
};
use starknet::secp256_trait::{Secp256Trait, Signature};
use starknet::secp256k1::{Secp256k1Point};
use crate::flags::ScriptFlags;
use crate::signature::{constants, schnorr};
use crate::signature::{sighash, sighash::{TaprootSighashOptionsTrait}};
use crate::transaction::{EngineTransactionOutput};
use shinigami_utils::byte_array::u256_from_byte_array_with_offset;
use crate::hash_cache::{TxSigHashes};
use crate::hash_cache::{SigHashMidstateTrait};
// use crate::signature::{sighash, constants, schnorr};
use crate::signature::{constants, schnorr, sighash, sighash::{TaprootSighashOptionsTrait}};
use crate::hash_cache::{TxSigHashes, SigHashMidstateTrait};
use crate::errors::Error;
// use crate::parser;
use starknet::SyscallResultTrait;

use shinigami_utils::byte_array::{U256IntoByteArray, u256_from_byte_array_with_offset};
use starknet::SyscallResultTrait;
use starknet::secp256_trait::{Secp256Trait, Signature};
use starknet::secp256k1::{Secp256k1Point};

pub const SCHNORR_SIGNATURE_LEN: usize = 64;

Expand Down Expand Up @@ -60,38 +56,6 @@ pub fn parse_taproot_sig_and_pk<
return Result::Ok((pk, sig, sighash_type));
}

// pub fn parse_schnorr_pub_key(pk_bytes: @ByteArray) -> Result<Secp256k1Point, felt252> {
// if pk_bytes.len() == 0 || pk_bytes.len() != 32 {
// return Result::Err('Invalid schnorr pubkey length');
// }

// let mut key_compressed: ByteArray = "\02";
// key_compressed.append(pk_bytes);
// return parse_pub_key(@key_compressed);
// }

// pub fn schnorr_parse_signature(sig_bytes: @ByteArray) -> Result<(Signature, u32), felt252> {
// let sig_bytes_len = sig_bytes.len();
// let mut hash_type: u32 = 0;
// if sig_bytes_len == SCHNORR_SIGNATURE_LEN {
// hash_type = constants::SIG_HASH_DEFAULT;
// } else if sig_bytes_len == SCHNORR_SIGNATURE_LEN + 1 && sig_bytes[64] != 0 {
// hash_type = sig_bytes[64].into();
// } else {
// return Result::Err('Invalid taproot signature len');
// }
// Result::Ok(
// (
// Signature {
// r: u256_from_byte_array_with_offset(sig_bytes, 0, 32),
// s: u256_from_byte_array_with_offset(sig_bytes, 32, 32),
// y_parity: false // Schnorr signatures don't use y_parity
// },
// hash_type,
// ),
// )
// }

#[derive(Drop)]
pub struct TaprootSigVerifier<T> {
// public key as a point on the secp256k1 curve, used to verify the signature
Expand Down Expand Up @@ -170,8 +134,6 @@ pub impl TaprootSigVerifierImpl<
sig_bytes: @ByteArray, pk_bytes: @ByteArray, annex: @ByteArray, ref engine: Engine<T>,
) -> Result<TaprootSigVerifier<T>, felt252> {
let (pub_key, sig, hash_type) = parse_taproot_sig_and_pk(ref engine, pk_bytes, sig_bytes)?;
// let pub_key = parse_schnorr_pub_key(pk_bytes)?;
// let (sig, hash_type) = schnorr_parse_signature(sig_bytes)?;
let sig_hashes = SigHashMidstateTrait::new(engine.transaction, engine.tx_idx);
let prevOutput = EngineTransactionOutput {
value: engine.amount, publickey_script: (*engine.scripts[1]).clone(),
Expand Down Expand Up @@ -241,7 +203,11 @@ pub impl TaprootSigVerifierImpl<
T,
>(self.hashCache, self.hash_type, self.tx, self.inputIndex, self.prevOuts, ref opts)?;

is_valid_schnorr_signature(sig_hash, self.sig, self.pub_key)?;
let is_valid_sig = schnorr::verify_schnorr(self.sig, @sig_hash.into(), self.pk_bytes)
.is_ok();
if !is_valid_sig {
return Result::Err(Error::TAPROOT_INVALID_SIG);
}
Result::Ok(())
}

Expand All @@ -251,10 +217,3 @@ pub impl TaprootSigVerifierImpl<
}
}

pub fn is_valid_schnorr_signature<
Secp256Point, +Drop<Secp256Point>, impl Secp256Impl: Secp256Trait<Secp256Point>,
>(
msg_hash: u256, sig: Signature, public_key: Secp256Point,
) -> Result<(), felt252> {
return Result::Ok(());
}
Loading

0 comments on commit da91b8d

Please sign in to comment.