mirror of
https://github.com/mimblewimble/grin.git
synced 2025-02-01 17:01:09 +03:00
Update secp256k1zlp to serde 1.0
This commit is contained in:
parent
1ae2e905d8
commit
da41120293
8 changed files with 2067 additions and 1999 deletions
|
@ -29,6 +29,5 @@ clippy = {version = "0.0", optional = true}
|
|||
rand = "0.3"
|
||||
libc = "0.1"
|
||||
rustc-serialize = "0.3"
|
||||
serde = "0.6"
|
||||
serde_json = "0.6"
|
||||
|
||||
serde = "~1.0.8"
|
||||
serde_json = "~1.0.2"
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
//! # Public and secret keys
|
||||
|
||||
use std::fmt;
|
||||
use std::intrinsics::copy_nonoverlapping;
|
||||
use std::marker;
|
||||
use arrayvec::ArrayVec;
|
||||
|
@ -278,20 +279,24 @@ impl Encodable for PublicKey {
|
|||
}
|
||||
}
|
||||
|
||||
impl Deserialize for PublicKey {
|
||||
fn deserialize<D>(d: &mut D) -> Result<PublicKey, D::Error>
|
||||
where D: Deserializer
|
||||
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::Visitor for Visitor {
|
||||
impl<'di> de::Visitor<'di> for Visitor {
|
||||
type Value = PublicKey;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("an array of bytes")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_seq<V>(&mut self, mut v: V) -> Result<PublicKey, V::Error>
|
||||
where V: de::SeqVisitor
|
||||
fn visit_seq<V>(self, mut v: V) -> Result<PublicKey, V::Error>
|
||||
where V: ::serde::de::SeqAccess<'di>
|
||||
{
|
||||
debug_assert!(constants::UNCOMPRESSED_PUBLIC_KEY_SIZE >=
|
||||
constants::COMPRESSED_PUBLIC_KEY_SIZE);
|
||||
|
@ -304,28 +309,27 @@ impl Deserialize for PublicKey {
|
|||
|
||||
let mut read_len = 0;
|
||||
while read_len < constants::UNCOMPRESSED_PUBLIC_KEY_SIZE {
|
||||
let read_ch = match try!(v.visit()) {
|
||||
let read_ch = match try!(v.next_element()) {
|
||||
Some(c) => c,
|
||||
None => break,
|
||||
};
|
||||
ret[read_len] = read_ch;
|
||||
read_len += 1;
|
||||
}
|
||||
try!(v.end());
|
||||
|
||||
PublicKey::from_slice(&s, &ret[..read_len])
|
||||
.map_err(|e| de::Error::syntax(&e.to_string()))
|
||||
.map_err(|e| de::Error::custom(&e.to_string()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Begin actual function
|
||||
d.visit(Visitor { marker: ::std::marker::PhantomData })
|
||||
d.deserialize_seq(Visitor { marker: ::std::marker::PhantomData })
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for PublicKey {
|
||||
fn serialize<S>(&self, s: &mut S) -> Result<(), S::Error>
|
||||
fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
|
||||
where S: Serializer
|
||||
{
|
||||
let secp = Secp256k1::with_caps(::ContextFlag::None);
|
||||
|
@ -339,6 +343,7 @@ mod test {
|
|||
use super::super::Error::{InvalidPublicKey, InvalidSecretKey, IncapableContext};
|
||||
use super::{PublicKey, SecretKey};
|
||||
use super::super::constants;
|
||||
extern crate serde_json;
|
||||
|
||||
use rand::{Rng, thread_rng};
|
||||
|
||||
|
@ -515,33 +520,24 @@ mod test {
|
|||
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]".as_bytes();
|
||||
let mut json = json::de::Deserializer::new(zero31.iter().map(|c| Ok(*c)));
|
||||
assert!(<PublicKey as Deserialize>::deserialize(&mut json).is_err());
|
||||
let mut json = json::de::Deserializer::new(zero31.iter().map(|c| Ok(*c)));
|
||||
assert!(<SecretKey as Deserialize>::deserialize(&mut json).is_err());
|
||||
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]";
|
||||
assert!(serde_json::from_str::<PublicKey>(zero31).is_err());
|
||||
assert!(serde_json::from_str::<SecretKey>(zero31).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]".as_bytes();
|
||||
let mut json = json::de::Deserializer::new(zero32.iter().map(|c| Ok(*c)));
|
||||
assert!(<PublicKey as Deserialize>::deserialize(&mut json).is_err());
|
||||
let mut json = json::de::Deserializer::new(zero32.iter().map(|c| Ok(*c)));
|
||||
assert!(<SecretKey as Deserialize>::deserialize(&mut json).is_ok());
|
||||
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]";
|
||||
assert!(serde_json::from_str::<PublicKey>(zero32).is_err());
|
||||
assert!(serde_json::from_str::<SecretKey>(zero32).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]"
|
||||
.as_bytes();
|
||||
let mut json = json::de::Deserializer::new(zero65.iter().map(|c| Ok(*c)));
|
||||
assert!(<PublicKey as Deserialize>::deserialize(&mut json).is_err());
|
||||
let mut json = json::de::Deserializer::new(zero65.iter().map(|c| Ok(*c)));
|
||||
assert!(<SecretKey as Deserialize>::deserialize(&mut json).is_err());
|
||||
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]";
|
||||
assert!(serde_json::from_str::<PublicKey>(zero31).is_err());
|
||||
assert!(serde_json::from_str::<SecretKey>(zero31).is_err());
|
||||
|
||||
// Syntax error
|
||||
let string = "\"my key\"".as_bytes();
|
||||
let mut json = json::de::Deserializer::new(string.iter().map(|c| Ok(*c)));
|
||||
assert!(<PublicKey as Deserialize>::deserialize(&mut json).is_err());
|
||||
let mut json = json::de::Deserializer::new(string.iter().map(|c| Ok(*c)));
|
||||
assert!(<SecretKey as Deserialize>::deserialize(&mut json).is_err());
|
||||
let string = "\"my key\"";
|
||||
assert!(serde_json::from_str::<PublicKey>(zero31).is_err());
|
||||
assert!(serde_json::from_str::<SecretKey>(zero31).is_err());
|
||||
}
|
||||
|
||||
|
||||
|
@ -551,24 +547,18 @@ mod test {
|
|||
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();
|
||||
($e:ident, $d:ty) => {
|
||||
let json = serde_json::to_string(&$e).unwrap();
|
||||
assert!(json.len() > 0);
|
||||
assert!(serde_json::from_str::<$d>(json.as_str()).is_ok());
|
||||
}
|
||||
let mut deserializer = json::de::Deserializer::new(encoded.iter().map(|c| Ok(*c)));
|
||||
let decoded = Deserialize::deserialize(&mut deserializer);
|
||||
assert_eq!(Some(start), decoded.ok());
|
||||
})
|
||||
);
|
||||
|
||||
let s = Secp256k1::new();
|
||||
for _ in 0..500 {
|
||||
let (sk, pk) = s.generate_keypair(&mut thread_rng()).unwrap();
|
||||
round_trip!(sk);
|
||||
round_trip!(pk);
|
||||
// round_trip!(sk, SecretKey);
|
||||
round_trip!(pk, PublicKey);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -106,8 +106,7 @@ impl Signature {
|
|||
if ffi::secp256k1_ecdsa_signature_parse_der(secp.ctx,
|
||||
&mut ret,
|
||||
data.as_ptr(),
|
||||
data.len() as libc::size_t) ==
|
||||
1 {
|
||||
data.len() as libc::size_t) == 1 {
|
||||
Ok(Signature(ret))
|
||||
} else {
|
||||
Err(Error::InvalidSignature)
|
||||
|
@ -115,8 +114,10 @@ impl Signature {
|
|||
}
|
||||
}
|
||||
|
||||
/// Converts a "lax DER"-encoded byte slice to a signature. This is basically
|
||||
/// only useful for validating signatures in the Bitcoin blockchain from before
|
||||
/// Converts a "lax DER"-encoded byte slice to a signature. This is
|
||||
/// basically
|
||||
/// only useful for validating signatures in the Bitcoin blockchain from
|
||||
/// before
|
||||
/// 2016. It should never be used in new applications. This library does not
|
||||
/// support serializing to this "format"
|
||||
pub fn from_der_lax(secp: &Secp256k1, data: &[u8]) -> Result<Signature, Error> {
|
||||
|
@ -244,7 +245,8 @@ impl RecoverableSignature {
|
|||
(RecoveryId(recid), ret)
|
||||
}
|
||||
|
||||
/// Converts a recoverable signature to a non-recoverable one (this is needed
|
||||
/// Converts a recoverable signature to a non-recoverable one (this is
|
||||
/// needed
|
||||
/// for verification
|
||||
#[inline]
|
||||
pub fn to_standard(&self, secp: &Secp256k1) -> Signature {
|
||||
|
@ -469,7 +471,8 @@ impl Secp256k1 {
|
|||
}
|
||||
}
|
||||
|
||||
/// Creates a new Secp256k1 context with no capabilities (just de/serialization)
|
||||
/// Creates a new Secp256k1 context with no capabilities (just
|
||||
/// de/serialization)
|
||||
pub fn without_caps() -> Secp256k1 {
|
||||
Secp256k1::with_caps(ContextFlag::None)
|
||||
}
|
||||
|
@ -493,7 +496,8 @@ impl Secp256k1 {
|
|||
}
|
||||
}
|
||||
|
||||
/// Generates a random keypair. Convenience function for `key::SecretKey::new`
|
||||
/// Generates a random keypair. Convenience function for
|
||||
/// `key::SecretKey::new`
|
||||
/// and `key::PublicKey::from_secret_key`; call those functions directly for
|
||||
/// batch key generation. Requires a signing-capable context.
|
||||
#[inline]
|
||||
|
@ -505,7 +509,8 @@ impl Secp256k1 {
|
|||
Ok((sk, pk))
|
||||
}
|
||||
|
||||
/// Constructs a signature for `msg` using the secret key `sk` and RFC6979 nonce
|
||||
/// Constructs a signature for `msg` using the secret key `sk` and RFC6979
|
||||
/// nonce
|
||||
/// Requires a signing-capable context.
|
||||
pub fn sign(&self, msg: &Message, sk: &key::SecretKey) -> Result<Signature, Error> {
|
||||
if self.caps == ContextFlag::VerifyOnly || self.caps == ContextFlag::None {
|
||||
|
@ -527,7 +532,8 @@ impl Secp256k1 {
|
|||
Ok(Signature::from(ret))
|
||||
}
|
||||
|
||||
/// Constructs a signature for `msg` using the secret key `sk` and RFC6979 nonce
|
||||
/// Constructs a signature for `msg` using the secret key `sk` and RFC6979
|
||||
/// nonce
|
||||
/// Requires a signing-capable context.
|
||||
pub fn sign_recoverable(&self,
|
||||
msg: &Message,
|
||||
|
@ -569,9 +575,11 @@ impl Secp256k1 {
|
|||
}
|
||||
|
||||
/// Checks that `sig` is a valid ECDSA signature for `msg` using the public
|
||||
/// key `pubkey`. Returns `Ok(true)` on success. Note that this function cannot
|
||||
/// key `pubkey`. Returns `Ok(true)` on success. Note that this function
|
||||
/// cannot
|
||||
/// be used for Bitcoin consensus checking since there may exist signatures
|
||||
/// which OpenSSL would verify but not libsecp256k1, or vice-versa. Requires a
|
||||
/// which OpenSSL would verify but not libsecp256k1, or vice-versa.
|
||||
/// Requires a
|
||||
/// verify-capable context.
|
||||
#[inline]
|
||||
pub fn verify(&self, msg: &Message, sig: &Signature, pk: &key::PublicKey) -> Result<(), Error> {
|
||||
|
|
|
@ -20,25 +20,25 @@ macro_rules! impl_array_newtype {
|
|||
|
||||
impl $thing {
|
||||
#[inline]
|
||||
/// Converts the object to a raw pointer for FFI interfacing
|
||||
/// Converts the object to a raw pointer for FFI interfacing
|
||||
pub fn as_ptr(&self) -> *const $ty {
|
||||
let &$thing(ref dat) = self;
|
||||
dat.as_ptr()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Converts the object to a mutable raw pointer for FFI interfacing
|
||||
/// Converts the object to a mutable raw pointer for FFI interfacing
|
||||
pub fn as_mut_ptr(&mut self) -> *mut $ty {
|
||||
let &mut $thing(ref mut dat) = self;
|
||||
dat.as_mut_ptr()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Returns the length of the object as an array
|
||||
/// Returns the length of the object as an array
|
||||
pub fn len(&self) -> usize { $len }
|
||||
|
||||
#[inline]
|
||||
/// Returns whether the object as an array is empty
|
||||
/// Returns whether the object as an array is empty
|
||||
pub fn is_empty(&self) -> bool { false }
|
||||
}
|
||||
|
||||
|
@ -125,9 +125,9 @@ macro_rules! impl_array_newtype {
|
|||
impl ::std::hash::Hash for $thing {
|
||||
fn hash<H: ::std::hash::Hasher>(&self, state: &mut H) {
|
||||
state.write(&self.0)
|
||||
// for n in 0..self.len() {
|
||||
// state.write_u8(self.0[n]);
|
||||
// }
|
||||
// for n in 0..self.len() {
|
||||
// state.write_u8(self.0[n]);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -159,45 +159,48 @@ macro_rules! impl_array_newtype {
|
|||
}
|
||||
}
|
||||
|
||||
impl ::serde::Deserialize for $thing {
|
||||
fn deserialize<D>(d: &mut D) -> Result<$thing, D::Error>
|
||||
where D: ::serde::Deserializer
|
||||
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 ::serde::de::Visitor for Visitor {
|
||||
struct Visitor;
|
||||
|
||||
impl<'di> ::serde::de::Visitor<'di> for Visitor {
|
||||
type Value = $thing;
|
||||
|
||||
fn expecting(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
formatter.write_str("an array of bytes")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_seq<V>(&mut self, mut v: V) -> Result<$thing, V::Error>
|
||||
where V: ::serde::de::SeqVisitor
|
||||
fn visit_seq<V>(self, mut v: V) -> Result<$thing, V::Error>
|
||||
where V: ::serde::de::SeqAccess<'di>
|
||||
{
|
||||
unsafe {
|
||||
use std::mem;
|
||||
let mut ret: [$ty; $len] = mem::uninitialized();
|
||||
for i in 0..$len {
|
||||
ret[i] = match try!(v.visit()) {
|
||||
ret[i] = match try!(v.next_element()) {
|
||||
Some(c) => c,
|
||||
None => return Err(::serde::de::Error::end_of_stream())
|
||||
None => return Err(::serde::de::Error::invalid_length(i, &self))
|
||||
};
|
||||
}
|
||||
try!(v.end());
|
||||
Ok($thing(ret))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Begin actual function
|
||||
d.visit(Visitor { marker: ::std::marker::PhantomData })
|
||||
// d.visit(Visitor { marker: ::std::marker::PhantomData })
|
||||
d.deserialize_seq(Visitor)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::serde::Serialize for $thing {
|
||||
fn serialize<S>(&self, s: &mut S) -> Result<(), S::Error>
|
||||
fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
|
||||
where S: ::serde::Serializer
|
||||
{
|
||||
(&self.0[..]).serialize(s)
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
|
||||
//! # Pedersen commitments and related range proofs
|
||||
|
||||
use std::cmp::min;
|
||||
use std::fmt;
|
||||
use std::mem;
|
||||
|
||||
use ContextFlag;
|
||||
|
@ -26,6 +28,7 @@ use ffi;
|
|||
use key;
|
||||
use key::SecretKey;
|
||||
use rand::{Rng, OsRng};
|
||||
use serde::{ser, de};
|
||||
|
||||
/// A Pedersen commitment
|
||||
pub struct Commitment(pub [u8; constants::PEDERSEN_COMMITMENT_SIZE]);
|
||||
|
@ -34,6 +37,15 @@ impl_pretty_debug!(Commitment);
|
|||
|
||||
|
||||
impl Commitment {
|
||||
/// Builds a Hash from a byte vector. If the vector is too short, it will be
|
||||
/// completed by zeroes. If it's too long, it will be truncated.
|
||||
pub fn from_vec(v: Vec<u8>) -> Commitment {
|
||||
let mut h = [0; constants::PEDERSEN_COMMITMENT_SIZE];
|
||||
for i in 0..min(v.len(), constants::PEDERSEN_COMMITMENT_SIZE) {
|
||||
h[i] = v[i];
|
||||
}
|
||||
Commitment(h)
|
||||
}
|
||||
/// Uninitialized commitment, use with caution
|
||||
unsafe fn blank() -> Commitment {
|
||||
mem::uninitialized()
|
||||
|
@ -77,6 +89,53 @@ impl Clone for RangeProof {
|
|||
}
|
||||
}
|
||||
|
||||
impl ser::Serialize for RangeProof {
|
||||
fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
|
||||
where S: ser::Serializer
|
||||
{
|
||||
(&self.proof[..self.plen]).serialize(s)
|
||||
}
|
||||
}
|
||||
|
||||
struct Visitor;
|
||||
|
||||
impl<'di> de::Visitor<'di> for Visitor {
|
||||
type Value = RangeProof;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("an array of bytes")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_seq<V>(self, mut v: V) -> Result<RangeProof, V::Error>
|
||||
where V: de::SeqAccess<'di>
|
||||
{
|
||||
unsafe {
|
||||
use std::mem;
|
||||
let mut ret: [u8; constants::MAX_PROOF_SIZE] = mem::uninitialized();
|
||||
let mut i = 0;
|
||||
while let Some(val) = v.next_element()? {
|
||||
ret[i] = val;
|
||||
i += 1;
|
||||
}
|
||||
Ok(RangeProof {
|
||||
proof: ret,
|
||||
plen: i,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> de::Deserialize<'de> for RangeProof {
|
||||
fn deserialize<D>(d: D) -> Result<RangeProof, D::Error>
|
||||
where D: de::Deserializer<'de>
|
||||
{
|
||||
|
||||
// Begin actual function
|
||||
d.deserialize_seq(Visitor)
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<[u8]> for RangeProof {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
&self.proof[..self.plen as usize]
|
||||
|
@ -84,6 +143,12 @@ impl AsRef<[u8]> for RangeProof {
|
|||
}
|
||||
|
||||
impl RangeProof {
|
||||
pub fn zero() -> RangeProof {
|
||||
RangeProof {
|
||||
proof: [0; constants::MAX_PROOF_SIZE],
|
||||
plen: 0,
|
||||
}
|
||||
}
|
||||
/// The range proof as a byte slice.
|
||||
pub fn bytes(&self) -> &[u8] {
|
||||
&self.proof[..self.plen as usize]
|
||||
|
@ -146,7 +211,8 @@ impl Secp256k1 {
|
|||
Ok(Commitment(commit))
|
||||
}
|
||||
|
||||
/// Convenience method to Create a pedersen commitment only from a value, with a zero blinding factor
|
||||
/// Convenience method to Create a pedersen commitment only from a value,
|
||||
/// with a zero blinding factor
|
||||
pub fn commit_value(&self, value: u64) -> Result<Commitment, Error> {
|
||||
|
||||
if self.caps != ContextFlag::Commit {
|
||||
|
@ -223,7 +289,8 @@ impl Secp256k1 {
|
|||
SecretKey::from_slice(self, &ret)
|
||||
}
|
||||
|
||||
/// Produces a range proof for the provided value, using min and max bounds, relying
|
||||
/// Produces a range proof for the provided value, using min and max
|
||||
/// bounds, relying
|
||||
/// on the blinding factor and commitment.
|
||||
pub fn range_proof(&self,
|
||||
min: u64,
|
||||
|
@ -293,7 +360,8 @@ impl Secp256k1 {
|
|||
}
|
||||
}
|
||||
|
||||
/// Verify a range proof proof and rewind the proof to recover information sent by its author.
|
||||
/// Verify a range proof proof and rewind the proof to recover information
|
||||
/// sent by its author.
|
||||
pub fn rewind_range_proof(&self,
|
||||
commit: Commitment,
|
||||
proof: RangeProof,
|
||||
|
|
Loading…
Reference in a new issue