Merge pull request #18 from real-or-random/patch-1
Implement serde traits for Signature
This commit is contained in:
commit
d0dc0f89d8
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
|
|
||||||
name = "secp256k1"
|
name = "secp256k1"
|
||||||
version = "0.7.0"
|
version = "0.7.1"
|
||||||
authors = [ "Dawid Ciężarkiewicz <dpc@ucore.info>",
|
authors = [ "Dawid Ciężarkiewicz <dpc@ucore.info>",
|
||||||
"Andrew Poelstra <apoelstra@wpsoftware.net>" ]
|
"Andrew Poelstra <apoelstra@wpsoftware.net>" ]
|
||||||
license = "CC0-1.0"
|
license = "CC0-1.0"
|
||||||
|
|
21
src/key.rs
21
src/key.rs
|
@ -559,28 +559,11 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_serialize_serde() {
|
fn test_serialize_serde() {
|
||||||
use serde::{Serialize, Deserialize};
|
|
||||||
use json;
|
|
||||||
|
|
||||||
macro_rules! round_trip (
|
|
||||||
($var:ident) => ({
|
|
||||||
let start = $var;
|
|
||||||
let mut encoded = Vec::new();
|
|
||||||
{
|
|
||||||
let mut serializer = json::ser::Serializer::new(&mut encoded);
|
|
||||||
start.serialize(&mut serializer).unwrap();
|
|
||||||
}
|
|
||||||
let mut deserializer = json::de::Deserializer::from_slice(&encoded);
|
|
||||||
let decoded = Deserialize::deserialize(&mut deserializer);
|
|
||||||
assert_eq!(Some(start), decoded.ok());
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
let s = Secp256k1::new();
|
let s = Secp256k1::new();
|
||||||
for _ in 0..500 {
|
for _ in 0..500 {
|
||||||
let (sk, pk) = s.generate_keypair(&mut thread_rng()).unwrap();
|
let (sk, pk) = s.generate_keypair(&mut thread_rng()).unwrap();
|
||||||
round_trip!(sk);
|
round_trip_serde!(sk);
|
||||||
round_trip!(pk);
|
round_trip_serde!(pk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
62
src/lib.rs
62
src/lib.rs
|
@ -202,6 +202,66 @@ impl Signature {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl serde::Serialize for Signature {
|
||||||
|
fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
|
||||||
|
where S: serde::Serializer
|
||||||
|
{
|
||||||
|
let secp = Secp256k1::with_caps(::ContextFlag::None);
|
||||||
|
(&self.serialize_compact(&secp)[..]).serialize(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> serde::Deserialize<'de> for Signature {
|
||||||
|
fn deserialize<D>(d: D) -> Result<Signature, D::Error>
|
||||||
|
where D: serde::Deserializer<'de>
|
||||||
|
{
|
||||||
|
use serde::de;
|
||||||
|
struct Visitor {
|
||||||
|
marker: std::marker::PhantomData<Signature>,
|
||||||
|
}
|
||||||
|
impl<'de> de::Visitor<'de> for Visitor {
|
||||||
|
type Value = Signature;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_seq<A>(self, mut a: A) -> Result<Signature, A::Error>
|
||||||
|
where A: de::SeqAccess<'de>
|
||||||
|
{
|
||||||
|
let s = Secp256k1::with_caps(::ContextFlag::None);
|
||||||
|
unsafe {
|
||||||
|
use std::mem;
|
||||||
|
let mut ret: [u8; constants::COMPACT_SIGNATURE_SIZE] = mem::uninitialized();
|
||||||
|
|
||||||
|
for i in 0..constants::COMPACT_SIGNATURE_SIZE {
|
||||||
|
ret[i] = match try!(a.next_element()) {
|
||||||
|
Some(c) => c,
|
||||||
|
None => return Err(::serde::de::Error::invalid_length(i, &self))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
let one_after_last : Option<u8> = try!(a.next_element());
|
||||||
|
if one_after_last.is_some() {
|
||||||
|
return Err(serde::de::Error::invalid_length(constants::COMPACT_SIGNATURE_SIZE + 1, &self));
|
||||||
|
}
|
||||||
|
|
||||||
|
Signature::from_compact(&s, &ret).map_err(
|
||||||
|
|e| match e {
|
||||||
|
Error::InvalidSignature => de::Error::invalid_value(de::Unexpected::Seq, &self),
|
||||||
|
_ => de::Error::custom(&e.to_string()),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expecting(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||||
|
write!(f, "a sequence of {} bytes representing a syntactically well-formed compact signature",
|
||||||
|
constants::COMPACT_SIGNATURE_SIZE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Begin actual function
|
||||||
|
d.deserialize_seq(Visitor { marker: std::marker::PhantomData })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a new signature from a FFI signature
|
/// Creates a new signature from a FFI signature
|
||||||
impl From<ffi::Signature> for Signature {
|
impl From<ffi::Signature> for Signature {
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -698,6 +758,8 @@ mod tests {
|
||||||
let sig2 = Signature::from_compact(&s, &compact[..]).unwrap();
|
let sig2 = Signature::from_compact(&s, &compact[..]).unwrap();
|
||||||
assert_eq!(sig1, sig2);
|
assert_eq!(sig1, sig2);
|
||||||
|
|
||||||
|
round_trip_serde!(sig1);
|
||||||
|
|
||||||
assert!(Signature::from_compact(&s, &der[..]).is_err());
|
assert!(Signature::from_compact(&s, &der[..]).is_err());
|
||||||
assert!(Signature::from_compact(&s, &compact[0..4]).is_err());
|
assert!(Signature::from_compact(&s, &compact[0..4]).is_err());
|
||||||
assert!(Signature::from_der(&s, &compact[..]).is_err());
|
assert!(Signature::from_der(&s, &compact[..]).is_err());
|
||||||
|
|
|
@ -225,3 +225,18 @@ macro_rules! impl_raw_debug {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
// A macro useful for serde (de)serialization tests
|
||||||
|
macro_rules! round_trip_serde (
|
||||||
|
($var:ident) => ({
|
||||||
|
let start = $var;
|
||||||
|
let mut encoded = Vec::new();
|
||||||
|
{
|
||||||
|
let mut serializer = ::json::ser::Serializer::new(&mut encoded);
|
||||||
|
::serde::Serialize::serialize(&start, &mut serializer).unwrap();
|
||||||
|
}
|
||||||
|
let mut deserializer = ::json::de::Deserializer::from_slice(&encoded);
|
||||||
|
let decoded = ::serde::Deserialize::deserialize(&mut deserializer);
|
||||||
|
assert_eq!(Some(start), decoded.ok());
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
Loading…
Reference in New Issue