Update for rustc changes

We can compile now, but not link -- there have been too many changes
in libsecp256k1 behind the scenes. Next commit :)
This commit is contained in:
Andrew Poelstra 2015-01-17 10:13:45 -06:00
parent 9cab4e023d
commit d495d9ca06
4 changed files with 176 additions and 161 deletions

View File

@ -16,25 +16,25 @@
//! Constants //! Constants
/// The size (in bytes) of a nonce /// 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 /// 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 /// 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 /// 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 /// 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 /// 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 /// 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, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b,
@ -42,7 +42,7 @@ pub static CURVE_ORDER: [u8, ..32] = [
]; ];
/// The X coordinate of the generator /// 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, 0x79, 0xbe, 0x66, 0x7e, 0xf9, 0xdc, 0xbb, 0xac,
0x55, 0xa0, 0x62, 0x95, 0xce, 0x87, 0x0b, 0x07, 0x55, 0xa0, 0x62, 0x95, 0xce, 0x87, 0x0b, 0x07,
0x02, 0x9b, 0xfc, 0xdb, 0x2d, 0xce, 0x28, 0xd9, 0x02, 0x9b, 0xfc, 0xdb, 0x2d, 0xce, 0x28, 0xd9,
@ -50,7 +50,7 @@ pub static GENERATOR_X: [u8, ..32] = [
]; ];
/// The Y coordinate of the generator /// 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, 0x48, 0x3a, 0xda, 0x77, 0x26, 0xa3, 0xc4, 0x65,
0x5d, 0xa4, 0xfb, 0xfc, 0x0e, 0x11, 0x08, 0xa8, 0x5d, 0xa4, 0xfb, 0xfc, 0x0e, 0x11, 0x08, 0xa8,
0xfd, 0x17, 0xb4, 0x48, 0xa6, 0x85, 0x54, 0x19, 0xfd, 0x17, 0xb4, 0x48, 0xa6, 0x85, 0x54, 0x19,

View File

