Skip to main content

Crate vsss_rs

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;alloc or std
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
uintbigint
Share element and identifier implementations using Uint<LIMBS> from the crypto-bigint version 6 crate.
uint5bigint
Share element and identifier implementations using Uint<LIMBS> from the elliptic-curve or crypto-bigint version 5 crate.

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.
HybridArrayFeldmanVerifierSet
A wrapper around a hybrid array of verifiers Allows for convenient type aliasing
HybridArrayPedersenVerifierSet
A wrapper around a hybrid array of verifiers Allows for convenient type aliasing
IdentifierBigUintserde
A share identifier represented as a big unsigned number
IdentifierConstMontyResiduebigint
A share identifier represented as a residue in Montgomery form modulo a constant modulus (crypto-bigint 0.6 ConstMontyForm).
IdentifierGf256
Represents an identifier in the Galois Field GF(2^8).
IdentifierMontyResiduebigint
A share identifier represented as a residue in Montgomery form modulo a modulus chosen at runtime (crypto-bigint 0.6 MontyForm).
IdentifierPrimeField
A share identifier represented as a prime field element.
IdentifierPrimitiveprimitive
A share identifier represented as a primitive integer.
IdentifierResiduebigint
A share identifier represented as a residue modulo known at compile time.
ParticipantIdGeneratorCollection
A collection of participant number generators
Saturatingbigint
Provides intentionally-saturating arithmetic on T.
StdVsssalloc or std
Standard verifiable secret sharing scheme
ValueGroup
A share element represented as a group field element.
VecFeldmanVerifierSetalloc or std
A wrapper around a Vec of verifiers Allows for convenient type aliasing
VecPedersenVerifierSetalloc or std
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
Primitiveprimitive
An extension trait for primitive integers that are used as share identifiers.
PrimitiveZeroizeprimitive and zeroize
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§

IdentifierI8primitive
A share identifier represented as i8
IdentifierI16primitive
A share identifier represented as i16
IdentifierI32primitive
A share identifier represented as i32
IdentifierI64primitive
A share identifier represented as i64
IdentifierI128primitive and 64-bit
A share identifier represented as i128
IdentifierIsizeprimitive
A share identifier represented as isize
IdentifierU8primitive
A share identifier represented as u8
IdentifierU16primitive
A share identifier represented as u16
IdentifierU32primitive
A share identifier represented as u32
IdentifierU64primitive
A share identifier represented as u64
IdentifierU128primitive and 64-bit
A share identifier represent as u128
IdentifierUsizeprimitive
A share identifier represented as usize
ShareVerifierGroup
A share verifier group element.
ValueConstMontyResiduebigint
A share value represented as a ConstMontyForm<MOD, LIMBS>.
ValueI8primitive
A share value represented as i8
ValueI16primitive
A share identifier represented as i16
ValueI32primitive
A share value represented as i32
ValueI64primitive
A share value represented as i64
ValueI128primitive and 64-bit
A share value represented as i128
ValueIsizeprimitive
A share value represented as isize
ValueMontyResiduebigint
A share value represented as a MontyForm<LIMBS> (runtime modulus).
ValuePrimeField
A share value represented as a PrimeField.
ValueResiduebigint
A share value represented as a Residue<MOD, LIMBS>
ValueU8primitive
A share value represented as u8
ValueU16primitive
A share value represented as u16
ValueU32primitive
A share value represented as u32
ValueU64primitive
A share value represented as u64
ValueU128primitive and 64-bit
A share value represent as u128
ValueUsizeprimitive
A share value represented as usize
VsssResult
Results returned by this crate