diff --git a/src/key.rs b/src/key.rs index adefcf2..55ecd23 100644 --- a/src/key.rs +++ b/src/key.rs @@ -19,8 +19,7 @@ use std::intrinsics::copy_nonoverlapping_memory; use std::cmp; use std::fmt; use std::rand::Rng; -use constants; -use ffi; +use serialize::{Decoder, Decodable, Encoder, Encodable}; use crypto::digest::Digest; use crypto::sha2::Sha512; @@ -29,6 +28,8 @@ use crypto::mac::Mac; use super::init; use super::{Result, InvalidNonce, InvalidPublicKey, InvalidSecretKey, Unknown}; +use constants; +use ffi; /// Secret 256-bit nonce used as `k` in an ECDSA signature pub struct Nonce([u8, ..constants::NONCE_SIZE]); @@ -386,6 +387,40 @@ impl fmt::Show for PublicKeyData { } } +impl, E> Decodable for PublicKey { + fn decode(d: &mut D) -> ::std::prelude::Result { + d.read_seq(|d, len| { + 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 range(0, len) { + ret[i] = try!(d.read_seq_elt(i, |d| Decodable::decode(d))); + } + Ok(PublicKey(Uncompressed(ret))) + } + } else if len == constants::COMPRESSED_PUBLIC_KEY_SIZE { + unsafe { + use std::mem; + let mut ret: [u8, ..constants::COMPRESSED_PUBLIC_KEY_SIZE] = mem::uninitialized(); + for i in range(0, len) { + ret[i] = try!(d.read_seq_elt(i, |d| Decodable::decode(d))); + } + Ok(PublicKey(Compressed(ret))) + } + } else { + Err(d.error("Invalid length")) + } + }) + } +} + +impl , S> Encodable for PublicKey { + fn encode(&self, e: &mut E) -> ::std::prelude::Result<(), S> { + self.as_slice().encode(e) + } +} + impl fmt::Show for SecretKey { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.as_slice().fmt(f) diff --git a/src/macros.rs b/src/macros.rs index da15704..f29bf45 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -116,7 +116,7 @@ macro_rules! impl_array_newtype( impl, S> ::serialize::Encodable for $thing { fn encode(&self, e: &mut E) -> ::std::prelude::Result<(), S> { self.as_slice().encode(e) - } + } } } )