More slicing

This commit is contained in:
Andrew Poelstra 2015-03-25 20:52:09 -05:00
parent ec6aea7ca1
commit 42dfa752ce
2 changed files with 53 additions and 22 deletions

View File

@ -16,9 +16,7 @@
//! Public/Private keys //! Public/Private keys
use std::intrinsics::copy_nonoverlapping; use std::intrinsics::copy_nonoverlapping;
use std::cmp; use std::{cmp, fmt, ops};
use std::fmt;
use std::ops;
use rand::Rng; use rand::Rng;
use serialize::{Decoder, Decodable, Encoder, Encodable}; use serialize::{Decoder, Decodable, Encoder, Encodable};
@ -534,7 +532,7 @@ impl fmt::Debug for SecretKey {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use serialize::hex::FromHex; use serialize::hex::FromHex;
use std::rand::thread_rng; use rand::thread_rng;
use test::Bencher; use test::Bencher;
@ -579,19 +577,19 @@ mod test {
let mut s = Secp256k1::new().unwrap(); let mut s = Secp256k1::new().unwrap();
let (sk1, pk1) = s.generate_keypair(true); let (sk1, pk1) = s.generate_keypair(true);
assert_eq!(SecretKey::from_slice(sk1.as_slice()), Ok(sk1)); assert_eq!(SecretKey::from_slice(&sk1[..]), Ok(sk1));
assert_eq!(PublicKey::from_slice(pk1.as_slice()), Ok(pk1)); assert_eq!(PublicKey::from_slice(&pk1[..]), Ok(pk1));
let (sk2, pk2) = s.generate_keypair(false); let (sk2, pk2) = s.generate_keypair(false);
assert_eq!(SecretKey::from_slice(sk2.as_slice()), Ok(sk2)); assert_eq!(SecretKey::from_slice(&sk2[..]), Ok(sk2));
assert_eq!(PublicKey::from_slice(pk2.as_slice()), Ok(pk2)); assert_eq!(PublicKey::from_slice(&pk2[..]), Ok(pk2));
} }
#[test] #[test]
fn nonce_slice_round_trip() { fn nonce_slice_round_trip() {
let mut rng = thread_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[..]), Ok(nonce));
} }
#[test] #[test]
@ -642,12 +640,12 @@ mod test {
// "%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[..],
hex_slice!("d954eddd184cac2b60edcd0e6be9ec54d93f633b28b366420d38ed9c346ffe27")); hex_slice!("d954eddd184cac2b60edcd0e6be9ec54d93f633b28b366420d38ed9c346ffe27"));
// "%x" % rfc6979.generate_k(SECP256k1.generator, sk, hashlib.sha512, hashlib.sha512('test').digest()) // "%x" % rfc6979.generate_k(SECP256k1.generator, sk, hashlib.sha512, hashlib.sha512('test').digest())
let nonce = Nonce::deterministic(b"test", &sk); let nonce = Nonce::deterministic(b"test", &sk);
assert_eq!(nonce.as_slice(), assert_eq!(&nonce[..],
hex_slice!("609cc24acce2f19e46e38a82afc56c1745dee16e04f2b27e24999e1fefeb08bd")); hex_slice!("609cc24acce2f19e46e38a82afc56c1745dee16e04f2b27e24999e1fefeb08bd"));
// # Decrease the secret key by one // # Decrease the secret key by one
@ -656,12 +654,12 @@ mod test {
// "%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[..],
hex_slice!("9f45f8d0a28e8956673c8da6db3db86ca4f172f0a2dbd62364fdbf786c7d96df")); hex_slice!("9f45f8d0a28e8956673c8da6db3db86ca4f172f0a2dbd62364fdbf786c7d96df"));
// "%x" % rfc6979.generate_k(SECP256k1.generator, sk, hashlib.sha512, hashlib.sha512('test').digest()) // "%x" % rfc6979.generate_k(SECP256k1.generator, sk, hashlib.sha512, hashlib.sha512('test').digest())
let nonce = Nonce::deterministic(b"test", &sk); let nonce = Nonce::deterministic(b"test", &sk);
assert_eq!(nonce.as_slice(), assert_eq!(&nonce[..],
hex_slice!("355c589ff662c838aee454d62b12c50a87b7e95ede2431c7cfa40b6ba2fddccd")); hex_slice!("355c589ff662c838aee454d62b12c50a87b7e95ede2431c7cfa40b6ba2fddccd"));
} }

View File

@ -43,7 +43,7 @@ extern crate libc;
extern crate rand; extern crate rand;
use std::intrinsics::copy_nonoverlapping; use std::intrinsics::copy_nonoverlapping;
use std::io; use std::{io, ops};
use std::sync::{Once, ONCE_INIT}; use std::sync::{Once, ONCE_INIT};
use libc::c_int; use libc::c_int;
use rand::{OsRng, Rng, SeedableRng}; use rand::{OsRng, Rng, SeedableRng};
@ -84,13 +84,6 @@ impl Signature {
data.as_mut_ptr() data.as_mut_ptr()
} }
/// Converts the signature to a byte slice suitable for verification
#[inline]
pub fn as_slice<'a>(&'a self) -> &'a [u8] {
let &Signature(len, ref data) = self;
&data[..len]
}
/// Returns the length of the signature /// Returns the length of the signature
#[inline] #[inline]
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
@ -115,6 +108,46 @@ impl Signature {
} }
} }
impl ops::Index<usize> for Signature {
type Output = u8;
#[inline]
fn index(&self, index: usize) -> &u8 {
let &Signature(_, ref dat) = self;
&dat[index]
}
}
impl ops::Index<ops::Range<usize>> for Signature {
type Output = [u8];
#[inline]
fn index(&self, index: ops::Range<usize>) -> &[u8] {
let &Signature(_, ref dat) = self;
&dat[index.start..index.end]
}
}
impl ops::Index<ops::RangeFrom<usize>> for Signature {
type Output = [u8];
#[inline]
fn index(&self, index: ops::RangeFrom<usize>) -> &[u8] {
let &Signature(_, ref dat) = self;
&dat[index.start..]
}
}
impl ops::Index<ops::RangeFull> for Signature {
type Output = [u8];
#[inline]
fn index(&self, _: ops::RangeFull) -> &[u8] {
let &Signature(_, ref dat) = self;
&dat[..]
}
}
/// An ECDSA error /// An ECDSA error
#[derive(PartialEq, Eq, Clone, Debug)] #[derive(PartialEq, Eq, Clone, Debug)]
pub enum Error { pub enum Error {
@ -245,7 +278,7 @@ impl Secp256k1 {
/// Use `verify_raw` instead. /// Use `verify_raw` instead.
#[inline] #[inline]
pub fn verify(msg: &[u8], sig: &Signature, pk: &key::PublicKey) -> Result<()> { pub fn verify(msg: &[u8], sig: &Signature, pk: &key::PublicKey) -> Result<()> {
Secp256k1::verify_raw(msg, sig.as_slice(), pk) Secp256k1::verify_raw(msg, &sig[..], pk)
} }
/// Checks that `sig` is a valid ECDSA signature for `msg` using the public /// Checks that `sig` is a valid ECDSA signature for `msg` using the public