secretsharing

package module
v0.7.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 7, 2024 License: MIT Imports: 3 Imported by: 9

README

Secure Secret Sharing

secret-sharing Go Reference codecov

  import "github.com/bytemare/secret-sharing"

This package implements Shamir's Secret Sharing extended with Feldman's Verifiable Secret Sharing over elliptic curve groups. It is aimed to be very easy to use.

Secret sharing enables to shard (or split) a secret key into an arbitrary number of shares n and to recover that same key with any subset of at minimum t of these key shares in a (t,n)-threshold scheme.

Note that the key distribution (sharding) algorithm used in this package is a trusted dealer (i.e. centralised). If you need a truly decentralized key generation, you can use the dkg package which builds on this package.

Documentation Go Reference

You can find the documentation and usage examples in the package doc.

Versioning

SemVer is used for versioning. For the versions available, see the tags on the repository.

Contributing

Please read CONTRIBUTING.md for details on the code of conduct, and the process for submitting pull requests.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Documentation

Overview

Package secretsharing provides Shamir Secret Sharing operations.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func CombineShares added in v0.2.0

func CombineShares(shares []keys.Share) (*ecc.Scalar, error)

CombineShares recovers the sharded secret by combining the key shares that implement the Share interface. It recovers the constant term of the interpolating polynomial defined by the set of key shares.

func PubKeyForCommitment added in v0.2.0

func PubKeyForCommitment(g ecc.Group, id uint16, commitment []*ecc.Element) (*ecc.Element, error)

PubKeyForCommitment computes the public key corresponding to the commitment of participant id.

func RecoverFromKeyShares added in v0.5.0

func RecoverFromKeyShares(keyShares []*keys.KeyShare) (*ecc.Scalar, error)

RecoverFromKeyShares recovers the constant secret by combining the key shares.

func Shard added in v0.1.1

func Shard(
	g ecc.Group,
	secret *ecc.Scalar,
	threshold, max uint16,
	polynomial ...*ecc.Scalar,
) ([]*keys.KeyShare, error)

Shard splits the secret into max shares, recoverable by a subset of threshold shares. If no secret is provided, a new random secret is created. To use Verifiable Secret Sharing, use ShardAndCommit.

Example

ExampleShard shows how to split a private key into shares and how to recombine it from a subset of shares. For an example of Verifiable Secret Sharing, see ExampleVerify.

package main

import (
	"fmt"

	"github.com/bytemare/ecc"

	secretsharing "github.com/bytemare/secret-sharing"
	"github.com/bytemare/secret-sharing/keys"
)

func main() {
	// These are the configuration parameters
	g := ecc.Ristretto255Sha512
	threshold := uint16(3)    // threshold is the minimum amount of necessary shares to recombine the secret
	shareholders := uint16(7) // the max amount of key share-holders

	// This is the global secret to be shared
	secret := g.NewScalar().Random()

	// Shard the secret into shares
	shares, err := secretsharing.Shard(g, secret, threshold, shareholders)
	if err != nil {
		panic(err)
	}

	// Assemble a subset of shares to recover the secret. We must use threshold or more shares.
	subset := []keys.Share{
		shares[5], shares[0], shares[3],
	}

	// Combine the subset of shares.
	recovered, err := secretsharing.CombineShares(subset)
	if err != nil {
		panic(err)
	}

	if !recovered.Equal(secret) {
		fmt.Println("ERROR: recovery failed")
	} else {
		fmt.Println("Key split into shares and recombined with a subset of shares!")
	}

}
Output:

Key split into shares and recombined with a subset of shares!

func ShardAndCommit added in v0.2.1

func ShardAndCommit(g ecc.Group,
	secret *ecc.Scalar,
	threshold, max uint16,
	polynomial ...*ecc.Scalar,
) ([]*keys.KeyShare, error)

ShardAndCommit does the same as Shard but populates the returned key shares with the VssCommitment to the polynomial. If no secret is provided, a new random secret is created.

func Verify

func Verify(g ecc.Group, id uint16, pk *ecc.Element, commitment []*ecc.Element) bool

Verify allows verification of participant id's public key given the VSS commitment to the secret polynomial.

Example

ExampleShardAndVerify shows how to split a private key into shares, commit to the underlying polynomial, and verify the generated public keys given the initial commitment.

package main

import (
	"fmt"

	"github.com/bytemare/ecc"

	secretsharing "github.com/bytemare/secret-sharing"
)

