Crate vsss_rs

Source
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 ShareElements. 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§

ArrayFeldmanVerifierSet
A wrapper around a fixed size array of verifiers Allows for convenient type aliasing
ArrayPedersenVerifierSet
A wrapper around arrays of verifiers Allows for convenient type aliasing
DefaultShare
A default share implementation providing named fields for the identifier and value.
GenericArrayFeldmanVerifierSet
A wrapper around a generic array of verifiers Allows for convenient type aliasing
GenericArrayPedersenVerifierSet
A wrapper around a generic array of verifiers Allows for convenient type aliasing
Gf256
Represents the finite field GF(2^8) with 256 elements.
IdentifierBigUintserde
A share identifier represented as a big unsigned number
IdentifierGf256
Represents an identifier in the Galois Field GF(2^8).
IdentifierPrimeField
A share identifier represented as a prime field element.
IdentifierPrimitive
A share identifier represented as a primitive integer.
IdentifierResidue
A share identifier represented as a residue modulo known at compile time.
IdentifierUint
A share identifier represented as a Big unsigned integer with a fixed number of limbs.
ParticipantIdGeneratorCollection
A collection of participant number generators
Saturating
Provides intentionally-saturating arithmetic on T.
StdVsss
Standard verifiable secret sharing scheme
ValueGroup
A share element represented as a group field element.
VecFeldmanVerifierSet
A wrapper around a Vec of verifiers Allows for convenient type aliasing
VecPedersenVerifierSet
A wrapper around a Vec of verifiers Allows for convenient type aliasing

Enums§

Error
Errors during secret sharing
ParticipantIdGeneratorType
The types of participant number generators

Traits§

CtIsNotZero
A trait for constant time indicating if a value is not zero.
CtIsZero
A trait for constant time indicating if a value is zero.
FeldmanVerifierSet
Objects that represent the ability to verify shamir shares using Feldman verifiers
FixedArray
A trait for converting a type to and from a fixed size array.
PedersenVerifierSet
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.
PrimitiveZeroize
Placeholder for conditionally compiling in zeroize::DefaultIsZeroes.
ReadableShareSet
Represents a readable data store for secret shares
Share
A share.
ShareElement
A value used to represent a share element for secret shares. A share element can either be the share identifier or the share value.
ShareElementInner
A share element inner type for secret sharing schemes.
ShareIdentifier
A share identifier for secret sharing schemes.
ShareIdentifierInner
A share identifier inner type for secret sharing schemes.
ShareVerifier
Objects that represent the ability to verify shamir shares
WriteableShareSet
Represents a data store for secret shares

Type Aliases§

IdentifierI8
A share identifier represented as i8
IdentifierI16
A share identifier represented as i16
IdentifierI32
A share identifier represented as i32
IdentifierI64
A share identifier represented as i64
IdentifierI128
A share identifier represented as i128
IdentifierIsize
A share identifier represented as isize
IdentifierU8
A share identifier represented as u8
IdentifierU16
A share identifier represented as u16
IdentifierU32
A share identifier represented as u32
IdentifierU64
A share identifier represented as u64
IdentifierU128
A share identifier represent as u128
IdentifierUsize
A share identifier represented as usize
ShareVerifierGroup
A share verifier group element.
ValueI8
A share value represented as i8
ValueI16
A share identifier represented as i16
ValueI32
A share value represented as i32
ValueI64
A share value represented as i64
ValueI128
A share value represented as i128
ValueIsize
A share value represented as isize
ValuePrimeField
A share value represented as a PrimeField.
ValueResidue
A share value represented as a Residue<MOD, LIMBS>
ValueU8
A share value represented as u8
ValueU16
A share value represented as u16
ValueU32
A share value represented as u32
ValueU64
A share value represented as u64
ValueU128
A share value represent as u128
ValueUint
A share value represented as Uint<LIMBS>
ValueUsize
A share value represented as usize
VsssResult
Results returned by this crate