vsss_rs_std/
lib.rs

1/*
2    Copyright Michael Lodder. All Rights Reserved.
3    SPDX-License-Identifier: Apache-2.0
4*/
5//! Verifiable Secret Sharing Schemes are using to split secrets into
6//! multiple shares and distribute them among different entities,
7//! with the ability to verify if the shares are correct and belong
8//! to a specific set. This crate includes Shamir's secret sharing
9//! scheme which does not support verification but is more of a
10//! building block for the other schemes.
11//!
12//! This crate supports Feldman and Pedersen verifiable secret sharing
13//! schemes.
14//!
15//! Feldman and Pedersen are similar in many ways. It's hard to describe when to use
16//! one over the other. Indeed both are used in
17//! <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.134.6445&rep=rep1&type=pdf>.
18//!
19//! Feldman reveals the public value of the verifier whereas Pedersen's hides it.
20//!
21//! Feldman and Pedersen are different from Shamir when splitting the secret.
22//! Combining shares back into the original secret is identical across all methods
23//! and is available for each scheme for convenience.
24//!
25//! This crate is no-standard compliant and uses const generics to specify sizes.
26//!
27//! This crate supports 255 as the maximum number of shares to be requested.
28//! Anything higher is pretty ridiculous but if such a use case exists please let me know.
29//!
30//! Shares are represented as byte arrays. Shares can represent finite fields or groups
31//! depending on the use case. The first byte is reserved for the share identifier (x-coordinate)
32//! and everything else is the actual value of the share (y-coordinate).
33//!
34//! When specifying share sizes, use the field size in bytes + 1 for the identifier.
35//!
36//! To split a p256 secret using Shamir
37//!
38//! ```
39//! use vsss_rs_std::{*, shamir};
40//! use elliptic_curve::ff::PrimeField;
41//! use p256::{NonZeroScalar, Scalar, SecretKey};
42//!
43//! let mut osrng = rand_core::OsRng::default();
44//! let sk = SecretKey::random(&mut osrng);
45//! let nzs = sk.to_nonzero_scalar();
46//! let res = shamir::split_secret::<Scalar, _>(2, 3, *nzs.as_ref(), &mut osrng);
47//! assert!(res.is_ok());
48//! let shares = res.unwrap();
49//! let res = combine_shares::<Scalar>(&shares);
50//! assert!(res.is_ok());
51//! let scalar = res.unwrap();
52//! let nzs_dup =  NonZeroScalar::from_repr(scalar.to_repr()).unwrap();
53//! let sk_dup = SecretKey::from(nzs_dup);
54//! assert_eq!(sk_dup.to_bytes(), sk.to_bytes());
55//! ```
56//!
57//! To split a k256 secret using Shamir
58//!
59//! ```
60//! use vsss_rs_std::{*, shamir};
61//! use elliptic_curve::ff::PrimeField;
62//! use k256::{NonZeroScalar, Scalar, ProjectivePoint, SecretKey};
63//!
64//! let mut osrng = rand_core::OsRng::default();
65//! let sk = SecretKey::random(&mut osrng);
66//! let secret = *sk.to_nonzero_scalar();
67//! let res = shamir::split_secret::<Scalar, _>(2, 3, secret, &mut osrng);
68//! assert!(res.is_ok());
69//! let shares = res.unwrap();
70//! let res = combine_shares::<Scalar>(&shares);
71//! assert!(res.is_ok());
72//! let scalar = res.unwrap();
73//! let nzs_dup = NonZeroScalar::from_repr(scalar.to_repr()).unwrap();
74//! let sk_dup = SecretKey::from(nzs_dup);
75//! assert_eq!(sk_dup.to_bytes(), sk.to_bytes());
76//! ```
77//!
78//! Feldman or Pedersen return extra information for verification using their respective verifiers
79//!
80//! ```
81//! use vsss_rs_std::{*, feldman};
82//! use bls12_381_plus::{Scalar, G1Projective};
83//! use elliptic_curve::ff::Field;
84//!
85//! let mut rng = rand_core::OsRng::default();
86//! let secret = Scalar::random(&mut rng);
87//! let res = feldman::split_secret::<Scalar, G1Projective, _>(2, 3, secret, None, &mut rng);
88//! assert!(res.is_ok());
89//! let (shares, verifier) = res.unwrap();
90//! for s in &shares {
91//!     assert!(verifier.verify(s).is_ok());
92//! }
93//! let res = combine_shares::<Scalar>(&shares);
94//! assert!(res.is_ok());
95//! let secret_1 = res.unwrap();
96//! assert_eq!(secret, secret_1);
97//! ```
98//!
99//! Curve25519 is not a prime field but this crate does support it using
100//! `features=["curve25519"]` which is enabled by default. This feature
101//! wraps curve25519-dalek libraries so they can be used with Shamir, Feldman, and Pedersen.
102//!
103//! Here's an example of using Ed25519 and x25519
104//!
105//! ```
106//! use curve25519_dalek::scalar::Scalar;
107//! use ed25519_dalek::SecretKey;
108//! use vsss_rs_std::{curve25519::WrappedScalar, *};
109//! use x25519_dalek::StaticSecret;
110//!
111//! let mut osrng_7 = rand_7::rngs::OsRng::default();
112//! let mut osrng_8 = rand::rngs::OsRng::default();
113//! let sc = Scalar::random(&mut osrng_7);
114//! let sk1 = StaticSecret::from(sc.to_bytes());
115//! let ske1 = SecretKey::from_bytes(&sc.to_bytes()).unwrap();
116//! let res = shamir::split_secret::<WrappedScalar, _>(2, 3, sc.into(), &mut osrng_8);
117//! assert!(res.is_ok());
118//! let shares = res.unwrap();
119//! let res = combine_shares::<WrappedScalar>(&shares);
120//! assert!(res.is_ok());
121//! let scalar = res.unwrap();
122//! assert_eq!(scalar.0, sc);
123//! let sk2 = StaticSecret::from(scalar.0.to_bytes());
124//! let ske2 = SecretKey::from_bytes(&scalar.0.to_bytes()).unwrap();
125//! assert_eq!(sk2.to_bytes(), sk1.to_bytes());
126//! assert_eq!(ske1.to_bytes(), ske2.to_bytes());
127//! ```
128#![deny(
129    missing_docs,
130    unused_import_braces,
131    unused_qualifications,
132    unused_parens,
133    unused_lifetimes,
134    unconditional_recursion,
135    unused_extern_crates,
136    trivial_casts,
137    trivial_numeric_casts
138)]
139#![cfg_attr(docsrs, feature(doc_cfg))]
140#![cfg_attr(feature = "nightly", generic_const_exprs)]
141
142#[cfg(test)]
143mod tests;
144
145mod error;
146pub mod feldman;
147pub mod pedersen;
148mod polynomial;
149pub mod shamir;
150mod share;
151mod util;
152mod verifier;
153
154use shamir::*;
155use util::*;
156
157pub use error::*;
158pub use pedersen::PedersenResult;
159pub use polynomial::*;
160pub use shamir::{combine_shares, combine_shares_group};
161pub use share::*;
162pub use verifier::*;
163
164#[cfg(feature = "curve25519")]
165#[cfg_attr(docsrs, doc(cfg(feature = "curve25519")))]
166pub mod curve25519;
167#[cfg(feature = "curve25519")]
168pub use curve25519_dalek;
169pub use elliptic_curve;
170#[cfg(feature = "curve25519")]
171pub use sha2_9;
172pub use subtle;