Merge pull request #22 from TheBlueMatt/master
Fix for older rustcs, removing serde/rustc-serialize and a missing include in fuzztarget
This commit is contained in:
commit
b45c3804e4
35
.travis.yml
35
.travis.yml
|
@ -1,23 +1,18 @@
|
||||||
language: rust
|
language: rust
|
||||||
sudo: false
|
rust:
|
||||||
|
- stable
|
||||||
matrix:
|
- beta
|
||||||
include:
|
- nightly
|
||||||
- rust: stable
|
- 1.14.0
|
||||||
- rust: beta
|
cache: cargo
|
||||||
- rust: nightly
|
|
||||||
|
|
||||||
install:
|
|
||||||
- |
|
|
||||||
pip install 'travis-cargo<0.2' --user &&
|
|
||||||
export PATH=$HOME/.local/bin:$PATH
|
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- |
|
- cargo build --verbose --features=fuzztarget
|
||||||
travis-cargo build &&
|
- cargo build --verbose --features=rand
|
||||||
travis-cargo build -- --release &&
|
- cargo test --verbose --features=rand
|
||||||
travis-cargo test &&
|
- cargo build --verbose
|
||||||
travis-cargo test -- --release &&
|
- cargo test --verbose
|
||||||
travis-cargo bench &&
|
- cargo build --release
|
||||||
travis-cargo --only stable doc
|
- cargo test --release
|
||||||
|
- cargo bench
|
||||||
|
- if [ "$(rustup show | grep default | grep stable)" != "" ]; then cargo doc; fi
|
||||||
|
|
15
Cargo.toml
15
Cargo.toml
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
|
|
||||||
name = "secp256k1"
|
name = "secp256k1"
|
||||||
version = "0.8.5"
|
version = "0.9.0"
|
||||||
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"
|
||||||
|
@ -26,10 +26,7 @@ default = []
|
||||||
fuzztarget = []
|
fuzztarget = []
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serde = "1.0"
|
|
||||||
serde_json = "1.0"
|
|
||||||
rand = "0.3"
|
rand = "0.3"
|
||||||
rustc-serialize = "0.3"
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
|
@ -37,13 +34,3 @@ libc = "0.2"
|
||||||
[dependencies.rand]
|
[dependencies.rand]
|
||||||
version = "0.3"
|
version = "0.3"
|
||||||
optional = true
|
optional = true
|
||||||
|
|
||||||
[dependencies.rustc-serialize]
|
|
||||||
version = "0.3"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[dependencies.serde]
|
|
||||||
version = "1.0"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,5 +11,5 @@ a C library by Peter Wuille for producing ECDSA signatures using the SECG curve
|
||||||
* implements many unit tests, adding to those already present in `libsecp256k1`
|
* implements many unit tests, adding to those already present in `libsecp256k1`
|
||||||
* makes no allocations (except in unit tests) for efficiency and use in freestanding implementations
|
* makes no allocations (except in unit tests) for efficiency and use in freestanding implementations
|
||||||
|
|
||||||
[Full documentation](https://docs.rs/secp256k1/0.8.3/secp256k1/)
|
[Full documentation](https://docs.rs/secp256k1/)
|
||||||
|
|
||||||
|
|
|
@ -278,7 +278,7 @@ extern "C" {
|
||||||
|
|
||||||
#[cfg(feature = "fuzztarget")]
|
#[cfg(feature = "fuzztarget")]
|
||||||
mod fuzz_dummy {
|
mod fuzz_dummy {
|
||||||
use libc::{c_int, c_uchar, c_uint, c_void};
|
use libc::{c_int, c_uchar, c_uint, c_void, size_t};
|
||||||
use ffi::*;
|
use ffi::*;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
|
|
263
src/key.rs
263
src/key.rs
|
@ -15,10 +15,7 @@
|
||||||
|
|
||||||
//! # Public and secret keys
|
//! # Public and secret keys
|
||||||
|
|
||||||
#[cfg(any(test, feature = "serde"))] use std::marker;
|
|
||||||
#[cfg(any(test, feature = "rand"))] use rand::Rng;
|
#[cfg(any(test, feature = "rand"))] use rand::Rng;
|
||||||
#[cfg(any(test, feature = "rustc-serialize"))] use serialize::{Decoder, Decodable, Encoder, Encodable};
|
|
||||||
#[cfg(any(test, feature = "serde"))] use serde::{Serialize, Deserialize, Serializer, Deserializer};
|
|
||||||
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
|
@ -271,36 +268,6 @@ impl PublicKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(test, feature = "rustc-serialize"))]
|
|
||||||
impl Decodable for PublicKey {
|
|
||||||
fn decode<D: Decoder>(d: &mut D) -> Result<PublicKey, D::Error> {
|
|
||||||
d.read_seq(|d, len| {
|
|
||||||
let s = Secp256k1::with_caps(::ContextFlag::None);
|
|
||||||
if len == constants::UNCOMPRESSED_PUBLIC_KEY_SIZE {
|
|
||||||
unsafe {
|
|
||||||
use std::mem;
|
|
||||||
let mut ret: [u8; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE] = mem::uninitialized();
|
|
||||||
for i in 0..len {
|
|
||||||
ret[i] = try!(d.read_seq_elt(i, |d| Decodable::decode(d)));
|
|
||||||
}
|
|
||||||
PublicKey::from_slice(&s, &ret).map_err(|_| d.error("invalid public key"))
|
|
||||||
}
|
|
||||||
} else if len == constants::PUBLIC_KEY_SIZE {
|
|
||||||
unsafe {
|
|
||||||
use std::mem;
|
|
||||||
let mut ret: [u8; constants::PUBLIC_KEY_SIZE] = mem::uninitialized();
|
|
||||||
for i in 0..len {
|
|
||||||
ret[i] = try!(d.read_seq_elt(i, |d| Decodable::decode(d)));
|
|
||||||
}
|
|
||||||
PublicKey::from_slice(&s, &ret).map_err(|_| d.error("invalid public key"))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Err(d.error("Invalid length"))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a new public key from a FFI public key
|
/// Creates a new public key from a FFI public key
|
||||||
impl From<ffi::PublicKey> for PublicKey {
|
impl From<ffi::PublicKey> for PublicKey {
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -309,84 +276,6 @@ impl From<ffi::PublicKey> for PublicKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[cfg(any(test, feature = "rustc-serialize"))]
|
|
||||||
impl Encodable for PublicKey {
|
|
||||||
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
|
|
||||||
self.serialize().encode(s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(any(test, feature = "serde"))]
|
|
||||||
impl<'de> Deserialize<'de> for PublicKey {
|
|
||||||
fn deserialize<D>(d: D) -> Result<PublicKey, D::Error>
|
|
||||||
where D: Deserializer<'de>
|
|
||||||
{
|
|
||||||
use serde::de;
|
|
||||||
struct Visitor {
|
|
||||||
marker: marker::PhantomData<PublicKey>,
|
|
||||||
}
|
|
||||||
impl<'de> de::Visitor<'de> for Visitor {
|
|
||||||
type Value = PublicKey;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_seq<A>(self, mut a: A) -> Result<PublicKey, A::Error>
|
|
||||||
where A: de::SeqAccess<'de>
|
|
||||||
{
|
|
||||||
debug_assert!(constants::UNCOMPRESSED_PUBLIC_KEY_SIZE >= constants::PUBLIC_KEY_SIZE);
|
|
||||||
|
|
||||||
let s = Secp256k1::with_caps(::ContextFlag::None);
|
|
||||||
unsafe {
|
|
||||||
use std::mem;
|
|
||||||
let mut ret: [u8; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE] = mem::uninitialized();
|
|
||||||
|
|
||||||
let mut read_len = 0;
|
|
||||||
while read_len < constants::UNCOMPRESSED_PUBLIC_KEY_SIZE {
|
|
||||||
let read_ch = match try!(a.next_element()) {
|
|
||||||
Some(c) => c,
|
|
||||||
None => break
|
|
||||||
};
|
|
||||||
ret[read_len] = read_ch;
|
|
||||||
read_len += 1;
|
|
||||||
}
|
|
||||||
let one_after_last : Option<u8> = try!(a.next_element());
|
|
||||||
if one_after_last.is_some() {
|
|
||||||
return Err(de::Error::invalid_length(read_len + 1, &self));
|
|
||||||
}
|
|
||||||
|
|
||||||
match read_len {
|
|
||||||
constants::UNCOMPRESSED_PUBLIC_KEY_SIZE | constants::PUBLIC_KEY_SIZE
|
|
||||||
=> PublicKey::from_slice(&s, &ret[..read_len]).map_err(
|
|
||||||
|e| match e {
|
|
||||||
InvalidPublicKey => de::Error::invalid_value(de::Unexpected::Seq, &self),
|
|
||||||
_ => de::Error::custom(&e.to_string()),
|
|
||||||
}
|
|
||||||
),
|
|
||||||
_ => Err(de::Error::invalid_length(read_len, &self)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn expecting(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
|
||||||
write!(f, "a sequence of {} or {} bytes representing a valid compressed or uncompressed public key",
|
|
||||||
constants::PUBLIC_KEY_SIZE, constants::UNCOMPRESSED_PUBLIC_KEY_SIZE)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Begin actual function
|
|
||||||
d.deserialize_seq(Visitor { marker: ::std::marker::PhantomData })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(any(test, feature = "serde"))]
|
|
||||||
impl Serialize for PublicKey {
|
|
||||||
fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
|
|
||||||
where S: Serializer
|
|
||||||
{
|
|
||||||
self.serialize().serialize(s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::super::{Secp256k1, ContextFlag};
|
use super::super::{Secp256k1, ContextFlag};
|
||||||
|
@ -394,10 +283,30 @@ mod test {
|
||||||
use super::{PublicKey, SecretKey};
|
use super::{PublicKey, SecretKey};
|
||||||
use super::super::constants;
|
use super::super::constants;
|
||||||
|
|
||||||
use serialize::hex::FromHex;
|
|
||||||
use rand::{Rng, thread_rng};
|
use rand::{Rng, thread_rng};
|
||||||
|
|
||||||
macro_rules! hex (($hex:expr) => (FromHex::from_hex($hex).unwrap()));
|
macro_rules! hex {
|
||||||
|
($hex:expr) => {
|
||||||
|
{
|
||||||
|
let mut vec = Vec::new();
|
||||||
|
let mut b = 0;
|
||||||
|
for (idx, c) in $hex.as_bytes().iter().enumerate() {
|
||||||
|
b <<= 4;
|
||||||
|
match *c {
|
||||||
|
b'A'...b'F' => b |= c - b'A' + 10,
|
||||||
|
b'a'...b'f' => b |= c - b'a' + 10,
|
||||||
|
b'0'...b'9' => b |= c - b'0',
|
||||||
|
_ => panic!("Bad hex"),
|
||||||
|
}
|
||||||
|
if (idx & 1) == 1 {
|
||||||
|
vec.push(b);
|
||||||
|
b = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vec
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn skey_from_slice() {
|
fn skey_from_slice() {
|
||||||
|
@ -486,134 +395,6 @@ mod test {
|
||||||
assert_eq!(pk.add_exp_assign(&s, &sk), Err(IncapableContext));
|
assert_eq!(pk.add_exp_assign(&s, &sk), Err(IncapableContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_bad_deserialize() {
|
|
||||||
use std::io::Cursor;
|
|
||||||
use serialize::{json, Decodable};
|
|
||||||
|
|
||||||
let zero31 = "[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]".as_bytes();
|
|
||||||
let json31 = json::Json::from_reader(&mut Cursor::new(zero31)).unwrap();
|
|
||||||
let zero32 = "[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]".as_bytes();
|
|
||||||
let json32 = json::Json::from_reader(&mut Cursor::new(zero32)).unwrap();
|
|
||||||
let zero65 = "[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]".as_bytes();
|
|
||||||
let json65 = json::Json::from_reader(&mut Cursor::new(zero65)).unwrap();
|
|
||||||
let string = "\"my key\"".as_bytes();
|
|
||||||
let json = json::Json::from_reader(&mut Cursor::new(string)).unwrap();
|
|
||||||
|
|
||||||
// Invalid length
|
|
||||||
let mut decoder = json::Decoder::new(json31.clone());
|
|
||||||
assert!(<PublicKey as Decodable>::decode(&mut decoder).is_err());
|
|
||||||
let mut decoder = json::Decoder::new(json31.clone());
|
|
||||||
assert!(<SecretKey as Decodable>::decode(&mut decoder).is_err());
|
|
||||||
let mut decoder = json::Decoder::new(json32.clone());
|
|
||||||
assert!(<PublicKey as Decodable>::decode(&mut decoder).is_err());
|
|
||||||
let mut decoder = json::Decoder::new(json32.clone());
|
|
||||||
assert!(<SecretKey as Decodable>::decode(&mut decoder).is_ok());
|
|
||||||
let mut decoder = json::Decoder::new(json65.clone());
|
|
||||||
assert!(<PublicKey as Decodable>::decode(&mut decoder).is_err());
|
|
||||||
let mut decoder = json::Decoder::new(json65.clone());
|
|
||||||
assert!(<SecretKey as Decodable>::decode(&mut decoder).is_err());
|
|
||||||
|
|
||||||
// Syntax error
|
|
||||||
let mut decoder = json::Decoder::new(json.clone());
|
|
||||||
assert!(<PublicKey as Decodable>::decode(&mut decoder).is_err());
|
|
||||||
let mut decoder = json::Decoder::new(json.clone());
|
|
||||||
assert!(<SecretKey as Decodable>::decode(&mut decoder).is_err());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_serialize() {
|
|
||||||
use std::io::Cursor;
|
|
||||||
use serialize::{json, Decodable, Encodable};
|
|
||||||
|
|
||||||
macro_rules! round_trip (
|
|
||||||
($var:ident) => ({
|
|
||||||
let start = $var;
|
|
||||||
let mut encoded = String::new();
|
|
||||||
{
|
|
||||||
let mut encoder = json::Encoder::new(&mut encoded);
|
|
||||||
start.encode(&mut encoder).unwrap();
|
|
||||||
}
|
|
||||||
let json = json::Json::from_reader(&mut Cursor::new(encoded.as_bytes())).unwrap();
|
|
||||||
let mut decoder = json::Decoder::new(json);
|
|
||||||
let decoded = Decodable::decode(&mut decoder);
|
|
||||||
assert_eq!(Ok(Some(start)), decoded);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
let s = Secp256k1::new();
|
|
||||||
for _ in 0..500 {
|
|
||||||
let (sk, pk) = s.generate_keypair(&mut thread_rng()).unwrap();
|
|
||||||
round_trip!(sk);
|
|
||||||
round_trip!(pk);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_bad_serde_deserialize() {
|
|
||||||
use serde::Deserialize;
|
|
||||||
use json;
|
|
||||||
|
|
||||||
// Invalid length
|
|
||||||
let zero31 = "[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]";
|
|
||||||
let mut json = json::de::Deserializer::from_str(zero31);
|
|
||||||
assert!(<PublicKey as Deserialize>::deserialize(&mut json).is_err());
|
|
||||||
let mut json = json::de::Deserializer::from_str(zero31);
|
|
||||||
assert!(<SecretKey as Deserialize>::deserialize(&mut json).is_err());
|
|
||||||
|
|
||||||
let zero32 = "[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]";
|
|
||||||
let mut json = json::de::Deserializer::from_str(zero32);
|
|
||||||
assert!(<PublicKey as Deserialize>::deserialize(&mut json).is_err());
|
|
||||||
let mut json = json::de::Deserializer::from_str(zero32);
|
|
||||||
assert!(<SecretKey as Deserialize>::deserialize(&mut json).is_ok());
|
|
||||||
|
|
||||||
let zero33 = "[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]";
|
|
||||||
let mut json = json::de::Deserializer::from_str(zero33);
|
|
||||||
assert!(<PublicKey as Deserialize>::deserialize(&mut json).is_err());
|
|
||||||
let mut json = json::de::Deserializer::from_str(zero33);
|
|
||||||
assert!(<SecretKey as Deserialize>::deserialize(&mut json).is_err());
|
|
||||||
|
|
||||||
let trailing66 = "[4,149,16,196,140,38,92,239,179,65,59,224,230,183,91,238,240,46,186,252,
|
|
||||||
175,102,52,249,98,178,123,72,50,171,196,254,236,1,189,143,242,227,16,87,
|
|
||||||
247,183,162,68,237,140,92,205,151,129,166,58,111,96,123,64,180,147,51,12,
|
|
||||||
209,89,236,213,206,17]";
|
|
||||||
let mut json = json::de::Deserializer::from_str(trailing66);
|
|
||||||
assert!(<PublicKey as Deserialize>::deserialize(&mut json).is_err());
|
|
||||||
|
|
||||||
// The first 65 bytes of trailing66 are valid
|
|
||||||
let valid65 = "[4,149,16,196,140,38,92,239,179,65,59,224,230,183,91,238,240,46,186,252,
|
|
||||||
175,102,52,249,98,178,123,72,50,171,196,254,236,1,189,143,242,227,16,87,
|
|
||||||
247,183,162,68,237,140,92,205,151,129,166,58,111,96,123,64,180,147,51,12,
|
|
||||||
209,89,236,213,206]";
|
|
||||||
let mut json = json::de::Deserializer::from_str(valid65);
|
|
||||||
assert!(<PublicKey as Deserialize>::deserialize(&mut json).is_ok());
|
|
||||||
|
|
||||||
// All zeroes pk is invalid
|
|
||||||
let zero65 = "[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]";
|
|
||||||
let mut json = json::de::Deserializer::from_str(zero65);
|
|
||||||
assert!(<PublicKey as Deserialize>::deserialize(&mut json).is_err());
|
|
||||||
let mut json = json::de::Deserializer::from_str(zero65);
|
|
||||||
assert!(<SecretKey as Deserialize>::deserialize(&mut json).is_err());
|
|
||||||
|
|
||||||
// Syntax error
|
|
||||||
let string = "\"my key\"";
|
|
||||||
let mut json = json::de::Deserializer::from_str(string);
|
|
||||||
assert!(<PublicKey as Deserialize>::deserialize(&mut json).is_err());
|
|
||||||
let mut json = json::de::Deserializer::from_str(string);
|
|
||||||
assert!(<SecretKey as Deserialize>::deserialize(&mut json).is_err());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_serialize_serde() {
|
|
||||||
let s = Secp256k1::new();
|
|
||||||
for _ in 0..500 {
|
|
||||||
let (sk, pk) = s.generate_keypair(&mut thread_rng()).unwrap();
|
|
||||||
round_trip_serde!(sk);
|
|
||||||
round_trip_serde!(pk);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_out_of_range() {
|
fn test_out_of_range() {
|
||||||
|
|
||||||
|
|
91
src/lib.rs
91
src/lib.rs
|
@ -38,10 +38,7 @@
|
||||||
|
|
||||||
#![cfg_attr(all(test, feature = "unstable"), feature(test))]
|
#![cfg_attr(all(test, feature = "unstable"), feature(test))]
|
||||||
#[cfg(all(test, feature = "unstable"))] extern crate test;
|
#[cfg(all(test, feature = "unstable"))] extern crate test;
|
||||||
#[cfg(any(test, feature = "serde"))] extern crate serde;
|
|
||||||
#[cfg(test)] extern crate serde_json as json;
|
|
||||||
#[cfg(any(test, feature = "rand"))] extern crate rand;
|
#[cfg(any(test, feature = "rand"))] extern crate rand;
|
||||||
#[cfg(any(test, feature = "rustc-serialize"))] extern crate rustc_serialize as serialize;
|
|
||||||
|
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
|
|
||||||
|
@ -203,68 +200,6 @@ impl Signature {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(test, feature = "serde"))]
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(any(test, feature = "serde"))]
|
|
||||||
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]
|
||||||
|
@ -636,7 +571,6 @@ impl Secp256k1 {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use rand::{Rng, thread_rng};
|
use rand::{Rng, thread_rng};
|
||||||
use serialize::hex::FromHex;
|
|
||||||
|
|
||||||
use key::{SecretKey, PublicKey};
|
use key::{SecretKey, PublicKey};
|
||||||
use super::constants;
|
use super::constants;
|
||||||
|
@ -644,7 +578,28 @@ mod tests {
|
||||||
use super::Error::{InvalidMessage, InvalidPublicKey, IncorrectSignature, InvalidSignature,
|
use super::Error::{InvalidMessage, InvalidPublicKey, IncorrectSignature, InvalidSignature,
|
||||||
IncapableContext};
|
IncapableContext};
|
||||||
|
|
||||||
macro_rules! hex (($hex:expr) => ($hex.from_hex().unwrap()));
|
macro_rules! hex {
|
||||||
|
($hex:expr) => {
|
||||||
|
{
|
||||||
|
let mut vec = Vec::new();
|
||||||
|
let mut b = 0;
|
||||||
|
for (idx, c) in $hex.as_bytes().iter().enumerate() {
|
||||||
|
b <<= 4;
|
||||||
|
match *c {
|
||||||
|
b'A'...b'F' => b |= c - b'A' + 10,
|
||||||
|
b'a'...b'f' => b |= c - b'a' + 10,
|
||||||
|
b'0'...b'9' => b |= c - b'0',
|
||||||
|
_ => panic!("Bad hex"),
|
||||||
|
}
|
||||||
|
if (idx & 1) == 1 {
|
||||||
|
vec.push(b);
|
||||||
|
b = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vec
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn capabilities() {
|
fn capabilities() {
|
||||||
|
@ -763,8 +718,6 @@ 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());
|
||||||
|
|
100
src/macros.rs
100
src/macros.rs
|
@ -115,90 +115,6 @@ macro_rules! impl_array_newtype {
|
||||||
&dat[..]
|
&dat[..]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(test, feature = "rustc-serialize"))]
|
|
||||||
impl ::serialize::Decodable for $thing {
|
|
||||||
fn decode<D: ::serialize::Decoder>(d: &mut D) -> Result<$thing, D::Error> {
|
|
||||||
use serialize::Decodable;
|
|
||||||
|
|
||||||
d.read_seq(|d, len| {
|
|
||||||
if len != $len {
|
|
||||||
Err(d.error("Invalid length"))
|
|
||||||
} else {
|
|
||||||
unsafe {
|
|
||||||
use std::mem;
|
|
||||||
let mut ret: [$ty; $len] = mem::uninitialized();
|
|
||||||
for i in 0..len {
|
|
||||||
ret[i] = try!(d.read_seq_elt(i, |d| Decodable::decode(d)));
|
|
||||||
}
|
|
||||||
Ok($thing(ret))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(any(test, feature = "rustc-serialize"))]
|
|
||||||
impl ::serialize::Encodable for $thing {
|
|
||||||
fn encode<S: ::serialize::Encoder>(&self, s: &mut S)
|
|
||||||
-> Result<(), S::Error> {
|
|
||||||
self[..].encode(s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(any(test, feature = "serde"))]
|
|
||||||
impl<'de> ::serde::Deserialize<'de> for $thing {
|
|
||||||
fn deserialize<D>(d: D) -> Result<$thing, D::Error>
|
|
||||||
where D: ::serde::Deserializer<'de>
|
|
||||||
{
|
|
||||||
// We have to define the Visitor struct inside the function
|
|
||||||
// to make it local ... all we really need is that it's
|
|
||||||
// local to the macro, but this works too :)
|
|
||||||
struct Visitor {
|
|
||||||
marker: ::std::marker::PhantomData<$thing>,
|
|
||||||
}
|
|
||||||
impl<'de> ::serde::de::Visitor<'de> for Visitor {
|
|
||||||
type Value = $thing;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_seq<A>(self, mut a: A) -> Result<$thing, A::Error>
|
|
||||||
where A: ::serde::de::SeqAccess<'de>
|
|
||||||
{
|
|
||||||
unsafe {
|
|
||||||
use std::mem;
|
|
||||||
let mut ret: [$ty; $len] = mem::uninitialized();
|
|
||||||
for i in 0..$len {
|
|
||||||
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($len + 1, &self));
|
|
||||||
}
|
|
||||||
Ok($thing(ret))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn expecting(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
|
||||||
write!(f, "a sequence of {} elements", $len)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Begin actual function
|
|
||||||
d.deserialize_seq(Visitor { marker: ::std::marker::PhantomData })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(any(test, feature = "serde"))]
|
|
||||||
impl ::serde::Serialize for $thing {
|
|
||||||
fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
|
|
||||||
where S: ::serde::Serializer
|
|
||||||
{
|
|
||||||
(&self.0[..]).serialize(s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,19 +144,3 @@ 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