mirror of
https://github.com/mii443/RustySecrets.git
synced 2025-08-22 16:25:32 +00:00
Add support for custom RNGs in SSS and WrappedSecrets (#64)
This commit is contained in:
committed by
Romain Ruetschi
parent
e84ff133bd
commit
f83ef1b2b6
@ -39,6 +39,7 @@ default-features = false
|
||||
itertools = "^0.7"
|
||||
quickcheck = "^0.4"
|
||||
flate2 = "^0.2"
|
||||
rand = "^0.4.2"
|
||||
|
||||
[profile.bench]
|
||||
opt-level = 3
|
||||
|
@ -13,11 +13,14 @@ pub(crate) use self::scheme::*;
|
||||
|
||||
mod encode;
|
||||
|
||||
use rand::{OsRng, Rng};
|
||||
use ring::digest::{Algorithm, SHA512};
|
||||
static HASH_ALGO: &'static Algorithm = &SHA512;
|
||||
|
||||
/// Performs threshold k-out-of-n Shamir's secret sharing.
|
||||
///
|
||||
/// Uses a `rand::OsRng` as a source of entropy.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
@ -37,7 +40,38 @@ static HASH_ALGO: &'static Algorithm = &SHA512;
|
||||
/// ```
|
||||
pub fn split_secret(k: u8, n: u8, secret: &[u8], sign_shares: bool) -> Result<Vec<String>> {
|
||||
SSS::default()
|
||||
.split_secret(k, n, secret, sign_shares)
|
||||
.split_secret(&mut OsRng::new()?, k, n, secret, sign_shares)
|
||||
.map(|shares| shares.into_iter().map(Share::into_string).collect())
|
||||
}
|
||||
|
||||
/// Performs threshold k-out-of-n Shamir's secret sharing with a custom RNG.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use rusty_secrets::sss::split_secret;
|
||||
///
|
||||
/// let secret = "These programs were never about terrorism: they’re about economic spying, \
|
||||
/// social control, and diplomatic manipulation. They’re about power.";
|
||||
///
|
||||
/// match split_secret(7, 10, &secret.as_bytes(), true) {
|
||||
/// Ok(shares) => {
|
||||
/// // Do something with the shares
|
||||
/// },
|
||||
/// Err(_) => {
|
||||
/// // Deal with error
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
pub fn split_secret_rng<R: Rng>(
|
||||
rng: &mut R,
|
||||
k: u8,
|
||||
n: u8,
|
||||
secret: &[u8],
|
||||
sign_shares: bool,
|
||||
) -> Result<Vec<String>> {
|
||||
SSS::default()
|
||||
.split_secret(rng, k, n, secret, sign_shares)
|
||||
.map(|shares| shares.into_iter().map(Share::into_string).collect())
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! SSS provides Shamir's secret sharing with raw data.
|
||||
|
||||
use merkle_sigs::sign_data_vec;
|
||||
use rand::{OsRng, Rng};
|
||||
use rand::Rng;
|
||||
|
||||
use errors::*;
|
||||
use lagrange::interpolate_at;
|
||||
@ -17,15 +17,16 @@ pub(crate) struct SSS;
|
||||
|
||||
impl SSS {
|
||||
/// Performs threshold k-out-of-n Shamir's secret sharing.
|
||||
pub fn split_secret(
|
||||
pub fn split_secret<R: Rng>(
|
||||
&self,
|
||||
rng: &mut R,
|
||||
threshold: u8,
|
||||
shares_count: u8,
|
||||
secret: &[u8],
|
||||
sign_shares: bool,
|
||||
) -> Result<Vec<Share>> {
|
||||
let (threshold, shares_count) = validate_share_count(threshold, shares_count)?;
|
||||
let shares = Self::secret_share(secret, threshold, shares_count)?;
|
||||
let shares = Self::secret_share(rng, secret, threshold, shares_count)?;
|
||||
|
||||
let signatures = if sign_shares {
|
||||
let shares_to_sign = shares
|
||||
@ -67,19 +68,23 @@ impl SSS {
|
||||
Ok(result.collect())
|
||||
}
|
||||
|
||||
fn secret_share(src: &[u8], threshold: u8, shares_count: u8) -> Result<Vec<Vec<u8>>> {
|
||||
fn secret_share<R: Rng>(
|
||||
rng: &mut R,
|
||||
src: &[u8],
|
||||
threshold: u8,
|
||||
shares_count: u8,
|
||||
) -> Result<Vec<Vec<u8>>> {
|
||||
let mut result = Vec::with_capacity(shares_count as usize);
|
||||
for _ in 0..(shares_count as usize) {
|
||||
result.push(vec![0u8; src.len()]);
|
||||
}
|
||||
let mut col_in = vec![0u8; threshold as usize];
|
||||
let mut col_out = Vec::with_capacity(shares_count as usize);
|
||||
let mut osrng = OsRng::new()?;
|
||||
for (c, &s) in src.iter().enumerate() {
|
||||
col_in[0] = s;
|
||||
// NOTE: switch to `try_fill_bytes` when it lands in a stable release:
|
||||
// https://github.com/rust-lang-nursery/rand/commit/230b2258dbd99ff8bd991008c972d923d4b5d10c
|
||||
osrng.fill_bytes(&mut col_in[1..]);
|
||||
rng.fill_bytes(&mut col_in[1..]);
|
||||
col_out.clear();
|
||||
encode_secret_byte(&*col_in, shares_count, &mut col_out)?;
|
||||
for (&y, share) in col_out.iter().zip(result.iter_mut()) {
|
||||
|
@ -3,11 +3,15 @@
|
||||
use errors::*;
|
||||
use proto::wrapped::SecretProto;
|
||||
|
||||
use rand::{OsRng, Rng};
|
||||
|
||||
mod scheme;
|
||||
pub(crate) use self::scheme::*;
|
||||
|
||||
/// Performs threshold k-out-of-n Shamir's secret sharing.
|
||||
///
|
||||
/// Uses an `OsRng` as a source of entropy.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
@ -41,7 +45,54 @@ pub fn split_secret(
|
||||
sign_shares: bool,
|
||||
) -> Result<Vec<String>> {
|
||||
WrappedSecrets::default()
|
||||
.split_secret(k, n, secret, mime_type, sign_shares)
|
||||
.split_secret(&mut OsRng::new()?, k, n, secret, mime_type, sign_shares)
|
||||
.map(|shares| shares.into_iter().map(Share::into_string).collect())
|
||||
}
|
||||
|
||||
/// Performs threshold k-out-of-n Shamir's secret sharing with a custom RNG.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate rusty_secrets;
|
||||
/// # extern crate rand;
|
||||
/// #
|
||||
/// # fn main() {
|
||||
/// use rusty_secrets::wrapped_secrets::split_secret_rng;
|
||||
/// use rand::ChaChaRng;
|
||||
///
|
||||
/// let secret = "These programs were never about terrorism: they’re about economic spying, \
|
||||
/// social control, and diplomatic manipulation. They’re about power.";
|
||||
///
|
||||
/// let result = split_secret_rng(
|
||||
/// &mut ChaChaRng::new_unseeded(),
|
||||
/// 7,
|
||||
/// 10,
|
||||
/// &secret.as_bytes(),
|
||||
/// Some("text/html".to_string()),
|
||||
/// true,
|
||||
/// );
|
||||
///
|
||||
/// match result {
|
||||
/// Ok(shares) => {
|
||||
/// // Do something with the shares
|
||||
/// },
|
||||
/// Err(_) => {
|
||||
/// // Deal with error
|
||||
/// }
|
||||
/// }
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn split_secret_rng<R: Rng>(
|
||||
rng: &mut R,
|
||||
k: u8,
|
||||
n: u8,
|
||||
secret: &[u8],
|
||||
mime_type: Option<String>,
|
||||
sign_shares: bool,
|
||||
) -> Result<Vec<String>> {
|
||||
WrappedSecrets::default()
|
||||
.split_secret(rng, k, n, secret, mime_type, sign_shares)
|
||||
.map(|shares| shares.into_iter().map(Share::into_string).collect())
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ use proto::VersionProto;
|
||||
use proto::wrapped::SecretProto;
|
||||
use protobuf;
|
||||
use protobuf::Message;
|
||||
use rand::Rng;
|
||||
|
||||
use sss::SSS;
|
||||
pub(crate) use sss::Share;
|
||||
@ -12,8 +13,9 @@ pub(crate) struct WrappedSecrets;
|
||||
|
||||
impl WrappedSecrets {
|
||||
/// Performs threshold k-out-of-n Shamir's secret sharing.
|
||||
pub fn split_secret(
|
||||
pub fn split_secret<R: Rng>(
|
||||
&self,
|
||||
rng: &mut R,
|
||||
k: u8,
|
||||
n: u8,
|
||||
secret: &[u8],
|
||||
@ -30,7 +32,7 @@ impl WrappedSecrets {
|
||||
|
||||
let data = rusty_secret.write_to_bytes().unwrap();
|
||||
|
||||
SSS::default().split_secret(k, n, data.as_slice(), sign_shares)
|
||||
SSS::default().split_secret(rng, k, n, data.as_slice(), sign_shares)
|
||||
}
|
||||
|
||||
/// Recovers the secret from a k-out-of-n Shamir's secret sharing.
|
||||
|
Reference in New Issue
Block a user