Clean up and add parity codec support (#91)
* clean Cargo.toml and add parity codec support * upgrade parity codec * fix travis * make clippy happy * use zeroize instead of memsec * fix zeroize and add test * Update .travis.yml * improve codec support * fix * add TODO for removing clear_frmaster
parent
48c7b7bd40
commit
036b720b7f
@ -0,0 +1,27 @@ |
||||
#[macro_export] |
||||
/// implement parity codec for type
|
||||
macro_rules! impl_codec_for { |
||||
($type:ty) => { |
||||
impl codec::Encode for $type { |
||||
fn encode(&self) -> Vec<u8> { |
||||
let encoded = bincode::serialize(&self).unwrap(); |
||||
codec::Encode::encode(&encoded) |
||||
} |
||||
} |
||||
|
||||
impl codec::Decode for $type { |
||||
fn decode<I: codec::Input>(value: &mut I) -> std::result::Result<Self, codec::Error> { |
||||
let decoded: Vec<u8> = codec::Decode::decode(value)?; |
||||
bincode::deserialize(decoded.as_slice()).map_err(|_| codec::Error) |
||||
} |
||||
} |
||||
}; |
||||
} |
||||
|
||||
use crate::{Ciphertext, DecryptionShare, PublicKey, PublicKeySet, Signature}; |
||||
|
||||
impl_codec_for!(PublicKey); |
||||
impl_codec_for!(Signature); |
||||
impl_codec_for!(DecryptionShare); |
||||
impl_codec_for!(PublicKeySet); |
||||
impl_codec_for!(Ciphertext); |
@ -1,90 +1,32 @@ |
||||
//! Utilities for working with secret values. This module includes functionality for overwriting
|
||||
//! memory with zeros.
|
||||
|
||||
use std::mem::{size_of, size_of_val}; |
||||
use std::ops::{Deref, DerefMut}; |
||||
use zeroize::Zeroize; |
||||
|
||||
use memsec::memzero; |
||||
|
||||
use crate::Fr; |
||||
|
||||
pub(crate) const FR_SIZE: usize = size_of::<Fr>(); |
||||
use crate::{Fr, FrRepr}; |
||||
|
||||
/// Overwrites a single field element with zeros.
|
||||
pub(crate) fn clear_fr(fr_ptr: *const Fr) { |
||||
unsafe { memzero(fr_ptr as *mut u8, FR_SIZE) }; |
||||
} |
||||
|
||||
pub(crate) struct MemRange { |
||||
pub ptr: *mut u8, |
||||
pub n_bytes: usize, |
||||
} |
||||
|
||||
/// Marks a type as containing some secret value.
|
||||
pub(crate) trait ContainsSecret { |
||||
/// Returns the range of memory marked as secret.
|
||||
fn secret_memory(&self) -> MemRange; |
||||
|
||||
/// Overwrites the secret region of memory with zeros.
|
||||
///
|
||||
/// This method should be called upon destruction of every type that implements `ContainsSecret`.
|
||||
fn zero_secret(&self) { |
||||
let MemRange { ptr, n_bytes } = self.secret_memory(); |
||||
unsafe { memzero(ptr, n_bytes) }; |
||||
} |
||||
pub(crate) fn clear_fr(fr: &mut Fr) { |
||||
// TODO: Remove this after pairing support `Zeroize`
|
||||
let fr_repr = unsafe { &mut *(fr as *mut Fr as *mut FrRepr) }; |
||||
fr_repr.0.zeroize(); |
||||
} |
||||
|
||||
/// A wrapper around temporary values to ensure that they are cleared on drop.
|
||||
///
|
||||
/// `Safe<T>` is meant to be used a wrapper around `T`, where `T` is either an `&mut U` or
|
||||
/// `Box<U>`.
|
||||
pub(crate) struct Safe<T: DerefMut>(T); |
||||
#[cfg(test)] |
||||
mod tests { |
||||
use super::*; |
||||
use pairing::Field; |
||||
use rand::thread_rng; |
||||
use rand04_compat::RngExt; |
||||
|
||||
impl<T> Deref for Safe<T> |
||||
where |
||||
T: DerefMut, |
||||
{ |
||||
type Target = T::Target; |
||||
#[test] |
||||
fn test_clear() { |
||||
let mut rng = thread_rng(); |
||||
|
||||
fn deref(&self) -> &Self::Target { |
||||
&*(self.0) |
||||
} |
||||
} |
||||
|
||||
impl<T> DerefMut for Safe<T> |
||||
where |
||||
T: DerefMut, |
||||
{ |
||||
fn deref_mut(&mut self) -> &mut Self::Target { |
||||
&mut *(self.0) |
||||
} |
||||
} |
||||
|
||||
impl<T> Drop for Safe<T> |
||||
where |
||||
T: DerefMut, |
||||
{ |
||||
fn drop(&mut self) { |
||||
self.zero_secret(); |
||||
} |
||||
} |
||||
|
||||
impl<T> ContainsSecret for Safe<T> |
||||
where |
||||
T: DerefMut, |
||||
{ |
||||
fn secret_memory(&self) -> MemRange { |
||||
let ptr = &*self.0 as *const T::Target as *mut u8; |
||||
let n_bytes = size_of_val(&*self.0); |
||||
MemRange { ptr, n_bytes } |
||||
} |
||||
} |
||||
let mut fr: Fr = rng.gen04(); |
||||
assert_ne!(fr, Fr::zero()); |
||||
|
||||
impl<T> Safe<T> |
||||
where |
||||
T: DerefMut, |
||||
{ |
||||
pub(crate) fn new(x: T) -> Self { |
||||
Safe(x) |
||||
clear_fr(&mut fr); |
||||
assert_eq!(fr, Fr::zero()); |
||||
} |
||||
} |
||||
|
Loading…
Reference in new issue