mod error;
mod field;
mod shamir;
mod util;
pub use error::Error;
pub fn split_secret(
threshold: u8,
share_count: u8,
shared_secret: &[u8],
) -> Result<Vec<Vec<u8>>, error::Error> {
let splitter = shamir::Splitter::new(None);
let proto_share = shamir::Share::new()?;
let shares = splitter
.split_secret(&proto_share, threshold, share_count, shared_secret)?
.into_iter()
.map(|s| s.to_u8_vec())
.collect::<Result<Vec<_>, _>>()?;
Ok(shares)
}
pub fn recover_secret<'a, I>(shares: I) -> Result<Vec<u8>, error::Error>
where
I: IntoIterator<Item = &'a [u8]>,
{
let shares = shares
.into_iter()
.map(shamir::Share::from_u8_vec)
.collect::<Result<Vec<_>, _>>()?;
let splitter = shamir::Splitter::new(None);
let secret = splitter.recover_secret(&shares)?;
Ok(secret)
}
#[cfg(test)]
mod tests {
use super::*;
use rand::{prelude::SliceRandom, thread_rng};
#[test]
fn split_recover() -> Result<(), error::Error> {
let secret = util::fill_vec_rand(100);
let shares = split_secret(5, 10, &secret)?;
let mut subset = shares.clone();
subset.shuffle(&mut thread_rng());
subset.truncate(5);
let recovered = recover_secret(subset.iter().map(|s| s.as_slice()))?;
assert_eq!(secret, recovered);
Ok(())
}
}