diff --git a/src/ffi.rs b/src/ffi.rs index dde4b0e..068c421 100644 --- a/src/ffi.rs +++ b/src/ffi.rs @@ -55,6 +55,8 @@ extern "C" { pub fn secp256k1_context_create(flags: c_uint) -> Context; + pub fn secp256k1_context_clone(cx: Context) -> Context; + pub fn secp256k1_context_destroy(cx: Context); pub fn secp256k1_ecdsa_verify(cx: Context, msg32: *const c_uchar, diff --git a/src/lib.rs b/src/lib.rs index a09b4b8..f1e3243 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -44,7 +44,7 @@ extern crate libc; extern crate rand; use std::intrinsics::copy_nonoverlapping; -use std::{fmt, io, ops, ptr}; +use std::{cmp, fmt, io, ops, ptr}; use libc::c_int; use rand::{OsRng, Rng, SeedableRng}; @@ -105,13 +105,23 @@ impl Signature { } } +impl fmt::Debug for Signature { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + try!(write!(f, "Signature(")); + for i in self[..].iter().cloned() { + try!(write!(f, "{:02x}", i)); + } + write!(f, ")") + } +} + impl ops::Index for Signature { type Output = u8; #[inline] fn index(&self, index: usize) -> &u8 { - let &Signature(_, ref dat) = self; - &dat[index] + assert!(index < self.0); + &self.1[index] } } @@ -120,8 +130,8 @@ impl ops::Index> for Signature { #[inline] fn index(&self, index: ops::Range) -> &[u8] { - let &Signature(_, ref dat) = self; - &dat[index.start..index.end] + assert!(index.end < self.0); + &self.1[index] } } @@ -130,8 +140,7 @@ impl ops::Index> for Signature { #[inline] fn index(&self, index: ops::RangeFrom) -> &[u8] { - let &Signature(_, ref dat) = self; - &dat[index.start..] + &self.1[index.start..self.0] } } @@ -140,11 +149,18 @@ impl ops::Index for Signature { #[inline] fn index(&self, _: ops::RangeFull) -> &[u8] { - let &Signature(_, ref dat) = self; - &dat[..] + &self.1[0..self.0] } } +impl cmp::PartialEq for Signature { + #[inline] + fn eq(&self, other: &Signature) -> bool { + &self[..] == &other[..] + } +} +impl cmp::Eq for Signature { } + impl Clone for Signature { #[inline] fn clone(&self) -> Signature { @@ -182,6 +198,16 @@ impl Message { } } +impl fmt::Debug for Message { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + try!(write!(f, "Message(")); + for i in self[..].iter().cloned() { + try!(write!(f, "{:02x}", i)); + } + write!(f, ")") + } +} + /// An ECDSA error #[derive(Copy, PartialEq, Eq, Clone, Debug)] pub enum Error { @@ -214,6 +240,29 @@ pub struct Secp256k1 { rng: R } +impl Clone for Secp256k1 { + fn clone(&self) -> Secp256k1 { + Secp256k1 { + ctx: unsafe { ffi::secp256k1_context_clone(self.ctx) }, + rng: self.rng.clone() + } + } +} + +impl PartialEq for Secp256k1 { + fn eq(&self, other: &Secp256k1) -> bool { + // The contexts will always be "equal" in a functional sense + self.rng == other.rng + } +} +impl Eq for Secp256k1 { } + +impl fmt::Debug for Secp256k1 { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + write!(f, "Secp256k1 {{ ctx: (secp256k1 context), rng: {:?} }}", self.rng) + } +} + impl Drop for Secp256k1 { fn drop(&mut self) { unsafe { ffi::secp256k1_context_destroy(self.ctx); }