|
| 1 | + |
| 2 | +extern crate bitcoin_hashes; |
| 3 | +extern crate secp256k1; |
| 4 | + |
| 5 | +use bitcoin_hashes::{sha256, Hash}; |
| 6 | +use secp256k1::recovery::{RecoverableSignature, RecoveryId}; |
| 7 | +use secp256k1::{Error, Message, PublicKey, Secp256k1, SecretKey, Signing, Verification}; |
| 8 | + |
| 9 | +fn recover<C: Verification>(secp: &Secp256k1<C>,msg: &[u8],sig: [u8; 64],recovery_id: u8) -> Result<PublicKey, Error> { |
| 10 | + let msg = sha256::Hash::hash(msg); |
| 11 | + let msg = Message::from_slice(&msg)?; |
| 12 | + let id = RecoveryId::from_i32(recovery_id as i32)?; |
| 13 | + let sig = RecoverableSignature::from_compact(&sig, id)?; |
| 14 | + |
| 15 | + secp.recover(&msg, &sig) |
| 16 | +} |
| 17 | + |
| 18 | +fn sign_recovery<C: Signing>(secp: &Secp256k1<C>, msg: &[u8], seckey: [u8; 32]) -> Result<RecoverableSignature, Error> { |
| 19 | + let msg = sha256::Hash::hash(msg); |
| 20 | + let msg = Message::from_slice(&msg)?; |
| 21 | + let seckey = SecretKey::from_slice(&seckey)?; |
| 22 | + Ok(secp.sign_recoverable(&msg, &seckey)) |
| 23 | +} |
| 24 | + |
| 25 | +fn main() { |
| 26 | + let secp = Secp256k1::new(); |
| 27 | + |
| 28 | + let seckey = [ |
| 29 | + 59, 148, 11, 85, 134, 130, 61, 253, 2, 174, 59, 70, 27, 180, 51, 107, |
| 30 | + 94, 203, 174, 253, 102, 39, 170, 146, 46, 252, 4, 143, 236, 12, 136, 28, |
| 31 | + ]; |
| 32 | + let pubkey = PublicKey::from_slice(&[ |
| 33 | + 2, |
| 34 | + 29, 21, 35, 7, 198, 183, 43, 14, 208, 65, 139, 14, 112, 205, 128, 231, |
| 35 | + 245, 41, 91, 141, 134, 245, 114, 45, 63, 82, 19, 251, 210, 57, 79, 54, |
| 36 | + ]).unwrap(); |
| 37 | + let msg = b"This is some message"; |
| 38 | + |
| 39 | + let signature = sign_recovery(&secp, msg, seckey).unwrap(); |
| 40 | + |
| 41 | + let (recovery_id, serialize_sig) = signature.serialize_compact(); |
| 42 | + |
| 43 | + assert_eq!( |
| 44 | + recover(&secp, msg, serialize_sig, recovery_id.to_i32() as u8), |
| 45 | + Ok(pubkey) |
| 46 | + ); |
| 47 | +} |
0 commit comments