Skip to content

Commit

Permalink
Merge pull request #178 from LLFourn/libsecp_28
Browse files Browse the repository at this point in the history
[libsecp_compat_0_28] Update compatibility to rust-libsecp256k1 v0.28
  • Loading branch information
LLFourn authored Feb 18, 2024
2 parents 4f2b86f + 2f270e9 commit aac6526
Show file tree
Hide file tree
Showing 12 changed files with 197 additions and 31 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
## Unreleased

- Change `Scalar::from_bytes` to work for `Scalar<_, NonZero>` as well.
- Updated compatibility to `rust-secp256k1` v0.28.0
- Bumped MSRV to 1.63.0 to reduce friction
- Added `share_backup` module in `schnorr_fun`
- Added `arithmetic_macros` to make `g!` and `s!` macros into procedural macros
Expand Down
3 changes: 2 additions & 1 deletion ecdsa_fun/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@ required-features = ["libsecp_compat"]

[features]
default = ["std"]
libsecp_compat = ["secp256kfun/libsecp_compat", "libsecp_compat_0_27"]
libsecp_compat = ["secp256kfun/libsecp_compat", "libsecp_compat_0_28"]
libsecp_compat_0_27 = ["secp256kfun/libsecp_compat_0_27"]
libsecp_compat_0_28 = ["secp256kfun/libsecp_compat_0_28"]
std = ["alloc"]
alloc = ["secp256kfun/alloc", "sigma_fun?/alloc" ]
serde = ["secp256kfun/serde","sigma_fun?/serde"]
Expand Down
9 changes: 7 additions & 2 deletions ecdsa_fun/benches/bench_ecdsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@ fn sign_ecdsa(c: &mut Criterion) {
let secret_key = SecretKey::from_slice(&SK.to_bytes()[..]).unwrap();
{
group.bench_function("secp256k1::ecdsa_sign", |b| {
b.iter(|| secp.sign_ecdsa(&Message::from_slice(&MESSAGE[..]).unwrap(), &secret_key))
b.iter(|| {
secp.sign_ecdsa(
&Message::from_digest_slice(&MESSAGE[..]).unwrap(),
&secret_key,
)
})
});
}
}
Expand Down Expand Up @@ -53,7 +58,7 @@ fn verify_ecdsa(c: &mut Criterion) {
group.bench_function("secp256k1::ecdsa_verify", |b| {
b.iter(|| {
secp.verify_ecdsa(
&Message::from_slice(&MESSAGE[..]).unwrap(),
&Message::from_digest_slice(&MESSAGE[..]).unwrap(),
&sig,
&public_key,
)
Expand Down
17 changes: 17 additions & 0 deletions ecdsa_fun/src/libsecp_compat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,20 @@ mod v0_27 {
}
}
}

#[cfg(feature = "libsecp_compat_0_28")]
mod v0_28 {
use crate::{fun::secp256k1_0_28::ecdsa, Signature};

impl From<Signature> for ecdsa::Signature {
fn from(sig: Signature) -> Self {
ecdsa::Signature::from_compact(sig.to_bytes().as_ref()).unwrap()
}
}

impl From<ecdsa::Signature> for Signature {
fn from(sig: ecdsa::Signature) -> Self {
Signature::from_bytes(sig.serialize_compact()).unwrap()
}
}
}
8 changes: 4 additions & 4 deletions ecdsa_fun/tests/against_c_lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ fn ecdsa_sign() {
let c_public_key = PublicKey::from(public_key);
let message = rand_32_bytes();
let signature = ecdsa.sign(&secret_key, &message);
let c_message = Message::from_slice(&message[..]).unwrap();
let c_message = Message::from_digest_slice(&message[..]).unwrap();
let c_siganture = ecdsa::Signature::from_compact(&signature.to_bytes()).unwrap();
assert!(secp
.verify_ecdsa(&c_message, &c_siganture, &c_public_key)
Expand All @@ -48,7 +48,7 @@ fn ecdsa_verify() {
let c_public_key = PublicKey::from_secret_key(&secp, &c_secret_key);
let public_key = Point::from(c_public_key);
let message = rand_32_bytes();
let c_message = Message::from_slice(&message[..]).unwrap();
let c_message = Message::from_digest_slice(&message[..]).unwrap();
let c_signature = secp.sign_ecdsa(&c_message, &c_secret_key);
let signature = ecdsa_fun::Signature::from(c_signature);
assert!(ecdsa.verify(&public_key, &message, &signature));
Expand All @@ -66,7 +66,7 @@ fn ecdsa_verify_high_message() {
let message =
hex::decode_array("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")
.unwrap();
let c_message = Message::from_slice(&message[..]).unwrap();
let c_message = Message::from_digest_slice(&message[..]).unwrap();
let c_signature = secp.sign_ecdsa(&c_message, &c_secret_key);
let signature = ecdsa_fun::Signature::from_bytes(c_signature.serialize_compact()).unwrap();

Expand All @@ -86,7 +86,7 @@ fn ecdsa_sign_high_message() {
hex::decode_array("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")
.unwrap();
let signature = ecdsa.sign(&secret_key, &message);
let c_message = Message::from_slice(&message[..]).unwrap();
let c_message = Message::from_digest_slice(&message[..]).unwrap();
let c_siganture = ecdsa::Signature::from_compact(&signature.to_bytes()).unwrap();
assert!(secp
.verify_ecdsa(&c_message, &c_siganture, &c_public_key)
Expand Down
3 changes: 2 additions & 1 deletion schnorr_fun/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@ alloc = ["secp256kfun/alloc" ]
std = ["alloc", "secp256kfun/std"]
bincode = ["secp256kfun/bincode"]
serde = ["secp256kfun/serde"]
libsecp_compat = ["secp256kfun/libsecp_compat", "libsecp_compat_0_27"]
libsecp_compat = ["secp256kfun/libsecp_compat", "libsecp_compat_0_28"]
libsecp_compat_0_27 = ["secp256kfun/libsecp_compat_0_27"]
libsecp_compat_0_28 = ["secp256kfun/libsecp_compat_0_28"]
proptest = ["secp256kfun/proptest"]
share_backup = ["dep:bech32"]

Expand Down
12 changes: 6 additions & 6 deletions schnorr_fun/benches/bench_schnorr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ fn sign_schnorr(c: &mut Criterion) {
}

{
use secp256k1::{KeyPair, Message, Secp256k1};
use secp256k1::{Keypair, Message, Secp256k1};
let secp = Secp256k1::new();
let kp = KeyPair::from_secret_key(&secp, &(*SK).into());
let msg = Message::from_slice(&MESSAGE[..]).unwrap();
let kp = Keypair::from_secret_key(&secp, &(*SK).into());
let msg = Message::from_digest_slice(&MESSAGE[..]).unwrap();
group.bench_function("secp::schnorrsig_sign_no_aux_rand", |b| {
b.iter(|| {
secp.sign_schnorr_no_aux_rand(&msg, &kp);
Expand Down Expand Up @@ -57,11 +57,11 @@ fn verify_schnorr(c: &mut Criterion) {
}

{
use secp256k1::{KeyPair, Message, Secp256k1, XOnlyPublicKey};
use secp256k1::{Keypair, Message, Secp256k1, XOnlyPublicKey};
let secp = Secp256k1::new();
let kp = KeyPair::from_secret_key(&secp, &(*SK).into());
let kp = Keypair::from_secret_key(&secp, &(*SK).into());
let pk = XOnlyPublicKey::from_keypair(&kp).0;
let msg = Message::from_slice(&MESSAGE[..]).unwrap();
let msg = Message::from_digest_slice(&MESSAGE[..]).unwrap();
let sig = secp.sign_schnorr_no_aux_rand(&msg, &kp);
group.bench_function("secp::schnorrsig_verify", |b| {
b.iter(|| secp.verify_schnorr(&sig, &msg, &pk));
Expand Down
17 changes: 17 additions & 0 deletions schnorr_fun/src/libsecp_compat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,20 @@ mod v0_27 {
}
}
}

#[cfg(feature = "libsecp_compat_0_28")]
mod v0_28 {
use secp256kfun::secp256k1_0_28::schnorr;

impl From<crate::Signature> for schnorr::Signature {
fn from(sig: crate::Signature) -> Self {
schnorr::Signature::from_slice(sig.to_bytes().as_ref()).unwrap()
}
}

impl From<schnorr::Signature> for crate::Signature {
fn from(sig: schnorr::Signature) -> Self {
crate::Signature::from_bytes(*sig.as_ref()).unwrap()
}
}
}
8 changes: 4 additions & 4 deletions schnorr_fun/tests/against_c_lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ proptest! {
msg in any::<[u8;32]>(),
) {
let secp = &*SECP;
let keypair = secp256k1::KeyPair::from_secret_key(secp, &key.into());
let secp_msg = secp256k1::Message::from_slice(&msg).unwrap();
let keypair = secp256k1::Keypair::from_secret_key(secp, &key.into());
let secp_msg = secp256k1::Message::from_digest_slice(&msg).unwrap();
let sig = secp.sign_schnorr_no_aux_rand(&secp_msg, &keypair);
let schnorr = Schnorr::<Sha256,Bip340NoAux>::default();
let fun_keypair = schnorr.new_keypair(key);
Expand All @@ -77,9 +77,9 @@ proptest! {
#[test]
fn verify_secp_sigs(key in any::<Scalar>(), msg in any::<[u8;32]>(), aux_rand in any::<[u8;32]>()) {
let secp = &*SECP;
let keypair = secp256k1::KeyPair::from_secret_key(secp, &key.into());
let keypair = secp256k1::Keypair::from_secret_key(secp, &key.into());
let fun_pk = secp256k1::XOnlyPublicKey::from_keypair(&keypair).0.into();
let secp_msg = secp256k1::Message::from_slice(&msg).unwrap();
let secp_msg = secp256k1::Message::from_digest_slice(&msg).unwrap();
let sig = secp.sign_schnorr_with_aux_rand(&secp_msg, &keypair, &aux_rand);
let schnorr = Schnorr::<Sha256,_>::verify_only();
let fun_msg = Message::<Public>::raw(&msg);
Expand Down
27 changes: 22 additions & 5 deletions secp256kfun/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,13 @@ secp256kfun_arithmetic_macros = { version = "0.9.0", path = "../arithmetic_macro

# optional
serde = { version = "1.0", optional = true, default-features = false, features = ["derive"] }
secp256k1_0_27 = { package = "secp256k1", version = "0.27", optional = true, default-features = false }
proptest = { version = "1", optional = true }
bincode = { version = "2.0.0-rc.3", optional = true, default-features = false, features = ["derive"] }

secp256k1_0_27 = { package = "secp256k1", version = "0.27", optional = true, default-features = false }
secp256k1_0_28 = { package = "secp256k1", version = "0.28", optional = true, default-features = false }


[dev-dependencies]
serde_json = "1"
rand = { version = "0.8" }
Expand All @@ -39,11 +42,25 @@ wasm-bindgen-test = "0.3"

[features]
default = ["std"]
libsecp_compat = ["libsecp_compat_0_28"]
alloc = [
"serde?/alloc",
"digest/alloc",
"bincode?/alloc",
"secp256k1_0_27?/alloc",
"secp256k1_0_28?/alloc",
]
std = ["alloc", "subtle/std", "digest/std", "bincode?/std", "secp256k1_0_27?/std", "secp256k1_0_28?/std"]
serde = [
"dep:serde",
"bincode?/serde",
"secp256k1_0_27?/serde",
"secp256k1_0_28?/serde",
]

libsecp_compat_0_27 = [ "dep:secp256k1_0_27" ]
libsecp_compat = ["libsecp_compat_0_27"]
alloc = ["serde?/alloc", "digest/alloc", "secp256k1_0_27?/alloc", "bincode?/alloc"]
std = ["alloc", "subtle/std", "digest/std", "bincode?/std", "secp256k1_0_27?/std"]
serde = [ "dep:serde", "secp256k1_0_27?/serde", "bincode?/serde" ]
libsecp_compat_0_28 = [ "dep:secp256k1_0_28" ]


[[bench]]
name = "bench_ecmult"
Expand Down
18 changes: 11 additions & 7 deletions secp256kfun/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,6 @@ pub use point::Point;
pub use scalar::Scalar;
pub use slice::Slice;

#[cfg(feature = "libsecp_compat_0_27")]
/// Re-export `secp256k1`
pub extern crate secp256k1_0_27;

#[cfg(feature = "libsecp_compat")]
pub use secp256k1_0_27 as secp256k1;

/// Re-export `serde`
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
#[cfg(feature = "serde")]
Expand Down Expand Up @@ -89,3 +82,14 @@ pub static G: &Point<marker::BasePoint, marker::Public, marker::NonZero> =

// it is applied to nonce generators too so export at root
pub use hash::Tag;

#[cfg(feature = "libsecp_compat_0_27")]
/// Re-export `secp256k1`
pub extern crate secp256k1_0_27;

#[cfg(feature = "libsecp_compat_0_28")]
/// Re-export `secp256k1`
pub extern crate secp256k1_0_28;

#[cfg(feature = "libsecp_compat")]
pub use secp256k1_0_28 as secp256k1;
105 changes: 104 additions & 1 deletion secp256kfun/src/libsecp_compat.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,108 @@
#[cfg(feature = "libsecp_compat_0_28")]
mod v0_28 {
use crate::{marker::*, Point, Scalar};
use secp256k1::{PublicKey, SecretKey, XOnlyPublicKey};
use secp256k1_0_28 as secp256k1;

impl From<Scalar> for SecretKey {
fn from(scalar: Scalar) -> Self {
SecretKey::from_slice(scalar.to_bytes().as_ref()).unwrap()
}
}

impl From<SecretKey> for Scalar {
fn from(sk: SecretKey) -> Self {
Scalar::from_slice(&sk[..])
.unwrap()
.non_zero()
.expect("SecretKey is never zero")
}
}

impl<Z> From<Scalar<Public, Z>> for secp256k1::Scalar {
fn from(value: Scalar<Public, Z>) -> Self {
secp256k1::Scalar::from_be_bytes(value.to_bytes()).unwrap()
}
}

impl From<secp256k1::Scalar> for Scalar<Public, Zero> {
fn from(value: secp256k1::Scalar) -> Self {
Scalar::from_bytes(value.to_be_bytes()).unwrap()
}
}

impl From<PublicKey> for Point {
fn from(pk: PublicKey) -> Self {
Point::<Normal, Public, NonZero>::from_bytes(pk.serialize()).unwrap()
}
}

impl From<Point> for PublicKey {
fn from(pk: Point) -> Self {
PublicKey::from_slice(pk.to_bytes().as_ref()).unwrap()
}
}

impl From<Point<EvenY>> for XOnlyPublicKey {
fn from(point: Point<EvenY>) -> Self {
XOnlyPublicKey::from_slice(point.to_xonly_bytes().as_ref()).unwrap()
}
}

impl From<XOnlyPublicKey> for Point<EvenY> {
fn from(pk: XOnlyPublicKey) -> Self {
Point::from_xonly_bytes(pk.serialize()).unwrap()
}
}

#[cfg(test)]
mod test {
use super::*;
use core::str::FromStr;
#[cfg(feature = "proptest")]
use proptest::prelude::*;

#[test]
fn public_key() {
let pk = PublicKey::from_str("0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8").unwrap();
let point = Point::from(pk);
assert_eq!(pk.serialize().as_ref(), point.to_bytes().as_ref());
}

#[cfg(feature = "proptest")]
proptest! {

#[test]
fn prop_public_key(first_byte in 0u8..10, x_bytes in any::<[u8;32]>()) {
let mut bytes = [0u8;33];
bytes[0] = first_byte;
bytes[1..33].copy_from_slice(&x_bytes[..]);
let pk = PublicKey::from_slice(&bytes[..]).ok();
let point = Point::<_,Public, >::from_bytes(bytes);
assert_eq!(pk.map(|pk| pk.serialize()), point.map(|point| point.to_bytes()));
}

#[test]
fn prop_secret_key(bytes in any::<[u8;32]>()) {
let sk = SecretKey::from_slice(&bytes[..]).unwrap();
let scalar = Scalar::from(sk);
assert_eq!(&sk[..], scalar.to_bytes().as_ref());
}



#[test]
fn scalar_roundtrip(scalar in any::<Scalar<Public, Zero>>()) {
let secp_scalar = secp256k1::Scalar::from(scalar);
let rt_scalar = Scalar::from(secp_scalar);
assert_eq!(rt_scalar, scalar);
}
}
}
}

#[cfg(feature = "libsecp_compat_0_27")]
mod v27_0 {
mod v0_27 {
use crate::{marker::*, Point, Scalar};
use secp256k1::{PublicKey, SecretKey, XOnlyPublicKey};
use secp256k1_0_27 as secp256k1;
Expand Down

0 comments on commit aac6526

Please sign in to comment.