Run cargo fmt

Run the command `cargo +nightly fmt` to fix formatting issues.

The formatter got confused in one place, adding an incorrect
indentation, this was manually fixed.
This commit is contained in:
Tobin C. Harding 2022-11-16 11:06:12 +11:00
parent 41449e455d
commit e0e575dde7
15 changed files with 728 additions and 744 deletions

View File

@ -2,9 +2,14 @@ extern crate bitcoin_hashes;
extern crate secp256k1;
use bitcoin_hashes::{sha256, Hash};
use secp256k1::{Error, Message, PublicKey, Secp256k1, SecretKey, ecdsa, Signing, Verification};
use secp256k1::{ecdsa, Error, Message, PublicKey, Secp256k1, SecretKey, Signing, Verification};
fn verify<C: Verification>(secp: &Secp256k1<C>, msg: &[u8], sig: [u8; 64], pubkey: [u8; 33]) -> Result<bool, Error> {
fn verify<C: Verification>(
secp: &Secp256k1<C>,
msg: &[u8],
sig: [u8; 64],
pubkey: [u8; 33],
) -> Result<bool, Error> {
let msg = sha256::Hash::hash(msg);
let msg = Message::from_slice(&msg)?;
let sig = ecdsa::Signature::from_compact(&sig)?;
@ -13,7 +18,11 @@ fn verify<C: Verification>(secp: &Secp256k1<C>, msg: &[u8], sig: [u8; 64], pubke
Ok(secp.verify_ecdsa(&msg, &sig, &pubkey).is_ok())
}
fn sign<C: Signing>(secp: &Secp256k1<C>, msg: &[u8], seckey: [u8; 32]) -> Result<ecdsa::Signature, Error> {
fn sign<C: Signing>(
secp: &Secp256k1<C>,
msg: &[u8],
seckey: [u8; 32],
) -> Result<ecdsa::Signature, Error> {
let msg = sha256::Hash::hash(msg);
let msg = Message::from_slice(&msg)?;
let seckey = SecretKey::from_slice(&seckey)?;
@ -23,8 +32,14 @@ fn sign<C: Signing>(secp: &Secp256k1<C>, msg: &[u8], seckey: [u8; 32]) -> Result
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 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();

View File

@ -1,11 +1,15 @@
extern crate bitcoin_hashes;
extern crate secp256k1;
use bitcoin_hashes::{sha256, Hash};
use secp256k1::{Error, Message, PublicKey, Secp256k1, SecretKey, Signing, Verification, ecdsa};
use secp256k1::{ecdsa, Error, Message, PublicKey, Secp256k1, SecretKey, Signing, Verification};
fn recover<C: Verification>(secp: &Secp256k1<C>,msg: &[u8],sig: [u8; 64],recovery_id: u8) -> Result<PublicKey, Error> {
fn recover<C: Verification>(
secp: &Secp256k1<C>,
msg: &[u8],
sig: [u8; 64],
recovery_id: u8,
) -> Result<PublicKey, Error> {
let msg = sha256::Hash::hash(msg);
let msg = Message::from_slice(&msg)?;
let id = ecdsa::RecoveryId::from_i32(recovery_id as i32)?;
@ -14,7 +18,11 @@ fn recover<C: Verification>(secp: &Secp256k1<C>,msg: &[u8],sig: [u8; 64],recover
secp.recover_ecdsa(&msg, &sig)
}
fn sign_recovery<C: Signing>(secp: &Secp256k1<C>, msg: &[u8], seckey: [u8; 32]) -> Result<ecdsa::RecoverableSignature, Error> {
fn sign_recovery<C: Signing>(
secp: &Secp256k1<C>,
msg: &[u8],
seckey: [u8; 32],
) -> Result<ecdsa::RecoverableSignature, Error> {
let msg = sha256::Hash::hash(msg);
let msg = Message::from_slice(&msg)?;
let seckey = SecretKey::from_slice(&seckey)?;
@ -25,22 +33,19 @@ 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,
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();
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)
);
assert_eq!(recover(&secp, msg, serialize_sig, recovery_id.to_i32() as u8), Ok(pubkey));
}

View File

@ -1,13 +1,12 @@
use core::marker::PhantomData;
use core::mem::ManuallyDrop;
use crate::{Error, Secp256k1};
use crate::ffi::{self, CPtr, types::AlignedType};
use crate::ffi::types::{c_uint, c_void};
#[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
pub use self::alloc_only::*;
use crate::ffi::types::{c_uint, c_void, AlignedType};
use crate::ffi::{self, CPtr};
use crate::{Error, Secp256k1};
#[cfg(all(feature = "global-context", feature = "std"))]
#[cfg_attr(docsrs, doc(cfg(all(feature = "global-context", feature = "std"))))]
@ -41,13 +40,17 @@ pub mod global {
impl Deref for GlobalContext {
type Target = Secp256k1<All>;
#[allow(unused_mut)] // Unused when `rand-std` is not enabled.
#[allow(unused_mut)] // Unused when `rand-std` is not enabled.
fn deref(&self) -> &Self::Target {
static ONCE: Once = Once::new();
static mut CONTEXT: Option<Secp256k1<All>> = None;
ONCE.call_once(|| unsafe {
let mut ctx = Secp256k1::new();
#[cfg(all(not(target_arch = "wasm32"), feature = "rand-std", not(feature = "global-context-less-secure")))]
#[cfg(all(
not(target_arch = "wasm32"),
feature = "rand-std",
not(feature = "global-context-less-secure")
))]
{
ctx.randomize(&mut rand::thread_rng());
}
@ -58,10 +61,9 @@ pub mod global {
}
}
/// A trait for all kinds of contexts that lets you define the exact flags and a function to
/// deallocate memory. It isn't possible to implement this for types outside this crate.
pub unsafe trait Context : private::Sealed {
pub unsafe trait Context: private::Sealed {
/// Flags for the ffi.
const FLAGS: c_uint;
/// A constant description of the context.
@ -106,13 +108,13 @@ mod private {
#[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(any(feature = "alloc"))))]
mod alloc_only {
use crate::alloc::alloc;
use core::marker::PhantomData;
use super::private;
use crate::ffi::{self, types::{c_uint, c_void}};
use crate::{Secp256k1, Signing, Verification, Context, AlignedType};
use crate::alloc::alloc;
use crate::ffi::types::{c_uint, c_void};
use crate::ffi::{self};
use crate::{AlignedType, Context, Secp256k1, Signing, Verification};
impl private::Sealed for SignOnly {}
impl private::Sealed for All {}
@ -195,16 +197,22 @@ mod alloc_only {
let size = unsafe { ffi::secp256k1_context_preallocated_size(C::FLAGS) };
let layout = alloc::Layout::from_size_align(size, ALIGN_TO).unwrap();
let ptr = unsafe {alloc::alloc(layout)};
let ptr = unsafe { alloc::alloc(layout) };
#[allow(unused_mut)] // ctx is not mutated under some feature combinations.
let mut ctx = Secp256k1 {
ctx: unsafe { ffi::secp256k1_context_preallocated_create(ptr as *mut c_void, C::FLAGS) },
ctx: unsafe {
ffi::secp256k1_context_preallocated_create(ptr as *mut c_void, C::FLAGS)
},
phantom: PhantomData,
size,
};
#[cfg(all(not(target_arch = "wasm32"), feature = "rand-std", not(feature = "global-context-less-secure")))]
#[cfg(all(
not(target_arch = "wasm32"),
feature = "rand-std",
not(feature = "global-context-less-secure")
))]
{
ctx.randomize(&mut rand::thread_rng());
}
@ -220,9 +228,7 @@ mod alloc_only {
/// If `rand-std` feature is enabled, context will have been randomized using `thread_rng`.
/// If `rand-std` feature is not enabled please consider randomizing the context (see docs
/// for `Secp256k1::gen_new()`).
pub fn new() -> Secp256k1<All> {
Secp256k1::gen_new()
}
pub fn new() -> Secp256k1<All> { Secp256k1::gen_new() }
}
impl Secp256k1<SignOnly> {
@ -231,9 +237,7 @@ mod alloc_only {
/// If `rand-std` feature is enabled, context will have been randomized using `thread_rng`.
/// If `rand-std` feature is not enabled please consider randomizing the context (see docs
/// for `Secp256k1::gen_new()`).
pub fn signing_only() -> Secp256k1<SignOnly> {
Secp256k1::gen_new()
}
pub fn signing_only() -> Secp256k1<SignOnly> { Secp256k1::gen_new() }
}
impl Secp256k1<VerifyOnly> {
@ -242,24 +246,22 @@ mod alloc_only {
/// If `rand-std` feature is enabled, context will have been randomized using `thread_rng`.
/// If `rand-std` feature is not enabled please consider randomizing the context (see docs
/// for `Secp256k1::gen_new()`).
pub fn verification_only() -> Secp256k1<VerifyOnly> {
Secp256k1::gen_new()
}
pub fn verification_only() -> Secp256k1<VerifyOnly> { Secp256k1::gen_new() }
}
impl Default for Secp256k1<All> {
fn default() -> Self {
Self::new()
}
fn default() -> Self { Self::new() }
}
impl<C: Context> Clone for Secp256k1<C> {
fn clone(&self) -> Secp256k1<C> {
let size = unsafe {ffi::secp256k1_context_preallocated_clone_size(self.ctx as _)};
let size = unsafe { ffi::secp256k1_context_preallocated_clone_size(self.ctx as _) };
let layout = alloc::Layout::from_size_align(size, ALIGN_TO).unwrap();
let ptr = unsafe {alloc::alloc(layout)};
let ptr = unsafe { alloc::alloc(layout) };
Secp256k1 {
ctx: unsafe { ffi::secp256k1_context_preallocated_clone(self.ctx, ptr as *mut c_void) },
ctx: unsafe {
ffi::secp256k1_context_preallocated_clone(self.ctx, ptr as *mut c_void)
},
phantom: PhantomData,
size,
}
@ -313,7 +315,8 @@ impl<'buf, C: Context + 'buf> Secp256k1<C> {
ctx: unsafe {
ffi::secp256k1_context_preallocated_create(
buf.as_mut_c_ptr() as *mut c_void,
C::FLAGS)
C::FLAGS,
)
},
phantom: PhantomData,
size: 0, // We don't care about the size because it's the caller responsibility to deallocate.
@ -323,13 +326,13 @@ impl<'buf, C: Context + 'buf> Secp256k1<C> {
impl<'buf> Secp256k1<AllPreallocated<'buf>> {
/// Creates a new Secp256k1 context with all capabilities
pub fn preallocated_new(buf: &'buf mut [AlignedType]) -> Result<Secp256k1<AllPreallocated<'buf>>, Error> {
pub fn preallocated_new(
buf: &'buf mut [AlignedType],
) -> Result<Secp256k1<AllPreallocated<'buf>>, Error> {
Secp256k1::preallocated_gen_new(buf)
}
/// Uses the ffi `secp256k1_context_preallocated_size` to check the memory size needed for a context.
pub fn preallocate_size() -> usize {
Self::preallocate_size_gen()
}
pub fn preallocate_size() -> usize { Self::preallocate_size_gen() }
/// Create a context from a raw context.
///
@ -342,7 +345,9 @@ impl<'buf> Secp256k1<AllPreallocated<'buf>> {
/// * The user must handle the freeing of the context(using the correct functions) by himself.
/// * Violating these may lead to Undefined Behavior.
///
pub unsafe fn from_raw_all(raw_ctx: *mut ffi::Context) -> ManuallyDrop<Secp256k1<AllPreallocated<'buf>>> {
pub unsafe fn from_raw_all(
raw_ctx: *mut ffi::Context,
) -> ManuallyDrop<Secp256k1<AllPreallocated<'buf>>> {
ManuallyDrop::new(Secp256k1 {
ctx: raw_ctx,
phantom: PhantomData,
@ -353,15 +358,15 @@ impl<'buf> Secp256k1<AllPreallocated<'buf>> {
impl<'buf> Secp256k1<SignOnlyPreallocated<'buf>> {
/// Creates a new Secp256k1 context that can only be used for signing.
pub fn preallocated_signing_only(buf: &'buf mut [AlignedType]) -> Result<Secp256k1<SignOnlyPreallocated<'buf>>, Error> {
pub fn preallocated_signing_only(
buf: &'buf mut [AlignedType],
) -> Result<Secp256k1<SignOnlyPreallocated<'buf>>, Error> {
Secp256k1::preallocated_gen_new(buf)
}
/// Uses the ffi `secp256k1_context_preallocated_size` to check the memory size needed for the context.
#[inline]
pub fn preallocate_signing_size() -> usize {
Self::preallocate_size_gen()
}
pub fn preallocate_signing_size() -> usize { Self::preallocate_size_gen() }
/// Create a context from a raw context.
///
@ -374,7 +379,9 @@ impl<'buf> Secp256k1<SignOnlyPreallocated<'buf>> {
/// * The user must handle the freeing of the context(using the correct functions) by himself.
/// * This list *is not* exhaustive, and any violation may lead to Undefined Behavior.
///
pub unsafe fn from_raw_signing_only(raw_ctx: *mut ffi::Context) -> ManuallyDrop<Secp256k1<SignOnlyPreallocated<'buf>>> {
pub unsafe fn from_raw_signing_only(
raw_ctx: *mut ffi::Context,
) -> ManuallyDrop<Secp256k1<SignOnlyPreallocated<'buf>>> {
ManuallyDrop::new(Secp256k1 {
ctx: raw_ctx,
phantom: PhantomData,
@ -385,15 +392,15 @@ impl<'buf> Secp256k1<SignOnlyPreallocated<'buf>> {
impl<'buf> Secp256k1<VerifyOnlyPreallocated<'buf>> {
/// Creates a new Secp256k1 context that can only be used for verification
pub fn preallocated_verification_only(buf: &'buf mut [AlignedType]) -> Result<Secp256k1<VerifyOnlyPreallocated<'buf>>, Error> {
pub fn preallocated_verification_only(
buf: &'buf mut [AlignedType],
) -> Result<Secp256k1<VerifyOnlyPreallocated<'buf>>, Error> {
Secp256k1::preallocated_gen_new(buf)
}
/// Uses the ffi `secp256k1_context_preallocated_size` to check the memory size needed for the context.
#[inline]
pub fn preallocate_verification_size() -> usize {
Self::preallocate_size_gen()
}
pub fn preallocate_verification_size() -> usize { Self::preallocate_size_gen() }
/// Create a context from a raw context.
///
@ -406,7 +413,9 @@ impl<'buf> Secp256k1<VerifyOnlyPreallocated<'buf>> {
/// * The user must handle the freeing of the context(using the correct functions) by himself.
/// * This list *is not* exhaustive, and any violation may lead to Undefined Behavior.
///
pub unsafe fn from_raw_verification_only(raw_ctx: *mut ffi::Context) -> ManuallyDrop<Secp256k1<VerifyOnlyPreallocated<'buf>>> {
pub unsafe fn from_raw_verification_only(
raw_ctx: *mut ffi::Context,
) -> ManuallyDrop<Secp256k1<VerifyOnlyPreallocated<'buf>>> {
ManuallyDrop::new(Secp256k1 {
ctx: raw_ctx,
phantom: PhantomData,

View File

@ -15,11 +15,14 @@
//! Support for shared secret computations.
//!
use core::{borrow::Borrow, ptr, str};
use core::borrow::Borrow;
use core::{ptr, str};
use secp256k1_sys::types::{c_int, c_uchar, c_void};
use crate::{constants, Error, ffi::{self, CPtr}, key::{PublicKey, SecretKey}};
use crate::ffi::{self, CPtr};
use crate::key::{PublicKey, SecretKey};
use crate::{constants, Error};
// The logic for displaying shared secrets relies on this (see `secret.rs`).
const SHARED_SECRET_SIZE: usize = constants::SECRET_KEY_SIZE;
@ -51,7 +54,7 @@ impl SharedSecret {
pub fn new(point: &PublicKey, scalar: &SecretKey) -> SharedSecret {
let mut buf = [0u8; SHARED_SECRET_SIZE];
let res = unsafe {
ffi::secp256k1_ecdh(
ffi::secp256k1_ecdh(
ffi::secp256k1_context_no_precomp,
buf.as_mut_ptr(),
point.as_c_ptr(),
@ -66,15 +69,11 @@ impl SharedSecret {
/// Returns the shared secret as a byte value.
#[inline]
pub fn secret_bytes(&self) -> [u8; SHARED_SECRET_SIZE] {
self.0
}
pub fn secret_bytes(&self) -> [u8; SHARED_SECRET_SIZE] { self.0 }
/// Creates a shared secret from `bytes` array.
#[inline]
pub fn from_bytes(bytes: [u8; SHARED_SECRET_SIZE]) -> SharedSecret {
SharedSecret(bytes)
}
pub fn from_bytes(bytes: [u8; SHARED_SECRET_SIZE]) -> SharedSecret { SharedSecret(bytes) }
/// Creates a shared secret from `bytes` slice.
#[inline]
@ -85,7 +84,7 @@ impl SharedSecret {
ret[..].copy_from_slice(bytes);
Ok(SharedSecret(ret))
}
_ => Err(Error::InvalidSharedSecret)
_ => Err(Error::InvalidSharedSecret),
}
}
}
@ -96,21 +95,17 @@ impl str::FromStr for SharedSecret {
let mut res = [0u8; SHARED_SECRET_SIZE];
match crate::from_hex(s, &mut res) {
Ok(SHARED_SECRET_SIZE) => Ok(SharedSecret::from_bytes(res)),
_ => Err(Error::InvalidSharedSecret)
_ => Err(Error::InvalidSharedSecret),
}
}
}
impl Borrow<[u8]> for SharedSecret {
fn borrow(&self) -> &[u8] {
&self.0
}
fn borrow(&self) -> &[u8] { &self.0 }
}
impl AsRef<[u8]> for SharedSecret {
fn as_ref(&self) -> &[u8] {
&self.0
}
fn as_ref(&self) -> &[u8] { &self.0 }
}
/// Creates a shared point from public key and secret key.
@ -162,7 +157,12 @@ pub fn shared_secret_point(point: &PublicKey, scalar: &SecretKey) -> [u8; 64] {
xy
}
unsafe extern "C" fn c_callback(output: *mut c_uchar, x: *const c_uchar, y: *const c_uchar, _data: *mut c_void) -> c_int {
unsafe extern "C" fn c_callback(
output: *mut c_uchar,
x: *const c_uchar,
y: *const c_uchar,
_data: *mut c_void,
) -> c_int {
ptr::copy_nonoverlapping(x, output, 32);
ptr::copy_nonoverlapping(y, output.offset(32), 32);
1
@ -187,12 +187,12 @@ impl<'de> ::serde::Deserialize<'de> for SharedSecret {
fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
if d.is_human_readable() {
d.deserialize_str(super::serde_util::FromStrVisitor::new(
"a hex string representing 32 byte SharedSecret"
"a hex string representing 32 byte SharedSecret",
))
} else {
d.deserialize_bytes(super::serde_util::BytesVisitor::new(
"raw 32 bytes SharedSecret",
SharedSecret::from_slice
SharedSecret::from_slice,
))
}
}
@ -205,11 +205,11 @@ mod tests {
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as test;
use crate::Secp256k1;
use super::SharedSecret;
use crate::Secp256k1;
#[test]
#[cfg(all(feature="rand-std", any(feature = "alloc", feature = "std")))]
#[cfg(all(feature = "rand-std", any(feature = "alloc", feature = "std")))]
fn ecdh() {
let s = Secp256k1::signing_only();
let (sk1, pk1) = s.generate_keypair(&mut thread_rng());
@ -227,7 +227,9 @@ mod tests {
let x = [5u8; 32];
let y = [7u8; 32];
let mut output = [0u8; 64];
let res = unsafe { super::c_callback(output.as_mut_ptr(), x.as_ptr(), y.as_ptr(), core::ptr::null_mut()) };
let res = unsafe {
super::c_callback(output.as_mut_ptr(), x.as_ptr(), y.as_ptr(), core::ptr::null_mut())
};
assert_eq!(res, 1);
let mut new_x = [0u8; 32];
let mut new_y = [0u8; 32];
@ -239,9 +241,10 @@ mod tests {
#[test]
#[cfg(not(fuzzing))]
#[cfg(all(feature="std", feature = "rand-std", feature = "bitcoin-hashes-std"))]
#[cfg(all(feature = "std", feature = "rand-std", feature = "bitcoin-hashes-std"))]
fn bitcoin_hashes_and_sys_generate_same_secret() {
use bitcoin_hashes::{sha256, Hash, HashEngine};
use crate::ecdh::shared_secret_point;
let s = Secp256k1::signing_only();
@ -265,7 +268,7 @@ mod tests {
#[test]
#[cfg(all(feature = "serde", any(feature = "alloc", feature = "std")))]
fn serde() {
use serde_test::{Configure, Token, assert_tokens};
use serde_test::{assert_tokens, Configure, Token};
#[rustfmt::skip]
static BYTES: [u8; 32] = [
1, 1, 1, 1, 1, 1, 1, 1,
@ -289,23 +292,20 @@ mod tests {
#[cfg(bench)]
mod benches {
use test::{Bencher, black_box};
use rand::thread_rng;
use crate::Secp256k1;
use test::{black_box, Bencher};
use super::SharedSecret;
use crate::Secp256k1;
#[bench]
pub fn bench_ecdh(bh: &mut Bencher) {
let s = Secp256k1::signing_only();
let (sk, pk) = s.generate_keypair(&mut thread_rng());
bh.iter( || {
bh.iter(|| {
let res = SharedSecret::new(&pk, &sk);
black_box(res);
});
}
}

View File

@ -4,7 +4,7 @@
mod recovery;
pub mod serialized_signature;
use core::{fmt, str, ptr};
use core::{fmt, ptr, str};
#[cfg(feature = "recovery")]
#[cfg_attr(docsrs, doc(cfg(feature = "recovery")))]
@ -22,9 +22,7 @@ use crate::{
pub struct Signature(pub(crate) ffi::Signature);
impl fmt::Debug for Signature {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(self, f)
}
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(self, f) }
}
impl fmt::Display for Signature {
@ -49,7 +47,9 @@ impl Signature {
#[inline]
/// Converts a DER-encoded byte slice to a signature
pub fn from_der(data: &[u8]) -> Result<Signature, Error> {
if data.is_empty() {return Err(Error::InvalidSignature);}
if data.is_empty() {
return Err(Error::InvalidSignature);
}
unsafe {
let mut ret = ffi::Signature::new();
@ -70,7 +70,7 @@ impl Signature {
/// Converts a 64-byte compact-encoded byte slice to a signature
pub fn from_compact(data: &[u8]) -> Result<Signature, Error> {
if data.len() != 64 {
return Err(Error::InvalidSignature)
return Err(Error::InvalidSignature);
}
unsafe {
@ -93,7 +93,9 @@ impl Signature {
/// 2016. It should never be used in new applications. This library does not
/// support serializing to this "format"
pub fn from_der_lax(data: &[u8]) -> Result<Signature, Error> {
if data.is_empty() {return Err(Error::InvalidSignature);}
if data.is_empty() {
return Err(Error::InvalidSignature);
}
unsafe {
let mut ret = ffi::Signature::new();
@ -143,16 +145,15 @@ impl Signature {
/// Obtains a raw pointer suitable for use with FFI functions
#[inline]
#[deprecated(since = "0.25.0", note = "Use Self::as_c_ptr if you need to access the FFI layer")]
pub fn as_ptr(&self) -> *const ffi::Signature {
self.as_c_ptr()
}
pub fn as_ptr(&self) -> *const ffi::Signature { self.as_c_ptr() }
/// Obtains a raw mutable pointer suitable for use with FFI functions
#[inline]
#[deprecated(since = "0.25.0", note = "Use Self::as_mut_c_ptr if you need to access the FFI layer")]
pub fn as_mut_ptr(&mut self) -> *mut ffi::Signature {
self.as_mut_c_ptr()
}
#[deprecated(
since = "0.25.0",
note = "Use Self::as_mut_c_ptr if you need to access the FFI layer"
)]
pub fn as_mut_ptr(&mut self) -> *mut ffi::Signature { self.as_mut_c_ptr() }
#[inline]
/// Serializes the signature in DER format
@ -198,21 +199,15 @@ impl Signature {
impl CPtr for Signature {
type Target = ffi::Signature;
fn as_c_ptr(&self) -> *const Self::Target {
&self.0
}
fn as_c_ptr(&self) -> *const Self::Target { &self.0 }
fn as_mut_c_ptr(&mut self) -> *mut Self::Target {
&mut self.0
}
fn as_mut_c_ptr(&mut self) -> *mut Self::Target { &mut self.0 }
}
/// Creates a new signature from a FFI signature
impl From<ffi::Signature> for Signature {
#[inline]
fn from(sig: ffi::Signature) -> Signature {
Signature(sig)
}
fn from(sig: ffi::Signature) -> Signature { Signature(sig) }
}
#[cfg(feature = "serde")]
@ -233,12 +228,12 @@ impl<'de> serde::Deserialize<'de> for Signature {
fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
if d.is_human_readable() {
d.deserialize_str(crate::serde_util::FromStrVisitor::new(
"a hex string representing a DER encoded Signature"
"a hex string representing a DER encoded Signature",
))
} else {
d.deserialize_bytes(crate::serde_util::BytesVisitor::new(
"raw byte stream, that represents a DER encoded Signature",
Signature::from_der
Signature::from_der,
))
}
}
@ -259,9 +254,17 @@ impl<C: Signing> Secp256k1<C> {
};
// We can assume the return value because it's not possible to construct
// an invalid signature from a valid `Message` and `SecretKey`
assert_eq!(ffi::secp256k1_ecdsa_sign(self.ctx, &mut ret, msg.as_c_ptr(),
sk.as_c_ptr(), ffi::secp256k1_nonce_function_rfc6979,
noncedata_ptr), 1);
assert_eq!(
ffi::secp256k1_ecdsa_sign(
self.ctx,
&mut ret,
msg.as_c_ptr(),
sk.as_c_ptr(),
ffi::secp256k1_nonce_function_rfc6979,
noncedata_ptr
),
1
);
Signature::from(ret)
}
}
@ -287,33 +290,43 @@ impl<C: Signing> Secp256k1<C> {
}
fn sign_grind_with_check(
&self, msg: &Message,
&self,
msg: &Message,
sk: &SecretKey,
check: impl Fn(&ffi::Signature) -> bool) -> Signature {
let mut entropy_p : *const ffi::types::c_void = ptr::null();
let mut counter : u32 = 0;
let mut extra_entropy = [0u8; 32];
loop {
unsafe {
let mut ret = ffi::Signature::new();
// We can assume the return value because it's not possible to construct
// an invalid signature from a valid `Message` and `SecretKey`
assert_eq!(ffi::secp256k1_ecdsa_sign(self.ctx, &mut ret, msg.as_c_ptr(),
sk.as_c_ptr(), ffi::secp256k1_nonce_function_rfc6979,
entropy_p), 1);
if check(&ret) {
return Signature::from(ret);
}
counter += 1;
extra_entropy[..4].copy_from_slice(&counter.to_le_bytes());
entropy_p = extra_entropy.as_c_ptr().cast::<ffi::types::c_void>();
// When fuzzing, these checks will usually spinloop forever, so just short-circuit them.
#[cfg(fuzzing)]
check: impl Fn(&ffi::Signature) -> bool,
) -> Signature {
let mut entropy_p: *const ffi::types::c_void = ptr::null();
let mut counter: u32 = 0;
let mut extra_entropy = [0u8; 32];
loop {
unsafe {
let mut ret = ffi::Signature::new();
// We can assume the return value because it's not possible to construct
// an invalid signature from a valid `Message` and `SecretKey`
assert_eq!(
ffi::secp256k1_ecdsa_sign(
self.ctx,
&mut ret,
msg.as_c_ptr(),
sk.as_c_ptr(),
ffi::secp256k1_nonce_function_rfc6979,
entropy_p
),
1
);
if check(&ret) {
return Signature::from(ret);
}
counter += 1;
extra_entropy[..4].copy_from_slice(&counter.to_le_bytes());
entropy_p = extra_entropy.as_c_ptr().cast::<ffi::types::c_void>();
// When fuzzing, these checks will usually spinloop forever, so just short-circuit them.
#[cfg(fuzzing)]
return Signature::from(ret);
}
}
}
/// Constructs a signature for `msg` using the secret key `sk`, RFC6979 nonce
@ -322,8 +335,13 @@ impl<C: Signing> Secp256k1<C> {
/// of signing operation performed by this function is exponential in the
/// number of bytes grinded.
/// Requires a signing capable context.
pub fn sign_ecdsa_grind_r(&self, msg: &Message, sk: &SecretKey, bytes_to_grind: usize) -> Signature {
let len_check = |s : &ffi::Signature| der_length_check(s, 71 - bytes_to_grind);
pub fn sign_ecdsa_grind_r(
&self,
msg: &Message,
sk: &SecretKey,
bytes_to_grind: usize,
) -> Signature {
let len_check = |s: &ffi::Signature| der_length_check(s, 71 - bytes_to_grind);
self.sign_grind_with_check(msg, sk, len_check)
}
@ -362,9 +380,16 @@ impl<C: Verification> Secp256k1<C> {
/// # }
/// ```
#[inline]
pub fn verify_ecdsa(&self, msg: &Message, sig: &Signature, pk: &PublicKey) -> Result<(), Error> {
pub fn verify_ecdsa(
&self,
msg: &Message,
sig: &Signature,
pk: &PublicKey,
) -> Result<(), Error> {
unsafe {
if ffi::secp256k1_ecdsa_verify(self.ctx, sig.as_c_ptr(), msg.as_c_ptr(), pk.as_c_ptr()) == 0 {
if ffi::secp256k1_ecdsa_verify(self.ctx, sig.as_c_ptr(), msg.as_c_ptr(), pk.as_c_ptr())
== 0
{
Err(Error::IncorrectSignature)
} else {
Ok(())

View File

@ -18,10 +18,12 @@
//!
use core::ptr;
use crate::{key, Secp256k1, Message, Error, Verification, Signing, ecdsa::Signature};
use super::ffi as super_ffi;
use self::super_ffi::CPtr;
use super::ffi as super_ffi;
use crate::ecdsa::Signature;
use crate::ffi::recovery as ffi;
use crate::{key, Error, Message, Secp256k1, Signing, Verification};
/// A tag used for recovering the public key from a compact signature.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
@ -32,20 +34,18 @@ pub struct RecoveryId(i32);
pub struct RecoverableSignature(ffi::RecoverableSignature);
impl RecoveryId {
#[inline]
/// Allows library users to create valid recovery IDs from i32.
pub fn from_i32(id: i32) -> Result<RecoveryId, Error> {
match id {
0..=3 => Ok(RecoveryId(id)),
_ => Err(Error::InvalidRecoveryId)
#[inline]
/// Allows library users to create valid recovery IDs from i32.
pub fn from_i32(id: i32) -> Result<RecoveryId, Error> {
match id {
0..=3 => Ok(RecoveryId(id)),
_ => Err(Error::InvalidRecoveryId),
}
}
}
#[inline]
/// Allows library users to convert recovery IDs to i32.
pub fn to_i32(self) -> i32 {
self.0
}
#[inline]
/// Allows library users to convert recovery IDs to i32.
pub fn to_i32(self) -> i32 { self.0 }
}
impl RecoverableSignature {
@ -53,7 +53,9 @@ impl RecoverableSignature {
/// Converts a compact-encoded byte slice to a signature. This
/// representation is nonstandard and defined by the libsecp256k1 library.
pub fn from_compact(data: &[u8], recid: RecoveryId) -> Result<RecoverableSignature, Error> {
if data.is_empty() {return Err(Error::InvalidSignature);}
if data.is_empty() {
return Err(Error::InvalidSignature);
}
let mut ret = ffi::RecoverableSignature::new();
@ -77,16 +79,15 @@ impl RecoverableSignature {
/// Obtains a raw pointer suitable for use with FFI functions.
#[inline]
#[deprecated(since = "0.25.0", note = "Use Self::as_c_ptr if you need to access the FFI layer")]
pub fn as_ptr(&self) -> *const ffi::RecoverableSignature {
self.as_c_ptr()
}
pub fn as_ptr(&self) -> *const ffi::RecoverableSignature { self.as_c_ptr() }
/// Obtains a raw mutable pointer suitable for use with FFI functions.
#[inline]
#[deprecated(since = "0.25.0", note = "Use Self::as_mut_c_ptr if you need to access the FFI layer")]
pub fn as_mut_ptr(&mut self) -> *mut ffi::RecoverableSignature {
self.as_mut_c_ptr()
}
#[deprecated(
since = "0.25.0",
note = "Use Self::as_mut_c_ptr if you need to access the FFI layer"
)]
pub fn as_mut_ptr(&mut self) -> *mut ffi::RecoverableSignature { self.as_mut_c_ptr() }
#[inline]
/// Serializes the recoverable signature in compact format.
@ -131,24 +132,17 @@ impl RecoverableSignature {
}
}
impl CPtr for RecoverableSignature {
type Target = ffi::RecoverableSignature;
fn as_c_ptr(&self) -> *const Self::Target {
&self.0
}
fn as_c_ptr(&self) -> *const Self::Target { &self.0 }
fn as_mut_c_ptr(&mut self) -> *mut Self::Target {
&mut self.0
}
fn as_mut_c_ptr(&mut self) -> *mut Self::Target { &mut self.0 }
}
/// Creates a new recoverable signature from a FFI one.
impl From<ffi::RecoverableSignature> for RecoverableSignature {
#[inline]
fn from(sig: ffi::RecoverableSignature) -> RecoverableSignature {
RecoverableSignature(sig)
}
fn from(sig: ffi::RecoverableSignature) -> RecoverableSignature { RecoverableSignature(sig) }
}
impl<C: Signing> Secp256k1<C> {
@ -180,7 +174,11 @@ impl<C: Signing> Secp256k1<C> {
/// Constructs a signature for `msg` using the secret key `sk` and RFC6979 nonce
/// Requires a signing-capable context.
pub fn sign_ecdsa_recoverable(&self, msg: &Message, sk: &key::SecretKey) -> RecoverableSignature {
pub fn sign_ecdsa_recoverable(
&self,
msg: &Message,
sk: &key::SecretKey,
) -> RecoverableSignature {
self.sign_ecdsa_recoverable_with_noncedata_pointer(msg, sk, ptr::null())
}
@ -203,13 +201,15 @@ impl<C: Signing> Secp256k1<C> {
impl<C: Verification> Secp256k1<C> {
/// Determines the public key for which `sig` is a valid signature for
/// `msg`. Requires a verify-capable context.
pub fn recover_ecdsa(&self, msg: &Message, sig: &RecoverableSignature)
-> Result<key::PublicKey, Error> {
pub fn recover_ecdsa(
&self,
msg: &Message,
sig: &RecoverableSignature,
) -> Result<key::PublicKey, Error> {
unsafe {
let mut pk = super_ffi::PublicKey::new();
if ffi::secp256k1_ecdsa_recover(self.ctx, &mut pk,
sig.as_c_ptr(), msg.as_c_ptr()) != 1 {
if ffi::secp256k1_ecdsa_recover(self.ctx, &mut pk, sig.as_c_ptr(), msg.as_c_ptr()) != 1
{
return Err(Error::InvalidSignature);
}
Ok(key::PublicKey::from(pk))
@ -217,21 +217,19 @@ impl<C: Verification> Secp256k1<C> {
}
}
#[cfg(test)]
#[allow(unused_imports)]
mod tests {
use rand::{RngCore, thread_rng};
use crate::{Error, SecretKey, Secp256k1, Message};
use crate::constants::ONE;
use super::{RecoveryId, RecoverableSignature};
use rand::{thread_rng, RngCore};
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as test;
use super::{RecoverableSignature, RecoveryId};
use crate::constants::ONE;
use crate::{Error, Message, Secp256k1, SecretKey};
#[test]
#[cfg(all(feature="std", feature = "rand-std"))]
#[cfg(all(feature = "std", feature = "rand-std"))]
fn capabilities() {
let sign = Secp256k1::signing_only();
let vrfy = Secp256k1::verification_only();
@ -252,8 +250,7 @@ mod tests {
assert!(vrfy.recover_ecdsa(&msg, &sigr).is_ok());
assert!(full.recover_ecdsa(&msg, &sigr).is_ok());
assert_eq!(vrfy.recover_ecdsa(&msg, &sigr),
full.recover_ecdsa(&msg, &sigr));
assert_eq!(vrfy.recover_ecdsa(&msg, &sigr), full.recover_ecdsa(&msg, &sigr));
assert_eq!(full.recover_ecdsa(&msg, &sigr), Ok(pk));
}
@ -315,7 +312,7 @@ mod tests {
}
#[test]
#[cfg(all(feature="std", feature = "rand-std"))]
#[cfg(all(feature = "std", feature = "rand-std"))]
fn sign_and_verify_fail() {
let mut s = Secp256k1::new();
s.randomize(&mut thread_rng());
@ -339,7 +336,7 @@ mod tests {
}
#[test]
#[cfg(all(feature="std", feature = "rand-std"))]
#[cfg(all(feature = "std", feature = "rand-std"))]
fn sign_with_recovery() {
let mut s = Secp256k1::new();
s.randomize(&mut thread_rng());
@ -356,7 +353,7 @@ mod tests {
}
#[test]
#[cfg(all(feature="std", feature = "rand-std"))]
#[cfg(all(feature = "std", feature = "rand-std"))]
fn sign_with_recovery_and_noncedata() {
let mut s = Secp256k1::new();
s.randomize(&mut thread_rng());
@ -375,7 +372,7 @@ mod tests {
}
#[test]
#[cfg(all(feature="std", feature = "rand-std"))]
#[cfg(all(feature = "std", feature = "rand-std"))]
fn bad_recovery() {
let mut s = Secp256k1::new();
s.randomize(&mut thread_rng());
@ -419,10 +416,7 @@ mod tests {
0x80, 0x12, 0x0e, 0xf8, 0x02, 0x5e, 0x70, 0x9f,
0xff, 0x20, 0x80, 0xc4, 0xa3, 0x9a, 0xae, 0x06,
0x8d, 0x12, 0xee, 0xd0, 0x09, 0xb6, 0x8c, 0x89];
let sig = RecoverableSignature::from_compact(
bytes_in,
recid_in,
).unwrap();
let sig = RecoverableSignature::from_compact(bytes_in, recid_in).unwrap();
let (recid_out, bytes_out) = sig.serialize_compact();
assert_eq!(recid_in, recid_out);
assert_eq!(&bytes_in[..], &bytes_out[..]);
@ -446,7 +440,8 @@ mod tests {
#[cfg(bench)]
mod benches {
use rand::{thread_rng, RngCore};
use test::{Bencher, black_box};
use test::{black_box, Bencher};
use super::{Message, Secp256k1};
#[bench]

View File

@ -5,11 +5,12 @@
//! unable to run on platforms without allocator. We implement a special type to encapsulate
//! serialized signatures and since it's a bit more complicated it has its own module.
use core::{fmt, ops};
pub use into_iter::IntoIter;
use core::{fmt, ops};
use crate::Error;
use super::Signature;
use crate::Error;
pub(crate) const MAX_LEN: usize = 72;
@ -21,9 +22,7 @@ pub struct SerializedSignature {
}
impl fmt::Debug for SerializedSignature {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(self, f)
}
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(self, f) }
}
impl fmt::Display for SerializedSignature {
@ -37,25 +36,19 @@ impl fmt::Display for SerializedSignature {
impl PartialEq for SerializedSignature {
#[inline]
fn eq(&self, other: &SerializedSignature) -> bool {
**self == **other
}
fn eq(&self, other: &SerializedSignature) -> bool { **self == **other }
}
impl AsRef<[u8]> for SerializedSignature {
#[inline]
fn as_ref(&self) -> &[u8] {
self
}
fn as_ref(&self) -> &[u8] { self }
}
impl ops::Deref for SerializedSignature {
type Target = [u8];
#[inline]
fn deref(&self) -> &[u8] {
&self.data[..self.len]
}
fn deref(&self) -> &[u8] { &self.data[..self.len] }
}
impl Eq for SerializedSignature {}
@ -65,9 +58,7 @@ impl IntoIterator for SerializedSignature {
type Item = u8;
#[inline]
fn into_iter(self) -> Self::IntoIter {
IntoIter::new(self)
}
fn into_iter(self) -> Self::IntoIter { IntoIter::new(self) }
}
impl<'a> IntoIterator for &'a SerializedSignature {
@ -75,9 +66,7 @@ impl<'a> IntoIterator for &'a SerializedSignature {
type Item = &'a u8;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
fn into_iter(self) -> Self::IntoIter { self.iter() }
}
impl SerializedSignature {
@ -89,43 +78,30 @@ impl SerializedSignature {
#[inline]
pub(crate) fn from_raw_parts(data: [u8; MAX_LEN], len: usize) -> Self {
assert!(len <= MAX_LEN, "attempt to set length to {} but the maximum is {}", len, MAX_LEN);
SerializedSignature {
data,
len,
}
SerializedSignature { data, len }
}
/// Get the capacity of the underlying data buffer.
#[inline]
pub fn capacity(&self) -> usize {
self.data.len()
}
pub fn capacity(&self) -> usize { self.data.len() }
/// Get the len of the used data.
#[inline]
pub fn len(&self) -> usize {
self.len
}
pub fn len(&self) -> usize { self.len }
/// Set the length of the object.
#[inline]
pub(crate) fn set_len_unchecked(&mut self, len: usize) {
self.len = len;
}
pub(crate) fn set_len_unchecked(&mut self, len: usize) { self.len = len; }
/// Convert the serialized signature into the Signature struct.
/// (This DER deserializes it)
#[inline]
pub fn to_signature(&self) -> Result<Signature, Error> {
Signature::from_der(self)
}
pub fn to_signature(&self) -> Result<Signature, Error> { Signature::from_der(self) }
/// Create a SerializedSignature from a Signature.
/// (this DER serializes it)
#[inline]
pub fn from_signature(sig: &Signature) -> SerializedSignature {
sig.serialize_der()
}
pub fn from_signature(sig: &Signature) -> SerializedSignature { sig.serialize_der() }
/// Check if the space is zero.
#[inline]
@ -162,9 +138,7 @@ mod into_iter {
///
/// This method is analogous to [`core::slice::Iter::as_slice`].
#[inline]
pub fn as_slice(&self) -> &[u8] {
&self.signature[self.pos..]
}
pub fn as_slice(&self) -> &[u8] { &self.signature[self.pos..] }
}
impl Iterator for IntoIter {

File diff suppressed because it is too large Load Diff

View File

@ -153,11 +153,8 @@
// Coding conventions
#![deny(non_upper_case_globals, non_camel_case_types, non_snake_case)]
#![warn(missing_docs, missing_copy_implementations, missing_debug_implementations)]
#![allow(clippy::missing_safety_doc)]
#![cfg_attr(all(not(test), not(feature = "std")), no_std)]
// Experimental features we need.
#![cfg_attr(docsrs, feature(doc_cfg))]
#![cfg_attr(bench, feature(test))]
@ -184,29 +181,30 @@ pub mod schnorr;
#[cfg(feature = "serde")]
mod serde_util;
#[cfg(any(test, feature = "rand"))]
#[cfg_attr(docsrs, doc(cfg(feature = "rand")))]
pub use rand;
#[cfg(feature = "serde")]
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
pub use serde;
use core::marker::PhantomData;
use core::{fmt, mem, str};
#[cfg(feature = "bitcoin-hashes")]
#[cfg_attr(docsrs, doc(cfg(feature = "bitcoin-hashes")))]
pub use bitcoin_hashes as hashes;
pub use secp256k1_sys as ffi;
pub use crate::key::{PublicKey, SecretKey};
pub use crate::context::*;
pub use crate::key::*;
pub use crate::scalar::Scalar;
#[cfg(feature = "global-context")]
#[cfg_attr(docsrs, doc(cfg(feature = "global-context")))]
pub use context::global::SECP256K1;
#[cfg(any(test, feature = "rand"))]
#[cfg_attr(docsrs, doc(cfg(feature = "rand")))]
pub use rand;
pub use secp256k1_sys as ffi;
#[cfg(feature = "serde")]
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
pub use serde;
use core::{fmt, str, mem, marker::PhantomData};
use crate::ffi::{CPtr, impl_array_newtype, types::AlignedType};
pub use crate::context::*;
use crate::ffi::types::AlignedType;
use crate::ffi::{impl_array_newtype, CPtr};
#[cfg(feature = "bitcoin-hashes")]
use crate::hashes::Hash;
pub use crate::key::{PublicKey, SecretKey, *};
pub use crate::scalar::Scalar;
/// Trait describing something that promises to be a 32-byte random number; in particular,
/// it has negligible probability of being zero or overflowing the group order. Such objects
@ -219,25 +217,19 @@ pub trait ThirtyTwoByteHash {
#[cfg(feature = "bitcoin-hashes")]
#[cfg_attr(docsrs, doc(cfg(feature = "bitcoin-hashes")))]
impl ThirtyTwoByteHash for hashes::sha256::Hash {
fn into_32(self) -> [u8; 32] {
self.into_inner()
}
fn into_32(self) -> [u8; 32] { self.into_inner() }
}
#[cfg(feature = "bitcoin-hashes")]
#[cfg_attr(docsrs, doc(cfg(feature = "bitcoin-hashes")))]
impl ThirtyTwoByteHash for hashes::sha256d::Hash {
fn into_32(self) -> [u8; 32] {
self.into_inner()
}
fn into_32(self) -> [u8; 32] { self.into_inner() }
}
#[cfg(feature = "bitcoin-hashes")]
#[cfg_attr(docsrs, doc(cfg(feature = "bitcoin-hashes")))]
impl<T: hashes::sha256t::Tag> ThirtyTwoByteHash for hashes::sha256t::Hash<T> {
fn into_32(self) -> [u8; 32] {
self.into_inner()
}
fn into_32(self) -> [u8; 32] { self.into_inner() }
}
/// A (hashed) message input to an ECDSA signature.
@ -260,7 +252,7 @@ impl Message {
ret[..].copy_from_slice(data);
Ok(Message(ret))
}
_ => Err(Error::InvalidMessage)
_ => Err(Error::InvalidMessage),
}
}
@ -291,9 +283,7 @@ impl Message {
impl<T: ThirtyTwoByteHash> From<T> for Message {
/// Converts a 32-byte hash directly to a message without error paths.
fn from(t: T) -> Message {
Message(t.into_32())
}
fn from(t: T) -> Message { Message(t.into_32()) }
}
impl fmt::LowerHex for Message {
@ -306,9 +296,7 @@ impl fmt::LowerHex for Message {
}
impl fmt::Display for Message {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::LowerHex::fmt(self, f)
}
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::LowerHex::fmt(self, f) }
}
/// An ECDSA error
@ -353,7 +341,9 @@ impl fmt::Display for Error {
InvalidRecoveryId => f.write_str("bad recovery id"),
InvalidTweak => f.write_str("bad tweak"),
NotEnoughMemory => f.write_str("not enough memory allocated"),
InvalidPublicKeySum => f.write_str("the sum of public keys was invalid or the input vector lengths was less than 1"),
InvalidPublicKeySum => f.write_str(
"the sum of public keys was invalid or the input vector lengths was less than 1",
),
InvalidParityValue(e) => write_err!(f, "couldn't create parity"; e),
}
}
@ -379,7 +369,6 @@ impl std::error::Error for Error {
}
}
/// The secp256k1 engine, used to execute all signature operations.
pub struct Secp256k1<C: Context> {
ctx: *mut ffi::Context,
@ -396,7 +385,7 @@ impl<C: Context> PartialEq for Secp256k1<C> {
fn eq(&self, _other: &Secp256k1<C>) -> bool { true }
}
impl<C: Context> Eq for Secp256k1<C> { }
impl<C: Context> Eq for Secp256k1<C> {}
impl<C: Context> Drop for Secp256k1<C> {
fn drop(&mut self) {
@ -414,14 +403,11 @@ impl<C: Context> fmt::Debug for Secp256k1<C> {
}
impl<C: Context> Secp256k1<C> {
/// Getter for the raw pointer to the underlying secp256k1 context. This
/// shouldn't be needed with normal usage of the library. It enables
/// extending the Secp256k1 with more cryptographic algorithms outside of
/// this crate.
pub fn ctx(&self) -> &*mut ffi::Context {
&self.ctx
}
pub fn ctx(&self) -> &*mut ffi::Context { &self.ctx }
/// Returns the required memory for a preallocated context buffer in a generic manner(sign/verify/all).
pub fn preallocate_size_gen() -> usize {
@ -468,8 +454,10 @@ impl<C: Signing> Secp256k1<C> {
#[inline]
#[cfg(any(test, feature = "rand"))]
#[cfg_attr(docsrs, doc(cfg(feature = "rand")))]
pub fn generate_keypair<R: rand::Rng + ?Sized>(&self, rng: &mut R)
-> (key::SecretKey, key::PublicKey) {
pub fn generate_keypair<R: rand::Rng + ?Sized>(
&self,
rng: &mut R,
) -> (key::SecretKey, key::PublicKey) {
let sk = key::SecretKey::new(rng);
let pk = key::PublicKey::from_secret_key(self, &sk);
(sk, pk)
@ -525,38 +513,38 @@ fn to_hex<'a>(src: &[u8], target: &'a mut [u8]) -> Result<&'a str, ()> {
let mut i = 0;
for &b in src {
target[i] = HEX_TABLE[usize::from(b >> 4)];
target[i+1] = HEX_TABLE[usize::from(b & 0b00001111)];
i +=2 ;
target[i + 1] = HEX_TABLE[usize::from(b & 0b00001111)];
i += 2;
}
let result = &target[..hex_len];
debug_assert!(str::from_utf8(result).is_ok());
return unsafe { Ok(str::from_utf8_unchecked(result)) };
}
#[cfg(test)]
mod tests {
use std::marker::PhantomData;
use std::str::FromStr;
use rand::{RngCore, thread_rng};
use rand::{thread_rng, RngCore};
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as test;
use crate::{constants, ecdsa, from_hex, to_hex, Message, PublicKey, Secp256k1, SecretKey, Error};
use crate::context::*;
use crate::ffi::{self, types::AlignedType};
use crate::ffi::types::AlignedType;
use crate::ffi::{self};
use crate::{
constants, ecdsa, from_hex, to_hex, Error, Message, PublicKey, Secp256k1, SecretKey,
};
macro_rules! hex {
($hex:expr) => ({
($hex:expr) => {{
let mut result = vec![0; $hex.len() / 2];
from_hex($hex, &mut result).expect("valid hex string");
result
});
}};
}
#[test]
#[cfg(feature = "std")]
fn test_manual_create_destroy() {
@ -565,9 +553,12 @@ mod tests {
let ctx_vrfy = unsafe { ffi::secp256k1_context_create(VerifyOnlyPreallocated::FLAGS) };
let size = 0;
let full: Secp256k1<AllPreallocated> = Secp256k1{ctx: ctx_full, phantom: PhantomData, size};
let sign: Secp256k1<SignOnlyPreallocated> = Secp256k1{ctx: ctx_sign, phantom: PhantomData, size};
let vrfy: Secp256k1<VerifyOnlyPreallocated> = Secp256k1{ctx: ctx_vrfy, phantom: PhantomData, size};
let full: Secp256k1<AllPreallocated> =
Secp256k1 { ctx: ctx_full, phantom: PhantomData, size };
let sign: Secp256k1<SignOnlyPreallocated> =
Secp256k1 { ctx: ctx_sign, phantom: PhantomData, size };
let vrfy: Secp256k1<VerifyOnlyPreallocated> =
Secp256k1 { ctx: ctx_vrfy, phantom: PhantomData, size };
let (sk, pk) = full.generate_keypair(&mut thread_rng());
let msg = Message::from_slice(&[2u8; 32]).unwrap();
@ -579,7 +570,9 @@ mod tests {
assert!(vrfy.verify_ecdsa(&msg, &sig, &pk).is_ok());
assert!(full.verify_ecdsa(&msg, &sig, &pk).is_ok());
drop(full);drop(sign);drop(vrfy);
drop(full);
drop(sign);
drop(vrfy);
unsafe { ffi::secp256k1_context_destroy(ctx_vrfy) };
unsafe { ffi::secp256k1_context_destroy(ctx_sign) };
@ -595,9 +588,9 @@ mod tests {
let ctx_sign = Secp256k1::signing_only();
let ctx_vrfy = Secp256k1::verification_only();
let mut full = unsafe {Secp256k1::from_raw_all(ctx_full.ctx)};
let mut sign = unsafe {Secp256k1::from_raw_signing_only(ctx_sign.ctx)};
let mut vrfy = unsafe {Secp256k1::from_raw_verification_only(ctx_vrfy.ctx)};
let mut full = unsafe { Secp256k1::from_raw_all(ctx_full.ctx) };
let mut sign = unsafe { Secp256k1::from_raw_signing_only(ctx_sign.ctx) };
let mut vrfy = unsafe { Secp256k1::from_raw_verification_only(ctx_vrfy.ctx) };
let (sk, pk) = full.generate_keypair(&mut thread_rng());
let msg = Message::from_slice(&[2u8; 32]).unwrap();
@ -613,7 +606,6 @@ mod tests {
ManuallyDrop::drop(&mut full);
ManuallyDrop::drop(&mut sign);
ManuallyDrop::drop(&mut vrfy);
}
drop(ctx_full);
drop(ctx_sign);
@ -640,8 +632,8 @@ mod tests {
let sign = Secp256k1::preallocated_signing_only(&mut buf_sign).unwrap();
let vrfy = Secp256k1::preallocated_verification_only(&mut buf_vfy).unwrap();
// drop(buf_vfy); // The buffer can't get dropped before the context.
// println!("{:?}", buf_ful[5]); // Can't even read the data thanks to the borrow checker.
// drop(buf_vfy); // The buffer can't get dropped before the context.
// println!("{:?}", buf_ful[5]); // Can't even read the data thanks to the borrow checker.
let (sk, pk) = full.generate_keypair(&mut thread_rng());
let msg = Message::from_slice(&[2u8; 32]).unwrap();
@ -709,7 +701,7 @@ mod tests {
assert!(ecdsa::Signature::from_compact(&compact[0..4]).is_err());
assert!(ecdsa::Signature::from_der(&compact[..]).is_err());
assert!(ecdsa::Signature::from_der(&der[0..4]).is_err());
}
}
}
#[test]
@ -729,15 +721,18 @@ mod tests {
assert!(ecdsa::Signature::from_str(
"3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a\
72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab4"
).is_err());
)
.is_err());
assert!(ecdsa::Signature::from_str(
"3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a\
72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab"
).is_err());
)
.is_err());
assert!(ecdsa::Signature::from_str(
"3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a\
72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eabxx"
).is_err());
)
.is_err());
assert!(ecdsa::Signature::from_str(
"3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a\
72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45\
@ -745,7 +740,8 @@ mod tests {
72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45\
72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45\
72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45"
).is_err());
)
.is_err());
// 71 byte signature
let hex_str = "30450221009d0bad576719d32ae76bedb34c774866673cbde3f4e12951555c9408e6ce774b02202876e7102f204f6bfee26c967c3926ce702cf97d4b010062e193f763190f6776";
@ -796,14 +792,14 @@ mod tests {
if compact[0] < 0x80 {
assert_eq!(sig, low_r_sig);
} else {
#[cfg(not(fuzzing))] // mocked sig generation doesn't produce low-R sigs
#[cfg(not(fuzzing))] // mocked sig generation doesn't produce low-R sigs
assert_ne!(sig, low_r_sig);
}
#[cfg(not(fuzzing))] // mocked sig generation doesn't produce low-R sigs
#[cfg(not(fuzzing))] // mocked sig generation doesn't produce low-R sigs
assert!(ecdsa::compact_sig_has_zero_first_bit(&low_r_sig.0));
#[cfg(not(fuzzing))] // mocked sig generation doesn't produce low-R sigs
#[cfg(not(fuzzing))] // mocked sig generation doesn't produce low-R sigs
assert!(ecdsa::der_length_check(&grind_r_sig.0, 70));
}
}
}
#[test]
@ -862,15 +858,23 @@ mod tests {
#[test]
fn test_bad_slice() {
assert_eq!(ecdsa::Signature::from_der(&[0; constants::MAX_SIGNATURE_SIZE + 1]),
Err(Error::InvalidSignature));
assert_eq!(ecdsa::Signature::from_der(&[0; constants::MAX_SIGNATURE_SIZE]),
Err(Error::InvalidSignature));
assert_eq!(
ecdsa::Signature::from_der(&[0; constants::MAX_SIGNATURE_SIZE + 1]),
Err(Error::InvalidSignature)
);
assert_eq!(
ecdsa::Signature::from_der(&[0; constants::MAX_SIGNATURE_SIZE]),
Err(Error::InvalidSignature)
);
assert_eq!(Message::from_slice(&[0; constants::MESSAGE_SIZE - 1]),
Err(Error::InvalidMessage));
assert_eq!(Message::from_slice(&[0; constants::MESSAGE_SIZE + 1]),
Err(Error::InvalidMessage));
assert_eq!(
Message::from_slice(&[0; constants::MESSAGE_SIZE - 1]),
Err(Error::InvalidMessage)
);
assert_eq!(
Message::from_slice(&[0; constants::MESSAGE_SIZE + 1]),
Err(Error::InvalidMessage)
);
assert!(Message::from_slice(&[0; constants::MESSAGE_SIZE]).is_ok());
assert!(Message::from_slice(&[1; constants::MESSAGE_SIZE]).is_ok());
}
@ -881,7 +885,7 @@ mod tests {
const AMOUNT: usize = 1024;
for i in 0..AMOUNT {
// 255 isn't a valid utf8 character.
let mut hex_buf = [255u8; AMOUNT*2];
let mut hex_buf = [255u8; AMOUNT * 2];
let mut src_buf = [0u8; AMOUNT];
let mut result_buf = [0u8; AMOUNT];
let src = &mut src_buf[0..i];
@ -892,9 +896,8 @@ mod tests {
assert_eq!(src, &result_buf[..i]);
}
assert!(to_hex(&[1;2], &mut [0u8; 3]).is_err());
assert!(to_hex(&[1;2], &mut [0u8; 4]).is_ok());
assert!(to_hex(&[1; 2], &mut [0u8; 3]).is_err());
assert!(to_hex(&[1; 2], &mut [0u8; 4]).is_ok());
assert!(from_hex("deadbeaf", &mut [0u8; 3]).is_err());
assert!(from_hex("deadbeaf", &mut [0u8; 4]).is_ok());
assert!(from_hex("a", &mut [0u8; 4]).is_err());
@ -902,14 +905,16 @@ mod tests {
}
#[test]
#[cfg(not(fuzzing))] // fuzz-sigs have fixed size/format
#[cfg(not(fuzzing))] // fuzz-sigs have fixed size/format
#[cfg(any(feature = "alloc", feature = "std"))]
fn test_noncedata() {
let secp = Secp256k1::new();
let msg = hex!("887d04bb1cf1b1554f1b268dfe62d13064ca67ae45348d50d1392ce2d13418ac");
let msg = Message::from_slice(&msg).unwrap();
let noncedata = [42u8; 32];
let sk = SecretKey::from_str("57f0148f94d13095cfda539d0da0d1541304b678d8b36e243980aab4e1b7cead").unwrap();
let sk =
SecretKey::from_str("57f0148f94d13095cfda539d0da0d1541304b678d8b36e243980aab4e1b7cead")
.unwrap();
let expected_sig = hex!("24861b3edd4e7da43319c635091405feced6efa4ec99c3c3c35f6c3ba0ed8816116772e84994084db85a6c20589f6a85af569d42275c2a5dd900da5776b99d5d");
let expected_sig = ecdsa::Signature::from_compact(&expected_sig).unwrap();
@ -919,7 +924,7 @@ mod tests {
}
#[test]
#[cfg(not(fuzzing))] // fixed sig vectors can't work with fuzz-sigs
#[cfg(not(fuzzing))] // fixed sig vectors can't work with fuzz-sigs
#[cfg(any(feature = "alloc", feature = "std"))]
fn test_low_s() {
// nb this is a transaction on testnet
@ -942,13 +947,15 @@ mod tests {
}
#[test]
#[cfg(not(fuzzing))] // fuzz-sigs have fixed size/format
#[cfg(not(fuzzing))] // fuzz-sigs have fixed size/format
#[cfg(any(feature = "alloc", feature = "std"))]
fn test_low_r() {
let secp = Secp256k1::new();
let msg = hex!("887d04bb1cf1b1554f1b268dfe62d13064ca67ae45348d50d1392ce2d13418ac");
let msg = Message::from_slice(&msg).unwrap();
let sk = SecretKey::from_str("57f0148f94d13095cfda539d0da0d1541304b678d8b36e243980aab4e1b7cead").unwrap();
let sk =
SecretKey::from_str("57f0148f94d13095cfda539d0da0d1541304b678d8b36e243980aab4e1b7cead")
.unwrap();
let expected_sig = hex!("047dd4d049db02b430d24c41c7925b2725bcd5a85393513bdec04b4dc363632b1054d0180094122b380f4cfa391e6296244da773173e78fc745c1b9c79f7b713");
let expected_sig = ecdsa::Signature::from_compact(&expected_sig).unwrap();
@ -958,13 +965,15 @@ mod tests {
}
#[test]
#[cfg(not(fuzzing))] // fuzz-sigs have fixed size/format
#[cfg(not(fuzzing))] // fuzz-sigs have fixed size/format
#[cfg(any(feature = "alloc", feature = "std"))]
fn test_grind_r() {
let secp = Secp256k1::new();
let msg = hex!("ef2d5b9a7c61865a95941d0f04285420560df7e9d76890ac1b8867b12ce43167");
let msg = Message::from_slice(&msg).unwrap();
let sk = SecretKey::from_str("848355d75fe1c354cf05539bb29b2015f1863065bcb6766b44d399ab95c3fa0b").unwrap();
let sk =
SecretKey::from_str("848355d75fe1c354cf05539bb29b2015f1863065bcb6766b44d399ab95c3fa0b")
.unwrap();
let expected_sig = ecdsa::Signature::from_str("304302202ffc447100d518c8ba643d11f3e6a83a8640488e7d2537b1954b942408be6ea3021f26e1248dd1e52160c3a38af9769d91a1a806cab5f9d508c103464d3c02d6e1").unwrap();
let sig = secp.sign_ecdsa_grind_r(&msg, &sk, 2);
@ -973,11 +982,11 @@ mod tests {
}
#[cfg(feature = "serde")]
#[cfg(not(fuzzing))] // fixed sig vectors can't work with fuzz-sigs
#[cfg(not(fuzzing))] // fixed sig vectors can't work with fuzz-sigs
#[cfg(any(feature = "alloc", feature = "std"))]
#[test]
fn test_serde() {
use serde_test::{Configure, Token, assert_tokens};
use serde_test::{assert_tokens, Configure, Token};
let s = Secp256k1::new();
@ -985,11 +994,10 @@ mod tests {
let sk = SecretKey::from_slice(&[2; 32]).unwrap();
let sig = s.sign_ecdsa(&msg, &sk);
static SIG_BYTES: [u8; 71] = [
48, 69, 2, 33, 0, 157, 11, 173, 87, 103, 25, 211, 42, 231, 107, 237,
179, 76, 119, 72, 102, 103, 60, 189, 227, 244, 225, 41, 81, 85, 92, 148,
8, 230, 206, 119, 75, 2, 32, 40, 118, 231, 16, 47, 32, 79, 107, 254,
226, 108, 150, 124, 57, 38, 206, 112, 44, 249, 125, 75, 1, 0, 98, 225,
147, 247, 99, 25, 15, 103, 118
48, 69, 2, 33, 0, 157, 11, 173, 87, 103, 25, 211, 42, 231, 107, 237, 179, 76, 119, 72,
102, 103, 60, 189, 227, 244, 225, 41, 81, 85, 92, 148, 8, 230, 206, 119, 75, 2, 32, 40,
118, 231, 16, 47, 32, 79, 107, 254, 226, 108, 150, 124, 57, 38, 206, 112, 44, 249, 125,
75, 1, 0, 98, 225, 147, 247, 99, 25, 15, 103, 118,
];
static SIG_STR: &str = "\
30450221009d0bad576719d32ae76bedb34c774866673cbde3f4e12951555c9408e6ce77\
@ -1003,7 +1011,6 @@ mod tests {
assert_tokens(&sig.readable(), &[Token::BorrowedStr(SIG_STR)]);
assert_tokens(&sig.readable(), &[Token::Str(SIG_STR)]);
assert_tokens(&sig.readable(), &[Token::String(SIG_STR)]);
}
#[cfg(feature = "global-context")]
@ -1033,37 +1040,29 @@ mod tests {
let hash = hashes::sha256::Hash::hash(test_bytes);
let msg = Message::from(hash);
assert_eq!(msg.0, hash.into_inner());
assert_eq!(
msg,
Message::from_hashed_data::<hashes::sha256::Hash>(test_bytes)
);
assert_eq!(msg, Message::from_hashed_data::<hashes::sha256::Hash>(test_bytes));
let hash = hashes::sha256d::Hash::hash(test_bytes);
let msg = Message::from(hash);
assert_eq!(msg.0, hash.into_inner());
assert_eq!(
msg,
Message::from_hashed_data::<hashes::sha256d::Hash>(test_bytes)
);
assert_eq!(msg, Message::from_hashed_data::<hashes::sha256d::Hash>(test_bytes));
}
}
#[cfg(bench)]
mod benches {
use test::{Bencher, black_box};
use rand::{RngCore, thread_rng};
use rand::rngs::mock::StepRng;
use rand::{thread_rng, RngCore};
use test::{black_box, Bencher};
use super::{Message, Secp256k1};
#[bench]
#[cfg(any(feature = "alloc", feature = "std"))]
pub fn generate(bh: &mut Bencher) {
let s = Secp256k1::new();
let mut r = StepRng::new(1, 1);
bh.iter( || {
bh.iter(|| {
let (sk, pk) = s.generate_keypair(&mut r);
black_box(sk);
black_box(pk);

View File

@ -24,7 +24,7 @@ macro_rules! impl_pretty_debug {
f.write_str(")")
}
}
}
};
}
/// Formats error. If `std` feature is OFF appends error source (delimited by `: `). We do this

View File

@ -25,7 +25,7 @@ pub struct Scalar([u8; 32]);
const MAX_RAW: [u8; 32] = [
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x40
0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x40,
];
impl Scalar {
@ -39,9 +39,7 @@ impl Scalar {
/// Generates a random scalar
#[cfg(any(test, feature = "rand-std"))]
#[cfg_attr(docsrs, doc(cfg(feature = "rand-std")))]
pub fn random() -> Self {
Self::random_custom(rand::thread_rng())
}
pub fn random() -> Self { Self::random_custom(rand::thread_rng()) }
/// Generates a random scalar using supplied RNG
#[cfg(any(test, feature = "rand"))]
@ -88,9 +86,7 @@ impl Scalar {
}
/// Serializes to big endian bytes
pub fn to_be_bytes(self) -> [u8; 32] {
self.0
}
pub fn to_be_bytes(self) -> [u8; 32] { self.0 }
/// Serializes to little endian bytes
pub fn to_le_bytes(self) -> [u8; 32] {
@ -101,9 +97,7 @@ impl Scalar {
// returns a reference to internal bytes
// non-public to not leak the internal representation
pub(crate) fn as_be_bytes(&self) -> &[u8; 32] {
&self.0
}
pub(crate) fn as_be_bytes(&self) -> &[u8; 32] { &self.0 }
pub(crate) fn as_c_ptr(&self) -> *const u8 {
use secp256k1_sys::CPtr;
@ -113,20 +107,16 @@ impl Scalar {
}
impl From<crate::SecretKey> for Scalar {
fn from(value: crate::SecretKey) -> Self {
Scalar(value.secret_bytes())
}
fn from(value: crate::SecretKey) -> Self { Scalar(value.secret_bytes()) }
}
/// Error returned when the value of scalar is invalid - larger than the curve order.
// Intentionally doesn't implement `Copy` to improve forward compatibility.
// Same reason for `non_exhaustive`.
#[allow(missing_copy_implementations)]
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
#[non_exhaustive]
pub struct OutOfRangeError {
}
pub struct OutOfRangeError {}
impl fmt::Display for OutOfRangeError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {

View File

@ -7,12 +7,11 @@ use core::{fmt, ptr, str};
#[cfg(any(test, feature = "rand"))]
use rand::{CryptoRng, Rng};
use crate::{constants, Error, from_hex, Message, Secp256k1, Signing, Verification};
use crate::ffi::{self, impl_array_newtype, CPtr};
use crate::key::{KeyPair, XOnlyPublicKey};
use crate::ffi::{self, CPtr, impl_array_newtype};
#[cfg(all(feature = "global-context", feature = "rand-std"))]
#[cfg(all(feature = "global-context", feature = "rand-std"))]
use crate::SECP256K1;
use crate::{constants, from_hex, Error, Message, Secp256k1, Signing, Verification};
/// Represents a Schnorr signature.
pub struct Signature([u8; constants::SCHNORR_SIGNATURE_SIZE]);
@ -35,12 +34,12 @@ impl<'de> serde::Deserialize<'de> for Signature {
fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
if d.is_human_readable() {
d.deserialize_str(super::serde_util::FromStrVisitor::new(
"a hex string representing 64 byte schnorr signature"
"a hex string representing 64 byte schnorr signature",
))
} else {
d.deserialize_bytes(super::serde_util::BytesVisitor::new(
"raw 64 bytes schnorr signature",
Signature::from_slice
Signature::from_slice,
))
}
}
@ -56,9 +55,7 @@ impl fmt::LowerHex for Signature {
}
impl fmt::Display for Signature {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::LowerHex::fmt(self, f)
}
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::LowerHex::fmt(self, f) }
}
impl str::FromStr for Signature {
@ -66,9 +63,8 @@ impl str::FromStr for Signature {
fn from_str(s: &str) -> Result<Signature, Error> {
let mut res = [0u8; constants::SCHNORR_SIGNATURE_SIZE];
match from_hex(s, &mut res) {
Ok(constants::SCHNORR_SIGNATURE_SIZE) => {
Signature::from_slice(&res[0..constants::SCHNORR_SIGNATURE_SIZE])
}
Ok(constants::SCHNORR_SIGNATURE_SIZE) =>
Signature::from_slice(&res[0..constants::SCHNORR_SIGNATURE_SIZE]),
_ => Err(Error::InvalidSignature),
}
}
@ -130,11 +126,7 @@ impl<C: Signing> Secp256k1<C> {
}
/// Create a schnorr signature without using any auxiliary random data.
pub fn sign_schnorr_no_aux_rand(
&self,
msg: &Message,
keypair: &KeyPair,
) -> Signature {
pub fn sign_schnorr_no_aux_rand(&self, msg: &Message, keypair: &KeyPair) -> Signature {
self.sign_schnorr_helper(msg, keypair, ptr::null())
}
@ -145,11 +137,7 @@ impl<C: Signing> Secp256k1<C> {
keypair: &KeyPair,
aux_rand: &[u8; 32],
) -> Signature {
self.sign_schnorr_helper(
msg,
keypair,
aux_rand.as_c_ptr() as *const ffi::types::c_uchar,
)
self.sign_schnorr_helper(msg, keypair, aux_rand.as_c_ptr() as *const ffi::types::c_uchar)
}
/// Create a schnorr signature using the given random number generator to
@ -199,15 +187,15 @@ impl<C: Verification> Secp256k1<C> {
mod tests {
use core::str::FromStr;
use rand::{RngCore, rngs::ThreadRng, thread_rng};
use rand::rngs::ThreadRng;
use rand::{thread_rng, RngCore};
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as test;
use crate::{constants, from_hex, Message, Secp256k1, SecretKey};
use crate::schnorr::{KeyPair, XOnlyPublicKey, Signature};
use crate::Error::InvalidPublicKey;
use super::*;
use crate::schnorr::{KeyPair, Signature, XOnlyPublicKey};
use crate::Error::InvalidPublicKey;
use crate::{constants, from_hex, Message, Secp256k1, SecretKey};
#[cfg(all(not(fuzzing), any(feature = "alloc", feature = "std")))]
macro_rules! hex_32 {
@ -231,25 +219,17 @@ mod tests {
#[test]
#[cfg(all(feature = "std", feature = "rand-std"))]
fn schnor_sign_with_rng_verify() {
sign_helper(|secp, msg, seckey, mut rng| {
secp.sign_schnorr_with_rng(msg, seckey, &mut rng)
})
sign_helper(|secp, msg, seckey, mut rng| secp.sign_schnorr_with_rng(msg, seckey, &mut rng))
}
#[test]
#[cfg(all(feature = "std", feature = "rand-std"))]
fn schnorr_sign_verify() {
sign_helper(|secp, msg, seckey, _| {
secp.sign_schnorr(msg, seckey)
})
}
fn schnorr_sign_verify() { sign_helper(|secp, msg, seckey, _| secp.sign_schnorr(msg, seckey)) }
#[test]
#[cfg(all(feature = "std", feature = "rand-std"))]
fn schnorr_sign_no_aux_rand_verify() {
sign_helper(|secp, msg, seckey, _| {
secp.sign_schnorr_no_aux_rand(msg, seckey)
})
sign_helper(|secp, msg, seckey, _| secp.sign_schnorr_no_aux_rand(msg, seckey))
}
#[cfg(all(feature = "std", feature = "rand-std"))]
@ -276,7 +256,7 @@ mod tests {
#[test]
#[cfg(any(feature = "alloc", feature = "std"))]
#[cfg(not(fuzzing))] // fixed sig vectors can't work with fuzz-sigs
#[cfg(not(fuzzing))] // fixed sig vectors can't work with fuzz-sigs
fn schnorr_sign() {
let secp = Secp256k1::new();
@ -291,14 +271,13 @@ mod tests {
hex_32!("02CCE08E913F22A36C5648D6405A2C7C50106E7AA2F1649E381C7F09D16B80AB");
let expected_sig = Signature::from_str("6470FD1303DDA4FDA717B9837153C24A6EAB377183FC438F939E0ED2B620E9EE5077C4A8B8DCA28963D772A94F5F0DDF598E1C47C137F91933274C7C3EDADCE8").unwrap();
let sig = secp
.sign_schnorr_with_aux_rand(&msg, &sk, &aux_rand);
let sig = secp.sign_schnorr_with_aux_rand(&msg, &sk, &aux_rand);
assert_eq!(expected_sig, sig);
}
#[test]
#[cfg(not(fuzzing))] // fixed sig vectors can't work with fuzz-sigs
#[cfg(not(fuzzing))] // fixed sig vectors can't work with fuzz-sigs
#[cfg(any(feature = "alloc", feature = "std"))]
fn schnorr_verify() {
let secp = Secp256k1::new();
@ -306,9 +285,10 @@ mod tests {
let hex_msg = hex_32!("E48441762FB75010B2AA31A512B62B4148AA3FB08EB0765D76B252559064A614");
let msg = Message::from_slice(&hex_msg).unwrap();
let sig = Signature::from_str("6470FD1303DDA4FDA717B9837153C24A6EAB377183FC438F939E0ED2B620E9EE5077C4A8B8DCA28963D772A94F5F0DDF598E1C47C137F91933274C7C3EDADCE8").unwrap();
let pubkey =
XOnlyPublicKey::from_str("B33CC9EDC096D0A83416964BD3C6247B8FECD256E4EFA7870D2C854BDEB33390")
.unwrap();
let pubkey = XOnlyPublicKey::from_str(
"B33CC9EDC096D0A83416964BD3C6247B8FECD256E4EFA7870D2C854BDEB33390",
)
.unwrap();
assert!(secp.verify_schnorr(&sig, &msg, &pubkey).is_ok());
}
@ -398,15 +378,22 @@ mod tests {
pk
};
#[cfg(fuzzing)]
let pk = XOnlyPublicKey::from_slice(&[0x18, 0x84, 0x57, 0x81, 0xf6, 0x31, 0xc4, 0x8f, 0x1c, 0x97, 0x09, 0xe2, 0x30, 0x92, 0x06, 0x7d, 0x06, 0x83, 0x7f, 0x30, 0xaa, 0x0c, 0xd0, 0x54, 0x4a, 0xc8, 0x87, 0xfe, 0x91, 0xdd, 0xd1, 0x66]).expect("pk");
let pk = XOnlyPublicKey::from_slice(&[
0x18, 0x84, 0x57, 0x81, 0xf6, 0x31, 0xc4, 0x8f, 0x1c, 0x97, 0x09, 0xe2, 0x30, 0x92,
0x06, 0x7d, 0x06, 0x83, 0x7f, 0x30, 0xaa, 0x0c, 0xd0, 0x54, 0x4a, 0xc8, 0x87, 0xfe,
0x91, 0xdd, 0xd1, 0x66,
])
.expect("pk");
assert_eq!(
pk.to_string(),
"18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166"
);
assert_eq!(
XOnlyPublicKey::from_str("18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166")
.unwrap(),
XOnlyPublicKey::from_str(
"18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166"
)
.unwrap(),
pk
);
@ -454,7 +441,7 @@ mod tests {
);
}
#[cfg(not(fuzzing))] // fixed sig vectors can't work with fuzz-sigs
#[cfg(not(fuzzing))] // fixed sig vectors can't work with fuzz-sigs
#[test]
#[cfg(all(feature = "serde", any(feature = "alloc", feature = "std")))]
fn test_serde() {
@ -465,8 +452,7 @@ mod tests {
let msg = Message::from_slice(&[1; 32]).unwrap();
let keypair = KeyPair::from_seckey_slice(&s, &[2; 32]).unwrap();
let aux = [3u8; 32];
let sig = s
.sign_schnorr_with_aux_rand(&msg, &keypair, &aux);
let sig = s.sign_schnorr_with_aux_rand(&msg, &keypair, &aux);
static SIG_BYTES: [u8; constants::SCHNORR_SIGNATURE_SIZE] = [
0x14, 0xd0, 0xbf, 0x1a, 0x89, 0x53, 0x50, 0x6f, 0xb4, 0x60, 0xf5, 0x8b, 0xe1, 0x41,
0xaf, 0x76, 0x7f, 0xd1, 0x12, 0x53, 0x5f, 0xb3, 0x92, 0x2e, 0xf2, 0x17, 0x30, 0x8e,
@ -479,8 +465,8 @@ mod tests {
";
static PK_BYTES: [u8; 32] = [
24, 132, 87, 129, 246, 49, 196, 143, 28, 151, 9, 226, 48, 146, 6, 125, 6, 131, 127,
48, 170, 12, 208, 84, 74, 200, 135, 254, 145, 221, 209, 102
24, 132, 87, 129, 246, 49, 196, 143, 28, 151, 9, 226, 48, 146, 6, 125, 6, 131, 127, 48,
170, 12, 208, 84, 74, 200, 135, 254, 145, 221, 209, 102,
];
static PK_STR: &str = "18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166";
let pk = XOnlyPublicKey::from_slice(&PK_BYTES).unwrap();

View File

@ -15,7 +15,11 @@
//! Helpers for displaying secret values
use core::fmt;
use crate::{to_hex, constants::SECRET_KEY_SIZE, key::{SecretKey, KeyPair}, ecdh::SharedSecret};
use crate::constants::SECRET_KEY_SIZE;
use crate::ecdh::SharedSecret;
use crate::key::{KeyPair, SecretKey};
use crate::to_hex;
macro_rules! impl_display_secret {
// Default hasher exists only in standard library and not alloc
($thing:ident) => {
@ -27,7 +31,7 @@ macro_rules! impl_display_secret {
const DEBUG_HASH_TAG: &[u8] = &[
0x66, 0xa6, 0x77, 0x1b, 0x9b, 0x6d, 0xae, 0xa1, 0xb2, 0xee, 0x4e, 0x07, 0x49,
0x4a, 0xac, 0x87, 0xa9, 0xb8, 0x5b, 0x4b, 0x35, 0x02, 0xaa, 0x6d, 0x0f, 0x79,
0xcb, 0x63, 0xe6, 0xf8, 0x66, 0x22
0xcb, 0x63, 0xe6, 0xf8, 0x66, 0x22,
]; // =SHA256(b"rust-secp256k1DEBUG");
let mut hasher = std::collections::hash_map::DefaultHasher::new();
@ -37,9 +41,7 @@ macro_rules! impl_display_secret {
hasher.write(&self.secret_bytes());
let hash = hasher.finish();
f.debug_tuple(stringify!($thing))
.field(&format_args!("#{:016x}", hash))
.finish()
f.debug_tuple(stringify!($thing)).field(&format_args!("#{:016x}", hash)).finish()
}
}
@ -57,9 +59,7 @@ macro_rules! impl_display_secret {
engine.input(&self.secret_bytes());
let hash = sha256::Hash::from_engine(engine);
f.debug_tuple(stringify!($thing))
.field(&format_args!("#{:016x}", hash))
.finish()
f.debug_tuple(stringify!($thing)).field(&format_args!("#{:016x}", hash)).finish()
}
}
@ -69,7 +69,7 @@ macro_rules! impl_display_secret {
write!(f, "<secret requires std or bitcoin_hashes feature to display>")
}
}
}
};
}
/// Helper struct for safely printing secrets (like [`SecretKey`] value).
@ -84,7 +84,7 @@ macro_rules! impl_display_secret {
/// [`Debug`]: fmt::Debug
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct DisplaySecret {
secret: [u8; SECRET_KEY_SIZE]
secret: [u8; SECRET_KEY_SIZE],
}
impl fmt::Debug for DisplaySecret {
@ -92,9 +92,7 @@ impl fmt::Debug for DisplaySecret {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut slice = [0u8; SECRET_KEY_SIZE * 2];
let hex = to_hex(&self.secret, &mut slice).expect("fixed-size hex serializer failed");
f.debug_tuple("DisplaySecret")
.field(&hex)
.finish()
f.debug_tuple("DisplaySecret").field(&hex).finish()
}
}
@ -136,9 +134,7 @@ impl SecretKey {
/// # }
/// ```
#[inline]
pub fn display_secret(&self) -> DisplaySecret {
DisplaySecret { secret: self.secret_bytes() }
}
pub fn display_secret(&self) -> DisplaySecret { DisplaySecret { secret: self.secret_bytes() } }
}
impl KeyPair {
@ -172,9 +168,7 @@ impl KeyPair {
/// # }
/// ```
#[inline]
pub fn display_secret(&self) -> DisplaySecret {
DisplaySecret { secret: self.secret_bytes() }
}
pub fn display_secret(&self) -> DisplaySecret { DisplaySecret { secret: self.secret_bytes() } }
}
impl SharedSecret {
@ -210,7 +204,5 @@ impl SharedSecret {
/// # }
/// ```
#[inline]
pub fn display_secret(&self) -> DisplaySecret {
DisplaySecret { secret: self.secret_bytes() }
}
pub fn display_secret(&self) -> DisplaySecret { DisplaySecret { secret: self.secret_bytes() } }
}

View File

@ -1,6 +1,7 @@
use core::fmt;
use core::marker::PhantomData;
use core::str::{self, FromStr};
use serde::de;
/// A serde visitor that works for `T`s implementing `FromStr`.
@ -11,10 +12,7 @@ pub struct FromStrVisitor<T> {
impl<T> FromStrVisitor<T> {
pub fn new(expectation: &'static str) -> Self {
FromStrVisitor {
expectation,
_pd: PhantomData,
}
FromStrVisitor { expectation, _pd: PhantomData }
}
}
@ -45,10 +43,7 @@ where
Err: fmt::Display,
{
pub fn new(expectation: &'static str, parse_fn: F) -> Self {
BytesVisitor {
expectation,
parse_fn,
}
BytesVisitor { expectation, parse_fn }
}
}
@ -81,10 +76,7 @@ macro_rules! impl_tuple_visitor {
E: fmt::Display,
{
pub fn new(expectation: &'static str, parse_fn: F) -> Self {
$thing {
expectation,
parse_fn,
}
$thing { expectation, parse_fn }
}
}
@ -115,7 +107,7 @@ macro_rules! impl_tuple_visitor {
(self.parse_fn)(&bytes).map_err(de::Error::custom)
}
}
}
};
}
impl_tuple_visitor!(Tuple32Visitor, 32);

View File

@ -5,9 +5,9 @@ extern crate bincode;
extern crate cbor;
extern crate secp256k1;
use secp256k1::{PublicKey, SecretKey, XOnlyPublicKey};
#[cfg(feature = "global-context")]
use secp256k1::{Secp256k1, KeyPair};
use secp256k1::{KeyPair, Secp256k1};
use secp256k1::{PublicKey, SecretKey, XOnlyPublicKey};
// Arbitrary key data.
@ -70,7 +70,8 @@ fn bincode_key_pair() {
#[test]
fn bincode_x_only_public_key() {
let pk = XOnlyPublicKey::from_slice(&XONLY_PK_BYTES).expect("failed to create xonly pk from slice");
let pk =
XOnlyPublicKey::from_slice(&XONLY_PK_BYTES).expect("failed to create xonly pk from slice");
let ser = bincode::serialize(&pk).unwrap();
assert_eq!(ser, XONLY_PK_BYTES);