npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@forgesworn/shamir-words

v1.0.4

Published

Shamir's Secret Sharing over GF(256) with BIP-39 word encoding for human-readable share exchange

Readme

shamir-words

Nostr: npub1mgvlrnf5hm9yf0n5mf9nqmvarhvxkc6remu5ec3vf8r0txqkuk7su0e7q2

Split secrets into human-readable word shares that can be spoken, written down, or stored separately.

Backing up cryptographic keys is hard. Raw byte shares are error-prone to transcribe and impossible to read over the phone. shamir-words combines Shamir's Secret Sharing over GF(256) with BIP-39 word encoding, so each share becomes a list of familiar English words — just like a Bitcoin seed phrase.

Why shamir-words?

  • Human-readable shares — each share is a BIP-39 word list, not a hex blob
  • Threshold recovery — any t of n shares reconstruct the secret; fewer reveal nothing
  • Integrity checking — SHA-256 checksum detects transcription errors before reconstruction
  • Minimal dependencies — only @noble/hashes and @scure/bip39 (audited cryptographic libraries)
  • TypeScript-first — full type safety with exported interfaces and error classes

Install

npm install @forgesworn/shamir-words

Quick Start

import {
  splitSecret,
  reconstructSecret,
  shareToWords,
  wordsToShare,
} from '@forgesworn/shamir-words';

// Your secret (e.g. a 32-byte private key)
const secret = new Uint8Array([
  0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0xba, 0xbe,
  0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
]);

// Split into 5 shares, any 3 can reconstruct
const shares = splitSecret(secret, 3, 5);

// Convert each share to speakable words
const wordShares = shares.map(shareToWords);
// e.g. ["abandon", "ability", "able", ...] — one word list per share

// Later: decode words back to shares and reconstruct
const decoded = wordShares.map(wordsToShare);
const recovered = reconstructSecret(decoded, 3);
// recovered === secret

API

splitSecret(secret, threshold, shares)

Split a secret into Shamir shares over GF(256).

| Parameter | Type | Description | |-----------|------|-------------| | secret | Uint8Array | The secret to split (1-255 bytes) | | threshold | number | Minimum shares needed to reconstruct (2-255) | | shares | number | Total shares to create (threshold-255) |

Returns ShamirShare[].

reconstructSecret(shares, threshold)

Reconstruct a secret from shares using Lagrange interpolation.

| Parameter | Type | Description | |-----------|------|-------------| | shares | ShamirShare[] | At least threshold shares | | threshold | number | The threshold used during splitting |

Returns Uint8Array — the original secret.

shareToWords(share)

Encode a share as BIP-39 words. The word list embeds the share ID, threshold, data, and a SHA-256 checksum byte for integrity.

Returns string[].

wordsToShare(words)

Decode BIP-39 words back to a share. Verifies the checksum and rejects corrupted or tampered input.

Returns ShamirShare.

Types

interface ShamirShare {
  id: number;        // 1-255 (the x-coordinate)
  threshold: number; // 2-255 (minimum shares for reconstruction)
  data: Uint8Array;  // evaluated polynomial bytes
}

Error Classes

  • ShamirError — base class for all errors
  • ShamirValidationError — invalid inputs (wrong types, out-of-range values)
  • ShamirCryptoError — cryptographic failures (e.g. GF(256) zero inverse)

Wire Format

Each word-encoded share packs bytes as:

[data_length, threshold, share_id, ...data, checksum]

The byte stream is split into 11-bit groups, each mapped to a BIP-39 word. The checksum is the first byte of SHA-256 over the preceding bytes.

Limitations

  • Secret size: 1-255 bytes (covers all standard key sizes up to 255 bytes)
  • Share count: up to 255 (the GF(256) field size minus zero)
  • Threshold: 2-255 (single-share schemes are just copying, not secret sharing)

Licence

MIT