Slicing fixes

This commit is contained in:
Andrew Poelstra 2015-03-25 20:36:57 -05:00
parent f910355043
commit d858d7f7e6
3 changed files with 178 additions and 61 deletions

View File

@ -18,6 +18,7 @@
use std::intrinsics::copy_nonoverlapping; use std::intrinsics::copy_nonoverlapping;
use std::cmp; use std::cmp;
use std::fmt; use std::fmt;
use std::ops;
use rand::Rng; use rand::Rng;
use serialize::{Decoder, Decodable, Encoder, Encodable}; use serialize::{Decoder, Decodable, Encoder, Encodable};
@ -106,8 +107,8 @@ impl Nonce {
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[..]);
$(hmacker.input($data.as_slice());)+ $(hmacker.input(&$data[..]);)+
hmacker.raw_result($res.as_mut_slice()); hmacker.raw_result($res.as_mut_slice());
}) })
} }
@ -118,7 +119,7 @@ impl Nonce {
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);
// Section 3.2b // Section 3.2b
let mut V = [0x01u8; HMAC_SIZE]; let mut V = [0x01u8; HMAC_SIZE];
@ -144,7 +145,7 @@ impl 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[..constants::NONCE_SIZE]);
// Replace K, V // Replace K, V
if k.is_err() { if k.is_err() {
@ -315,13 +316,6 @@ impl PublicKey {
} }
} }
/// Converts the public key into a byte slice
#[inline]
pub fn as_slice<'a>(&'a self) -> &'a [u8] {
let &PublicKey(ref data) = self;
data.as_slice()
}
/// Converts the public key to a raw pointer suitable for use /// Converts the public key to a raw pointer suitable for use
/// with the FFI functions /// with the FFI functions
#[inline] #[inline]
@ -360,21 +354,11 @@ impl PublicKey {
} }
} }
impl PublicKeyData {
#[inline]
fn as_slice<'a>(&'a self) -> &'a [u8] {
match *self {
PublicKeyData::Compressed(ref x) => x.as_slice(),
PublicKeyData::Uncompressed(ref x) => x.as_slice()
}
}
}
// We have to do all these impls ourselves as Rust can't derive // We have to do all these impls ourselves as Rust can't derive
// them for arrays // them for arrays
impl fmt::Debug for Nonce { impl fmt::Debug for Nonce {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.as_slice().fmt(f) (&self[..]).fmt(f)
} }
} }
@ -384,7 +368,7 @@ impl Clone for PublicKeyData {
impl PartialEq for PublicKeyData { impl PartialEq for PublicKeyData {
fn eq(&self, other: &PublicKeyData) -> bool { fn eq(&self, other: &PublicKeyData) -> bool {
self.as_slice() == other.as_slice() &self[..] == &other[..]
} }
} }
@ -392,7 +376,118 @@ impl Eq for PublicKeyData {}
impl fmt::Debug for PublicKeyData { impl fmt::Debug for PublicKeyData {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.as_slice().fmt(f) (&self[..]).fmt(f)
}
}
impl ops::Index<usize> for PublicKeyData {
type Output = u8;
#[inline]
fn index(&self, index: usize) -> &u8 {
match *self {
PublicKeyData::Compressed(ref x) => &x[index],
PublicKeyData::Uncompressed(ref x) => &x[index]
}
}
}
impl ops::Index<usize> for PublicKey {
type Output = u8;
#[inline]
fn index(&self, index: usize) -> &u8 {
let &PublicKey(ref dat) = self;
&dat[index]
}
}
impl ops::Index<ops::Range<usize>> for PublicKeyData {
type Output = [u8];
#[inline]
fn index(&self, index: ops::Range<usize>) -> &[u8] {
match *self {
PublicKeyData::Compressed(ref x) => &x[index.start..index.end],
PublicKeyData::Uncompressed(ref x) => &x[index.start..index.end]
}
}
}
impl ops::Index<ops::Range<usize>> for PublicKey {
type Output = [u8];
#[inline]
fn index(&self, index: ops::Range<usize>) -> &[u8] {
let &PublicKey(ref dat) = self;
&dat[index.start..index.end]
}
}
impl ops::Index<ops::RangeTo<usize>> for PublicKeyData {
type Output = [u8];
#[inline]
fn index(&self, index: ops::RangeTo<usize>) -> &[u8] {
match *self {
PublicKeyData::Compressed(ref x) => &x[..index.end],
PublicKeyData::Uncompressed(ref x) => &x[..index.end]
}
}
}
impl ops::Index<ops::RangeTo<usize>> for PublicKey {
type Output = [u8];
#[inline]
fn index(&self, index: ops::RangeTo<usize>) -> &[u8] {
let &PublicKey(ref dat) = self;
&dat[..index.end]
}
}
impl ops::Index<ops::RangeFrom<usize>> for PublicKeyData {
type Output = [u8];
#[inline]
fn index(&self, index: ops::RangeFrom<usize>) -> &[u8] {
match *self {
PublicKeyData::Compressed(ref x) => &x[index.start..],
PublicKeyData::Uncompressed(ref x) => &x[index.start..]
}
}
}
impl ops::Index<ops::RangeFrom<usize>> for PublicKey {
type Output = [u8];
#[inline]
fn index(&self, index: ops::RangeFrom<usize>) -> &[u8] {
let &PublicKey(ref dat) = self;
&dat[index.start..]
}
}
impl ops::Index<ops::RangeFull> for PublicKeyData {
type Output = [u8];
#[inline]
fn index(&self, _: ops::RangeFull) -> &[u8] {
match *self {
PublicKeyData::Compressed(ref x) => &x[..],
PublicKeyData::Uncompressed(ref x) => &x[..]
}
}
}
impl ops::Index<ops::RangeFull> for PublicKey {
type Output = [u8];
#[inline]
fn index(&self, _: ops::RangeFull) -> &[u8] {
let &PublicKey(ref dat) = self;
&dat[..]
} }
} }
@ -426,13 +521,13 @@ impl Decodable for PublicKey {
impl Encodable for PublicKey { impl Encodable for PublicKey {
fn encode<S: Encoder>(&self, s: &mut S) -> ::std::result::Result<(), S::Error> { fn encode<S: Encoder>(&self, s: &mut S) -> ::std::result::Result<(), S::Error> {
self.as_slice().encode(s) (&self[..]).encode(s)
} }
} }
impl fmt::Debug for SecretKey { impl fmt::Debug for SecretKey {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.as_slice().fmt(f) (&self[..]).fmt(f)
} }
} }

