> For the complete documentation index, see [llms.txt](https://bsv.brc.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bsv.brc.dev/key-derivation/0140.md).

# Threshold Key Sharing and Backup via Shamir's Secret Sharing Scheme

Deggen (<d.kellenschwiler@bsvassociation.org>)

## Abstract

This standard defines a method for splitting a secp256k1 private key into `m` shares such that any `n` of those shares (where `2 ≤ n ≤ m`) can reconstruct the original key, while any fewer than `n` shares reveal nothing about it. The scheme is an application of Shamir's Secret Sharing over the secp256k1 prime field, augmented with a cryptographically secure, non-deterministic share-coordinate generation procedure and a short integrity tag. A canonical textual ("backup") serialization is specified so that individual shares can be written down, stored offline, and later recombined. This codifies the `toKeyShares` / `fromKeyShares` and `toBackupShares` / `fromBackupShares` methods of the `PrivateKey` class in the BSV TypeScript SDK.

## Motivation

A single private key is a single point of failure: lose it and funds or identity are gone; leak it and they are stolen. Common mitigations — full copies in multiple locations — multiply the leak surface for every copy made. Threshold secret sharing breaks this trade-off: a key is distributed across `m` custodians or locations, a quorum of `n` is required to recover it, and a minority of compromised or lost shares neither reveals the key nor prevents recovery.

This standard targets the backup and recovery use case (e.g. `toBackupShares(2, 3)`: split into three shares, any two recover the key). It specifies the field arithmetic, the share-coordinate generation, the integrity tag, and the textual serialization precisely enough that an independent implementation can produce shares recoverable by, and recover keys from, the reference implementation.

This scheme covers **storage and reconstruction** of a key. It is not a threshold-signature scheme: the key is fully reassembled in one place at recovery time, and the dealer (the party performing the split) sees the whole key. It does not provide verifiable secret sharing (a malicious dealer is not provably constrained beyond the integrity tag), nor does it protect the key while reassembled.

## Specification

### Field

All share arithmetic is performed in the prime field 𝔽<sub>p</sub>, where `p` is the secp256k1 **field** prime:

```
p = 0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F
```

> **Note.** `p` is the curve's coordinate-field prime, **not** the group order `n`. A private key is a scalar in `[1, n-1]` and `n < p`, so every valid private key is also a valid element of 𝔽<sub>p</sub>. The secret is treated purely as an integer; no elliptic-curve point operations are involved in the sharing itself.

### Secret encoding

Let `k` be the private key interpreted as a big-endian unsigned integer. `k` is the secret and is defined as the value of the sharing polynomial at `x = 0`:

```
f(0) = k
```

### Polynomial

To support a threshold of `n`, the dealer defines a polynomial of degree `n − 1` over 𝔽<sub>p</sub>. The reference implementation represents this polynomial implicitly by `n` points rather than by explicit coefficients:

* Point 0 is `(0, k)` — the secret.
* Points `1 … n−1` are `(xᵢ, yᵢ)` where each `xᵢ` and `yᵢ` is a fresh 32-byte random value reduced mod `p`.

These `n` points uniquely determine a degree `(n − 1)` polynomial. The polynomial is evaluated at an arbitrary coordinate `x` by Lagrange interpolation through its defining points:

```
f(x) = Σ_{i=0}^{n-1}  yᵢ · Π_{j≠i} (x − xⱼ) · (xᵢ − xⱼ)⁻¹   (mod p)
```

All additions, subtractions, multiplications, and the modular inverse `(·)⁻¹` are performed mod `p`.

### Share-coordinate generation

For each of the `m` shares the dealer must choose a distinct, non-zero x-coordinate at which to evaluate `f`. Coordinates MUST be generated as follows so that a split is non-deterministic and remains safe even if the system RNG is partially compromised:

1. Draw a single 64-byte master `seed` from a CSPRNG, used as the HMAC key for the whole split.
2. For share index `i` (`0 ≤ i < m`), starting at `attempt = 0`: a. Build the message `counter = [ i, attempt, r₀ … r₃₁ ]` where `r₀ … r₃₁` are 32 fresh CSPRNG bytes drawn for this attempt. b. Compute `x = HMAC-SHA-512(seed, counter) mod p`. c. If `x = 0` or `x` was already used by an earlier share, increment `attempt` and retry from (a). d. Abort with an error if a share's coordinate is not resolved within 5 attempts.
3. Record `x`, then compute `y = f(x)`. The share is the point `(x, y)`.

The combination of a per-split master seed, the per-share index, the retry counter, and fresh per-attempt randomness ensures non-determinism, uniqueness, and resistance to RNG bias.

### Integrity tag

Each share carries an 8-character integrity tag binding it to its key. The tag is the first 8 hexadecimal characters (4 bytes) of the HASH160 (`RIPEMD-160(SHA-256(·))`) of the compressed public key corresponding to the private key:

```
integrity = hex( HASH160( compressedPublicKey ) )[0:8]
```

All shares of one key carry the same tag. The tag lets a recovery implementation reject shares that belong to different keys and confirm that a reconstructed key matches the original. It is a non-secret checksum, not an authentication mechanism: 4 bytes is enough to catch accidental mismatch but MUST NOT be relied upon to prove key ownership.

### Backup serialization

A share is serialized to text as four `.`-separated fields:

```
<x>.<y>.<threshold>.<integrity>
```

| Field       | Encoding                                                              |
| ----------- | --------------------------------------------------------------------- |
| `x`         | Base58 of the big-endian byte array of the x-coordinate (no checksum) |
| `y`         | Base58 of the big-endian byte array of the y-coordinate (no checksum) |
| `threshold` | The threshold `n`, as a base-10 integer                               |
| `integrity` | The 8-character hex integrity tag                                     |

`x` and `y` together form the point; the leading `<x>.<y>` substring is the point serialization. Example shares for a `(3, 5)` split (threshold 3, integrity `2f804d43`):

```
45s4vLL2hFvqmxrarvbRT2vZoQYGZGocsmaEksZ64o5M.A7nZrGux15nEsQGNZ1mbfnMKugNnS6SYYEQwfhfbDZG8.3.2f804d43
7aPzkiGZgvU4Jira5PN9Qf9o7FEg6uwy1zcxd17NBhh3.CCt7NH1sPFgceb6phTRkfviim2WvmUycJCQd2BxauxP9.3.2f804d43
9GaS2Tw5sXqqbuigdjwGPwPsQuEFqzqUXo5MAQhdK3es.8MLh2wyE3huyq6hiBXjSkJRucgyKh4jVY6ESq5jNtXRE.3.2f804d43
```

A parser MUST reject any share that does not split into exactly four fields, and MUST reject a set of shares whose `threshold` fields or `integrity` fields are not all equal.

### Reconstruction

Given a set `S` of distinct shares with common threshold `n`:

1. Verify `|S| ≥ n`. (Additional shares beyond `n` are permitted; the first `n` are used.)
2. Verify that no two of the shares used share the same x-coordinate; reject duplicates with an error.
3. Reconstruct the polynomial from the `n` points and evaluate it at `x = 0` by Lagrange interpolation:

   ```
   k = f(0) = Σ_{i=0}^{n-1}  yᵢ · Π_{j≠i} (0 − xⱼ) · (xᵢ − xⱼ)⁻¹   (mod p)
   ```
4. Derive the public key from `k`, compute its integrity tag as above, and compare against the shares' tag. If they differ, abort with an integrity-mismatch error.
5. Return `k` as the recovered private key.

### Parameter constraints

* `threshold` (`n`) and `totalShares` (`m`) MUST be integers.
* `n ≥ 2`.
* `m ≥ 2`.
* `n ≤ m`.

A threshold of 1 is disallowed: it would make any single share equal to the key.

### Security considerations

* **Dealer trust.** The party that splits the key sees the whole key and, at recovery, the key is fully reassembled in one place. This scheme protects keys at rest across distributed shares; it does not provide threshold signing or guard the key while in use.
* **Information-theoretic secrecy below threshold.** Fewer than `n` shares reveal no information about `k`, because the remaining coefficient(s) of the degree `(n − 1)` polynomial are uniformly random over 𝔽<sub>p</sub>.
* **Integrity tag is not authentication.** The 4-byte tag detects accidental share mismatch and confirms a correct reconstruction. It is short and public; it does not prevent a motivated adversary who controls share distribution from substituting a different key, and it MUST NOT be treated as proof of ownership.
* **Coordinate generation.** Implementations MUST use the HMAC-based, per-attempt-randomized coordinate generation so that repeated splits of the same key produce different shares and a biased or partially compromised RNG does not yield colliding or predictable coordinates.
* **Share storage.** Each serialized share is sufficient, in quorum, to recover spending authority. Shares SHOULD be stored with the same care as the key fragments they are, in mutually independent locations.

## Implementations

The scheme is implemented in the BSV TypeScript SDK (`@bsv/sdk`) on the `PrivateKey` primitive:

```typescript
import { PrivateKey } from '@bsv/sdk'

// Split into 3 shares, any 2 of which can recover the key.
const key = PrivateKey.fromRandom()
const shares: string[] = key.toBackupShares(2, 3)

// Later, recover from any 2 of the 3 shares.
const recovered = PrivateKey.fromBackupShares([shares[0], shares[2]])
// recovered.toWif() === key.toWif()
```

Relevant methods:

* `PrivateKey.toKeyShares(threshold, totalShares): KeyShares` — split into a structured `KeyShares` object.
* `PrivateKey.toBackupShares(threshold, totalShares): string[]` — split and serialize to backup strings.
* `PrivateKey.fromKeyShares(keyShares): PrivateKey` — reconstruct from a `KeyShares` object.
* `PrivateKey.fromBackupShares(shares): PrivateKey` — parse backup strings and reconstruct.
* The `KeyShares` class (`points`, `threshold`, `integrity`) with `toBackupFormat()` / `fromBackupFormat()`.
* The `Polynomial` and `PointInFiniteField` primitives implementing the field arithmetic and Lagrange interpolation.

## References

* 1: Shamir, A. (1979). "How to share a secret." *Communications of the ACM*, 22(11), 612–613.
* 2: [BRC-42: BSV Key Derivation Scheme (BKDS)](/key-derivation/0042.md)
* 3: [SEC 2: Recommended Elliptic Curve Domain Parameters (secp256k1)](https://www.secg.org/sec2-v2.pdf)
* 4: BSV Blockchain TypeScript SDK — `PrivateKey` primitive: <https://github.com/bsv-blockchain/ts-stack/tree/main/packages/sdk>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://bsv.brc.dev/key-derivation/0140.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
