From 7e5916b61ff4d49a8881f7a6447acb54dece66f5 Mon Sep 17 00:00:00 2001 From: Elichai Turkel Date: Mon, 28 Oct 2019 22:10:31 +0200 Subject: [PATCH] Aded an example for recoverable signatures and recovering the pubkey --- .travis.yml | 1 + Cargo.toml | 4 +++ examples/sign_verify_recovery.rs | 47 ++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 examples/sign_verify_recovery.rs diff --git a/.travis.yml b/.travis.yml index 0501078..301d4e7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -37,6 +37,7 @@ script: - cargo build --verbose --release - cargo test --verbose --release - cargo run --example sign_verify + - cargo run --example sign_verify_recovery --features=recovery - cargo run --example generate_keys --features=rand - if [ ${TRAVIS_RUST_VERSION} == "stable" ]; then cargo doc --verbose --features="rand,serde,recovery,endomorphism"; fi - if [ ${TRAVIS_RUST_VERSION} == "nightly" ]; then cargo test --verbose --benches --features=unstable; fi diff --git a/Cargo.toml b/Cargo.toml index 78e4ce8..1299bd0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,6 +51,10 @@ version = "1.0" optional = true default-features = false +[[example]] +name = "sign_verify_recovery" +required-features = ["recovery"] + [[example]] name = "sign_verify" diff --git a/examples/sign_verify_recovery.rs b/examples/sign_verify_recovery.rs new file mode 100644 index 0000000..1644be4 --- /dev/null +++ b/examples/sign_verify_recovery.rs @@ -0,0 +1,47 @@ + +extern crate bitcoin_hashes; +extern crate secp256k1; + +use bitcoin_hashes::{sha256, Hash}; +use secp256k1::recovery::{RecoverableSignature, RecoveryId}; +use secp256k1::{Error, Message, PublicKey, Secp256k1, SecretKey, Signing, Verification}; + +fn recover(secp: &Secp256k1,msg: &[u8],sig: [u8; 64],recovery_id: u8) -> Result { + let msg = sha256::Hash::hash(msg); + let msg = Message::from_slice(&msg)?; + let id = RecoveryId::from_i32(recovery_id as i32)?; + let sig = RecoverableSignature::from_compact(&sig, id)?; + + secp.recover(&msg, &sig) +} + +fn sign_recovery(secp: &Secp256k1, msg: &[u8], seckey: [u8; 32]) -> Result { + let msg = sha256::Hash::hash(msg); + let msg = Message::from_slice(&msg)?; + let seckey = SecretKey::from_slice(&seckey)?; + Ok(secp.sign_recoverable(&msg, &seckey)) +} + +fn main() { + let secp = Secp256k1::new(); + + let seckey = [ + 59, 148, 11, 85, 134, 130, 61, 253, 2, 174, 59, 70, 27, 180, 51, 107, + 94, 203, 174, 253, 102, 39, 170, 146, 46, 252, 4, 143, 236, 12, 136, 28, + ]; + let pubkey = PublicKey::from_slice(&[ + 2, + 29, 21, 35, 7, 198, 183, 43, 14, 208, 65, 139, 14, 112, 205, 128, 231, + 245, 41, 91, 141, 134, 245, 114, 45, 63, 82, 19, 251, 210, 57, 79, 54, + ]).unwrap(); + let msg = b"This is some message"; + + let signature = sign_recovery(&secp, msg, seckey).unwrap(); + + let (recovery_id, serialize_sig) = signature.serialize_compact(); + + assert_eq!( + recover(&secp, msg, serialize_sig, recovery_id.to_i32() as u8), + Ok(pubkey) + ); +}