View File

@ -19,34 +19,6 @@ macro_rules! impl_array_newtype {
impl Copy for $thing {} impl Copy for $thing {}
impl $thing { impl $thing {
#[inline]
/// Provides an immutable view into the object
pub fn as_slice<'a>(&'a self) -> &'a [$ty] {
let &$thing(ref dat) = self;
dat.as_slice()
}
#[inline]
/// Provides an immutable view into the object from index `s` inclusive to `e` exclusive
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: 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: usize) -> &'a [$ty] {
let &$thing(ref dat) = self;
dat.slice_from(n)
}
#[inline] #[inline]
/// Converts the object to a raw pointer for FFI interfacing /// Converts the object to a raw pointer for FFI interfacing
pub fn as_ptr(&self) -> *const $ty { pub fn as_ptr(&self) -> *const $ty {
@ -69,7 +41,7 @@ macro_rules! impl_array_newtype {
impl PartialEq for $thing { impl PartialEq for $thing {
#[inline] #[inline]
fn eq(&self, other: &$thing) -> bool { fn eq(&self, other: &$thing) -> bool {
self.as_slice() == other.as_slice() &self[..] == &other[..]
} }
} }
@ -90,6 +62,56 @@ macro_rules! impl_array_newtype {
} }
} }
impl ::std::ops::Index<usize> for $thing {
type Output = $ty;
#[inline]
fn index(&self, index: usize) -> &$ty {
let &$thing(ref dat) = self;
&dat[index]
}
}
impl ::std::ops::Index<::std::ops::Range<usize>> for $thing {
type Output = [$ty];
#[inline]
fn index(&self, index: ::std::ops::Range<usize>) -> &[$ty] {
let &$thing(ref dat) = self;
&dat[index.start..index.end]
}
}
impl ::std::ops::Index<::std::ops::RangeTo<usize>> for $thing {
type Output = [$ty];
#[inline]
fn index(&self, index: ::std::ops::RangeTo<usize>) -> &[$ty] {
let &$thing(ref dat) = self;
&dat[..index.end]
}
}
impl ::std::ops::Index<::std::ops::RangeFrom<usize>> for $thing {
type Output = [$ty];
#[inline]
fn index(&self, index: ::std::ops::RangeFrom<usize>) -> &[$ty] {
let &$thing(ref dat) = self;
&dat[index.start..]
}
}
impl ::std::ops::Index<::std::ops::RangeFull> for $thing {
type Output = [$ty];
#[inline]
fn index(&self, _: ::std::ops::RangeFull) -> &[$ty] {
let &$thing(ref dat) = self;
&dat[..]
}
}
impl ::serialize::Decodable for $thing { impl ::serialize::Decodable for $thing {
fn decode<D: ::serialize::Decoder>(d: &mut D) -> ::std::result::Result<$thing, D::Error> { fn decode<D: ::serialize::Decoder>(d: &mut D) -> ::std::result::Result<$thing, D::Error> {
use serialize::Decodable; use serialize::Decodable;
@ -116,7 +138,7 @@ macro_rules! impl_array_newtype {
impl ::serialize::Encodable for $thing { impl ::serialize::Encodable for $thing {
fn encode<S: ::serialize::Encoder>(&self, s: &mut S) fn encode<S: ::serialize::Encoder>(&self, s: &mut S)
-> ::std::result::Result<(), S::Error> { -> ::std::result::Result<(), S::Error> {
self.as_slice().encode(s) self[..].encode(s)
} }
} }
} }
@ -126,7 +148,7 @@ macro_rules! impl_array_newtype {
// 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()[..]
) )
} }

