secrets.js

A single-file JavaScript implementation of Shamir's Secret Sharing scheme for splitting and reconstructing secrets.

Library
npm
v2.0.0
306stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
36/100Needs Attention
Development Activity0
Maintenance0
Community64
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
59/100Fair
Architecture58
Code Quality62
Innovation45
Learning Curve70

secrets.js-grempe implements Shamir’s threshold secret sharing scheme in plain JavaScript, letting you split any secret — a password, private key, or text file — into a number of shares such that only a threshold subset of them is required to reconstruct the original value. It runs unmodified in Node.js, browsers with global-variable loading, and AMD environments like require.js, making it usable in both server and client contexts without a build step.

The library works entirely with hexadecimal-encoded secrets and uses configurable Galois-field arithmetic (3-20 bits) to control how many shares can be generated. It automatically selects a cryptographically secure random number generator — Node’s crypto.randomBytes() on the server or window.crypto.getRandomValues() in supporting browsers — and exposes helpers (str2hex/hex2str) for converting plain text secrets into the hex form the core API expects.

This fork of the original amper5and/secrets.js project was the subject of an independent security audit by Cure53 in 2019 (commissioned for the Slant PrivEOS project), which found no issues in the Shamir’s Secret Sharing implementation. The audit report is included in the repository.

What You Get

  • secrets.share(secret, numShares, threshold) to split a hex-encoded secret into n shares with a t-of-n reconstruction threshold
  • secrets.combine(shares) to reconstruct the original secret from any threshold-sized subset of shares
  • secrets.newShare(id, shares) to generate an additional share from an existing valid set without changing the original secret
  • str2hex/hex2str helpers for converting UTF-8 text secrets to and from the hex format the API operates on
  • Automatic CSPRNG selection (Node crypto.randomBytes, browser crypto.getRandomValues) with setRNG() override support
  • TypeScript type definitions (secrets.js.d.ts) bundled with the package

Common Use Cases

  • Splitting a cryptocurrency wallet private key across multiple trusted parties or storage locations
  • Distributing a master password or root credential among team members so no single person can act alone
  • Building recoverable backup schemes where a secret survives the loss of some (but not all) shares
  • Implementing custodial or multi-party approval schemes for signing keys in browser or Node.js applications

Under The Hood

Architecture The library is a single-file UMD module using closures rather than classes: mutable config/defaults state is created and reset via an internal reset() function, and the core Lagrange interpolation and Galois-field arithmetic (in combine() and share()) rely on precomputed log/exp tables sized to that shared config. The share string format encodes the bit configuration and share id inline with the hex data, so extractShareComponents() and the share-building code are tightly coupled to that config state — changing how a share is represented would require touching parsing, construction, and validation together rather than a single isolated layer.

Tech Stack Written in vanilla, ES5-style JavaScript (var-based, jslint/eslint directive comments) with zero runtime dependencies. Development tooling is Grunt-based (grunt-contrib-uglify for minification, grunt-contrib-watch) with Jasmine for testing. The package ships both an unminified (secrets.js) and minified (secrets.min.js) build, plus a hand-written TypeScript declaration file (secrets.js.d.ts) rather than being authored in TypeScript itself.

Code Quality Tested with two sizeable Jasmine spec files covering initialization/config, RNG selection, share/combine round trips for both ASCII and multi-byte UTF-8 text, and boundary conditions (minimum/maximum bit widths, invalid arguments), including tests against private internal functions. Error handling is explicit throw new Error(...) on invalid input rather than typed error classes. No CI configuration or linter/formatter setup was found beyond inline jslint/eslint annotations in the source.

What Makes It Unique Rather than an unaudited reimplementation of Shamir’s Secret Sharing, this fork’s cryptographic core was independently reviewed by the security firm Cure53 in 2019, with the audit report bundled directly in the repository — a level of external verification uncommon for a small utility package in this space. It also supports issuing an additional share from an existing threshold set via newShare() without ever re-exposing or re-splitting the original secret, useful for rotating custodians over time.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search