Documentation
¶
Overview ¶
Package slip39 implements SLIP-0039: Shamir's Secret Sharing for Mnemonic Codes.
Split splits a secret into mnemonic shares using a two-level (group + member) Shamir scheme. Combine reconstructs the original secret from a sufficient set of shares.
The secret is encrypted with a passphrase via a 4-round Feistel cipher using PBKDF2-HMAC-SHA256 before splitting. An empty passphrase is valid and provides plausible deniability: any passphrase produces a valid-looking secret, but only the correct passphrase produces the original one.
All GF(2^8) arithmetic is bitsliced and constant-time. Intermediate secrets are zeroed after use. The caller is responsible for zeroing the returned secret from Combine and the input secret passed to Split.
Split is non-deterministic: each call produces different shares due to random identifier and random polynomial coefficients. Use WithRandom for deterministic testing only.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( ErrInvalidMnemonic = errors.New("slip39: invalid mnemonic") ErrInvalidChecksum = errors.New("slip39: invalid checksum") ErrInvalidSecret = errors.New("slip39: invalid secret") ErrInvalidPassphrase = errors.New("slip39: invalid passphrase") ErrDigestMismatch = errors.New("slip39: digest verification failed") )
Error sentinels for SLIP-0039 operations. All error returns use %w wrapping so callers can use errors.Is.
Functions ¶
func Combine ¶
Combine reconstructs a secret from mnemonic shares.
The passphrase must match the one used during Split. A wrong passphrase produces a different secret without any error (plausible deniability by design).
The caller is responsible for zeroing the returned secret when done.
Example ¶
secret := bytes.Repeat([]byte{0x42}, 16)
// Split into 2-of-3.
groups, err := slip39.Split(secret, nil,
slip39.WithGroups([]slip39.Group{
{Threshold: 2, Count: 3},
}),
slip39.WithIterationExponent(0),
)
if err != nil {
fmt.Println("error:", err)
return
}
// Recover from any 2 of 3 shares.
recovered, err := slip39.Combine(groups[0][:2], nil)
if err != nil {
fmt.Println("error:", err)
return
}
defer slip39.ZeroBytes(recovered)
fmt.Println("Recovery successful:", bytes.Equal(recovered, secret))
Output: Recovery successful: true
func Split ¶
Split splits a secret into mnemonic shares.
The secret must be an even number of bytes, at least 16 and at most 64. The passphrase must contain only printable ASCII characters (codes 32-126) and is used to encrypt the secret before splitting. A nil or empty passphrase is valid.
Returns a slice of groups, where each group is a slice of mnemonic strings.
Example ¶
secret := bytes.Repeat([]byte{0x42}, 16)
groups, err := slip39.Split(secret, nil,
slip39.WithGroups([]slip39.Group{
{Threshold: 2, Count: 3},
}),
slip39.WithIterationExponent(0),
)
if err != nil {
fmt.Println("error:", err)
return
}
fmt.Printf("Generated %d shares\n", len(groups[0]))
Output: Generated 3 shares
Types ¶
type Group ¶
type Group struct {
Threshold int // number of shares required to reconstruct the group secret
Count int // total number of shares in this group
}
Group defines a threshold scheme for one share group.
type Option ¶
type Option func(*splitConfig)
Option configures Split behavior.
func WithExtendable ¶
WithExtendable sets the extendable backup flag. When true, the backup can be extended with additional groups without invalidating existing shares. Default: true (spec default).
func WithGroupThreshold ¶
WithGroupThreshold sets the number of groups required to reconstruct the secret. Default: 1.
func WithGroups ¶
WithGroups sets the group configuration. Each Group specifies a member threshold and member count. Default: single group with Threshold=1, Count=1.
func WithIterationExponent ¶
WithIterationExponent sets the PBKDF2 iteration exponent for the Feistel cipher. Total iterations per round = 2500 << e. Higher values increase encryption time exponentially: exponent 0 = 10,000 total, 1 = 20,000, 2 = 40,000. Range: 0-15. Default: 1.
func WithRandom ¶
WithRandom overrides the random source for deterministic testing. In production, the default crypto/rand.Reader is used. This option is for testing only; do not use in production.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
examples
|
|
|
basic
command
Example: basic 1-of-1 split and combine with no passphrase.
|
Example: basic 1-of-1 split and combine with no passphrase. |
|
multigroup
command
Example: multi-group sharing (2-of-3 groups: family, lawyer, vault).
|
Example: multi-group sharing (2-of-3 groups: family, lawyer, vault). |
|
sharing
command
Example: 2-of-3 sharing with a passphrase.
|
Example: 2-of-3 sharing with a passphrase. |