use crate::error::{ConsensusError, Result};
use crate::types::Hash;
use blvm_secp256k1::ecdsa::{ecdsa_sig_parse_compact, ecdsa_sig_verify, ge_from_compressed};
use blvm_secp256k1::scalar::Scalar;
use blvm_secp256k1::schnorr::{schnorr_verify, schnorr_verify_batch};
use blvm_secp256k1::taproot::taproot_output_key as blvm_taproot_output_key;
pub fn verify_ecdsa(
msg_hash: &[u8; 32],
sig_compact: &[u8; 64],
pubkey_compressed: &[u8; 33],
) -> Result<bool> {
let (sigr, sigs) = match ecdsa_sig_parse_compact(sig_compact) {
Some(s) => s,
None => return Ok(false),
};
let pk = match ge_from_compressed(pubkey_compressed) {
Some(p) => p,
None => return Ok(false),
};
let mut msg = Scalar::zero();
msg.set_b32(msg_hash);
Ok(ecdsa_sig_verify(&sigr, &sigs, &pk, &msg))
}
pub fn verify_schnorr(sig: &[u8; 64], msg: &[u8], pubkey: &[u8; 32]) -> Result<bool> {
Ok(schnorr_verify(sig, msg, pubkey))
}
pub fn verify_schnorr_batch(
sigs: &[[u8; 64]],
msgs: &[&[u8]],
pubkeys: &[[u8; 32]],
) -> Result<Vec<bool>> {
let n = sigs.len().min(msgs.len()).min(pubkeys.len());
if n == 0 {
return Ok(Vec::new());
}
let ok = schnorr_verify_batch(sigs, msgs, pubkeys);
if ok {
Ok(vec![true; n])
} else {
let mut results = Vec::with_capacity(n);
for i in 0..n {
results.push(schnorr_verify(&sigs[i], msgs[i], &pubkeys[i]));
}
Ok(results)
}
}
pub fn taproot_output_key(internal_pubkey: &[u8; 32], merkle_root: &Hash) -> Result<[u8; 32]> {
blvm_taproot_output_key(internal_pubkey, merkle_root)
.ok_or_else(|| ConsensusError::InvalidSignature("Invalid internal public key".into()))
}