Replace unsafe copy_nonoverlapping() with safe copy_from_slice()

This commit is contained in:
Peter Todd 2017-05-08 07:18:35 -04:00
parent 70f54e1dea
commit 20c5b903db
No known key found for this signature in database
GPG Key ID: 2481403DA5F091FB
3 changed files with 16 additions and 43 deletions

View File

@ -15,7 +15,6 @@
//! # Public and secret keys //! # Public and secret keys
use std::intrinsics::copy_nonoverlapping;
use std::marker; use std::marker;
use arrayvec::ArrayVec; use arrayvec::ArrayVec;
use rand::Rng; use rand::Rng;
@ -86,10 +85,8 @@ impl SecretKey {
if ffi::secp256k1_ec_seckey_verify(secp.ctx, data.as_ptr()) == 0 { if ffi::secp256k1_ec_seckey_verify(secp.ctx, data.as_ptr()) == 0 {
return Err(InvalidSecretKey); return Err(InvalidSecretKey);
} }
copy_nonoverlapping(data.as_ptr(),
ret.as_mut_ptr(),
data.len());
} }
ret[..].copy_from_slice(data);
Ok(SecretKey(ret)) Ok(SecretKey(ret))
} }
_ => Err(InvalidSecretKey) _ => Err(InvalidSecretKey)
@ -565,12 +562,7 @@ mod test {
0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b,
0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41]; 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41];
assert_eq!(data.len(), 32); assert_eq!(data.len(), 32);
unsafe { data.copy_from_slice(&group_order[..]);
use std::intrinsics::copy_nonoverlapping;
copy_nonoverlapping(group_order.as_ptr(),
data.as_mut_ptr(),
32);
}
data[31] = self.0; data[31] = self.0;
self.0 -= 1; self.0 -= 1;
} }

View File

@ -290,11 +290,7 @@ impl Message {
match data.len() { match data.len() {
constants::MESSAGE_SIZE => { constants::MESSAGE_SIZE => {
let mut ret = [0; constants::MESSAGE_SIZE]; let mut ret = [0; constants::MESSAGE_SIZE];
unsafe { ret[..].copy_from_slice(data);
ptr::copy_nonoverlapping(data.as_ptr(),
ret.as_mut_ptr(),
data.len());
}
Ok(Message(ret)) Ok(Message(ret))
} }
_ => Err(Error::InvalidMessage) _ => Err(Error::InvalidMessage)
@ -539,7 +535,6 @@ impl Secp256k1 {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use rand::{Rng, thread_rng}; use rand::{Rng, thread_rng};
use std::ptr;
use serialize::hex::FromHex; use serialize::hex::FromHex;
use key::{SecretKey, PublicKey}; use key::{SecretKey, PublicKey};
@ -712,20 +707,14 @@ mod tests {
wild_keys[0][0] = 1; wild_keys[0][0] = 1;
wild_msgs[1][0] = 1; wild_msgs[1][0] = 1;
unsafe {
use constants; use constants;
ptr::copy_nonoverlapping(constants::CURVE_ORDER.as_ptr(), wild_keys[1][..].copy_from_slice(&constants::CURVE_ORDER[..]);
wild_keys[1].as_mut_ptr(), wild_msgs[1][..].copy_from_slice(&constants::CURVE_ORDER[..]);
32); wild_msgs[2][..].copy_from_slice(&constants::CURVE_ORDER[..]);
ptr::copy_nonoverlapping(constants::CURVE_ORDER.as_ptr(),
wild_msgs[1].as_mut_ptr(),
32);
ptr::copy_nonoverlapping(constants::CURVE_ORDER.as_ptr(),
wild_msgs[2].as_mut_ptr(),
32);
wild_keys[1][0] -= 1; wild_keys[1][0] -= 1;
wild_msgs[1][0] -= 1; wild_msgs[1][0] -= 1;
}
for key in wild_keys.iter().map(|k| SecretKey::from_slice(&s, &k[..]).unwrap()) { for key in wild_keys.iter().map(|k| SecretKey::from_slice(&s, &k[..]).unwrap()) {
for msg in wild_msgs.iter().map(|m| Message::from_slice(&m[..]).unwrap()) { for msg in wild_msgs.iter().map(|m| Message::from_slice(&m[..]).unwrap()) {

View File

@ -25,6 +25,7 @@ use ffi;
use key::{SecretKey, PublicKey}; use key::{SecretKey, PublicKey};
use std::{mem, ptr}; use std::{mem, ptr};
use std::convert::From;
/// A Schnorr signature. /// A Schnorr signature.
pub struct Signature([u8; constants::SCHNORR_SIGNATURE_SIZE]); pub struct Signature([u8; constants::SCHNORR_SIGNATURE_SIZE]);
@ -35,23 +36,14 @@ impl Signature {
/// Deserializes a signature from a 64-byte vector /// Deserializes a signature from a 64-byte vector
pub fn deserialize(data: &[u8]) -> Signature { pub fn deserialize(data: &[u8]) -> Signature {
assert_eq!(data.len(), constants::SCHNORR_SIGNATURE_SIZE); assert_eq!(data.len(), constants::SCHNORR_SIGNATURE_SIZE);
unsafe { let mut ret = [0; constants::SCHNORR_SIGNATURE_SIZE];
let mut ret: Signature = mem::uninitialized(); ret[..].copy_from_slice(data);
ptr::copy_nonoverlapping(data.as_ptr(), ret.as_mut_ptr(), Signature(ret)
constants::SCHNORR_SIGNATURE_SIZE);
ret
}
} }
/// Serializes a signature to a 64-byte vector /// Serializes a signature to a 64-byte vector
pub fn serialize(&self) -> Vec<u8> { pub fn serialize(&self) -> Vec<u8> {
let mut ret = Vec::with_capacity(constants::SCHNORR_SIGNATURE_SIZE); Vec::from(&self.0[..])
unsafe {
ptr::copy_nonoverlapping(self.as_ptr(), ret.as_mut_ptr(),
constants::SCHNORR_SIGNATURE_SIZE);
ret.set_len(constants::SCHNORR_SIGNATURE_SIZE);
}
ret
} }
} }