Skip to content

Commit f0f4ff2

Browse files
authored
Merge pull request #199 from LLFourn/libsecp_compat_0_30
Libsecp v0.30.0 compat
2 parents 55edbf2 + ff70dff commit f0f4ff2

File tree

9 files changed

+157
-14
lines changed

9 files changed

+157
-14
lines changed

ecdsa_fun/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,11 @@ required-features = ["libsecp_compat"]
3434

3535
[features]
3636
default = ["std"]
37-
libsecp_compat = ["libsecp_compat_0_28", "secp256kfun/libsecp_compat"]
37+
libsecp_compat = ["libsecp_compat_0_30", "secp256kfun/libsecp_compat"]
3838
libsecp_compat_0_27 = ["secp256kfun/libsecp_compat_0_27"]
3939
libsecp_compat_0_28 = ["secp256kfun/libsecp_compat_0_28"]
4040
libsecp_compat_0_29 = ["secp256kfun/libsecp_compat_0_29"]
41+
libsecp_compat_0_30 = ["secp256kfun/libsecp_compat_0_30"]
4142
std = ["alloc"]
4243
alloc = ["secp256kfun/alloc", "sigma_fun?/alloc" ]
4344
serde = ["secp256kfun/serde","sigma_fun?/serde"]

ecdsa_fun/src/libsecp_compat.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,20 @@ mod v0_29 {
4848
}
4949
}
5050
}
51+
52+
#[cfg(feature = "libsecp_compat_0_30")]
53+
mod v0_30 {
54+
use crate::{fun::secp256k1_0_30::ecdsa, Signature};
55+
56+
impl From<Signature> for ecdsa::Signature {
57+
fn from(sig: Signature) -> Self {
58+
ecdsa::Signature::from_compact(sig.to_bytes().as_ref()).unwrap()
59+
}
60+
}
61+
62+
impl From<ecdsa::Signature> for Signature {
63+
fn from(sig: ecdsa::Signature) -> Self {
64+
Signature::from_bytes(sig.serialize_compact()).unwrap()
65+
}
66+
}
67+
}

schnorr_fun/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ libsecp_compat = ["libsecp_compat_0_29", "secp256kfun/libsecp_compat"]
4646
libsecp_compat_0_27 = ["secp256kfun/libsecp_compat_0_27"]
4747
libsecp_compat_0_28 = ["secp256kfun/libsecp_compat_0_28"]
4848
libsecp_compat_0_29 = ["secp256kfun/libsecp_compat_0_29"]
49+
libsecp_compat_0_30 = ["secp256kfun/libsecp_compat_0_30"]
4950
proptest = ["secp256kfun/proptest"]
5051
share_backup = ["dep:bech32"]
5152

schnorr_fun/benches/bench_schnorr.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,12 @@ fn sign_schnorr(c: &mut Criterion) {
2525
}
2626

2727
{
28-
use secp256k1::{Keypair, Message, Secp256k1};
28+
use secp256k1::{Keypair, Secp256k1};
2929
let secp = Secp256k1::new();
3030
let kp = Keypair::from_secret_key(&secp, &(*SK).into());
31-
let msg = Message::from_digest_slice(&MESSAGE[..]).unwrap();
3231
group.bench_function("secp::schnorrsig_sign_no_aux_rand", |b| {
3332
b.iter(|| {
34-
secp.sign_schnorr_no_aux_rand(&msg, &kp);
33+
secp.sign_schnorr_no_aux_rand(&MESSAGE[..], &kp);
3534
});
3635
});
3736
}
@@ -57,14 +56,13 @@ fn verify_schnorr(c: &mut Criterion) {
5756
}
5857

5958
{
60-
use secp256k1::{Keypair, Message, Secp256k1, XOnlyPublicKey};
59+
use secp256k1::{Keypair, Secp256k1, XOnlyPublicKey};
6160
let secp = Secp256k1::new();
6261
let kp = Keypair::from_secret_key(&secp, &(*SK).into());
6362
let pk = XOnlyPublicKey::from_keypair(&kp).0;
64-
let msg = Message::from_digest_slice(&MESSAGE[..]).unwrap();
65-
let sig = secp.sign_schnorr_no_aux_rand(&msg, &kp);
63+
let sig = secp.sign_schnorr_no_aux_rand(&MESSAGE[..], &kp);
6664
group.bench_function("secp::schnorrsig_verify", |b| {
67-
b.iter(|| secp.verify_schnorr(&sig, &msg, &pk));
65+
b.iter(|| secp.verify_schnorr(&sig, &MESSAGE[..], &pk));
6866
});
6967
}
7068
}

