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"
|
itertools = "^0.7"
|
||||||
quickcheck = "^0.4"
|
quickcheck = "^0.4"
|
||||||
flate2 = "^0.2"
|
flate2 = "^0.2"
|
||||||
|
rand = "^0.4.2"
|
||||||
|
|
||||||
[profile.bench]
|
[profile.bench]
|
||||||
opt-level = 3
|
opt-level = 3
|
||||||
|
@ -13,11 +13,14 @@ pub(crate) use self::scheme::*;
|
|||||||
|
|
||||||
mod encode;
|
mod encode;
|
||||||
|
|
||||||
|
use rand::{OsRng, Rng};
|
||||||
use ring::digest::{Algorithm, SHA512};
|
use ring::digest::{Algorithm, SHA512};
|
||||||
static HASH_ALGO: &'static Algorithm = &SHA512;
|
static HASH_ALGO: &'static Algorithm = &SHA512;
|
||||||
|
|
||||||
/// Performs threshold k-out-of-n Shamir's secret sharing.
|
/// Performs threshold k-out-of-n Shamir's secret sharing.
|
||||||
///
|
///
|
||||||
|
/// Uses a `rand::OsRng` as a source of entropy.
|
||||||
|
///
|
||||||
/// # Examples
|
/// # 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>> {
|
pub fn split_secret(k: u8, n: u8, secret: &[u8], sign_shares: bool) -> Result<Vec<String>> {
|
||||||
SSS::default()
|
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())
|
.map(|shares| shares.into_iter().map(Share::into_string).collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//! SSS provides Shamir's secret sharing with raw data.
|
//! SSS provides Shamir's secret sharing with raw data.
|
||||||
|
|
||||||
use merkle_sigs::sign_data_vec;
|
use merkle_sigs::sign_data_vec;
|
||||||
use rand::{OsRng, Rng};
|
use rand::Rng;
|
||||||
|
|
||||||
use errors::*;
|
use errors::*;
|
||||||
use lagrange::interpolate_at;
|
use lagrange::interpolate_at;
|
||||||
@ -17,15 +17,16 @@ pub(crate) struct SSS;
|
|||||||
|
|
||||||
impl SSS {
|
impl SSS {
|
||||||
/// Performs threshold k-out-of-n Shamir's secret sharing.
|
/// Performs threshold k-out-of-n Shamir's secret sharing.
|
||||||
pub fn split_secret(
|
pub fn split_secret<R: Rng>(
|
||||||
&self,
|
&self,
|
||||||
|
rng: &mut R,
|
||||||
threshold: u8,
|
threshold: u8,
|
||||||
shares_count: u8,
|
shares_count: u8,
|
||||||
secret: &[u8],
|
secret: &[u8],
|
||||||
sign_shares: bool,
|
sign_shares: bool,
|
||||||
) -> Result<Vec<Share>> {
|
) -> Result<Vec<Share>> {
|
||||||
let (threshold, shares_count) = validate_share_count(threshold, shares_count)?;
|
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 signatures = if sign_shares {
|
||||||
let shares_to_sign = shares
|
let shares_to_sign = shares
|
||||||
@ -67,19 +68,23 @@ impl SSS {
|
|||||||
Ok(result.collect())
|
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);
|
let mut result = Vec::with_capacity(shares_count as usize);
|
||||||
for _ in 0..(shares_count as usize) {
|
for _ in 0..(shares_count as usize) {
|
||||||
result.push(vec![0u8; src.len()]);
|
result.push(vec![0u8; src.len()]);
|
||||||
}
|
}
|
||||||
let mut col_in = vec![0u8; threshold as usize];
|
let mut col_in = vec![0u8; threshold as usize];
|
||||||
let mut col_out = Vec::with_capacity(shares_count 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() {
|
for (c, &s) in src.iter().enumerate() {
|
||||||
col_in[0] = s;
|
col_in[0] = s;
|
||||||
// NOTE: switch to `try_fill_bytes` when it lands in a stable release:
|
// NOTE: switch to `try_fill_bytes` when it lands in a stable release:
|
||||||
// https://github.com/rust-lang-nursery/rand/commit/230b2258dbd99ff8bd991008c972d923d4b5d10c
|
// 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();
|
col_out.clear();
|
||||||
encode_secret_byte(&*col_in, shares_count, &mut col_out)?;
|
encode_secret_byte(&*col_in, shares_count, &mut col_out)?;
|
||||||
for (&y, share) in col_out.iter().zip(result.iter_mut()) {
|
for (&y, share) in col_out.iter().zip(result.iter_mut()) {
|
||||||
|
@ -3,11 +3,15 @@
|
|||||||
use errors::*;
|
use errors::*;
|
||||||
use proto::wrapped::SecretProto;
|
use proto::wrapped::SecretProto;
|
||||||
|
|
||||||
|
use rand::{OsRng, Rng};
|
||||||
|
|
||||||
mod scheme;
|
mod scheme;
|
||||||
pub(crate) use self::scheme::*;
|
pub(crate) use self::scheme::*;
|
||||||
|
|
||||||
/// Performs threshold k-out-of-n Shamir's secret sharing.
|
/// Performs threshold k-out-of-n Shamir's secret sharing.
|
||||||
///
|
///
|
||||||
|
/// Uses an `OsRng` as a source of entropy.
|
||||||
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
@ -41,7 +45,54 @@ pub fn split_secret(
|
|||||||
sign_shares: bool,
|
sign_shares: bool,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<String>> {
|
||||||
WrappedSecrets::default()
|
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())
|
.map(|shares| shares.into_iter().map(Share::into_string).collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ use proto::VersionProto;
|
|||||||
use proto::wrapped::SecretProto;
|
use proto::wrapped::SecretProto;
|
||||||
use protobuf;
|
use protobuf;
|
||||||
use protobuf::Message;
|
use protobuf::Message;
|
||||||
|
use rand::Rng;
|
||||||
|
|
||||||
use sss::SSS;
|
use sss::SSS;
|
||||||
pub(crate) use sss::Share;
|
pub(crate) use sss::Share;
|
||||||
@ -12,8 +13,9 @@ pub(crate) struct WrappedSecrets;
|
|||||||
|
|
||||||
impl WrappedSecrets {
|
impl WrappedSecrets {
|
||||||
/// Performs threshold k-out-of-n Shamir's secret sharing.
|
/// Performs threshold k-out-of-n Shamir's secret sharing.
|
||||||
pub fn split_secret(
|
pub fn split_secret<R: Rng>(
|
||||||
&self,
|
&self,
|
||||||
|
rng: &mut R,
|
||||||
k: u8,
|
k: u8,
|
||||||
n: u8,
|
n: u8,
|
||||||
secret: &[u8],
|
secret: &[u8],
|
||||||
@ -30,7 +32,7 @@ impl WrappedSecrets {
|
|||||||
|
|
||||||
let data = rusty_secret.write_to_bytes().unwrap();
|
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.
|
/// Recovers the secret from a k-out-of-n Shamir's secret sharing.
|
||||||
|
Reference in New Issue
Block a user