Expand description
Verifiable Secret Sharing Schemes are using to split secrets into multiple shares and distribute them among different entities, with the ability to verify if the shares are correct and belong to a specific set. This crate includes Shamir’s secret sharing scheme which does not support verification but is more of a building block for the other schemes.
This crate supports Feldman and Pedersen verifiable secret sharing schemes.
Feldman and Pedersen are similar in many ways. It’s hard to describe when to use one over the other. Indeed, both are used in GennaroDKG.
Feldman reveals the public value of the verifier whereas Pedersen’s hides it.
Feldman and Pedersen are different from Shamir when splitting the secret. Combining shares back into the original secret is identical across all methods and is available for each scheme for convenience.
This crate is no-standard compliant and uses const generics to specify sizes.
This crate supports any number as the maximum number of shares to be requested. Anything higher than 255 is pretty ridiculous but if such a use case exists please let me know. This said, any number of shares can be requested since identifiers can be any size.
Shares are represented as ShareElement
s. Shares can be represented by
really but is most commonly finite fields or groups
depending on the use case. In the simplest case,
the share identifier is the x-coordinate
and the actual value of the share the y-coordinate.
However, anything can be used as the identifier as long as it implements the
ShareIdentifier
trait.
Feldman and Pedersen use the ShareVerifier
trait to verify shares.
In version 5, many of the required generics were removed and replaced with associated types. This simplifies the API and makes it easier to use and reduced the amount of necessary code.
To split a p256 secret using Shamir
#[cfg(any(feature = "alloc", feature = "std"))]
{
use vsss_rs::{*, shamir};
use elliptic_curve::ff::PrimeField;
use p256::{NonZeroScalar, Scalar, SecretKey};
type P256Share = DefaultShare<IdentifierPrimeField<Scalar>, IdentifierPrimeField<Scalar>>;
let mut osrng = rand_core::OsRng::default();
let sk = SecretKey::random(&mut osrng);
let nzs = sk.to_nonzero_scalar();
let shared_secret = IdentifierPrimeField(*nzs.as_ref());
let res = shamir::split_secret::<P256Share>(2, 3, &shared_secret, &mut osrng);
assert!(res.is_ok());
let shares = res.unwrap();
let res = shares.combine();
assert!(res.is_ok());
let scalar = res.unwrap();
let nzs_dup = NonZeroScalar::from_repr(scalar.0.to_repr()).unwrap();
let sk_dup = SecretKey::from(nzs_dup);
assert_eq!(sk_dup.to_bytes(), sk.to_bytes());
}
To split a k256 secret using Shamir
#[cfg(any(feature = "alloc", feature = "std"))]
{
use vsss_rs::{*, shamir};
use elliptic_curve::ff::PrimeField;
use k256::{NonZeroScalar, Scalar, ProjectivePoint, SecretKey};
type K256Share = DefaultShare<IdentifierPrimeField<Scalar>, IdentifierPrimeField<Scalar>>;
let mut osrng = rand_core::OsRng::default();
let sk = SecretKey::random(&mut osrng);
let secret = IdentifierPrimeField(*sk.to_nonzero_scalar());
let res = shamir::split_secret::<K256Share>(2, 3, &secret, &mut osrng);
assert!(res.is_ok());
let shares = res.unwrap();
let res = shares.combine();
assert!(res.is_ok());
let scalar = res.unwrap();
let nzs_dup = NonZeroScalar::from_repr(scalar.0.to_repr()).unwrap();
let sk_dup = SecretKey::from(nzs_dup);
assert_eq!(sk_dup.to_bytes(), sk.to_bytes());
}
Feldman or Pedersen return extra information for verification using their respective verifiers
#[cfg(any(feature = "alloc", feature = "std"))]
{
use vsss_rs::{*, feldman};
use bls12_381_plus::{Scalar, G1Projective};
use elliptic_curve::ff::Field;
type BlsShare = DefaultShare<IdentifierPrimeField<Scalar>, IdentifierPrimeField<Scalar>>;
type BlsShareVerifier = ShareVerifierGroup<G1Projective>;
let mut rng = rand_core::OsRng::default();
let secret = IdentifierPrimeField(Scalar::random(&mut rng));
let res = feldman::split_secret::<BlsShare, BlsShareVerifier>(2, 3, &secret, None, &mut rng);
assert!(res.is_ok());
let (shares, verifier) = res.unwrap();
for s in &shares {
assert!(verifier.verify_share(s).is_ok());
}
let res = shares.combine();
assert!(res.is_ok());
let secret_1 = res.unwrap();
assert_eq!(secret, secret_1);
}
Curve25519 is not a prime field but this crate does support it using
features=["curve25519"]
which is enabled by default. This feature
wraps curve25519-dalek libraries so they can be used with Shamir, Feldman, and Pedersen.
Here’s an example of using Ed25519 and x25519
#[cfg(all(feature = "curve25519", any(feature = "alloc", feature = "std")))] {
use curve25519_dalek::scalar::Scalar;
use rand::Rng;
use ed25519_dalek::SigningKey;
use vsss_rs::{curve25519::WrappedScalar, *};
use x25519_dalek::StaticSecret;
type Ed25519Share = DefaultShare<IdentifierPrimeField<WrappedScalar>, IdentifierPrimeField<WrappedScalar>>;
let mut osrng = rand::rngs::OsRng::default();
let sc = Scalar::hash_from_bytes::<sha2::Sha512>(&osrng.gen::<[u8; 32]>());
let sk1 = StaticSecret::from(sc.to_bytes());
let ske1 = SigningKey::from_bytes(&sc.to_bytes());
let secret = IdentifierPrimeField(WrappedScalar(sc));
let res = shamir::split_secret::<Ed25519Share>(2, 3, &secret, &mut osrng);
assert!(res.is_ok());
let shares = res.unwrap();
let res = shares.combine();
assert!(res.is_ok());
let scalar = res.unwrap();
assert_eq!(scalar.0.0, sc);
let sk2 = StaticSecret::from(scalar.0.0.to_bytes());
let ske2 = SigningKey::from_bytes(&scalar.0.0.to_bytes());
assert_eq!(sk2.to_bytes(), sk1.to_bytes());
assert_eq!(ske1.to_bytes(), ske2.to_bytes());
}
Re-exports§
pub use feldman::Feldman;
pub use pedersen::Pedersen;
pub use pedersen::PedersenResult;
pub use shamir::Shamir;
pub use pedersen::StdPedersenResult;
pub use elliptic_curve;
pub use subtle;
Modules§
- feldman
- Feldman’s Verifiable secret sharing scheme. see https://www.cs.umd.edu/~gasarch/TOPICS/secretsharing/feldmanVSS.pdf.
- macros
- Macros for creating VSSS implementations
- pedersen
- Pedersen’s Verifiable secret sharing scheme. (see https://www.cs.cornell.edu/courses/cs754/2001fa/129.PDF)
- shamir
- Secret splitting for Shamir Secret Sharing Scheme and combine methods for field and group elements
Macros§
- vsss_
fixed_ array_ impl - Implements all the VSSS traits for a fixed array
Structs§
- Array
Feldman Verifier Set - A wrapper around a fixed size array of verifiers Allows for convenient type aliasing
- Array
Pedersen Verifier Set - A wrapper around arrays of verifiers Allows for convenient type aliasing
- Default
Share - A default share implementation providing named fields for the identifier and value.
- Generic
Array Feldman Verifier Set - A wrapper around a generic array of verifiers Allows for convenient type aliasing
- Generic
Array Pedersen Verifier Set - A wrapper around a generic array of verifiers Allows for convenient type aliasing
- Gf256
- Represents the finite field GF(2^8) with 256 elements.
- Identifier
BigUint serde
- A share identifier represented as a big unsigned number
- Identifier
Gf256 - Represents an identifier in the Galois Field GF(2^8).
- Identifier
Prime Field - A share identifier represented as a prime field element.
- Identifier
Primitive - A share identifier represented as a primitive integer.
- Identifier
Residue - A share identifier represented as a residue modulo known at compile time.
- Identifier
Uint - A share identifier represented as a Big unsigned integer with a fixed number of limbs.
- Participant
IdGenerator Collection - A collection of participant number generators
- Saturating
- Provides intentionally-saturating arithmetic on
T
. - StdVsss
- Standard verifiable secret sharing scheme
- Value
Group - A share element represented as a group field element.
- VecFeldman
Verifier Set - A wrapper around a Vec of verifiers Allows for convenient type aliasing
- VecPedersen
Verifier Set - A wrapper around a Vec of verifiers Allows for convenient type aliasing
Enums§
- Error
- Errors during secret sharing
- Participant
IdGenerator Type - The types of participant number generators
Traits§
- CtIs
NotZero - A trait for constant time indicating if a value is not zero.
- CtIs
Zero - A trait for constant time indicating if a value is zero.
- Feldman
Verifier Set - Objects that represent the ability to verify shamir shares using Feldman verifiers
- Fixed
Array - A trait for converting a type to and from a fixed size array.
- Pedersen
Verifier Set - Objects that represent the ability to verify shamir shares using Pedersen verifiers
- Polynomial
- The polynomial used for generating the shares
- Primitive
- An extension trait for primitive integers that are used as share identifiers.
- Primitive
Zeroize - Placeholder for conditionally compiling in
zeroize::DefaultIsZeroes
. - Readable
Share Set - Represents a readable data store for secret shares
- Share
- A share.
- Share
Element - A value used to represent a share element for secret shares. A share element can either be the share identifier or the share value.
- Share
Element Inner - A share element inner type for secret sharing schemes.
- Share
Identifier - A share identifier for secret sharing schemes.
- Share
Identifier Inner - A share identifier inner type for secret sharing schemes.
- Share
Verifier - Objects that represent the ability to verify shamir shares
- Writeable
Share Set - Represents a data store for secret shares
Type Aliases§
- Identifier
I8 - A share identifier represented as i8
- Identifier
I16 - A share identifier represented as i16
- Identifier
I32 - A share identifier represented as i32
- Identifier
I64 - A share identifier represented as i64
- Identifier
I128 - A share identifier represented as i128
- Identifier
Isize - A share identifier represented as isize
- Identifier
U8 - A share identifier represented as u8
- Identifier
U16 - A share identifier represented as u16
- Identifier
U32 - A share identifier represented as u32
- Identifier
U64 - A share identifier represented as u64
- Identifier
U128 - A share identifier represent as u128
- Identifier
Usize - A share identifier represented as usize
- Share
Verifier Group - A share verifier group element.
- ValueI8
- A share value represented as i8
- Value
I16 - A share identifier represented as i16
- Value
I32 - A share value represented as i32
- Value
I64 - A share value represented as i64
- Value
I128 - A share value represented as i128
- Value
Isize - A share value represented as isize
- Value
Prime Field - A share value represented as a
PrimeField
. - Value
Residue - A share value represented as a
Residue<MOD, LIMBS>
- ValueU8
- A share value represented as u8
- Value
U16 - A share value represented as u16
- Value
U32 - A share value represented as u32
- Value
U64 - A share value represented as u64
- Value
U128 - A share value represent as u128
- Value
Uint - A share value represented as
Uint<LIMBS>
- Value
Usize - A share value represented as usize
- Vsss
Result - Results returned by this crate