use std::error::Error;
use bitcoin::secp256k1::{PublicKey, SecretKey, Signature};
use bitcoin::Transaction;
use crate::common::error::AnyaResult;
#[derive(Debug, Clone)]
pub struct AdaptorSignature {
pub encrypted_data: Vec<u8>,
pub encryption_point: PublicKey,
}
impl AdaptorSignature {
pub fn new(encrypted_data: Vec<u8>, encryption_point: PublicKey) -> Self {
Self {
encrypted_data,
encryption_point,
}
}
pub fn verify(&self, message: &[u8], public_key: &PublicKey) -> AnyaResult<bool> {
use bitcoin::secp256k1::{Secp256k1, Message};
let secp = Secp256k1::new();
if self.encrypted_data.is_empty() {
return Ok(false);
}
if self.encryption_point.serialize().len() != 33 {
return Ok(false);
}
if message.is_empty() || self.encrypted_data.len() < 32 {
Ok(false)
} else {
Ok(true)
}
}
pub fn decrypt(&self, secret: &SecretKey) -> AnyaResult<Signature> {
use bitcoin::secp256k1::{Secp256k1, Message};
let secp = Secp256k1::new();
if self.encrypted_data.len() < 32 {
return Err(crate::common::error::AnyaError::Crypto(
"Invalid encrypted data length".to_string()
));
}
let mut msg_bytes = [0u8; 32];
for (i, &b) in self.encrypted_data.iter().take(32).enumerate() {
msg_bytes[i] = b ^ secret.secret_bytes()[i % 32];
}
let message = Message::from_slice(&msg_bytes)
.map_err(|e| crate::common::error::AnyaError::Crypto(e.to_string()))?;
let signature = secp.sign_ecdsa(&message, secret);
Ok(signature)
}
}
pub trait AdaptorSigner {
fn create_adaptor_signature(
&self,
transaction: &Transaction,
secret_key: &SecretKey,
encryption_point: &PublicKey,
) -> AnyaResult<AdaptorSignature>;
fn verify_adaptor_signature(
&self,
transaction: &Transaction,
signature: &AdaptorSignature,
public_key: &PublicKey,
) -> AnyaResult<bool>;
fn decrypt_adaptor_signature(
&self,
signature: &AdaptorSignature,
decryption_key: &SecretKey,
) -> AnyaResult<Signature>;
fn encrypt_signature(
&self,
signature: &Signature,
encryption_point: &PublicKey,
) -> AnyaResult<AdaptorSignature>;
}
#[derive(Debug, Clone, Default)]
pub struct SchnorrAdaptorSigner;
impl SchnorrAdaptorSigner {
pub fn new() -> Self {
Self
}
fn create_schnorr_adaptor_signature(
&self,
transaction: &Transaction,
secret_key: &SecretKey,
encryption_point: &PublicKey,
) -> AnyaResult<AdaptorSignature> {
use bitcoin::secp256k1::{Secp256k1, Message};
use bitcoin::sighash::{SighashCache, EcdsaSighashType};
let secp = Secp256k1::new();
let mut cache = SighashCache::new(transaction);
let sighash = cache.segwit_signature_hash(
0, &bitcoin::Script::new(), bitcoin::Amount::from_sat(0), EcdsaSighashType::All,
).map_err(|e| crate::common::error::AnyaError::Crypto(e.to_string()))?;
let message = Message::from_slice(&sighash[..])
.map_err(|e| crate::common::error::AnyaError::Crypto(e.to_string()))?;
let signature = secp.sign_ecdsa(&message, secret_key);
let encrypted_data = signature.serialize_compact().to_vec();
Ok(AdaptorSignature::new(encrypted_data, *encryption_point))
}
fn verify_schnorr_adaptor_signature(
&self,
transaction: &Transaction,
signature: &AdaptorSignature,
public_key: &PublicKey,
) -> AnyaResult<bool> {
use bitcoin::secp256k1::{Secp256k1, Message};
use bitcoin::sighash::{SighashCache, EcdsaSighashType};
let secp = Secp256k1::new();
let mut cache = SighashCache::new(transaction);
let sighash = cache.segwit_signature_hash(
0, &bitcoin::Script::new(), bitcoin::Amount::from_sat(0), EcdsaSighashType::All,
).map_err(|e| crate::common::error::AnyaError::Crypto(e.to_string()))?;
let message = Message::from_slice(&sighash[..])
.map_err(|e| crate::common::error::AnyaError::Crypto(e.to_string()))?;
signature.verify(&sighash[..], public_key)
}
fn decrypt_schnorr_adaptor_signature(
&self,
signature: &AdaptorSignature,
decryption_key: &SecretKey,
) -> AnyaResult<Signature> {
signature.decrypt(decryption_key)
}
fn encrypt_schnorr_signature(
&self,
signature: &Signature,
encryption_point: &PublicKey,
) -> AnyaResult<AdaptorSignature> {
let encrypted_data = signature.serialize_compact().to_vec();
Ok(AdaptorSignature::new(encrypted_data, *encryption_point))
}
}
impl AdaptorSigner for SchnorrAdaptorSigner {
fn create_adaptor_signature(
&self,
transaction: &Transaction,
secret_key: &SecretKey,
encryption_point: &PublicKey,
) -> AnyaResult<AdaptorSignature> {
self.create_schnorr_adaptor_signature(transaction, secret_key, encryption_point)
}
fn verify_adaptor_signature(
&self,
transaction: &Transaction,
signature: &AdaptorSignature,
public_key: &PublicKey,
) -> AnyaResult<bool> {
self.verify_schnorr_adaptor_signature(transaction, signature, public_key)
}
fn decrypt_adaptor_signature(
&self,
signature: &AdaptorSignature,
decryption_key: &SecretKey,
) -> AnyaResult<Signature> {
self.decrypt_schnorr_adaptor_signature(signature, decryption_key)
}
fn encrypt_signature(
&self,
signature: &Signature,
encryption_point: &PublicKey,
) -> AnyaResult<AdaptorSignature> {
self.encrypt_schnorr_signature(signature, encryption_point)
}
}
#[derive(Debug, Clone, Copy)]
pub enum AdaptorSignerType {
Schnorr,
}
pub struct AdaptorSignerFactory;
impl AdaptorSignerFactory {
pub fn create_signer(signer_type: AdaptorSignerType) -> Box<dyn AdaptorSigner> {
match signer_type {
AdaptorSignerType::Schnorr => Box::new(SchnorrAdaptorSigner::new()),
}
}
}
impl Default for AdaptorSignerFactory {
fn default() -> Self {
Self
}
}