Skip to content

Commit

Permalink
Removed arrayvec and added a different serialize function for no-std
Browse files Browse the repository at this point in the history
  • Loading branch information
elichai committed Apr 11, 2019
1 parent ef4662e commit 9427070
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 10 deletions.
3 changes: 0 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ features = [ "rand", "serde" ]
all-features = true


[dependencies]
arrayvec = { version = "0.4.10", default-features = false }

[build-dependencies]
cc = "=1.0.26"

Expand Down
59 changes: 52 additions & 7 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,6 @@
#[cfg(any(test, feature = "rand"))] use rand::Rng;
#[cfg(any(test, feature = "std"))] extern crate core;

extern crate arrayvec;

use arrayvec::ArrayVec;
use core::{fmt, ptr, str};

#[macro_use]
Expand Down Expand Up @@ -338,10 +335,11 @@ impl Signature {
&mut self.0 as *mut _
}

#[cfg(feature = "std")]
#[inline]
/// Serializes the signature in DER format
pub fn serialize_der(&self) -> ArrayVec<[u8; 72]> {
let mut ret = ArrayVec::<[_; 72]>::new();
pub fn serialize_der(&self) -> Vec<u8>{
let mut ret = Vec::with_capacity(72);
let mut len: usize = ret.capacity() as usize;
unsafe {
let err = ffi::secp256k1_ecdsa_signature_serialize_der(
Expand All @@ -351,12 +349,30 @@ impl Signature {
self.as_ptr(),
);
debug_assert!(err == 1);
// ret.set_len(len as usize);
ret.set_len(len as usize);
}
ret
}

#[inline]
/// Serializes the signature in DER format without allocating memory
/// The signature can be anywhere from 8 bytes to 72 bytes
/// So the function needs a buffer that is equal or larger than 72 bytes
/// It will write into that buffer and return a slice containing only the signature
pub fn serialize_der_no_alloc<'a>(&self, buf: &'a mut [u8]) -> &'a [u8] {
let mut len: usize = buf.len();
unsafe {
let err = ffi::secp256k1_ecdsa_signature_serialize_der(
ffi::secp256k1_context_no_precomp,
buf.as_mut_ptr(),
&mut len,
self.as_ptr(),
);
debug_assert!(err == 1);
}
&buf[..len]
}

#[inline]
/// Serializes the signature in compact format
pub fn serialize_compact(&self) -> [u8; 64] {
Expand Down Expand Up @@ -458,7 +474,8 @@ impl From<ffi::RecoverableSignature> for RecoverableSignature {
#[cfg(feature = "serde")]
impl ::serde::Serialize for Signature {
fn serialize<S: ::serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
s.serialize_bytes(&self.serialize_der())
let mut buf = [0u8; 72];
s.serialize_bytes(&self.serialize_der_no_alloc(&mut buf))
}
}

Expand Down Expand Up @@ -915,6 +932,34 @@ mod tests {
}
}

#[test]
fn signature_serialize_no_alloc_roundtrip() {
let mut s = Secp256k1::new();
s.randomize(&mut thread_rng());

let mut msg = [0; 32];
for _ in 0..100 {
thread_rng().fill_bytes(&mut msg);
let msg = Message::from_slice(&msg).unwrap();

let (sk, _) = s.generate_keypair(&mut thread_rng());
let sig1 = s.sign(&msg, &sk);
let mut buf = vec![0u8; 172];
let der = sig1.serialize_der_no_alloc(&mut buf);
let sig2 = Signature::from_der(&der[..]).unwrap();
assert_eq!(sig1, sig2);

let compact = sig1.serialize_compact();
let sig2 = Signature::from_compact(&compact[..]).unwrap();
assert_eq!(sig1, sig2);

assert!(Signature::from_compact(&der[..]).is_err());
assert!(Signature::from_compact(&compact[0..4]).is_err());
assert!(Signature::from_der(&compact[..]).is_err());
assert!(Signature::from_der(&der[0..4]).is_err());
}
}

#[test]
fn signature_display() {
let hex_str = "3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45";
Expand Down

0 comments on commit 9427070

Please sign in to comment.