View File

@ -73,7 +73,7 @@ impl Signature {
#[inline] #[inline]
pub fn as_ptr(&self) -> *const u8 { pub fn as_ptr(&self) -> *const u8 {
let &Signature(_, ref data) = self; let &Signature(_, ref data) = self;
data.as_slice().as_ptr() data.as_ptr()
} }
/// Converts the signature to a mutable raw pointer suitable for use /// Converts the signature to a mutable raw pointer suitable for use
@ -81,14 +81,14 @@ impl Signature {
#[inline] #[inline]
pub fn as_mut_ptr(&mut self) -> *mut u8 { pub fn as_mut_ptr(&mut self) -> *mut u8 {
let &mut Signature(_, ref mut data) = self; let &mut Signature(_, ref mut data) = self;
data.as_mut_slice().as_mut_ptr() data.as_mut_ptr()
} }
/// Converts the signature to a byte slice suitable for verification /// Converts the signature to a byte slice suitable for verification
#[inline] #[inline]
pub fn as_slice<'a>(&'a self) -> &'a [u8] { pub fn as_slice<'a>(&'a self) -> &'a [u8] {
let &Signature(len, ref data) = self; let &Signature(len, ref data) = self;
data.slice_to(len) &data[..len]
} }
/// Returns the length of the signature /// Returns the length of the signature
@ -164,7 +164,7 @@ impl Secp256k1 {
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[..]) })
} }
/// Generates a random keypair. Convenience function for `key::SecretKey::new` /// Generates a random keypair. Convenience function for `key::SecretKey::new`