From 5ee0afbde4c2f8b41f0b4fd306c5330cdbc3646c Mon Sep 17 00:00:00 2001 From: Elichai Turkel Date: Mon, 28 Oct 2019 22:09:18 +0200 Subject: [PATCH 1/3] Added an example for generating keys using OsRng --- .travis.yml | 1 + Cargo.toml | 6 ++++++ examples/generate_keys.rs | 17 +++++++++++++++++ 3 files changed, 24 insertions(+) create mode 100644 examples/generate_keys.rs diff --git a/.travis.yml b/.travis.yml index 23321e9..a6c6fb2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,6 +36,7 @@ script: - cargo test --verbose - cargo build --verbose --release - cargo test --verbose --release + - 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 - if [ ${TRAVIS_RUST_VERSION} == "stable" -a "$TRAVIS_OS_NAME" = "linux" ]; then diff --git a/Cargo.toml b/Cargo.toml index 9808c9d..aaf3797 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ keywords = [ "crypto", "ECDSA", "secp256k1", "libsecp256k1", "bitcoin" ] readme = "README.md" build = "build.rs" links = "secp256k1" +autoexamples = false # Remove when edition 2018 https://github.com/rust-lang/cargo/issues/5330 # Should make docs.rs show all functions, even those behind non-default features [package.metadata.docs.rs] @@ -38,6 +39,7 @@ lowmemory = [] rand = "0.6" rand_core = "0.4" serde_test = "1.0" +bitcoin_hashes = "0.7" [dependencies.rand] version = "0.6" @@ -48,3 +50,7 @@ default-features = false version = "1.0" optional = true default-features = false + +[[example]] +name = "generate_keys" +required-features = ["rand"] \ No newline at end of file diff --git a/examples/generate_keys.rs b/examples/generate_keys.rs new file mode 100644 index 0000000..ae1ec2b --- /dev/null +++ b/examples/generate_keys.rs @@ -0,0 +1,17 @@ +extern crate secp256k1; + +use secp256k1::rand::rngs::OsRng; +use secp256k1::{PublicKey, Secp256k1, SecretKey}; + +fn main() { + let secp = Secp256k1::new(); + let mut rng = OsRng::new().unwrap(); + // First option: + let (seckey, pubkey) = secp.generate_keypair(&mut rng); + + assert_eq!(pubkey, PublicKey::from_secret_key(&secp, &seckey)); + + // Second option: + let seckey = SecretKey::new(&mut rng); + let _pubkey = PublicKey::from_secret_key(&secp, &seckey); +} From e28f7567889c6c983d6aa45ef833d6fa165c50df Mon Sep 17 00:00:00 2001 From: Elichai Turkel Date: Mon, 28 Oct 2019 22:09:59 +0200 Subject: [PATCH 2/3] Added an example for signing and verification --- .travis.yml | 1 + Cargo.toml | 3 +++ examples/sign_verify.rs | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 examples/sign_verify.rs diff --git a/.travis.yml b/.travis.yml index a6c6fb2..0501078 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,6 +36,7 @@ script: - cargo test --verbose - cargo build --verbose --release - cargo test --verbose --release + - cargo run --example sign_verify - 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 aaf3797..78e4ce8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,6 +51,9 @@ version = "1.0" optional = true default-features = false +[[example]] +name = "sign_verify" + [[example]] name = "generate_keys" required-features = ["rand"] \ No newline at end of file diff --git a/examples/sign_verify.rs b/examples/sign_verify.rs new file mode 100644 index 0000000..ca474a8 --- /dev/null +++ b/examples/sign_verify.rs @@ -0,0 +1,35 @@ +extern crate bitcoin_hashes; +extern crate secp256k1; + +use bitcoin_hashes::{sha256, Hash}; +use secp256k1::{Error, Message, PublicKey, Secp256k1, SecretKey, Signature, Signing, Verification}; + +fn verify(secp: &Secp256k1, msg: &[u8], sig: [u8; 64], pubkey: [u8; 33]) -> Result { + let msg = sha256::Hash::hash(msg); + let msg = Message::from_slice(&msg)?; + let sig = Signature::from_compact(&sig)?; + let pubkey = PublicKey::from_slice(&pubkey)?; + + Ok(secp.verify(&msg, &sig, &pubkey).is_ok()) +} + +fn sign(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(&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 = [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]; + let msg = b"This is some message"; + + let signature = sign(&secp, msg, seckey).unwrap(); + + let serialize_sig = signature.serialize_compact(); + + assert!(verify(&secp, msg, serialize_sig, pubkey).unwrap()); +} From 7e5916b61ff4d49a8881f7a6447acb54dece66f5 Mon Sep 17 00:00:00 2001 From: Elichai Turkel Date: Mon, 28 Oct 2019 22:10:31 +0200 Subject: [PATCH 3/3] 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) + ); +}