Skip to content

Commit

Permalink
secp256k1 v0.30.0 compat
Browse files Browse the repository at this point in the history
  • Loading branch information
LLFourn committed Dec 30, 2024
1 parent b473bcb commit 95e0b88
Show file tree
Hide file tree
Showing 8 changed files with 152 additions and 7 deletions.
3 changes: 2 additions & 1 deletion ecdsa_fun/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,11 @@ required-features = ["libsecp_compat"]

[features]
default = ["std"]
libsecp_compat = ["libsecp_compat_0_28", "secp256kfun/libsecp_compat"]
libsecp_compat = ["libsecp_compat_0_30", "secp256kfun/libsecp_compat"]
libsecp_compat_0_27 = ["secp256kfun/libsecp_compat_0_27"]
libsecp_compat_0_28 = ["secp256kfun/libsecp_compat_0_28"]
libsecp_compat_0_29 = ["secp256kfun/libsecp_compat_0_29"]
libsecp_compat_0_30 = ["secp256kfun/libsecp_compat_0_30"]
std = ["alloc"]
alloc = ["secp256kfun/alloc", "sigma_fun?/alloc" ]
serde = ["secp256kfun/serde","sigma_fun?/serde"]
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 @@ -48,3 +48,20 @@ mod v0_29 {
}
}
}

#[cfg(feature = "libsecp_compat_0_30")]
mod v0_30 {
use crate::{fun::secp256k1_0_30::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()
}
}
}
1 change: 1 addition & 0 deletions schnorr_fun/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ libsecp_compat = ["libsecp_compat_0_29", "secp256kfun/libsecp_compat"]
libsecp_compat_0_27 = ["secp256kfun/libsecp_compat_0_27"]
libsecp_compat_0_28 = ["secp256kfun/libsecp_compat_0_28"]
libsecp_compat_0_29 = ["secp256kfun/libsecp_compat_0_29"]
libsecp_compat_0_30 = ["secp256kfun/libsecp_compat_0_30"]
proptest = ["secp256kfun/proptest"]
share_backup = ["dep:bech32"]

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 @@ -48,3 +48,20 @@ mod v0_29 {
}
}
}

#[cfg(feature = "libsecp_compat_0_30")]
mod v0_30 {
use secp256kfun::secp256k1_0_30::schnorr;

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

impl From<schnorr::Signature> for crate::Signature {
fn from(sig: schnorr::Signature) -> Self {
crate::Signature::from_bytes(*sig.as_ref()).unwrap()
}
}
}
6 changes: 2 additions & 4 deletions schnorr_fun/tests/against_c_lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,7 @@ proptest! {
) {
let secp = &*SECP;
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 sig = secp.sign_schnorr_no_aux_rand(&msg, &keypair);
let schnorr = Schnorr::<Sha256,Bip340NoAux>::default();
let fun_keypair = schnorr.new_keypair(key);
let fun_msg = Message::<Public>::raw(&msg);
Expand All @@ -79,8 +78,7 @@ proptest! {
let secp = &*SECP;
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_digest_slice(&msg).unwrap();
let sig = secp.sign_schnorr_with_aux_rand(&secp_msg, &keypair, &aux_rand);
let sig = secp.sign_schnorr_with_aux_rand(&msg, &keypair, &aux_rand);
let schnorr = Schnorr::<Sha256,_>::verify_only();
let fun_msg = Message::<Public>::raw(&msg);
prop_assert!(schnorr.verify(&fun_pk, fun_msg, &sig.into()));
Expand Down
6 changes: 5 additions & 1 deletion secp256kfun/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ bincode = { version = "2.0.0-rc.3", optional = true, default-features = false, f
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 }
secp256k1_0_29 = { package = "secp256k1", version = "0.29", optional = true, default-features = false }
secp256k1_0_30 = { package = "secp256k1", version = "0.30", optional = true, default-features = false }


[dev-dependencies]
Expand All @@ -43,14 +44,15 @@ wasm-bindgen-test = "0.3"

[features]
default = ["std"]
libsecp_compat = ["libsecp_compat_0_29"]
libsecp_compat = ["libsecp_compat_0_30"]
alloc = [
"serde?/alloc",
"digest/alloc",
"bincode?/alloc",
"secp256k1_0_27?/alloc",
"secp256k1_0_28?/alloc",
"secp256k1_0_29?/alloc",
"secp256k1_0_30?/alloc"
]
std = ["alloc", "subtle/std", "digest/std", "bincode?/std", "secp256k1_0_27?/std", "secp256k1_0_28?/std"]
serde = [
Expand All @@ -59,11 +61,13 @@ serde = [
"secp256k1_0_27?/serde",
"secp256k1_0_28?/serde",
"secp256k1_0_29?/serde",
"secp256k1_0_30?/serde"
]

libsecp_compat_0_27 = [ "dep:secp256k1_0_27" ]
libsecp_compat_0_28 = [ "dep:secp256k1_0_28" ]
libsecp_compat_0_29 = [ "dep:secp256k1_0_29" ]
libsecp_compat_0_30 = [ "dep:secp256k1_0_30" ]


[[bench]]
Expand Down
6 changes: 5 additions & 1 deletion secp256kfun/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,12 @@ pub extern crate secp256k1_0_28;
/// Re-export `secp256k1`
pub extern crate secp256k1_0_29;

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

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

/// Convenience module to import the most frequently used tools
pub mod prelude {
Expand Down
103 changes: 103 additions & 0 deletions secp256kfun/src/libsecp_compat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,109 @@ mod v0_29 {



#[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_30")]
mod v0_30 {
use crate::{marker::*, Point, Scalar};
use secp256k1::{PublicKey, SecretKey, XOnlyPublicKey};
use secp256k1_0_30 as secp256k1;

impl From<Scalar> for SecretKey {
fn from(scalar: Scalar) -> Self {
SecretKey::from_byte_array(&scalar.to_bytes()).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_byte_array(&point.to_xonly_bytes()).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);
Expand Down

0 comments on commit 95e0b88

Please sign in to comment.