Support no_std (#13)
* feat: support no_std * simplify rng usage, update tests, upgrade version to 0.4 * fix workflow no-std test * unignore doc-tests * refactor tests Co-authored-by: Aitor Ruano <codearm@pm.me>
This commit is contained in:
parent
eb05d00080
commit
31c8cb7650
|
@ -17,7 +17,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
command: check
|
command: check
|
||||||
|
|
||||||
test:
|
test-std:
|
||||||
name: Test
|
name: Test
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
@ -31,6 +31,21 @@ jobs:
|
||||||
with:
|
with:
|
||||||
command: test
|
command: test
|
||||||
|
|
||||||
|
test-nostd:
|
||||||
|
name: Test
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
profile: minimal
|
||||||
|
toolchain: stable
|
||||||
|
override: true
|
||||||
|
- uses: actions-rs/cargo@v1
|
||||||
|
with:
|
||||||
|
command: test
|
||||||
|
args: --no-default-features
|
||||||
|
|
||||||
format:
|
format:
|
||||||
name: Format
|
name: Format
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
|
@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [0.4.0] - 2020-04-02
|
||||||
|
### Added
|
||||||
|
- It is now possible to compile without `std` with `--no-default-features`
|
||||||
|
|
||||||
## [0.3.3] - 2020-03-23
|
## [0.3.3] - 2020-03-23
|
||||||
### Changed
|
### Changed
|
||||||
- Fix codecov badge
|
- Fix codecov badge
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "sharks"
|
name = "sharks"
|
||||||
version = "0.3.3"
|
version = "0.4.0"
|
||||||
authors = ["Aitor Ruano <codearm@pm.me>"]
|
authors = ["Aitor Ruano <codearm@pm.me>"]
|
||||||
description = "Fast, small and secure Shamir's Secret Sharing library crate"
|
description = "Fast, small and secure Shamir's Secret Sharing library crate"
|
||||||
homepage = "https://github.com/c0dearm/sharks"
|
homepage = "https://github.com/c0dearm/sharks"
|
||||||
|
@ -16,12 +16,17 @@ maintenance = { status = "actively-developed" }
|
||||||
codecov = { repository = "c0dearm/sharks" }
|
codecov = { repository = "c0dearm/sharks" }
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
[features]
|
||||||
|
default = ["std"]
|
||||||
|
std = ["rand/std"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rand = "0.7"
|
rand = { version = "0.7", default-features = false }
|
||||||
|
hashbrown = "0.7"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
criterion = "0.3"
|
criterion = "0.3"
|
||||||
|
rand_chacha = "0.2"
|
||||||
|
|
||||||
[[bench]]
|
[[bench]]
|
||||||
name = "benchmarks"
|
name = "benchmarks"
|
||||||
|
|
|
@ -17,7 +17,14 @@ Add this to your `Cargo.toml`:
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
[dependencies]
|
[dependencies]
|
||||||
sharks = "0.3"
|
sharks = "0.4"
|
||||||
|
```
|
||||||
|
|
||||||
|
If your environment doesn't support `std`:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[dependencies]
|
||||||
|
sharks = { version = "0.4", default-features = false }
|
||||||
```
|
```
|
||||||
|
|
||||||
To get started using Sharks, see the [Rust docs](https://docs.rs/sharks)
|
To get started using Sharks, see the [Rust docs](https://docs.rs/sharks)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
// Basic operations overrided for the Galois Field 256 (2**8)
|
// Basic operations overrided for the Galois Field 256 (2**8)
|
||||||
// Uses pre-calculated tables for 0x11d primitive polynomial (x**8 + x**4 + x**3 + x**2 + 1)
|
// Uses pre-calculated tables for 0x11d primitive polynomial (x**8 + x**4 + x**3 + x**2 + 1)
|
||||||
|
|
||||||
use std::iter::{Product, Sum};
|
use core::iter::{Product, Sum};
|
||||||
use std::ops::{Add, Div, Mul, Sub};
|
use core::ops::{Add, Div, Mul, Sub};
|
||||||
|
|
||||||
const LOG_TABLE: [u8; 256] = [
|
const LOG_TABLE: [u8; 256] = [
|
||||||
0x00, 0x00, 0x01, 0x19, 0x02, 0x32, 0x1a, 0xc6, 0x03, 0xdf, 0x33, 0xee, 0x1b, 0x68, 0xc7, 0x4b,
|
0x00, 0x00, 0x01, 0x19, 0x02, 0x32, 0x1a, 0xc6, 0x03, 0xdf, 0x33, 0xee, 0x1b, 0x68, 0xc7, 0x4b,
|
||||||
|
@ -126,6 +126,7 @@ impl Product for GF256 {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{EXP_TABLE, GF256, LOG_TABLE};
|
use super::{EXP_TABLE, GF256, LOG_TABLE};
|
||||||
|
use alloc::vec;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add_works() {
|
fn add_works() {
|
||||||
|
|
101
src/lib.rs
101
src/lib.rs
|
@ -1,25 +1,49 @@
|
||||||
//! Fast, small and secure [Shamir's Secret Sharing](https://en.wikipedia.org/wiki/Shamir%27s_Secret_Sharing) library crate
|
//! Fast, small and secure [Shamir's Secret Sharing](https://en.wikipedia.org/wiki/Shamir%27s_Secret_Sharing) library crate
|
||||||
//!
|
//!
|
||||||
//! Usage example:
|
//! Usage example (std):
|
||||||
//! ```
|
//! ```
|
||||||
//! use sharks::{ Sharks, Share };
|
//! use sharks::{ Sharks, Share };
|
||||||
//!
|
//!
|
||||||
//! // Set a minimum threshold of 10 shares
|
//! // Set a minimum threshold of 10 shares
|
||||||
//! let sharks = Sharks(10);
|
//! let sharks = Sharks(10);
|
||||||
//! // Obtain an iterator over the shares for secret [1, 2, 3, 4]
|
//! // Obtain an iterator over the shares for secret [1, 2, 3, 4]
|
||||||
|
//! # #[cfg(feature = "std")]
|
||||||
|
//! # {
|
||||||
//! let dealer = sharks.dealer(&[1, 2, 3, 4]);
|
//! let dealer = sharks.dealer(&[1, 2, 3, 4]);
|
||||||
//! // Get 10 shares
|
//! // Get 10 shares
|
||||||
//! let shares: Vec<Share> = dealer.take(10).collect();
|
//! let shares: Vec<Share> = dealer.take(10).collect();
|
||||||
//! // Recover the original secret!
|
//! // Recover the original secret!
|
||||||
//! let secret = sharks.recover(shares.as_slice()).unwrap();
|
//! let secret = sharks.recover(shares.as_slice()).unwrap();
|
||||||
//! assert_eq!(secret, vec![1, 2, 3, 4]);
|
//! assert_eq!(secret, vec![1, 2, 3, 4]);
|
||||||
|
//! # }
|
||||||
//! ```
|
//! ```
|
||||||
|
//!
|
||||||
|
//! Usage example (no std):
|
||||||
|
//! ```
|
||||||
|
//! use sharks::{ Sharks, Share };
|
||||||
|
//! use rand_chacha::rand_core::SeedableRng;
|
||||||
|
//!
|
||||||
|
//! // Set a minimum threshold of 10 shares
|
||||||
|
//! let sharks = Sharks(10);
|
||||||
|
//! // Obtain an iterator over the shares for secret [1, 2, 3, 4]
|
||||||
|
//! let mut rng = rand_chacha::ChaCha8Rng::from_seed([0x90; 32]);
|
||||||
|
//! let dealer = sharks.dealer_rng(&[1, 2, 3, 4], &mut rng);
|
||||||
|
//! // Get 10 shares
|
||||||
|
//! let shares: Vec<Share> = dealer.take(10).collect();
|
||||||
|
//! // Recover the original secret!
|
||||||
|
//! let secret = sharks.recover(shares.as_slice()).unwrap();
|
||||||
|
//! assert_eq!(secret, vec![1, 2, 3, 4]);
|
||||||
|
//! ```
|
||||||
|
#![no_std]
|
||||||
|
|
||||||
mod field;
|
mod field;
|
||||||
mod math;
|
mod math;
|
||||||
mod share;
|
mod share;
|
||||||
|
|
||||||
use std::collections::HashSet;
|
extern crate alloc;
|
||||||
|
|
||||||
|
use alloc::vec::Vec;
|
||||||
|
use hashbrown::HashSet;
|
||||||
|
|
||||||
use field::GF256;
|
use field::GF256;
|
||||||
pub use share::Share;
|
pub use share::Share;
|
||||||
|
@ -33,16 +57,50 @@ pub use share::Share;
|
||||||
/// // Set a minimum threshold of 10 shares
|
/// // Set a minimum threshold of 10 shares
|
||||||
/// let sharks = Sharks(10);
|
/// let sharks = Sharks(10);
|
||||||
/// // Obtain an iterator over the shares for secret [1, 2, 3, 4]
|
/// // Obtain an iterator over the shares for secret [1, 2, 3, 4]
|
||||||
|
/// # #[cfg(feature = "std")]
|
||||||
|
/// # {
|
||||||
/// let dealer = sharks.dealer(&[1, 2, 3, 4]);
|
/// let dealer = sharks.dealer(&[1, 2, 3, 4]);
|
||||||
/// // Get 10 shares
|
/// // Get 10 shares
|
||||||
/// let shares: Vec<Share> = dealer.take(10).collect();
|
/// let shares: Vec<Share> = dealer.take(10).collect();
|
||||||
/// // Recover the original secret!
|
/// // Recover the original secret!
|
||||||
/// let secret = sharks.recover(shares.as_slice()).unwrap();
|
/// let secret = sharks.recover(shares.as_slice()).unwrap();
|
||||||
/// assert_eq!(secret, vec![1, 2, 3, 4]);
|
/// assert_eq!(secret, vec![1, 2, 3, 4]);
|
||||||
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub struct Sharks(pub u8);
|
pub struct Sharks(pub u8);
|
||||||
|
|
||||||
impl Sharks {
|
impl Sharks {
|
||||||
|
/// This method is useful when `std` is not available. For typical usage
|
||||||
|
/// see the `dealer` method.
|
||||||
|
///
|
||||||
|
/// Given a `secret` byte slice, returns an `Iterator` along new shares.
|
||||||
|
/// The maximum number of shares that can be generated is 256.
|
||||||
|
/// A random number generator has to be provided.
|
||||||
|
///
|
||||||
|
/// Example:
|
||||||
|
/// ```
|
||||||
|
/// # use sharks::{ Sharks, Share };
|
||||||
|
/// # use rand_chacha::rand_core::SeedableRng;
|
||||||
|
/// # let sharks = Sharks(3);
|
||||||
|
/// // Obtain an iterator over the shares for secret [1, 2]
|
||||||
|
/// let mut rng = rand_chacha::ChaCha8Rng::from_seed([0x90; 32]);
|
||||||
|
/// let dealer = sharks.dealer_rng(&[1, 2], &mut rng);
|
||||||
|
/// // Get 3 shares
|
||||||
|
/// let shares: Vec<Share> = dealer.take(3).collect();
|
||||||
|
pub fn dealer_rng<R: rand::Rng>(
|
||||||
|
&self,
|
||||||
|
secret: &[u8],
|
||||||
|
rng: &mut R,
|
||||||
|
) -> impl Iterator<Item = Share> {
|
||||||
|
let mut polys = Vec::with_capacity(secret.len());
|
||||||
|
|
||||||
|
for chunk in secret {
|
||||||
|
polys.push(math::random_polynomial(GF256(*chunk), self.0, rng))
|
||||||
|
}
|
||||||
|
|
||||||
|
math::get_evaluator(polys)
|
||||||
|
}
|
||||||
|
|
||||||
/// Given a `secret` byte slice, returns an `Iterator` along new shares.
|
/// Given a `secret` byte slice, returns an `Iterator` along new shares.
|
||||||
/// The maximum number of shares that can be generated is 256.
|
/// The maximum number of shares that can be generated is 256.
|
||||||
///
|
///
|
||||||
|
@ -54,14 +112,10 @@ impl Sharks {
|
||||||
/// let dealer = sharks.dealer(&[1, 2]);
|
/// let dealer = sharks.dealer(&[1, 2]);
|
||||||
/// // Get 3 shares
|
/// // Get 3 shares
|
||||||
/// let shares: Vec<Share> = dealer.take(3).collect();
|
/// let shares: Vec<Share> = dealer.take(3).collect();
|
||||||
|
#[cfg(feature = "std")]
|
||||||
pub fn dealer(&self, secret: &[u8]) -> impl Iterator<Item = Share> {
|
pub fn dealer(&self, secret: &[u8]) -> impl Iterator<Item = Share> {
|
||||||
let mut polys = Vec::with_capacity(secret.len());
|
let mut rng = rand::thread_rng();
|
||||||
|
self.dealer_rng(secret, &mut rng)
|
||||||
for chunk in secret {
|
|
||||||
polys.push(math::random_polynomial(GF256(*chunk), self.0))
|
|
||||||
}
|
|
||||||
|
|
||||||
math::get_evaluator(polys)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given an iterable collection of shares, recovers the original secret.
|
/// Given an iterable collection of shares, recovers the original secret.
|
||||||
|
@ -71,8 +125,10 @@ impl Sharks {
|
||||||
/// Example:
|
/// Example:
|
||||||
/// ```
|
/// ```
|
||||||
/// # use sharks::{ Sharks, Share };
|
/// # use sharks::{ Sharks, Share };
|
||||||
|
/// # use rand_chacha::rand_core::SeedableRng;
|
||||||
/// # let sharks = Sharks(3);
|
/// # let sharks = Sharks(3);
|
||||||
/// # let mut shares: Vec<Share> = sharks.dealer(&[1]).take(3).collect();
|
/// # let mut rng = rand_chacha::ChaCha8Rng::from_seed([0x90; 32]);
|
||||||
|
/// # let mut shares: Vec<Share> = sharks.dealer_rng(&[1], &mut rng).take(3).collect();
|
||||||
/// // Recover original secret from shares
|
/// // Recover original secret from shares
|
||||||
/// let mut secret = sharks.recover(&shares);
|
/// let mut secret = sharks.recover(&shares);
|
||||||
/// // Secret correctly recovered
|
/// // Secret correctly recovered
|
||||||
|
@ -111,12 +167,27 @@ impl Sharks {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{Share, Sharks};
|
use super::{Share, Sharks};
|
||||||
|
use alloc::{vec, vec::Vec};
|
||||||
|
|
||||||
|
impl Sharks {
|
||||||
|
#[cfg(not(feature = "std"))]
|
||||||
|
fn make_shares(&self, secret: &[u8]) -> impl Iterator<Item = Share> {
|
||||||
|
use rand_chacha::{rand_core::SeedableRng, ChaCha8Rng};
|
||||||
|
|
||||||
|
let mut rng = ChaCha8Rng::from_seed([0x90; 32]);
|
||||||
|
self.dealer_rng(secret, &mut rng)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
fn make_shares(&self, secret: &[u8]) -> impl Iterator<Item = Share> {
|
||||||
|
self.dealer(secret)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_insufficient_shares_err() {
|
fn test_insufficient_shares_err() {
|
||||||
let sharks = Sharks(255);
|
let sharks = Sharks(255);
|
||||||
let dealer = sharks.dealer(&[1]);
|
let shares: Vec<Share> = sharks.make_shares(&[1]).take(254).collect();
|
||||||
let shares: Vec<Share> = dealer.take(254).collect();
|
|
||||||
let secret = sharks.recover(&shares);
|
let secret = sharks.recover(&shares);
|
||||||
assert!(secret.is_err());
|
assert!(secret.is_err());
|
||||||
}
|
}
|
||||||
|
@ -124,8 +195,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_duplicate_shares_err() {
|
fn test_duplicate_shares_err() {
|
||||||
let sharks = Sharks(255);
|
let sharks = Sharks(255);
|
||||||
let dealer = sharks.dealer(&[1]);
|
let mut shares: Vec<Share> = sharks.make_shares(&[1]).take(255).collect();
|
||||||
let mut shares: Vec<Share> = dealer.take(255).collect();
|
|
||||||
shares[1] = Share {
|
shares[1] = Share {
|
||||||
x: shares[0].x,
|
x: shares[0].x,
|
||||||
y: shares[0].y.clone(),
|
y: shares[0].y.clone(),
|
||||||
|
@ -137,8 +207,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_integration_works() {
|
fn test_integration_works() {
|
||||||
let sharks = Sharks(255);
|
let sharks = Sharks(255);
|
||||||
let dealer = sharks.dealer(&[1, 2, 3, 4]);
|
let shares: Vec<Share> = sharks.make_shares(&[1, 2, 3, 4]).take(255).collect();
|
||||||
let shares: Vec<Share> = dealer.take(255).collect();
|
|
||||||
let secret = sharks.recover(&shares).unwrap();
|
let secret = sharks.recover(&shares).unwrap();
|
||||||
assert_eq!(secret, vec![1, 2, 3, 4]);
|
assert_eq!(secret, vec![1, 2, 3, 4]);
|
||||||
}
|
}
|
||||||
|
|
15
src/math.rs
15
src/math.rs
|
@ -1,5 +1,7 @@
|
||||||
// A module which contains necessary algorithms to compute Shamir's shares and recover secrets
|
// A module which contains necessary algorithms to compute Shamir's shares and recover secrets
|
||||||
|
|
||||||
|
use alloc::vec::Vec;
|
||||||
|
|
||||||
use rand::distributions::{Distribution, Uniform};
|
use rand::distributions::{Distribution, Uniform};
|
||||||
|
|
||||||
use super::field::GF256;
|
use super::field::GF256;
|
||||||
|
@ -30,14 +32,13 @@ pub fn interpolate(shares: &[Share]) -> Vec<u8> {
|
||||||
|
|
||||||
// Generates `k` polynomial coefficients, being the last one `s` and the others randomly generated between `[1, 255]`.
|
// Generates `k` polynomial coefficients, being the last one `s` and the others randomly generated between `[1, 255]`.
|
||||||
// Coefficient degrees go from higher to lower in the returned vector order.
|
// Coefficient degrees go from higher to lower in the returned vector order.
|
||||||
pub fn random_polynomial(s: GF256, k: u8) -> Vec<GF256> {
|
pub fn random_polynomial<R: rand::Rng>(s: GF256, k: u8, rng: &mut R) -> Vec<GF256> {
|
||||||
let k = k as usize;
|
let k = k as usize;
|
||||||
let mut poly = Vec::with_capacity(k);
|
let mut poly = Vec::with_capacity(k);
|
||||||
let between = Uniform::new_inclusive(1, 255);
|
let between = Uniform::new_inclusive(1, 255);
|
||||||
let mut rng = rand::thread_rng();
|
|
||||||
|
|
||||||
for _ in 1..k {
|
for _ in 1..k {
|
||||||
poly.push(GF256(between.sample(&mut rng)));
|
poly.push(GF256(between.sample(rng)));
|
||||||
}
|
}
|
||||||
poly.push(s);
|
poly.push(s);
|
||||||
|
|
||||||
|
@ -61,10 +62,13 @@ pub fn get_evaluator(polys: Vec<Vec<GF256>>) -> impl Iterator<Item = Share> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{get_evaluator, interpolate, random_polynomial, Share, GF256};
|
use super::{get_evaluator, interpolate, random_polynomial, Share, GF256};
|
||||||
|
use alloc::{vec, vec::Vec};
|
||||||
|
use rand_chacha::rand_core::SeedableRng;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn random_polynomial_works() {
|
fn random_polynomial_works() {
|
||||||
let poly = random_polynomial(GF256(1), 3);
|
let mut rng = rand_chacha::ChaCha8Rng::from_seed([0x90; 32]);
|
||||||
|
let poly = random_polynomial(GF256(1), 3, &mut rng);
|
||||||
assert_eq!(poly.len(), 3);
|
assert_eq!(poly.len(), 3);
|
||||||
assert_eq!(poly[2], GF256(1));
|
assert_eq!(poly[2], GF256(1));
|
||||||
}
|
}
|
||||||
|
@ -81,7 +85,8 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn interpolate_works() {
|
fn interpolate_works() {
|
||||||
let poly = random_polynomial(GF256(185), 10);
|
let mut rng = rand_chacha::ChaCha8Rng::from_seed([0x90; 32]);
|
||||||
|
let poly = random_polynomial(GF256(185), 10, &mut rng);
|
||||||
let iter = get_evaluator(vec![poly]);
|
let iter = get_evaluator(vec![poly]);
|
||||||
let shares: Vec<Share> = iter.take(10).collect();
|
let shares: Vec<Share> = iter.take(10).collect();
|
||||||
let root = interpolate(&shares);
|
let root = interpolate(&shares);
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use alloc::vec::Vec;
|
||||||
|
|
||||||
use super::field::GF256;
|
use super::field::GF256;
|
||||||
|
|
||||||
/// A share used to reconstruct the secret. Can be serialized to and from a byte array.
|
/// A share used to reconstruct the secret. Can be serialized to and from a byte array.
|
||||||
|
@ -5,12 +7,14 @@ use super::field::GF256;
|
||||||
/// Usage example:
|
/// Usage example:
|
||||||
/// ```
|
/// ```
|
||||||
/// use sharks::{Sharks, Share};
|
/// use sharks::{Sharks, Share};
|
||||||
|
/// # use rand_chacha::rand_core::SeedableRng;
|
||||||
/// # fn send_to_printer(_: Vec<u8>) {}
|
/// # fn send_to_printer(_: Vec<u8>) {}
|
||||||
/// # fn ask_shares() -> Vec<Vec<u8>> {vec![vec![1, 2], vec![2, 3], vec![3, 4]]}
|
/// # fn ask_shares() -> Vec<Vec<u8>> {vec![vec![1, 2], vec![2, 3], vec![3, 4]]}
|
||||||
///
|
///
|
||||||
/// // Transmit the share bytes to a printer
|
/// // Transmit the share bytes to a printer
|
||||||
/// let sharks = Sharks(3);
|
/// let sharks = Sharks(3);
|
||||||
/// let dealer = sharks.dealer(&[1, 2, 3]);
|
/// let mut rng = rand_chacha::ChaCha8Rng::from_seed([0x90; 32]);
|
||||||
|
/// let dealer = sharks.dealer_rng(&[1, 2, 3], &mut rng);
|
||||||
///
|
///
|
||||||
/// // Get 5 shares and print paper keys
|
/// // Get 5 shares and print paper keys
|
||||||
/// for s in dealer.take(5) {
|
/// for s in dealer.take(5) {
|
||||||
|
@ -49,6 +53,7 @@ impl From<&[u8]> for Share {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{Share, GF256};
|
use super::{Share, GF256};
|
||||||
|
use alloc::{vec, vec::Vec};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn vec_from_share_works() {
|
fn vec_from_share_works() {
|
||||||
|
|
Loading…
Reference in New Issue