From d495d9ca0609689324cc24b6657beb39cb6ffd91 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Sat, 17 Jan 2015 10:13:45 -0600 Subject: [PATCH] Update for rustc changes We can compile now, but not link -- there have been too many changes in libsecp256k1 behind the scenes. Next commit :) --- src/constants.rs | 18 ++--- src/key.rs | 174 +++++++++++++++++++++++++---------------------- src/macros.rs | 35 +++++----- src/secp256k1.rs | 110 +++++++++++++++--------------- 4 files changed, 176 insertions(+), 161 deletions(-) diff --git a/src/constants.rs b/src/constants.rs index d10517b..ba70fb3 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -16,25 +16,25 @@ //! Constants /// The size (in bytes) of a nonce -pub static NONCE_SIZE: uint = 32; +pub const NONCE_SIZE: usize = 32; /// The size (in bytes) of a secret key -pub static SECRET_KEY_SIZE: uint = 32; +pub const SECRET_KEY_SIZE: usize = 32; /// The size (in bytes) of an uncompressed public key -pub static UNCOMPRESSED_PUBLIC_KEY_SIZE: uint = 65; +pub const UNCOMPRESSED_PUBLIC_KEY_SIZE: usize = 65; /// The size (in bytes) of a compressed public key -pub static COMPRESSED_PUBLIC_KEY_SIZE: uint = 33; +pub const COMPRESSED_PUBLIC_KEY_SIZE: usize = 33; /// The maximum size of a signature -pub static MAX_SIGNATURE_SIZE: uint = 72; +pub const MAX_SIGNATURE_SIZE: usize = 72; /// The maximum size of a compact signature -pub static MAX_COMPACT_SIGNATURE_SIZE: uint = 64; +pub const MAX_COMPACT_SIGNATURE_SIZE: usize = 64; /// The order of the secp256k1 curve -pub static CURVE_ORDER: [u8, ..32] = [ +pub const CURVE_ORDER: [u8; 32] = [ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, @@ -42,7 +42,7 @@ pub static CURVE_ORDER: [u8, ..32] = [ ]; /// The X coordinate of the generator -pub static GENERATOR_X: [u8, ..32] = [ +pub const GENERATOR_X: [u8; 32] = [ 0x79, 0xbe, 0x66, 0x7e, 0xf9, 0xdc, 0xbb, 0xac, 0x55, 0xa0, 0x62, 0x95, 0xce, 0x87, 0x0b, 0x07, 0x02, 0x9b, 0xfc, 0xdb, 0x2d, 0xce, 0x28, 0xd9, @@ -50,7 +50,7 @@ pub static GENERATOR_X: [u8, ..32] = [ ]; /// The Y coordinate of the generator -pub static GENERATOR_Y: [u8, ..32] = [ +pub const GENERATOR_Y: [u8; 32] = [ 0x48, 0x3a, 0xda, 0x77, 0x26, 0xa3, 0xc4, 0x65, 0x5d, 0xa4, 0xfb, 0xfc, 0x0e, 0x11, 0x08, 0xa8, 0xfd, 0x17, 0xb4, 0x48, 0xa6, 0x85, 0x54, 0x19, diff --git a/src/key.rs b/src/key.rs index 55ecd23..1c0255d 100644 --- a/src/key.rs +++ b/src/key.rs @@ -27,17 +27,18 @@ use crypto::hmac::Hmac; use crypto::mac::Mac; use super::init; -use super::{Result, InvalidNonce, InvalidPublicKey, InvalidSecretKey, Unknown}; +use super::Result; +use super::Error::{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]); -impl_array_newtype!(Nonce, u8, constants::NONCE_SIZE) +pub struct Nonce([u8; constants::NONCE_SIZE]); +impl_array_newtype!(Nonce, u8, constants::NONCE_SIZE); /// Secret 256-bit key used as `x` in an ECDSA signature -pub struct SecretKey([u8, ..constants::SECRET_KEY_SIZE]); -impl_array_newtype!(SecretKey, u8, constants::SECRET_KEY_SIZE) +pub struct SecretKey([u8; constants::SECRET_KEY_SIZE]); +impl_array_newtype!(SecretKey, u8, constants::SECRET_KEY_SIZE); /// The number 1 encoded as a secret key pub static ONE: SecretKey = SecretKey([0, 0, 0, 0, 0, 0, 0, 0, @@ -46,23 +47,25 @@ pub static ONE: SecretKey = SecretKey([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]); /// Public key -#[deriving(Clone, PartialEq, Eq, Show)] +#[derive(Clone, PartialEq, Eq, Show)] pub struct PublicKey(PublicKeyData); +impl Copy for PublicKey {} enum PublicKeyData { - Compressed([u8, ..constants::COMPRESSED_PUBLIC_KEY_SIZE]), - Uncompressed([u8, ..constants::UNCOMPRESSED_PUBLIC_KEY_SIZE]), + Compressed([u8; constants::COMPRESSED_PUBLIC_KEY_SIZE]), + Uncompressed([u8; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE]) } +impl Copy for PublicKeyData {} -fn random_32_bytes(rng: &mut R) -> [u8, ..32] { - let mut ret = [0u8, ..32]; - rng.fill_bytes(ret); +fn random_32_bytes(rng: &mut R) -> [u8; 32] { + let mut ret = [0u8; 32]; + rng.fill_bytes(&mut ret); ret } /// As described in RFC 6979 -fn bits2octets(data: &[u8]) -> [u8, ..32] { - let mut ret = [0, ..32]; +fn bits2octets(data: &[u8]) -> [u8; 32] { + let mut ret = [0; 32]; unsafe { copy_nonoverlapping_memory(ret.as_mut_ptr(), data.as_ptr(), @@ -83,7 +86,7 @@ impl Nonce { pub fn from_slice(data: &[u8]) -> Result { match data.len() { constants::NONCE_SIZE => { - let mut ret = [0, ..constants::NONCE_SIZE]; + let mut ret = [0; constants::NONCE_SIZE]; unsafe { copy_nonoverlapping_memory(ret.as_mut_ptr(), data.as_ptr(), @@ -99,54 +102,54 @@ impl Nonce { #[inline] #[allow(non_snake_case)] // so we can match the names in the RFC pub fn deterministic(msg: &[u8], key: &SecretKey) -> Nonce { - static HMAC_SIZE: uint = 64; + const HMAC_SIZE: usize = 64; - macro_rules! hmac( - ($res:expr <- key $key:expr, data $($data:expr),+) => ({ + macro_rules! hmac { + ($res:expr; key $key:expr, data $($data:expr),+) => ({ let mut hmacker = Hmac::new(Sha512::new(), $key.as_slice()); $(hmacker.input($data.as_slice());)+ hmacker.raw_result($res.as_mut_slice()); }) - ) + } // Section 3.2a // Goofy block just to avoid marking `msg_hash` as mutable let mut hasher = Sha512::new(); hasher.input(msg); - let mut x = [0, ..HMAC_SIZE]; + let mut x = [0; HMAC_SIZE]; hasher.result(x.as_mut_slice()); let msg_hash = bits2octets(x.as_slice()); // Section 3.2b - let mut V = [0x01u8, ..HMAC_SIZE]; + let mut V = [0x01u8; HMAC_SIZE]; // Section 3.2c - let mut K = [0x00u8, ..HMAC_SIZE]; + let mut K = [0x00u8; HMAC_SIZE]; // Section 3.2d - hmac!(K <- key K, data V, [0x00], key, msg_hash) + hmac!(K; key K, data V, [0x00], key, msg_hash); // Section 3.2e - hmac!(V <- key K, data V) + hmac!(V; key K, data V); // Section 3.2f - hmac!(K <- key K, data V, [0x01], key, msg_hash) + hmac!(K; key K, data V, [0x01], key, msg_hash); // Section 3.2g - hmac!(V <- key K, data V) + hmac!(V; key K, data V); // Section 3.2 let mut k = Err(InvalidSecretKey); while k.is_err() { // Try to generate the nonce - let mut T = [0x00u8, ..HMAC_SIZE]; - hmac!(T <- key K, data V) + let mut T = [0x00u8; HMAC_SIZE]; + hmac!(T; key K, data V); k = Nonce::from_slice(T.slice_to(constants::NONCE_SIZE)); // Replace K, V if k.is_err() { - hmac!(K <- key K, data V, [0x00]) - hmac!(V <- key K, data V) + hmac!(K; key K, data V, [0x00]); + hmac!(V; key K, data V); } } @@ -174,7 +177,7 @@ impl SecretKey { init(); match data.len() { constants::SECRET_KEY_SIZE => { - let mut ret = [0, ..constants::SECRET_KEY_SIZE]; + let mut ret = [0; constants::SECRET_KEY_SIZE]; unsafe { if ffi::secp256k1_ecdsa_seckey_verify(data.as_ptr()) == 0 { return Err(InvalidSecretKey); @@ -218,8 +221,11 @@ pub struct Sequence { compressed: bool, last_sk: SecretKey, } +impl Copy for Sequence {} + +impl Iterator for Sequence { + type Item = (SecretKey, PublicKey); -impl<'a> Iterator<(SecretKey, PublicKey)> for Sequence { #[inline] fn next(&mut self) -> Option<(SecretKey, PublicKey)> { self.last_sk.add_assign(&ONE).unwrap(); @@ -232,8 +238,11 @@ impl PublicKey { #[inline] pub fn new(compressed: bool) -> PublicKey { PublicKey( - if compressed { Compressed([0, ..constants::COMPRESSED_PUBLIC_KEY_SIZE]) } - else { Uncompressed([0, ..constants::UNCOMPRESSED_PUBLIC_KEY_SIZE]) } + if compressed { + PublicKeyData::Compressed([0; constants::COMPRESSED_PUBLIC_KEY_SIZE]) + } else { + PublicKeyData::Uncompressed([0; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE]) + } ) } @@ -252,7 +261,7 @@ impl PublicKey { pk.as_mut_ptr(), &mut len, sk.as_ptr(), compressed), 1); } - assert_eq!(len as uint, pk.len()); + assert_eq!(len as usize, pk.len()); pk } @@ -261,7 +270,7 @@ impl PublicKey { pub fn from_slice(data: &[u8]) -> Result { match data.len() { constants::COMPRESSED_PUBLIC_KEY_SIZE => { - let mut ret = [0, ..constants::COMPRESSED_PUBLIC_KEY_SIZE]; + let mut ret = [0; constants::COMPRESSED_PUBLIC_KEY_SIZE]; unsafe { if ffi::secp256k1_ecdsa_pubkey_verify(data.as_ptr(), data.len() as ::libc::c_int) == 0 { @@ -271,16 +280,16 @@ impl PublicKey { data.as_ptr(), data.len()); } - Ok(PublicKey(Compressed(ret))) + Ok(PublicKey(PublicKeyData::Compressed(ret))) } constants::UNCOMPRESSED_PUBLIC_KEY_SIZE => { - let mut ret = [0, ..constants::UNCOMPRESSED_PUBLIC_KEY_SIZE]; + let mut ret = [0; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE]; unsafe { copy_nonoverlapping_memory(ret.as_mut_ptr(), data.as_ptr(), data.len()); } - Ok(PublicKey(Uncompressed(ret))) + Ok(PublicKey(PublicKeyData::Uncompressed(ret))) } _ => Err(InvalidPublicKey) } @@ -291,18 +300,18 @@ impl PublicKey { pub fn is_compressed(&self) -> bool { let &PublicKey(ref data) = self; match *data { - Compressed(_) => true, - Uncompressed(_) => false + PublicKeyData::Compressed(_) => true, + PublicKeyData::Uncompressed(_) => false } } /// Returns the length of the public key #[inline] - pub fn len(&self) -> uint { + pub fn len(&self) -> usize { let &PublicKey(ref data) = self; match *data { - Compressed(ref x) => x.len(), - Uncompressed(ref x) => x.len() + PublicKeyData::Compressed(ref x) => x.len(), + PublicKeyData::Uncompressed(ref x) => x.len() } } @@ -319,8 +328,8 @@ impl PublicKey { pub fn as_ptr(&self) -> *const u8 { let &PublicKey(ref data) = self; match *data { - Compressed(ref x) => x.as_ptr(), - Uncompressed(ref x) => x.as_ptr() + PublicKeyData::Compressed(ref x) => x.as_ptr(), + PublicKeyData::Uncompressed(ref x) => x.as_ptr() } } @@ -328,10 +337,10 @@ impl PublicKey { /// with the FFI functions #[inline] pub fn as_mut_ptr(&mut self) -> *mut u8 { - let &PublicKey(ref mut data) = self; + let &mut PublicKey(ref mut data) = self; match *data { - Compressed(ref mut x) => x.as_mut_ptr(), - Uncompressed(ref mut x) => x.as_mut_ptr() + PublicKeyData::Compressed(ref mut x) => x.as_mut_ptr(), + PublicKeyData::Uncompressed(ref mut x) => x.as_mut_ptr() } } @@ -355,8 +364,8 @@ impl PublicKeyData { #[inline] fn as_slice<'a>(&'a self) -> &'a [u8] { match *self { - Compressed(ref x) => x.as_slice(), - Uncompressed(ref x) => x.as_slice() + PublicKeyData::Compressed(ref x) => x.as_slice(), + PublicKeyData::Uncompressed(ref x) => x.as_slice() } } } @@ -387,26 +396,26 @@ impl fmt::Show for PublicKeyData { } } -impl, E> Decodable for PublicKey { - fn decode(d: &mut D) -> ::std::prelude::Result { +impl Decodable for PublicKey { + fn decode(d: &mut D) -> ::std::result::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(); + 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))) + Ok(PublicKey(PublicKeyData::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(); + 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))) + Ok(PublicKey(PublicKeyData::Compressed(ret))) } } else { Err(d.error("Invalid length")) @@ -415,9 +424,9 @@ impl, E> Decodable for PublicKey { } } -impl , S> Encodable for PublicKey { - fn encode(&self, e: &mut E) -> ::std::prelude::Result<(), S> { - self.as_slice().encode(e) +impl Encodable for PublicKey { + fn encode(&self, s: &mut S) -> ::std::result::Result<(), S::Error> { + self.as_slice().encode(s) } } @@ -430,41 +439,42 @@ impl fmt::Show for SecretKey { #[cfg(test)] mod test { use serialize::hex::FromHex; - use std::rand::task_rng; + use std::rand::thread_rng; use test::Bencher; - use super::super::{Secp256k1, InvalidNonce, InvalidPublicKey, InvalidSecretKey}; + use super::super::Secp256k1; + use super::super::Error::{InvalidNonce, InvalidPublicKey, InvalidSecretKey}; use super::{Nonce, PublicKey, SecretKey}; #[test] fn nonce_from_slice() { - let n = Nonce::from_slice([1, ..31]); + let n = Nonce::from_slice(&[1; 31]); assert_eq!(n, Err(InvalidNonce)); - let n = SecretKey::from_slice([1, ..32]); + let n = SecretKey::from_slice(&[1; 32]); assert!(n.is_ok()); } #[test] fn skey_from_slice() { - let sk = SecretKey::from_slice([1, ..31]); + let sk = SecretKey::from_slice(&[1; 31]); assert_eq!(sk, Err(InvalidSecretKey)); - let sk = SecretKey::from_slice([1, ..32]); + let sk = SecretKey::from_slice(&[1; 32]); assert!(sk.is_ok()); } #[test] fn pubkey_from_slice() { - assert_eq!(PublicKey::from_slice([]), Err(InvalidPublicKey)); - assert_eq!(PublicKey::from_slice([1, 2, 3]), Err(InvalidPublicKey)); + assert_eq!(PublicKey::from_slice(&[]), Err(InvalidPublicKey)); + assert_eq!(PublicKey::from_slice(&[1, 2, 3]), Err(InvalidPublicKey)); - let uncompressed = PublicKey::from_slice([4, 54, 57, 149, 239, 162, 148, 175, 246, 254, 239, 75, 154, 152, 10, 82, 234, 224, 85, 220, 40, 100, 57, 121, 30, 162, 94, 156, 135, 67, 74, 49, 179, 57, 236, 53, 162, 124, 149, 144, 168, 77, 74, 30, 72, 211, 229, 110, 111, 55, 96, 193, 86, 227, 183, 152, 195, 155, 51, 247, 123, 113, 60, 228, 188]); + let uncompressed = PublicKey::from_slice(&[4, 54, 57, 149, 239, 162, 148, 175, 246, 254, 239, 75, 154, 152, 10, 82, 234, 224, 85, 220, 40, 100, 57, 121, 30, 162, 94, 156, 135, 67, 74, 49, 179, 57, 236, 53, 162, 124, 149, 144, 168, 77, 74, 30, 72, 211, 229, 110, 111, 55, 96, 193, 86, 227, 183, 152, 195, 155, 51, 247, 123, 113, 60, 228, 188]); assert!(uncompressed.is_ok()); assert!(!uncompressed.unwrap().is_compressed()); - let compressed = PublicKey::from_slice([3, 23, 183, 225, 206, 31, 159, 148, 195, 42, 67, 115, 146, 41, 248, 140, 11, 3, 51, 41, 111, 180, 110, 143, 114, 134, 88, 73, 198, 174, 52, 184, 78]); + let compressed = PublicKey::from_slice(&[3, 23, 183, 225, 206, 31, 159, 148, 195, 42, 67, 115, 146, 41, 248, 140, 11, 3, 51, 41, 111, 180, 110, 143, 114, 134, 88, 73, 198, 174, 52, 184, 78]); assert!(compressed.is_ok()); assert!(compressed.unwrap().is_compressed()); } @@ -484,7 +494,7 @@ mod test { #[test] fn nonce_slice_round_trip() { - let mut rng = task_rng(); + let mut rng = thread_rng(); let nonce = Nonce::new(&mut rng); assert_eq!(Nonce::from_slice(nonce.as_slice()), Ok(nonce)); } @@ -492,19 +502,19 @@ mod test { #[test] fn invalid_secret_key() { // Zero - assert_eq!(SecretKey::from_slice([0, ..32]), Err(InvalidSecretKey)); + assert_eq!(SecretKey::from_slice(&[0; 32]), Err(InvalidSecretKey)); // -1 - assert_eq!(SecretKey::from_slice([0xff, ..32]), Err(InvalidSecretKey)); + assert_eq!(SecretKey::from_slice(&[0xff; 32]), Err(InvalidSecretKey)); // Top of range - assert!(SecretKey::from_slice([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, - 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, - 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x40]).is_ok()); + assert!(SecretKey::from_slice(&[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, + 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x40]).is_ok()); // One past top of range - assert!(SecretKey::from_slice([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, - 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, - 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41]).is_err()); + assert!(SecretKey::from_slice(&[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, + 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41]).is_err()); } #[test] @@ -536,7 +546,7 @@ mod test { let sk = SecretKey::from_slice(hex_slice!("09e918bbea76205445e9a73eaad2080a135d1e33e9dd1b3ca8a9a1285e7c1f81")).unwrap(); // "%x" % rfc6979.generate_k(SECP256k1.generator, sk, hashlib.sha512, hashlib.sha512('').digest()) - let nonce = Nonce::deterministic([], &sk); + let nonce = Nonce::deterministic(&[], &sk); assert_eq!(nonce.as_slice(), hex_slice!("d954eddd184cac2b60edcd0e6be9ec54d93f633b28b366420d38ed9c346ffe27")); @@ -550,7 +560,7 @@ mod test { let sk = SecretKey::from_slice(hex_slice!("09e918bbea76205445e9a73eaad2080a135d1e33e9dd1b3ca8a9a1285e7c1f80")).unwrap(); // "%x" % rfc6979.generate_k(SECP256k1.generator, sk, hashlib.sha512, hashlib.sha512('').digest()) - let nonce = Nonce::deterministic([], &sk); + let nonce = Nonce::deterministic(&[], &sk); assert_eq!(nonce.as_slice(), hex_slice!("9f45f8d0a28e8956673c8da6db3db86ca4f172f0a2dbd62364fdbf786c7d96df")); diff --git a/src/macros.rs b/src/macros.rs index f29bf45..db234e5 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -13,11 +13,11 @@ // If not, see . // -#![macro_escape] - // This is a macro that routinely comes in handy -macro_rules! impl_array_newtype( +macro_rules! impl_array_newtype { ($thing:ident, $ty:ty, $len:expr) => { + impl Copy for $thing {} + impl $thing { #[inline] /// Provides an immutable view into the object @@ -28,21 +28,21 @@ macro_rules! impl_array_newtype( #[inline] /// Provides an immutable view into the object from index `s` inclusive to `e` exclusive - pub fn slice<'a>(&'a self, s: uint, e: uint) -> &'a [$ty] { + pub fn slice<'a>(&'a self, s: usize, e: usize) -> &'a [$ty] { let &$thing(ref dat) = self; dat.slice(s, e) } #[inline] /// Provides an immutable view into the object, up to index `n` exclusive - pub fn slice_to<'a>(&'a self, n: uint) -> &'a [$ty] { + pub fn slice_to<'a>(&'a self, n: usize) -> &'a [$ty] { let &$thing(ref dat) = self; dat.slice_to(n) } #[inline] /// Provides an immutable view into the object, starting from index `n` - pub fn slice_from<'a>(&'a self, n: uint) -> &'a [$ty] { + pub fn slice_from<'a>(&'a self, n: usize) -> &'a [$ty] { let &$thing(ref dat) = self; dat.slice_from(n) } @@ -57,13 +57,13 @@ macro_rules! impl_array_newtype( #[inline] /// Converts the object to a mutable raw pointer for FFI interfacing pub fn as_mut_ptr(&mut self) -> *mut $ty { - let &$thing(ref mut dat) = self; + let &mut $thing(ref mut dat) = self; dat.as_mut_ptr() } #[inline] /// Returns the length of the object as an array - pub fn len(&self) -> uint { $len } + pub fn len(&self) -> usize { $len } } impl PartialEq for $thing { @@ -90,8 +90,8 @@ macro_rules! impl_array_newtype( } } - impl, E> ::serialize::Decodable for $thing { - fn decode(d: &mut D) -> ::std::prelude::Result<$thing, E> { + impl ::serialize::Decodable for $thing { + fn decode(d: &mut D) -> ::std::result::Result<$thing, D::Error> { use serialize::Decodable; ::assert_type_is_copy::<$ty>(); @@ -102,7 +102,7 @@ macro_rules! impl_array_newtype( } else { unsafe { use std::mem; - let mut ret: [$ty, ..$len] = mem::uninitialized(); + let mut ret: [$ty; $len] = mem::uninitialized(); for i in range(0, len) { ret[i] = try!(d.read_seq_elt(i, |d| Decodable::decode(d))); } @@ -113,19 +113,20 @@ 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) + impl ::serialize::Encodable for $thing { + fn encode(&self, s: &mut S) + -> ::std::result::Result<(), S::Error> { + self.as_slice().encode(s) } } } -) +} // for testing -macro_rules! hex_slice( +macro_rules! hex_slice { ($s:expr) => ( $s.from_hex().unwrap().as_slice() ) -) +} diff --git a/src/secp256k1.rs b/src/secp256k1.rs index dd62976..5444e55 100644 --- a/src/secp256k1.rs +++ b/src/secp256k1.rs @@ -24,33 +24,32 @@ #![crate_type = "rlib"] #![crate_type = "dylib"] #![crate_name = "bitcoin-secp256k1-rs"] -#![comment = "Bindings and wrapper functions for bitcoin secp256k1 library."] -#![feature(phase)] -#![feature(macro_rules)] -#![feature(globs)] // for tests only + +// Keep this until 1.0 I guess; it's needed for `black_box` at least +#![allow(unstable)] // Coding conventions -#![deny(non_uppercase_statics)] +#![deny(non_upper_case_globals)] #![deny(non_camel_case_types)] #![deny(non_snake_case)] #![deny(unused_mut)] -#![warn(missing_doc)] +#![warn(missing_docs)] -extern crate "rust-crypto" as crypto; +extern crate crypto; extern crate libc; extern crate serialize; -extern crate sync; extern crate test; use std::intrinsics::copy_nonoverlapping_memory; use std::io::IoResult; use std::rand::{OsRng, Rng, SeedableRng}; +use std::sync::{Once, ONCE_INIT}; use libc::c_int; -use sync::one::{Once, ONCE_INIT}; use crypto::fortuna::Fortuna; +#[macro_use] mod macros; pub mod constants; pub mod ffi; @@ -61,9 +60,11 @@ fn assert_type_is_copy() { } /// A tag used for recovering the public key from a compact signature pub struct RecoveryId(i32); +impl Copy for RecoveryId {} /// An ECDSA signature -pub struct Signature(uint, [u8, ..constants::MAX_SIGNATURE_SIZE]); +pub struct Signature(usize, [u8; constants::MAX_SIGNATURE_SIZE]); +impl Copy for Signature {} impl Signature { /// Converts the signature to a raw pointer suitable for use @@ -78,7 +79,7 @@ impl Signature { /// with the FFI functions #[inline] pub fn as_mut_ptr(&mut self) -> *mut u8 { - let &Signature(_, ref mut data) = self; + let &mut Signature(_, ref mut data) = self; data.as_mut_slice().as_mut_ptr() } @@ -91,7 +92,7 @@ impl Signature { /// Returns the length of the signature #[inline] - pub fn len(&self) -> uint { + pub fn len(&self) -> usize { let &Signature(len, _) = self; len } @@ -100,7 +101,7 @@ impl Signature { #[inline] pub fn from_slice(data: &[u8]) -> Result { if data.len() <= constants::MAX_SIGNATURE_SIZE { - let mut ret = [0, ..constants::MAX_SIGNATURE_SIZE]; + let mut ret = [0; constants::MAX_SIGNATURE_SIZE]; unsafe { copy_nonoverlapping_memory(ret.as_mut_ptr(), data.as_ptr(), @@ -108,13 +109,13 @@ impl Signature { } Ok(Signature(data.len(), ret)) } else { - Err(InvalidSignature) + Err(Error::InvalidSignature) } } } /// An ECDSA error -#[deriving(PartialEq, Eq, Clone, Show)] +#[derive(PartialEq, Eq, Clone, Show)] pub enum Error { /// Signature failed verification IncorrectSignature, @@ -129,11 +130,12 @@ pub enum Error { /// Boolean-returning function returned the wrong boolean Unknown } +impl Copy for Error {} /// Result type -pub type Result = ::std::prelude::Result; +pub type Result = ::std::result::Result; -static mut Secp256k1_init : Once = ONCE_INIT; +static mut Secp256k1_init: Once = ONCE_INIT; /// The secp256k1 engine, used to execute all signature operations pub struct Secp256k1 { @@ -147,7 +149,7 @@ pub struct Secp256k1 { /// `key::PublicKey::from_secret_key`. pub fn init() { unsafe { - Secp256k1_init.doit(|| { + Secp256k1_init.call_once(|| { ffi::secp256k1_start(); }); } @@ -158,7 +160,7 @@ impl Secp256k1 { pub fn new() -> IoResult { init(); let mut osrng = try!(OsRng::new()); - let mut seed = [0, ..2048]; + let mut seed = [0; 2048]; osrng.fill_bytes(seed.as_mut_slice()); Ok(Secp256k1 { rng: SeedableRng::from_seed(seed.as_slice()) }) } @@ -170,7 +172,8 @@ impl Secp256k1 { pub fn generate_keypair(&mut self, compressed: bool) -> (key::SecretKey, key::PublicKey) { let sk = key::SecretKey::new(&mut self.rng); - (sk, key::PublicKey::from_secret_key(&sk, compressed)) + let pk = key::PublicKey::from_secret_key(&sk, compressed); + (sk, pk) } /// Generates a random nonce. Convenience function for `key::Nonce::new`; call @@ -183,30 +186,30 @@ impl Secp256k1 { /// Constructs a signature for `msg` using the secret key `sk` and nonce `nonce` pub fn sign(&self, msg: &[u8], sk: &key::SecretKey, nonce: &key::Nonce) -> Result { - let mut sig = [0, ..constants::MAX_SIGNATURE_SIZE]; + let mut sig = [0; constants::MAX_SIGNATURE_SIZE]; let mut len = constants::MAX_SIGNATURE_SIZE as c_int; unsafe { if ffi::secp256k1_ecdsa_sign(msg.as_ptr(), msg.len() as c_int, sig.as_mut_slice().as_mut_ptr(), &mut len, sk.as_ptr(), nonce.as_ptr()) != 1 { - return Err(InvalidNonce); + return Err(Error::InvalidNonce); } // This assertation is probably too late :) - assert!(len as uint <= constants::MAX_SIGNATURE_SIZE); + assert!(len as usize <= constants::MAX_SIGNATURE_SIZE); }; - Ok(Signature(len as uint, sig)) + Ok(Signature(len as usize, sig)) } /// Constructs a compact signature for `msg` using the secret key `sk` pub fn sign_compact(&self, msg: &[u8], sk: &key::SecretKey, nonce: &key::Nonce) -> Result<(Signature, RecoveryId)> { - let mut sig = [0, ..constants::MAX_SIGNATURE_SIZE]; + let mut sig = [0; constants::MAX_SIGNATURE_SIZE]; let mut recid = 0; unsafe { if ffi::secp256k1_ecdsa_sign_compact(msg.as_ptr(), msg.len() as c_int, sig.as_mut_slice().as_mut_ptr(), sk.as_ptr(), nonce.as_ptr(), &mut recid) != 1 { - return Err(InvalidNonce); + return Err(Error::InvalidNonce); } }; Ok((Signature(constants::MAX_COMPACT_SIGNATURE_SIZE, sig), RecoveryId(recid))) @@ -226,9 +229,9 @@ impl Secp256k1 { sig.as_ptr(), pk.as_mut_ptr(), &mut len, if compressed {1} else {0}, recid) != 1 { - return Err(InvalidSignature); + return Err(Error::InvalidSignature); } - assert_eq!(len as uint, pk.len()); + assert_eq!(len as usize, pk.len()); }; Ok(pk) } @@ -256,9 +259,9 @@ impl Secp256k1 { match res { 1 => Ok(()), - 0 => Err(IncorrectSignature), - -1 => Err(InvalidPublicKey), - -2 => Err(InvalidSignature), + 0 => Err(Error::IncorrectSignature), + -1 => Err(Error::InvalidPublicKey), + -2 => Err(Error::InvalidSignature), _ => unreachable!() } } @@ -267,6 +270,7 @@ impl Secp256k1 { #[cfg(test)] mod tests { + use std::iter::repeat; use std::rand; use std::rand::Rng; @@ -274,15 +278,15 @@ mod tests { use key::{PublicKey, Nonce}; use super::{Secp256k1, Signature}; - use super::{InvalidPublicKey, IncorrectSignature, InvalidSignature}; + use super::Error::{InvalidPublicKey, IncorrectSignature, InvalidSignature}; #[test] fn invalid_pubkey() { - let mut msg = Vec::from_elem(32, 0u8); - let sig = Signature::from_slice([0, ..72]).unwrap(); + let mut msg: Vec = repeat(0).take(32).collect(); + let sig = Signature::from_slice(&[0; 72]).unwrap(); let pk = PublicKey::new(true); - rand::task_rng().fill_bytes(msg.as_mut_slice()); + rand::thread_rng().fill_bytes(msg.as_mut_slice()); assert_eq!(Secp256k1::verify(msg.as_mut_slice(), &sig, &pk), Err(InvalidPublicKey)); } @@ -293,10 +297,10 @@ mod tests { let (_, pk) = s.generate_keypair(false); - let mut msg = Vec::from_elem(32, 0u8); - let sig = Signature::from_slice([0, ..72]).unwrap(); + let mut msg: Vec = repeat(0).take(32).collect(); + let sig = Signature::from_slice(&[0; 72]).unwrap(); - rand::task_rng().fill_bytes(msg.as_mut_slice()); + rand::thread_rng().fill_bytes(msg.as_mut_slice()); assert_eq!(Secp256k1::verify(msg.as_mut_slice(), &sig, &pk), Err(InvalidSignature)); } @@ -306,10 +310,10 @@ mod tests { let mut s = Secp256k1::new().unwrap(); let (_, pk) = s.generate_keypair(true); - let mut msg = Vec::from_elem(32, 0u8); - let sig = Signature::from_slice([0, ..72]).unwrap(); + let mut msg: Vec = repeat(0).take(32).collect(); + let sig = Signature::from_slice(&[0; 72]).unwrap(); - rand::task_rng().fill_bytes(msg.as_mut_slice()); + rand::thread_rng().fill_bytes(msg.as_mut_slice()); assert_eq!(Secp256k1::verify(msg.as_mut_slice(), &sig, &pk), Err(InvalidSignature)); } @@ -318,8 +322,8 @@ mod tests { fn sign() { let mut s = Secp256k1::new().unwrap(); - let mut msg = [0u8, ..32]; - rand::task_rng().fill_bytes(msg); + let mut msg = [0u8; 32]; + rand::thread_rng().fill_bytes(&mut msg); let (sk, _) = s.generate_keypair(false); let nonce = s.generate_nonce(); @@ -331,8 +335,8 @@ mod tests { fn sign_and_verify() { let mut s = Secp256k1::new().unwrap(); - let mut msg = Vec::from_elem(32, 0u8); - rand::task_rng().fill_bytes(msg.as_mut_slice()); + let mut msg: Vec = repeat(0).take(32).collect(); + rand::thread_rng().fill_bytes(msg.as_mut_slice()); let (sk, pk) = s.generate_keypair(false); let nonce = s.generate_nonce(); @@ -346,15 +350,15 @@ mod tests { fn sign_and_verify_fail() { let mut s = Secp256k1::new().unwrap(); - let mut msg = Vec::from_elem(32, 0u8); - rand::task_rng().fill_bytes(msg.as_mut_slice()); + let mut msg: Vec = repeat(0).take(32).collect(); + rand::thread_rng().fill_bytes(msg.as_mut_slice()); let (sk, pk) = s.generate_keypair(false); let nonce = s.generate_nonce(); let sig = s.sign(msg.as_slice(), &sk, &nonce).unwrap(); - rand::task_rng().fill_bytes(msg.as_mut_slice()); + rand::thread_rng().fill_bytes(msg.as_mut_slice()); assert_eq!(Secp256k1::verify(msg.as_slice(), &sig, &pk), Err(IncorrectSignature)); } @@ -362,8 +366,8 @@ mod tests { fn sign_compact_with_recovery() { let mut s = Secp256k1::new().unwrap(); - let mut msg = [0u8, ..32]; - rand::task_rng().fill_bytes(msg.as_mut_slice()); + let mut msg = [0u8; 32]; + rand::thread_rng().fill_bytes(msg.as_mut_slice()); let (sk, pk) = s.generate_keypair(false); let nonce = s.generate_nonce(); @@ -375,12 +379,12 @@ mod tests { #[test] fn deterministic_sign() { - let mut msg = [0u8, ..32]; - rand::task_rng().fill_bytes(msg.as_mut_slice()); + let mut msg = [0u8; 32]; + rand::thread_rng().fill_bytes(msg.as_mut_slice()); let mut s = Secp256k1::new().unwrap(); let (sk, pk) = s.generate_keypair(true); - let nonce = Nonce::deterministic(msg, &sk); + let nonce = Nonce::deterministic(&mut msg, &sk); let sig = s.sign(msg.as_slice(), &sk, &nonce).unwrap();