@ -27,17 +27,18 @@ use crypto::hmac::Hmac;
use crypto::mac::Mac; use crypto::mac::Mac;
use super::init; use super::init;
use super::{Result, InvalidNonce, InvalidPublicKey, InvalidSecretKey, Unknown}; use super::Result;
use super::Error::{InvalidNonce, InvalidPublicKey, InvalidSecretKey, Unknown};
use constants; use constants;
use ffi; use ffi;
/// Secret 256-bit nonce used as `k` in an ECDSA signature /// Secret 256-bit nonce used as `k` in an ECDSA signature
pub struct Nonce([u8, ..constants::NONCE_SIZE]); pub struct Nonce([u8; constants::NONCE_SIZE]);
impl_array_newtype!(Nonce, u8, constants::NONCE_SIZE) impl_array_newtype!(Nonce, u8, constants::NONCE_SIZE);
/// Secret 256-bit key used as `x` in an ECDSA signature /// Secret 256-bit key used as `x` in an ECDSA signature
pub struct SecretKey([u8, ..constants::SECRET_KEY_SIZE]); pub struct SecretKey([u8; constants::SECRET_KEY_SIZE]);
impl_array_newtype!(SecretKey, u8, constants::SECRET_KEY_SIZE) impl_array_newtype!(SecretKey, u8, constants::SECRET_KEY_SIZE);
/// The number 1 encoded as a secret key /// The number 1 encoded as a secret key
pub static ONE: SecretKey = SecretKey([0, 0, 0, 0, 0, 0, 0, 0, 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]); 0, 0, 0, 0, 0, 0, 0, 1]);
/// Public key /// Public key
#[deriving(Clone, PartialEq, Eq, Show)] #[derive(Clone, PartialEq, Eq, Show)]
pub struct PublicKey(PublicKeyData); pub struct PublicKey(PublicKeyData);
impl Copy for PublicKey {}
enum PublicKeyData { enum PublicKeyData {
Compressed([u8, ..constants::COMPRESSED_PUBLIC_KEY_SIZE]), Compressed([u8; constants::COMPRESSED_PUBLIC_KEY_SIZE]),
Uncompressed([u8, ..constants::UNCOMPRESSED_PUBLIC_KEY_SIZE]), Uncompressed([u8; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE])
} }
impl Copy for PublicKeyData {}
fn random_32_bytes<R:Rng>(rng: &mut R) -> [u8, ..32] { fn random_32_bytes<R:Rng>(rng: &mut R) -> [u8; 32] {
let mut ret = [0u8, ..32]; let mut ret = [0u8; 32];
rng.fill_bytes(ret); rng.fill_bytes(&mut ret);
ret ret
} }
/// As described in RFC 6979 /// As described in RFC 6979
fn bits2octets(data: &[u8]) -> [u8, ..32] { fn bits2octets(data: &[u8]) -> [u8; 32] {
let mut ret = [0, ..32]; let mut ret = [0; 32];
unsafe { unsafe {
copy_nonoverlapping_memory(ret.as_mut_ptr(), copy_nonoverlapping_memory(ret.as_mut_ptr(),
data.as_ptr(), data.as_ptr(),
@ -83,7 +86,7 @@ impl Nonce {
pub fn from_slice(data: &[u8]) -> Result<Nonce> { pub fn from_slice(data: &[u8]) -> Result<Nonce> {
match data.len() { match data.len() {
constants::NONCE_SIZE => { constants::NONCE_SIZE => {
let mut ret = [0, ..constants::NONCE_SIZE]; let mut ret = [0; constants::NONCE_SIZE];
unsafe { unsafe {
copy_nonoverlapping_memory(ret.as_mut_ptr(), copy_nonoverlapping_memory(ret.as_mut_ptr(),
data.as_ptr(), data.as_ptr(),
@ -99,54 +102,54 @@ impl Nonce {
#[inline] #[inline]
#[allow(non_snake_case)] // so we can match the names in the RFC #[allow(non_snake_case)] // so we can match the names in the RFC
pub fn deterministic(msg: &[u8], key: &SecretKey) -> Nonce { pub fn deterministic(msg: &[u8], key: &SecretKey) -> Nonce {
static HMAC_SIZE: uint = 64; const HMAC_SIZE: usize = 64;
macro_rules! hmac( macro_rules! hmac {
($res:expr <- key $key:expr, data $($data:expr),+) => ({ ($res:expr; key $key:expr, data $($data:expr),+) => ({
let mut hmacker = Hmac::new(Sha512::new(), $key.as_slice()); let mut hmacker = Hmac::new(Sha512::new(), $key.as_slice());
$(hmacker.input($data.as_slice());)+ $(hmacker.input($data.as_slice());)+
hmacker.raw_result($res.as_mut_slice()); hmacker.raw_result($res.as_mut_slice());
}) })
) }
// Section 3.2a // Section 3.2a
// Goofy block just to avoid marking `msg_hash` as mutable // Goofy block just to avoid marking `msg_hash` as mutable
let mut hasher = Sha512::new(); let mut hasher = Sha512::new();
hasher.input(msg); hasher.input(msg);
let mut x = [0, ..HMAC_SIZE]; let mut x = [0; HMAC_SIZE];
hasher.result(x.as_mut_slice()); hasher.result(x.as_mut_slice());
let msg_hash = bits2octets(x.as_slice()); let msg_hash = bits2octets(x.as_slice());
// Section 3.2b // Section 3.2b
let mut V = [0x01u8, ..HMAC_SIZE]; let mut V = [0x01u8; HMAC_SIZE];
// Section 3.2c // Section 3.2c
let mut K = [0x00u8, ..HMAC_SIZE]; let mut K = [0x00u8; HMAC_SIZE];
// Section 3.2d // 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 // Section 3.2e
hmac!(V <- key K, data V) hmac!(V; key K, data V);
// Section 3.2f // 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 // Section 3.2g
hmac!(V <- key K, data V) hmac!(V; key K, data V);
// Section 3.2 // Section 3.2
let mut k = Err(InvalidSecretKey); let mut k = Err(InvalidSecretKey);
while k.is_err() { while k.is_err() {
// Try to generate the nonce // Try to generate the nonce
let mut T = [0x00u8, ..HMAC_SIZE]; let mut T = [0x00u8; HMAC_SIZE];
hmac!(T <- key K, data V) hmac!(T; key K, data V);
k = Nonce::from_slice(T.slice_to(constants::NONCE_SIZE)); k = Nonce::from_slice(T.slice_to(constants::NONCE_SIZE));
// Replace K, V // Replace K, V
if k.is_err() { if k.is_err() {
hmac!(K <- key K, data V, [0x00]) hmac!(K; key K, data V, [0x00]);
hmac!(V <- key K, data V) hmac!(V; key K, data V);
} }
} }
@ -174,7 +177,7 @@ impl SecretKey {
init(); init();
match data.len() { match data.len() {
constants::SECRET_KEY_SIZE => { constants::SECRET_KEY_SIZE => {
let mut ret = [0, ..constants::SECRET_KEY_SIZE]; let mut ret = [0; constants::SECRET_KEY_SIZE];
unsafe { unsafe {
if ffi::secp256k1_ecdsa_seckey_verify(data.as_ptr()) == 0 { if ffi::secp256k1_ecdsa_seckey_verify(data.as_ptr()) == 0 {
return Err(InvalidSecretKey); return Err(InvalidSecretKey);
@ -218,8 +221,11 @@ pub struct Sequence {
compressed: bool, compressed: bool,
last_sk: SecretKey, last_sk: SecretKey,
} }
impl Copy for Sequence {}
impl Iterator for Sequence {
type Item = (SecretKey, PublicKey);
impl<'a> Iterator<(SecretKey, PublicKey)> for Sequence {
#[inline] #[inline]
fn next(&mut self) -> Option<(SecretKey, PublicKey)> { fn next(&mut self) -> Option<(SecretKey, PublicKey)> {
self.last_sk.add_assign(&ONE).unwrap(); self.last_sk.add_assign(&ONE).unwrap();
@ -232,8 +238,11 @@ impl PublicKey {
#[inline] #[inline]
pub fn new(compressed: bool) -> PublicKey { pub fn new(compressed: bool) -> PublicKey {
PublicKey( PublicKey(
if compressed { Compressed([0, ..constants::COMPRESSED_PUBLIC_KEY_SIZE]) } if compressed {
else { Uncompressed([0, ..constants::UNCOMPRESSED_PUBLIC_KEY_SIZE]) } 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, pk.as_mut_ptr(), &mut len,
sk.as_ptr(), compressed), 1); sk.as_ptr(), compressed), 1);
} }
assert_eq!(len as uint, pk.len()); assert_eq!(len as usize, pk.len());
pk pk
} }
@ -261,7 +270,7 @@ impl PublicKey {
pub fn from_slice(data: &[u8]) -> Result<PublicKey> { pub fn from_slice(data: &[u8]) -> Result<PublicKey> {
match data.len() { match data.len() {
constants::COMPRESSED_PUBLIC_KEY_SIZE => { constants::COMPRESSED_PUBLIC_KEY_SIZE => {
let mut ret = [0, ..constants::COMPRESSED_PUBLIC_KEY_SIZE]; let mut ret = [0; constants::COMPRESSED_PUBLIC_KEY_SIZE];
unsafe { unsafe {
if ffi::secp256k1_ecdsa_pubkey_verify(data.as_ptr(), if ffi::secp256k1_ecdsa_pubkey_verify(data.as_ptr(),
data.len() as ::libc::c_int) == 0 { data.len() as ::libc::c_int) == 0 {
@ -271,16 +280,16 @@ impl PublicKey {
data.as_ptr(), data.as_ptr(),
data.len()); data.len());
} }
Ok(PublicKey(Compressed(ret))) Ok(PublicKey(PublicKeyData::Compressed(ret)))
} }
constants::UNCOMPRESSED_PUBLIC_KEY_SIZE => { constants::UNCOMPRESSED_PUBLIC_KEY_SIZE => {
let mut ret = [0, ..constants::UNCOMPRESSED_PUBLIC_KEY_SIZE]; let mut ret = [0; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE];
unsafe { unsafe {
copy_nonoverlapping_memory(ret.as_mut_ptr(), copy_nonoverlapping_memory(ret.as_mut_ptr(),
data.as_ptr(), data.as_ptr(),
data.len()); data.len());
} }
Ok(PublicKey(Uncompressed(ret))) Ok(PublicKey(PublicKeyData::Uncompressed(ret)))
} }
_ => Err(InvalidPublicKey) _ => Err(InvalidPublicKey)
} }
@ -291,18 +300,18 @@ impl PublicKey {
pub fn is_compressed(&self) -> bool { pub fn is_compressed(&self) -> bool {
let &PublicKey(ref data) = self; let &PublicKey(ref data) = self;
match *data { match *data {
Compressed(_) => true, PublicKeyData::Compressed(_) => true,
Uncompressed(_) => false PublicKeyData::Uncompressed(_) => false
} }
} }
/// Returns the length of the public key /// Returns the length of the public key
#[inline] #[inline]
pub fn len(&self) -> uint { pub fn len(&self) -> usize {
let &PublicKey(ref data) = self; let &PublicKey(ref data) = self;
match *data { match *data {
Compressed(ref x) => x.len(), PublicKeyData::Compressed(ref x) => x.len(),
Uncompressed(ref x) => x.len() PublicKeyData::Uncompressed(ref x) => x.len()
} }
} }
@ -319,8 +328,8 @@ impl PublicKey {
pub fn as_ptr(&self) -> *const u8 { pub fn as_ptr(&self) -> *const u8 {
let &PublicKey(ref data) = self; let &PublicKey(ref data) = self;
match *data { match *data {
Compressed(ref x) => x.as_ptr(), PublicKeyData::Compressed(ref x) => x.as_ptr(),
Uncompressed(ref x) => x.as_ptr() PublicKeyData::Uncompressed(ref x) => x.as_ptr()
} }
} }
@ -328,10 +337,10 @@ impl PublicKey {
/// with the FFI functions /// with the FFI functions
#[inline] #[inline]
pub fn as_mut_ptr(&mut self) -> *mut u8 { pub fn as_mut_ptr(&mut self) -> *mut u8 {
let &PublicKey(ref mut data) = self; let &mut PublicKey(ref mut data) = self;
match *data { match *data {
Compressed(ref mut x) => x.as_mut_ptr(), PublicKeyData::Compressed(ref mut x) => x.as_mut_ptr(),
Uncompressed(ref mut x) => x.as_mut_ptr() PublicKeyData::Uncompressed(ref mut x) => x.as_mut_ptr()
} }
} }
@ -355,8 +364,8 @@ impl PublicKeyData {
#[inline] #[inline]
fn as_slice<'a>(&'a self) -> &'a [u8] { fn as_slice<'a>(&'a self) -> &'a [u8] {
match *self { match *self {
Compressed(ref x) => x.as_slice(), PublicKeyData::Compressed(ref x) => x.as_slice(),
Uncompressed(ref x) => x.as_slice() PublicKeyData::Uncompressed(ref x) => x.as_slice()
} }
} }
} }
@ -387,26 +396,26 @@ impl fmt::Show for PublicKeyData {
} }
} }
impl<D: Decoder<E>, E> Decodable<D, E> for PublicKey { impl Decodable for PublicKey {
fn decode(d: &mut D) -> ::std::prelude::Result<PublicKey, E> { fn decode<D: Decoder>(d: &mut D) -> ::std::result::Result<PublicKey, D::Error> {
d.read_seq(|d, len| { d.read_seq(|d, len| {
if len == constants::UNCOMPRESSED_PUBLIC_KEY_SIZE { if len == constants::UNCOMPRESSED_PUBLIC_KEY_SIZE {
unsafe { unsafe {
use std::mem; 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) { for i in range(0, len) {
ret[i] = try!(d.read_seq_elt(i, |d| Decodable::decode(d))); 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 { } else if len == constants::COMPRESSED_PUBLIC_KEY_SIZE {
unsafe { unsafe {
use std::mem; 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) { for i in range(0, len) {
ret[i] = try!(d.read_seq_elt(i, |d| Decodable::decode(d))); ret[i] = try!(d.read_seq_elt(i, |d| Decodable::decode(d)));
} }
Ok(PublicKey(Compressed(ret))) Ok(PublicKey(PublicKeyData::Compressed(ret)))
} }
} else { } else {
Err(d.error("Invalid length")) Err(d.error("Invalid length"))
@ -415,9 +424,9 @@ impl<D: Decoder<E>, E> Decodable<D, E> for PublicKey {
} }
} }
impl <E: Encoder<S>, S> Encodable<E, S> for PublicKey { impl Encodable for PublicKey {
fn encode(&self, e: &mut E) -> ::std::prelude::Result<(), S> { fn encode<S: Encoder>(&self, s: &mut S) -> ::std::result::Result<(), S::Error> {
self.as_slice().encode(e) self.as_slice().encode(s)
} }
} }
@ -430,41 +439,42 @@ impl fmt::Show for SecretKey {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use serialize::hex::FromHex; use serialize::hex::FromHex;
use std::rand::task_rng; use std::rand::thread_rng;
use test::Bencher; 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}; use super::{Nonce, PublicKey, SecretKey};
#[test] #[test]
fn nonce_from_slice() { fn nonce_from_slice() {
let n = Nonce::from_slice([1, ..31]); let n = Nonce::from_slice(&[1; 31]);
assert_eq!(n, Err(InvalidNonce)); assert_eq!(n, Err(InvalidNonce));
let n = SecretKey::from_slice([1, ..32]); let n = SecretKey::from_slice(&[1; 32]);
assert!(n.is_ok()); assert!(n.is_ok());
} }
#[test] #[test]
fn skey_from_slice() { fn skey_from_slice() {
let sk = SecretKey::from_slice([1, ..31]); let sk = SecretKey::from_slice(&[1; 31]);
assert_eq!(sk, Err(InvalidSecretKey)); assert_eq!(sk, Err(InvalidSecretKey));
let sk = SecretKey::from_slice([1, ..32]); let sk = SecretKey::from_slice(&[1; 32]);
assert!(sk.is_ok()); assert!(sk.is_ok());
} }
#[test] #[test]
fn pubkey_from_slice() { fn pubkey_from_slice() {
assert_eq!(PublicKey::from_slice([]), Err(InvalidPublicKey)); assert_eq!(PublicKey::from_slice(&[]), Err(InvalidPublicKey));
assert_eq!(PublicKey::from_slice([1, 2, 3]), 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.is_ok());
assert!(!uncompressed.unwrap().is_compressed()); 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.is_ok());
assert!(compressed.unwrap().is_compressed()); assert!(compressed.unwrap().is_compressed());
} }
@ -484,7 +494,7 @@ mod test {
#[test] #[test]
fn nonce_slice_round_trip() { fn nonce_slice_round_trip() {
let mut rng = task_rng(); let mut rng = thread_rng();
let nonce = Nonce::new(&mut rng); let nonce = Nonce::new(&mut rng);
assert_eq!(Nonce::from_slice(nonce.as_slice()), Ok(nonce)); assert_eq!(Nonce::from_slice(nonce.as_slice()), Ok(nonce));
} }
@ -492,19 +502,19 @@ mod test {
#[test] #[test]
fn invalid_secret_key() { fn invalid_secret_key() {
// Zero // Zero
assert_eq!(SecretKey::from_slice([0, ..32]), Err(InvalidSecretKey)); assert_eq!(SecretKey::from_slice(&[0; 32]), Err(InvalidSecretKey));
// -1 // -1
assert_eq!(SecretKey::from_slice([0xff, ..32]), Err(InvalidSecretKey)); assert_eq!(SecretKey::from_slice(&[0xff; 32]), Err(InvalidSecretKey));
// Top of range // Top of range
assert!(SecretKey::from_slice([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, assert!(SecretKey::from_slice(&[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B,
0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x40]).is_ok()); 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x40]).is_ok());
// One past top of range // One past top of range
assert!(SecretKey::from_slice([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, assert!(SecretKey::from_slice(&[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B,
0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41]).is_err()); 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41]).is_err());
} }
#[test] #[test]
@ -536,7 +546,7 @@ mod test {
let sk = SecretKey::from_slice(hex_slice!("09e918bbea76205445e9a73eaad2080a135d1e33e9dd1b3ca8a9a1285e7c1f81")).unwrap(); let sk = SecretKey::from_slice(hex_slice!("09e918bbea76205445e9a73eaad2080a135d1e33e9dd1b3ca8a9a1285e7c1f81")).unwrap();
// "%x" % rfc6979.generate_k(SECP256k1.generator, sk, hashlib.sha512, hashlib.sha512('').digest()) // "%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(), assert_eq!(nonce.as_slice(),
hex_slice!("d954eddd184cac2b60edcd0e6be9ec54d93f633b28b366420d38ed9c346ffe27")); hex_slice!("d954eddd184cac2b60edcd0e6be9ec54d93f633b28b366420d38ed9c346ffe27"));
@ -550,7 +560,7 @@ mod test {
let sk = SecretKey::from_slice(hex_slice!("09e918bbea76205445e9a73eaad2080a135d1e33e9dd1b3ca8a9a1285e7c1f80")).unwrap(); let sk = SecretKey::from_slice(hex_slice!("09e918bbea76205445e9a73eaad2080a135d1e33e9dd1b3ca8a9a1285e7c1f80")).unwrap();
// "%x" % rfc6979.generate_k(SECP256k1.generator, sk, hashlib.sha512, hashlib.sha512('').digest()) // "%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(), assert_eq!(nonce.as_slice(),
hex_slice!("9f45f8d0a28e8956673c8da6db3db86ca4f172f0a2dbd62364fdbf786c7d96df")); hex_slice!("9f45f8d0a28e8956673c8da6db3db86ca4f172f0a2dbd62364fdbf786c7d96df"));

View File

@ -13,11 +13,11 @@
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. // If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
// //
#![macro_escape]
// This is a macro that routinely comes in handy // 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) => { ($thing:ident, $ty:ty, $len:expr) => {
impl Copy for $thing {}
impl $thing { impl $thing {
#[inline] #[inline]
/// Provides an immutable view into the object /// Provides an immutable view into the object
@ -28,21 +28,21 @@ macro_rules! impl_array_newtype(
#[inline] #[inline]
/// Provides an immutable view into the object from index `s` inclusive to `e` exclusive /// 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; let &$thing(ref dat) = self;
dat.slice(s, e) dat.slice(s, e)
} }
#[inline] #[inline]
/// Provides an immutable view into the object, up to index `n` exclusive /// 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; let &$thing(ref dat) = self;
dat.slice_to(n) dat.slice_to(n)
} }
#[inline] #[inline]
/// Provides an immutable view into the object, starting from index `n` /// 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; let &$thing(ref dat) = self;
dat.slice_from(n) dat.slice_from(n)
} }
@ -57,13 +57,13 @@ macro_rules! impl_array_newtype(
#[inline] #[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 { 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() dat.as_mut_ptr()
} }
#[inline] #[inline]
/// Returns the length of the object as an array /// 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 { impl PartialEq for $thing {
@ -90,8 +90,8 @@ macro_rules! impl_array_newtype(
} }
} }
impl<D: ::serialize::Decoder<E>, E> ::serialize::Decodable<D, E> for $thing { impl ::serialize::Decodable for $thing {
fn decode(d: &mut D) -> ::std::prelude::Result<$thing, E> { fn decode<D: ::serialize::Decoder>(d: &mut D) -> ::std::result::Result<$thing, D::Error> {
use serialize::Decodable; use serialize::Decodable;
::assert_type_is_copy::<$ty>(); ::assert_type_is_copy::<$ty>();
@ -102,7 +102,7 @@ macro_rules! impl_array_newtype(
} else { } else {
unsafe { unsafe {
use std::mem; use std::mem;
let mut ret: [$ty, ..$len] = mem::uninitialized(); let mut ret: [$ty; $len] = mem::uninitialized();
for i in range(0, len) { for i in range(0, len) {
ret[i] = try!(d.read_seq_elt(i, |d| Decodable::decode(d))); ret[i] = try!(d.read_seq_elt(i, |d| Decodable::decode(d)));
} }
@ -113,19 +113,20 @@ macro_rules! impl_array_newtype(
} }
} }
impl<E: ::serialize::Encoder<S>, S> ::serialize::Encodable<E, S> for $thing { impl ::serialize::Encodable for $thing {
fn encode(&self, e: &mut E) -> ::std::prelude::Result<(), S> { fn encode<S: ::serialize::Encoder>(&self, s: &mut S)
self.as_slice().encode(e) -> ::std::result::Result<(), S::Error> {
self.as_slice().encode(s)
} }
} }
} }
) }
// for testing // for testing
macro_rules! hex_slice( macro_rules! hex_slice {
($s:expr) => ( ($s:expr) => (
$s.from_hex().unwrap().as_slice() $s.from_hex().unwrap().as_slice()
) )
) }

View File

@ -24,33 +24,32 @@
#![crate_type = "rlib"] #![crate_type = "rlib"]
#![crate_type = "dylib"] #![crate_type = "dylib"]
#![crate_name = "bitcoin-secp256k1-rs"] #![crate_name = "bitcoin-secp256k1-rs"]
#![comment = "Bindings and wrapper functions for bitcoin secp256k1 library."]
#![feature(phase)] // Keep this until 1.0 I guess; it's needed for `black_box` at least
#![feature(macro_rules)] #![allow(unstable)]
#![feature(globs)] // for tests only
// Coding conventions // Coding conventions
#![deny(non_uppercase_statics)] #![deny(non_upper_case_globals)]
#![deny(non_camel_case_types)] #![deny(non_camel_case_types)]
#![deny(non_snake_case)] #![deny(non_snake_case)]
#![deny(unused_mut)] #![deny(unused_mut)]
#![warn(missing_doc)] #![warn(missing_docs)]
extern crate "rust-crypto" as crypto; extern crate crypto;
extern crate libc; extern crate libc;
extern crate serialize; extern crate serialize;
extern crate sync;
extern crate test; extern crate test;
use std::intrinsics::copy_nonoverlapping_memory; use std::intrinsics::copy_nonoverlapping_memory;
use std::io::IoResult; use std::io::IoResult;
use std::rand::{OsRng, Rng, SeedableRng}; use std::rand::{OsRng, Rng, SeedableRng};
use std::sync::{Once, ONCE_INIT};
use libc::c_int; use libc::c_int;
use sync::one::{Once, ONCE_INIT};
use crypto::fortuna::Fortuna; use crypto::fortuna::Fortuna;
#[macro_use]
mod macros; mod macros;
pub mod constants; pub mod constants;
pub mod ffi; pub mod ffi;
@ -61,9 +60,11 @@ fn assert_type_is_copy<T: Copy>() { }
/// A tag used for recovering the public key from a compact signature /// A tag used for recovering the public key from a compact signature
pub struct RecoveryId(i32); pub struct RecoveryId(i32);
impl Copy for RecoveryId {}
/// An ECDSA signature /// 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 { impl Signature {
/// Converts the signature to a raw pointer suitable for use /// Converts the signature to a raw pointer suitable for use
@ -78,7 +79,7 @@ impl Signature {
/// with the FFI functions /// with the FFI functions
#[inline] #[inline]
pub fn as_mut_ptr(&mut self) -> *mut u8 { 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() data.as_mut_slice().as_mut_ptr()
} }
@ -91,7 +92,7 @@ impl Signature {
/// Returns the length of the signature /// Returns the length of the signature
#[inline] #[inline]
pub fn len(&self) -> uint { pub fn len(&self) -> usize {
let &Signature(len, _) = self; let &Signature(len, _) = self;
len len
} }
@ -100,7 +101,7 @@ impl Signature {
#[inline] #[inline]
pub fn from_slice(data: &[u8]) -> Result<Signature> { pub fn from_slice(data: &[u8]) -> Result<Signature> {
if data.len() <= constants::MAX_SIGNATURE_SIZE { if data.len() <= constants::MAX_SIGNATURE_SIZE {
let mut ret = [0, ..constants::MAX_SIGNATURE_SIZE]; let mut ret = [0; constants::MAX_SIGNATURE_SIZE];
unsafe { unsafe {
copy_nonoverlapping_memory(ret.as_mut_ptr(), copy_nonoverlapping_memory(ret.as_mut_ptr(),
data.as_ptr(), data.as_ptr(),
@ -108,13 +109,13 @@ impl Signature {
} }
Ok(Signature(data.len(), ret)) Ok(Signature(data.len(), ret))
} else { } else {
Err(InvalidSignature) Err(Error::InvalidSignature)
} }
} }
} }
/// An ECDSA error /// An ECDSA error
#[deriving(PartialEq, Eq, Clone, Show)] #[derive(PartialEq, Eq, Clone, Show)]
pub enum Error { pub enum Error {
/// Signature failed verification /// Signature failed verification
IncorrectSignature, IncorrectSignature,
@ -129,11 +130,12 @@ pub enum Error {
/// Boolean-returning function returned the wrong boolean /// Boolean-returning function returned the wrong boolean
Unknown Unknown
} }
impl Copy for Error {}
/// Result type /// Result type
pub type Result<T> = ::std::prelude::Result<T, Error>; pub type Result<T> = ::std::result::Result<T, Error>;
static mut Secp256k1_init : Once = ONCE_INIT; static mut Secp256k1_init: Once = ONCE_INIT;
/// The secp256k1 engine, used to execute all signature operations /// The secp256k1 engine, used to execute all signature operations
pub struct Secp256k1 { pub struct Secp256k1 {
@ -147,7 +149,7 @@ pub struct Secp256k1 {
/// `key::PublicKey::from_secret_key`. /// `key::PublicKey::from_secret_key`.
pub fn init() { pub fn init() {
unsafe { unsafe {
Secp256k1_init.doit(|| { Secp256k1_init.call_once(|| {
ffi::secp256k1_start(); ffi::secp256k1_start();
}); });
} }
@ -158,7 +160,7 @@ impl Secp256k1 {
pub fn new() -> IoResult<Secp256k1> { pub fn new() -> IoResult<Secp256k1> {
init(); init();
let mut osrng = try!(OsRng::new()); let mut osrng = try!(OsRng::new());
let mut seed = [0, ..2048]; let mut seed = [0; 2048];
osrng.fill_bytes(seed.as_mut_slice()); osrng.fill_bytes(seed.as_mut_slice());
Ok(Secp256k1 { rng: SeedableRng::from_seed(seed.as_slice()) }) Ok(Secp256k1 { rng: SeedableRng::from_seed(seed.as_slice()) })
} }
@ -170,7 +172,8 @@ impl Secp256k1 {
pub fn generate_keypair(&mut self, compressed: bool) pub fn generate_keypair(&mut self, compressed: bool)
-> (key::SecretKey, key::PublicKey) { -> (key::SecretKey, key::PublicKey) {
let sk = key::SecretKey::new(&mut self.rng); 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 /// 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` /// 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) pub fn sign(&self, msg: &[u8], sk: &key::SecretKey, nonce: &key::Nonce)
-> Result<Signature> { -> Result<Signature> {
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; let mut len = constants::MAX_SIGNATURE_SIZE as c_int;
unsafe { unsafe {
if ffi::secp256k1_ecdsa_sign(msg.as_ptr(), msg.len() as c_int, if ffi::secp256k1_ecdsa_sign(msg.as_ptr(), msg.len() as c_int,
sig.as_mut_slice().as_mut_ptr(), &mut len, sig.as_mut_slice().as_mut_ptr(), &mut len,
sk.as_ptr(), nonce.as_ptr()) != 1 { sk.as_ptr(), nonce.as_ptr()) != 1 {
return Err(InvalidNonce); return Err(Error::InvalidNonce);
} }
// This assertation is probably too late :) // 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` /// Constructs a compact signature for `msg` using the secret key `sk`
pub fn sign_compact(&self, msg: &[u8], sk: &key::SecretKey, nonce: &key::Nonce) pub fn sign_compact(&self, msg: &[u8], sk: &key::SecretKey, nonce: &key::Nonce)
-> Result<(Signature, RecoveryId)> { -> Result<(Signature, RecoveryId)> {
let mut sig = [0, ..constants::MAX_SIGNATURE_SIZE]; let mut sig = [0; constants::MAX_SIGNATURE_SIZE];
let mut recid = 0; let mut recid = 0;
unsafe { unsafe {
if ffi::secp256k1_ecdsa_sign_compact(msg.as_ptr(), msg.len() as c_int, if ffi::secp256k1_ecdsa_sign_compact(msg.as_ptr(), msg.len() as c_int,
sig.as_mut_slice().as_mut_ptr(), sk.as_ptr(), sig.as_mut_slice().as_mut_ptr(), sk.as_ptr(),
nonce.as_ptr(), &mut recid) != 1 { nonce.as_ptr(), &mut recid) != 1 {
return Err(InvalidNonce); return Err(Error::InvalidNonce);
} }
}; };
Ok((Signature(constants::MAX_COMPACT_SIGNATURE_SIZE, sig), RecoveryId(recid))) 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, sig.as_ptr(), pk.as_mut_ptr(), &mut len,
if compressed {1} else {0}, if compressed {1} else {0},
recid) != 1 { 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) Ok(pk)
} }
@ -256,9 +259,9 @@ impl Secp256k1 {
match res { match res {
1 => Ok(()), 1 => Ok(()),
0 => Err(IncorrectSignature), 0 => Err(Error::IncorrectSignature),
-1 => Err(InvalidPublicKey), -1 => Err(Error::InvalidPublicKey),
-2 => Err(InvalidSignature), -2 => Err(Error::InvalidSignature),
_ => unreachable!() _ => unreachable!()
} }
} }
@ -267,6 +270,7 @@ impl Secp256k1 {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::iter::repeat;
use std::rand; use std::rand;
use std::rand::Rng; use std::rand::Rng;
@ -274,15 +278,15 @@ mod tests {
use key::{PublicKey, Nonce}; use key::{PublicKey, Nonce};
use super::{Secp256k1, Signature}; use super::{Secp256k1, Signature};
use super::{InvalidPublicKey, IncorrectSignature, InvalidSignature}; use super::Error::{InvalidPublicKey, IncorrectSignature, InvalidSignature};
#[test] #[test]
fn invalid_pubkey() { fn invalid_pubkey() {
let mut msg = Vec::from_elem(32, 0u8); let mut msg: Vec<u8> = repeat(0).take(32).collect();
let sig = Signature::from_slice([0, ..72]).unwrap(); let sig = Signature::from_slice(&[0; 72]).unwrap();
let pk = PublicKey::new(true); 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)); 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 (_, pk) = s.generate_keypair(false);
let mut msg = Vec::from_elem(32, 0u8); let mut msg: Vec<u8> = repeat(0).take(32).collect();
let sig = Signature::from_slice([0, ..72]).unwrap(); 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)); 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 mut s = Secp256k1::new().unwrap();
let (_, pk) = s.generate_keypair(true); let (_, pk) = s.generate_keypair(true);
let mut msg = Vec::from_elem(32, 0u8); let mut msg: Vec<u8> = repeat(0).take(32).collect();
let sig = Signature::from_slice([0, ..72]).unwrap(); 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)); assert_eq!(Secp256k1::verify(msg.as_mut_slice(), &sig, &pk), Err(InvalidSignature));
} }
@ -318,8 +322,8 @@ mod tests {
fn sign() { fn sign() {
let mut s = Secp256k1::new().unwrap(); let mut s = Secp256k1::new().unwrap();
let mut msg = [0u8, ..32]; let mut msg = [0u8; 32];
rand::task_rng().fill_bytes(msg); rand::thread_rng().fill_bytes(&mut msg);
let (sk, _) = s.generate_keypair(false); let (sk, _) = s.generate_keypair(false);
let nonce = s.generate_nonce(); let nonce = s.generate_nonce();
@ -331,8 +335,8 @@ mod tests {
fn sign_and_verify() { fn sign_and_verify() {
let mut s = Secp256k1::new().unwrap(); let mut s = Secp256k1::new().unwrap();
let mut msg = Vec::from_elem(32, 0u8); let mut msg: Vec<u8> = repeat(0).take(32).collect();
rand::task_rng().fill_bytes(msg.as_mut_slice()); rand::thread_rng().fill_bytes(msg.as_mut_slice());
let (sk, pk) = s.generate_keypair(false); let (sk, pk) = s.generate_keypair(false);
let nonce = s.generate_nonce(); let nonce = s.generate_nonce();
@ -346,15 +350,15 @@ mod tests {
fn sign_and_verify_fail() { fn sign_and_verify_fail() {
let mut s = Secp256k1::new().unwrap(); let mut s = Secp256k1::new().unwrap();
let mut msg = Vec::from_elem(32, 0u8); let mut msg: Vec<u8> = repeat(0).take(32).collect();
rand::task_rng().fill_bytes(msg.as_mut_slice()); rand::thread_rng().fill_bytes(msg.as_mut_slice());
let (sk, pk) = s.generate_keypair(false); let (sk, pk) = s.generate_keypair(false);
let nonce = s.generate_nonce(); let nonce = s.generate_nonce();
let sig = s.sign(msg.as_slice(), &sk, &nonce).unwrap(); 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)); assert_eq!(Secp256k1::verify(msg.as_slice(), &sig, &pk), Err(IncorrectSignature));
} }
@ -362,8 +366,8 @@ mod tests {
fn sign_compact_with_recovery() { fn sign_compact_with_recovery() {
let mut s = Secp256k1::new().unwrap(); let mut s = Secp256k1::new().unwrap();
let mut msg = [0u8, ..32]; let mut msg = [0u8; 32];
rand::task_rng().fill_bytes(msg.as_mut_slice()); rand::thread_rng().fill_bytes(msg.as_mut_slice());
let (sk, pk) = s.generate_keypair(false); let (sk, pk) = s.generate_keypair(false);
let nonce = s.generate_nonce(); let nonce = s.generate_nonce();
@ -375,12 +379,12 @@ mod tests {
#[test] #[test]
fn deterministic_sign() { fn deterministic_sign() {
let mut msg = [0u8, ..32]; let mut msg = [0u8; 32];
rand::task_rng().fill_bytes(msg.as_mut_slice()); rand::thread_rng().fill_bytes(msg.as_mut_slice());
let mut s = Secp256k1::new().unwrap(); let mut s = Secp256k1::new().unwrap();
let (sk, pk) = s.generate_keypair(true); 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(); let sig = s.sign(msg.as_slice(), &sk, &nonce).unwrap();