Skip to content

Commit

Permalink
move schnorr sig verification to bitcoin lib
Browse files Browse the repository at this point in the history
  • Loading branch information
SebastianElvis committed Sep 5, 2024
1 parent 9a99084 commit 958826b
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 19 deletions.
5 changes: 5 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions packages/bitcoin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@ edition.workspace = true

[dependencies]
bitcoin = { workspace = true }
digest = { workspace = true }
sha2 = { workspace = true }
serde = { workspace = true }
schemars = { workspace = true }
cosmwasm-std = { workspace = true }
k256 = { workspace = true }
thiserror = { workspace = true }

[dev-dependencies]
hex = { workspace = true }
9 changes: 9 additions & 0 deletions packages/bitcoin/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use thiserror::Error;

#[derive(Error, Debug, PartialEq)]
pub enum Error {
#[error("Failed to parse public key")]
FailedToParsePublicKey(String),
#[error("Invalid schnorr signature")]
InvalidSchnorrSignature(String),
}
4 changes: 4 additions & 0 deletions packages/bitcoin/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@ pub use bitcoin::{
pub use cosmwasm_std::Uint256;

pub mod chain_params;
pub mod error;
pub mod merkle;
pub mod op_return;
pub mod pow;
pub mod schnorr;

pub type Result<T> = std::result::Result<T, error::Error>;

#[cfg(test)]
mod tests {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@
//!
//! Adapted from `sha2` [sha256.rs](https://github.com/RustCrypto/hashes/blob/master/sha2/src/sha256.rs)
//! and https://github.com/CosmWasm/cosmwasm/blob/main/packages/crypto/src/identity_digest.rs
use crate::error::Error;
use crate::Result;
use digest::consts::U32;
use digest::generic_array::GenericArray;
use digest::{FixedOutput, HashMarker, Output, OutputSizeUser, Reset, Update};
use k256::schnorr::signature::DigestVerifier;
use k256::schnorr::Signature as SchnorrSignature;
use k256::schnorr::VerifyingKey;
use sha2::Digest;

/// The 256-bits identity container
Expand Down Expand Up @@ -40,6 +45,22 @@ impl Reset for Identity256 {
}
}

pub fn new_digest(msg_hash: [u8; 32]) -> Identity256 {
pub fn new_digest(msg_hash: &[u8; 32]) -> Identity256 {
Identity256::new().chain(msg_hash)
}

pub fn verify_digest(
pub_key: &[u8],
msg_hash: &[u8; 32],
signature: &SchnorrSignature,
) -> Result<()> {
let digest = new_digest(msg_hash);

// verify the signature w.r.t. the signature, the sig hash, and the public key
let verifying_key = VerifyingKey::from_bytes(pub_key)
.map_err(|e| Error::FailedToParsePublicKey(e.to_string()))?;

verifying_key
.verify_digest(digest, signature)
.map_err(|e| Error::InvalidSchnorrSignature(e.to_string()))
}
17 changes: 9 additions & 8 deletions packages/btcstaking/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ version.workspace = true
edition.workspace = true

[dependencies]
bitcoin = { workspace = true }
digest = { workspace = true }
rust_decimal = { workspace = true }
hex = { workspace = true }
sha2 = { workspace = true }
k256 = { workspace = true }
thiserror = { workspace = true }
eots = { path = "../eots" }
babylon-bitcoin = { workspace = true }
bitcoin = { workspace = true }
digest = { workspace = true }
rust_decimal = { workspace = true }
hex = { workspace = true }
sha2 = { workspace = true }
k256 = { workspace = true }
thiserror = { workspace = true }
eots = { path = "../eots" }

[dev-dependencies]
test-utils = { path = "../test-utils" }
Expand Down
2 changes: 2 additions & 0 deletions packages/btcstaking/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ use thiserror::Error;

#[derive(Error, Debug, PartialEq)]
pub enum Error {
#[error("Bitcoin error: {0}")]
BitcoinError(#[from] babylon_bitcoin::error::Error),
#[error("Failed to decompress bytes to a projective point")]
DecompressPointFailed {},
#[error("Point {0} is at infinity")]
Expand Down
1 change: 0 additions & 1 deletion packages/btcstaking/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
mod adaptor_sig;
pub mod error;
mod identity_digest;
pub mod scripts_utils;
pub mod sig_verify;
pub mod tx_verify;
Expand Down
11 changes: 2 additions & 9 deletions packages/btcstaking/src/sig_verify.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::adaptor_sig::AdaptorSignature;
use crate::error::Error;
use crate::identity_digest::new_digest;
use crate::Result;
use babylon_bitcoin::schnorr;
use bitcoin::hashes::Hash;
use bitcoin::sighash::{Prevouts, SighashCache};
use bitcoin::Transaction;
Expand Down Expand Up @@ -47,15 +47,8 @@ pub fn verify_transaction_sig_with_output(
) -> Result<()> {
// calculate the sig hash of the tx for the given spending path
let sighash = calc_sighash(transaction, funding_output, path_script)?;
let sighash_digest = new_digest(sighash);

// verify the signature w.r.t. the signature, the sig hash, and the public key
let verifying_key = VerifyingKey::from_bytes(&pub_key.serialize())
.map_err(|e| Error::FailedToParsePublicKey(e.to_string()))?;

verifying_key
.verify_digest(sighash_digest, signature)
.map_err(|e| Error::InvalidSchnorrSignature(e.to_string()))
schnorr::verify_digest(&pub_key.serialize(), &sighash, signature).map_err(Error::BitcoinError)
}

/// enc_verify_transaction_sig_with_output verifies the validity of a Schnorr adaptor signature for a given transaction
Expand Down

0 comments on commit 958826b

Please sign in to comment.