shamir

package module
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Jul 9, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package shamir implements Shamir's Secret Sharing over GF(2^8).

A secret is split into n shares such that any threshold (k) of them reconstruct it, while any k-1 shares reveal nothing about it. Each byte of the secret is shared independently with its own random degree k-1 polynomial.

Basic usage:

shares, err := shamir.GenerateShares(secret, 5, 3)
// ...
secret, err := shamir.Reconstruct(shares[:3])

Share format: each share is len(secret)+1 bytes — the y-values followed by a single non-zero x-coordinate byte. Treat shares as opaque and store them separately.

Reconstruction requires exactly threshold distinct shares. Supplying fewer (but at least two) returns a wrong secret with no error, because the scheme reveals nothing below the threshold. Pass WithIntegrity to both GenerateShares and Reconstruct to detect insufficient or corrupted shares via a keyless SHA-256 tag; it catches accidents, not deliberate forgery.

Security: this package provides confidentiality, not authentication. Its field arithmetic avoids secret-dependent branches and table lookups to reduce cache-timing exposure, though the Go compiler does not guarantee constant-time execution. Secret material is not zeroized. See SECURITY.md.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func GenerateShares

func GenerateShares(secret []byte, numberOfShares, threshold int, opts ...Option) ([][]byte, error)

GenerateShares takes in a secret and splits it into n shares, not greater than 255 shares Threshold is the minimum number of shares required to reconstruct the secret

Example

Split a secret into 5 shares and reconstruct it from any 3.

package main

import (
	"fmt"
	"log"

	"github.com/lydianpay/shamir-secret-sharing"
)

func main() {
	secret := []byte("my secret")

	shares, err := shamir.GenerateShares(secret, 5, 3)
	if err != nil {
		log.Fatal(err)
	}

	recovered, err := shamir.Reconstruct(shares[:3])
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("%s\n", recovered)
}
Output:
my secret

func Reconstruct

func Reconstruct(shares [][]byte, opts ...Option) (secret []byte, err error)

Reconstruct This method takes n number of shares and reconstructs the original secret

Types

type Option added in v1.1.0

type Option func(*config)

Option customizes GenerateShares and Reconstruct.

func WithIntegrity added in v1.1.0

func WithIntegrity() Option

WithIntegrity appends a truncated SHA-256 tag to the secret before splitting and verifies it on reconstruction, so Reconstruct can detect insufficient or corrupted shares and return a generic error instead of silently returning a wrong secret. It does not reveal the threshold and does not defend against a deliberate forger (the tag is keyless) — it catches accidental misuse and corruption. Off by default; the same option must be passed to both GenerateShares and Reconstruct, and shares are not interchangeable between the two modes.

Example

WithIntegrity lets Reconstruct detect insufficient or corrupted shares instead of silently returning a wrong secret. Pass it to both calls.

package main

import (
	"fmt"
	"log"

	"github.com/lydianpay/shamir-secret-sharing"
)

func main() {
	secret := []byte("my secret")

	shares, err := shamir.GenerateShares(secret, 5, 3, shamir.WithIntegrity())
	if err != nil {
		log.Fatal(err)
	}

	// Too few shares: reported as an error rather than returning garbage.
	if _, err := shamir.Reconstruct(shares[:2], shamir.WithIntegrity()); err != nil {
		fmt.Println("2 shares:", err)
	}

	recovered, err := shamir.Reconstruct(shares[:3], shamir.WithIntegrity())
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("3 shares: %s\n", recovered)

}
Output:
2 shares: invalid or insufficient shares
3 shares: my secret

Jump to

Keyboard shortcuts

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