func main() {
	// These are the configuration parameters
	g := ecc.Ristretto255Sha512
	threshold := uint16(3)    // threshold is minimum amount of necessary shares to recombine the secret
	shareholders := uint16(7) // the max amount of key share-holders

	// This is the global secret to be shared
	secret := g.NewScalar().Random()

	// Shard the secret into shares
	shares, err := secretsharing.ShardAndCommit(g, secret, threshold, shareholders)
	if err != nil {
		panic(err)
	}

	// You can verify any public key using the commitment. This can be run by a single participant or any other
	// participant access to the participant's public key.
	for _, keyshare := range shares {
		// Let's get the public key. Other parties won't have access to the private key, naturally.
		publicShare := keyshare.Public()

		// Verify that the key share's public key is consistent with the commitment.
		if !secretsharing.Verify(g, publicShare.ID, publicShare.PublicKey, publicShare.VssCommitment) {
			panic("invalid public key for shareholder")
		}
	}

	fmt.Println("All key shares verified.")

}
Output:

All key shares verified.

func VerifyPublicKeyShare added in v0.5.0

func VerifyPublicKeyShare(p *keys.PublicKeyShare) bool

VerifyPublicKeyShare returns whether the PublicKeyShare's public key is valid given its VSS commitment to the secret polynomial.

Types

type Polynomial

type Polynomial []*ecc.Scalar

Polynomial over scalars, represented as a list of t+1 coefficients, where t is the threshold. The constant term is in the first position and the highest degree coefficient is in the last position. All operations on the polynomial's coefficient are done modulo the scalar's group order.

func NewPolynomial

func NewPolynomial(coefficients uint16) Polynomial

NewPolynomial returns a slice of Scalars with the capacity to hold the desired coefficients.

func NewPolynomialFromIntegers added in v0.1.4

func NewPolynomialFromIntegers(g ecc.Group, ints []uint16) Polynomial

NewPolynomialFromIntegers returns a Polynomial from a slice of uint16.

func NewPolynomialFromListFunc added in v0.1.4

func NewPolynomialFromListFunc[S ~[]E, E any](g ecc.Group, s S, f func(E) *ecc.Scalar) Polynomial

NewPolynomialFromListFunc returns a Polynomial from the ecc.Scalar returned by f applied on each element of the slice.

func ShardReturnPolynomial added in v0.1.1

func ShardReturnPolynomial(
	g ecc.Group,
	secret *ecc.Scalar,
	threshold, max uint16,
	polynomial ...*ecc.Scalar,
) ([]*keys.KeyShare, Polynomial, error)

ShardReturnPolynomial splits the secret into max shares, recoverable by a subset of threshold shares, and returns the constructed secret polynomial without committing to it. If no secret is provided, a new random secret is created. Use the Commit function if you want to commit to the returned polynomial.

func (Polynomial) DeriveInterpolatingValue

func (p Polynomial) DeriveInterpolatingValue(g ecc.Group, id *ecc.Scalar) (*ecc.Scalar, error)

DeriveInterpolatingValue derives a value used for polynomial interpolation. id and all the coefficients must be non-zero scalars.

func (Polynomial) Evaluate

func (p Polynomial) Evaluate(x *ecc.Scalar) *ecc.Scalar

Evaluate evaluates the polynomial p at point x using Horner's method.

func (Polynomial) Verify added in v0.1.2

func (p Polynomial) Verify() error

Verify returns an appropriate error if the polynomial has a nil or 0 coefficient, or duplicates.

func (Polynomial) VerifyInterpolatingInput added in v0.5.0

func (p Polynomial) VerifyInterpolatingInput(id *ecc.Scalar) error

VerifyInterpolatingInput checks compatibility of the input id with the polynomial. If not, an error is returned.

type VssCommitment added in v0.5.0

type VssCommitment []*ecc.Element

VssCommitment is the tuple defining a Verifiable Secret Sharing VssCommitment to a secret Polynomial.

func Commit

func Commit(g ecc.Group, polynomial Polynomial) VssCommitment

Commit builds a Verifiable Secret Sharing vector VssCommitment to each of the coefficients (of threshold length which uniquely determines the polynomial).

Directories

Path Synopsis
Package keys defines key material holding structures for secret sharing setups, like public key shares, private, and a registry to hold and manage a set of public key shares.
Package keys defines key material holding structures for secret sharing setups, like public key shares, private, and a registry to hold and manage a set of public key shares.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL