secp256k1.rs
1 use std::io::{Error, Read, Write}; 2 3 use secp256k1_zkp::ecdsa::Signature; 4 5 use crate::encoding::{Decodable, DecodeError, Encodable}; 6 use crate::module::registry::ModuleDecoderRegistry; 7 8 impl Encodable for secp256k1_zkp::ecdsa::Signature { 9 fn consensus_encode<W: std::io::Write>(&self, writer: &mut W) -> Result<usize, std::io::Error> { 10 let bytes = self.serialize_compact(); 11 writer.write_all(&bytes)?; 12 Ok(bytes.len()) 13 } 14 } 15 16 impl Decodable for secp256k1_zkp::ecdsa::Signature { 17 fn consensus_decode<D: std::io::Read>( 18 d: &mut D, 19 modules: &ModuleDecoderRegistry, 20 ) -> Result<Self, DecodeError> { 21 Signature::from_compact(&<[u8; 64]>::consensus_decode(d, modules)?) 22 .map_err(DecodeError::from_err) 23 } 24 } 25 26 impl Encodable for secp256k1_zkp::PublicKey { 27 fn consensus_encode<W: std::io::Write>(&self, writer: &mut W) -> Result<usize, std::io::Error> { 28 self.serialize().consensus_encode(writer) 29 } 30 } 31 32 impl Decodable for secp256k1_zkp::PublicKey { 33 fn consensus_decode<D: std::io::Read>( 34 d: &mut D, 35 modules: &ModuleDecoderRegistry, 36 ) -> Result<Self, DecodeError> { 37 secp256k1_zkp::PublicKey::from_slice(&<[u8; 33]>::consensus_decode(d, modules)?) 38 .map_err(DecodeError::from_err) 39 } 40 } 41 42 impl Encodable for secp256k1_zkp::SecretKey { 43 fn consensus_encode<W: std::io::Write>(&self, writer: &mut W) -> Result<usize, std::io::Error> { 44 self.secret_bytes().consensus_encode(writer) 45 } 46 } 47 48 impl Decodable for secp256k1_zkp::SecretKey { 49 fn consensus_decode<D: std::io::Read>( 50 d: &mut D, 51 modules: &ModuleDecoderRegistry, 52 ) -> Result<Self, DecodeError> { 53 secp256k1_zkp::SecretKey::from_slice(&<[u8; 32]>::consensus_decode(d, modules)?) 54 .map_err(DecodeError::from_err) 55 } 56 } 57 58 impl Encodable for secp256k1_zkp::schnorr::Signature { 59 fn consensus_encode<W: std::io::Write>(&self, writer: &mut W) -> Result<usize, std::io::Error> { 60 let bytes = &self[..]; 61 assert_eq!( 62 bytes.len(), 63 secp256k1_zkp::constants::SCHNORR_SIGNATURE_SIZE 64 ); 65 writer.write_all(bytes)?; 66 Ok(secp256k1_zkp::constants::SCHNORR_SIGNATURE_SIZE) 67 } 68 } 69 70 impl Decodable for secp256k1_zkp::schnorr::Signature { 71 fn consensus_decode<D: std::io::Read>( 72 d: &mut D, 73 modules: &ModuleDecoderRegistry, 74 ) -> Result<Self, DecodeError> { 75 let bytes = 76 <[u8; secp256k1_zkp::constants::SCHNORR_SIGNATURE_SIZE]>::consensus_decode(d, modules)?; 77 secp256k1_zkp::schnorr::Signature::from_slice(&bytes).map_err(DecodeError::from_err) 78 } 79 } 80 81 impl Encodable for bitcoin::key::KeyPair { 82 fn consensus_encode<W: Write>(&self, writer: &mut W) -> Result<usize, Error> { 83 self.secret_bytes().consensus_encode(writer) 84 } 85 } 86 87 impl Decodable for bitcoin::key::KeyPair { 88 fn consensus_decode<D: Read>( 89 d: &mut D, 90 modules: &ModuleDecoderRegistry, 91 ) -> Result<Self, DecodeError> { 92 let sec_bytes = <[u8; 32]>::consensus_decode(d, modules)?; 93 Self::from_seckey_slice(secp256k1_zkp::global::SECP256K1, &sec_bytes) // FIXME: evaluate security risk of global ctx 94 .map_err(DecodeError::from_err) 95 } 96 } 97 98 #[cfg(test)] 99 mod tests { 100 use secp256k1_zkp::hashes::Hash as BitcoinHash; 101 use secp256k1_zkp::Message; 102 103 use super::super::tests::test_roundtrip; 104 105 #[test_log::test] 106 fn test_ecdsa_sig() { 107 let ctx = secp256k1_zkp::Secp256k1::new(); 108 let (sk, _pk) = ctx.generate_keypair(&mut rand::thread_rng()); 109 let sig = ctx.sign_ecdsa( 110 &Message::from_hashed_data::<secp256k1_zkp::hashes::sha256::Hash>(b"Hello World!"), 111 &sk, 112 ); 113 114 test_roundtrip(sig); 115 } 116 117 #[test_log::test] 118 fn test_schnorr_pub_key() { 119 let ctx = secp256k1_zkp::global::SECP256K1; 120 let mut rng = rand::rngs::OsRng; 121 let sec_key = bitcoin::key::KeyPair::new(ctx, &mut rng); 122 let pub_key = sec_key.public_key(); 123 test_roundtrip(pub_key); 124 125 let sig = ctx.sign_schnorr( 126 &secp256k1_zkp::hashes::sha256::Hash::hash(b"Hello World!").into(), 127 &sec_key, 128 ); 129 130 test_roundtrip(sig); 131 } 132 }