schnorr_fun/src/libsecp_compat.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,20 @@ mod v0_29 {
4848
}
4949
}
5050
}
51+
52+
#[cfg(feature = "libsecp_compat_0_30")]
53+
mod v0_30 {
54+
use secp256kfun::secp256k1_0_30::schnorr;
55+
56+
impl From<crate::Signature> for schnorr::Signature {
57+
fn from(sig: crate::Signature) -> Self {
58+
schnorr::Signature::from_byte_array(sig.to_bytes())
59+
}
60+
}
61+
62+
impl From<schnorr::Signature> for crate::Signature {
63+
fn from(sig: schnorr::Signature) -> Self {
64+
crate::Signature::from_bytes(*sig.as_ref()).unwrap()
65+
}
66+
}
67+
}

schnorr_fun/tests/against_c_lib.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,7 @@ proptest! {
6464
) {
6565
let secp = &*SECP;
6666
let keypair = secp256k1::Keypair::from_secret_key(secp, &key.into());
67-
let secp_msg = secp256k1::Message::from_digest_slice(&msg).unwrap();
68-
let sig = secp.sign_schnorr_no_aux_rand(&secp_msg, &keypair);
67+
let sig = secp.sign_schnorr_no_aux_rand(&msg, &keypair);
6968
let schnorr = Schnorr::<Sha256,Bip340NoAux>::default();
7069
let fun_keypair = schnorr.new_keypair(key);
7170
let fun_msg = Message::<Public>::raw(&msg);
@@ -79,8 +78,7 @@ proptest! {
7978
let secp = &*SECP;
8079
let keypair = secp256k1::Keypair::from_secret_key(secp, &key.into());
8180
let fun_pk = secp256k1::XOnlyPublicKey::from_keypair(&keypair).0.into();
82-
let secp_msg = secp256k1::Message::from_digest_slice(&msg).unwrap();
83-
let sig = secp.sign_schnorr_with_aux_rand(&secp_msg, &keypair, &aux_rand);
81+
let sig = secp.sign_schnorr_with_aux_rand(&msg, &keypair, &aux_rand);
8482
let schnorr = Schnorr::<Sha256,_>::verify_only();
8583
let fun_msg = Message::<Public>::raw(&msg);
8684
prop_assert!(schnorr.verify(&fun_pk, fun_msg, &sig.into()));

secp256kfun/Cargo.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ bincode = { version = "2.0.0-rc.3", optional = true, default-features = false, f
2828
secp256k1_0_27 = { package = "secp256k1", version = "0.27", optional = true, default-features = false }
2929
secp256k1_0_28 = { package = "secp256k1", version = "0.28", optional = true, default-features = false }
3030
secp256k1_0_29 = { package = "secp256k1", version = "0.29", optional = true, default-features = false }
31+
secp256k1_0_30 = { package = "secp256k1", version = "0.30", optional = true, default-features = false }
3132

3233

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

4445
[features]
4546
default = ["std"]
46-
libsecp_compat = ["libsecp_compat_0_29"]
47+
libsecp_compat = ["libsecp_compat_0_30"]
4748
alloc = [
4849
"serde?/alloc",
4950
"digest/alloc",
5051
"bincode?/alloc",
5152
"secp256k1_0_27?/alloc",
5253
"secp256k1_0_28?/alloc",
5354
"secp256k1_0_29?/alloc",
55+
"secp256k1_0_30?/alloc"
5456
]
5557
std = ["alloc", "subtle/std", "digest/std", "bincode?/std", "secp256k1_0_27?/std", "secp256k1_0_28?/std"]
5658
serde = [
@@ -59,11 +61,13 @@ serde = [
5961
"secp256k1_0_27?/serde",
6062
"secp256k1_0_28?/serde",
6163
"secp256k1_0_29?/serde",
64+
"secp256k1_0_30?/serde"
6265
]
6366

6467
libsecp_compat_0_27 = [ "dep:secp256k1_0_27" ]
6568
libsecp_compat_0_28 = [ "dep:secp256k1_0_28" ]
6669
libsecp_compat_0_29 = [ "dep:secp256k1_0_29" ]
70+
libsecp_compat_0_30 = [ "dep:secp256k1_0_30" ]
6771

6872

6973
[[bench]]

secp256kfun/src/lib.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,12 @@ pub extern crate secp256k1_0_28;
9595
/// Re-export `secp256k1`
9696
pub extern crate secp256k1_0_29;
9797

98+
#[cfg(feature = "libsecp_compat_0_30")]
99+
/// Re-export `secp256k1`
100+
pub extern crate secp256k1_0_30;
101+
98102
#[cfg(feature = "libsecp_compat")]
99-
pub use secp256k1_0_29 as secp256k1;
103+
pub use secp256k1_0_30 as secp256k1;
100104

101105
/// Convenience module to import the most frequently used tools
102106
pub mod prelude {

secp256kfun/src/libsecp_compat.rs

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,109 @@ mod v0_29 {
297297

298298

299299

300+
#[test]
301+
fn scalar_roundtrip(scalar in any::<Scalar<Public, Zero>>()) {
302+
let secp_scalar = secp256k1::Scalar::from(scalar);
303+
let rt_scalar = Scalar::from(secp_scalar);
304+
assert_eq!(rt_scalar, scalar);
305+
}
306+
}
307+
}
308+
}
309+
310+
#[cfg(feature = "libsecp_compat_0_30")]
311+
mod v0_30 {
312+
use crate::{marker::*, Point, Scalar};
313+
use secp256k1::{PublicKey, SecretKey, XOnlyPublicKey};
314+
use secp256k1_0_30 as secp256k1;
315+
316+
impl From<Scalar> for SecretKey {
317+
fn from(scalar: Scalar) -> Self {
318+
SecretKey::from_byte_array(&scalar.to_bytes()).unwrap()
319+
}
320+
}
321+
322+
impl From<SecretKey> for Scalar {
323+
fn from(sk: SecretKey) -> Self {
324+
Scalar::from_slice(&sk[..])
325+
.unwrap()
326+
.non_zero()
327+
.expect("SecretKey is never zero")
328+
}
329+
}
330+
331+
impl<Z> From<Scalar<Public, Z>> for secp256k1::Scalar {
332+
fn from(value: Scalar<Public, Z>) -> Self {
333+
secp256k1::Scalar::from_be_bytes(value.to_bytes()).unwrap()
334+
}
335+
}
336+
337+
impl From<secp256k1::Scalar> for Scalar<Public, Zero> {
338+
fn from(value: secp256k1::Scalar) -> Self {
339+
Scalar::from_bytes(value.to_be_bytes()).unwrap()
340+
}
341+
}
342+
343+
impl From<PublicKey> for Point {
344+
fn from(pk: PublicKey) -> Self {
345+
Point::<Normal, Public, NonZero>::from_bytes(pk.serialize()).unwrap()
346+
}
347+
}
348+
349+
impl From<Point> for PublicKey {
350+
fn from(pk: Point) -> Self {
351+
PublicKey::from_slice(pk.to_bytes().as_ref()).unwrap()
352+
}
353+
}
354+
355+
impl From<Point<EvenY>> for XOnlyPublicKey {
356+
fn from(point: Point<EvenY>) -> Self {
357+
XOnlyPublicKey::from_byte_array(&point.to_xonly_bytes()).unwrap()
358+
}
359+
}
360+
361+
impl From<XOnlyPublicKey> for Point<EvenY> {
362+
fn from(pk: XOnlyPublicKey) -> Self {
363+
Point::from_xonly_bytes(pk.serialize()).unwrap()
364+
}
365+
}
366+
367+
#[cfg(test)]
368+
mod test {
369+
use super::*;
370+
use core::str::FromStr;
371+
#[cfg(feature = "proptest")]
372+
use proptest::prelude::*;
373+
374+
#[test]
375+
fn public_key() {
376+
let pk = PublicKey::from_str("0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8").unwrap();
377+
let point = Point::from(pk);
378+
assert_eq!(pk.serialize().as_ref(), point.to_bytes().as_ref());
379+
}
380+
381+
#[cfg(feature = "proptest")]
382+
proptest! {
383+
384+
#[test]
385+
fn prop_public_key(first_byte in 0u8..10, x_bytes in any::<[u8;32]>()) {
386+
let mut bytes = [0u8;33];
387+
bytes[0] = first_byte;
388+
bytes[1..33].copy_from_slice(&x_bytes[..]);
389+
let pk = PublicKey::from_slice(&bytes[..]).ok();
390+
let point = Point::<_,Public, >::from_bytes(bytes);
391+
assert_eq!(pk.map(|pk| pk.serialize()), point.map(|point| point.to_bytes()));
392+
}
393+
394+
#[test]
395+
fn prop_secret_key(bytes in any::<[u8;32]>()) {
396+
let sk = SecretKey::from_slice(&bytes[..]).unwrap();
397+
let scalar = Scalar::from(sk);
398+
assert_eq!(&sk[..], scalar.to_bytes().as_ref());
399+
}
400+
401+
402+
300403
#[test]
301404
fn scalar_roundtrip(scalar in any::<Scalar<Public, Zero>>()) {
302405
let secp_scalar = secp256k1::Scalar::from(scalar);

0 commit comments

Comments
 (0)