Skip to content

gitsynctrade/thresh

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

thresh

Threshold Encryption Toolkit — encrypt data so no single key can decrypt it. Decryption requires t of n committee members.

License Rust Node.js

thresh is a developer-friendly toolkit for threshold encryption. Encrypt secrets so that no single person can decrypt them — you need t of n committee members to collaborate. Think of it as a cryptographic safety deposit box that requires multiple keys to open.

Use cases: database credentials, API keys, deployment secrets, legal hold data, zero-trust architectures, confidential mempools, sealed-bid auctions.


Why thresh?

Concern Without thresh With thresh
Single point of failure One leaked key = total compromise Need t of n keys to decrypt
Insider threat Any admin can read secrets No single admin can decrypt alone
Compliance "Who accessed the secret?" — no audit trail Every decryption produces verifiable transcripts
Key rotation Distribute new keys everywhere Rotate committee members without changing the public key
Cross-platform Custom crypto per language Rust core + Node.js, Python, Go bindings (coming)

Architecture

┌─────────────────────────────────────────────┐
│               USER / APPLICATION             │
│  CLI (thresh) │ Node.js SDK │ Python SDK     │
└──────────────────┬──────────────────────────┘
                   │
┌──────────────────▼───────────────────────────┐
│                thresh-core (Rust)             │
│  ┌──────────┐ ┌──────────┐ ┌──────────────┐ │
│  │  Keygen  │ │ Encrypt  │ │   Decrypt    │ │
│  │ (SSS)    │ │(ElGamal) │ │ (Lagrange)   │ │
│  └──────────┘ └──────────┘ └──────────────┘ │
│  ┌──────────┐ ┌──────────┐ ┌──────────────┐ │
│  │   DKG    │ │  Proofs  │ │    Audit     │ │
│  │(Pedersen)│ │(Schnorr) │ │ (Verifier)   │ │
│  └──────────┘ └──────────┘ └──────────────┘ │
└──────────────────┬───────────────────────────┘
                   │
┌──────────────────▼───────────────────────────┐
│            COMMITTEE NETWORK                  │
│  ┌────────┐  ┌────────┐  ┌────────┐         │
│  │ Node 1 │  │ Node 2 │  │ Node N │  gRPC   │
│  │(share) │  │(share) │  │(share) │         │
│  └────────┘  └────────┘  └────────┘         │
└──────────────────────────────────────────────┘

Quick Start

CLI

# Generate a (3-of-5) threshold keypair
thresh keygen --threshold 3 --participants 5 -o ./keys

# Encrypt a message
thresh encrypt --key keys/committee_public_key.json --message "launch codes" -o ct.json

# Each committee member produces a partial decryption share
thresh decrypt --ciphertext ct.json --share keys/shares/share_1.json -o share_1.json
thresh decrypt --ciphertext ct.json --share keys/shares/share_2.json -o share_2.json
thresh decrypt --ciphertext ct.json --share keys/shares/share_3.json -o share_3.json

# Combine 3 shares to recover plaintext
thresh combine --shares ./shares_dir --ciphertext ct.json

# DKG ceremony (no trusted dealer)
thresh dkg init --threshold 3 --participants 5 -o ./dkg_output
thresh dkg verify ./dkg_output/dkg_transcript.json

# Audit an epoch
thresh-auditor verify-epoch --ciphertext ct.json --shares ./shares_dir --public-key keys/committee_public_key.json

Node.js

npm install @gitsynctrade/thresh
import { keygen, encryptMessage, decryptShare, combineDecryptionShares } from "@gitsynctrade/thresh";

// Generate keys
const result = JSON.parse(keygen(3, 5));
const { publicKey, shares } = result;

// Encrypt
const msg = "secret data";
const ct = encryptMessage(
  Buffer.from(msg).toString("hex"),
  JSON.stringify(publicKey),
  1
);

// Each member decrypts
const s1 = decryptShare(ct, JSON.stringify(shares[0]));
const s2 = decryptShare(ct, JSON.stringify(shares[1]));
const s3 = decryptShare(ct, JSON.stringify(shares[2]));

// Combine
const plainHex = combineDecryptionShares([s1, s2, s3], ct);
const plaintext = Buffer.from(plainHex, "hex").toString();
console.log(plaintext); // "secret data"

Rust

[dependencies]
thresh-core = "0.1"
use thresh_core::{keygen::generate_keypair, encrypt::encrypt, decrypt::{partial_decrypt, combine_shares}};

let committee = generate_keypair(3, 5).unwrap();
let msg = [0x42u8; 32];
let ct = encrypt(&msg, &committee.public_key, 1).unwrap();

let shares: Vec<_> = committee.shares[0..3]
    .iter()
    .map(|s| partial_decrypt(&ct, s).unwrap())
    .collect();

let plaintext = combine_shares(&shares, &ct).unwrap();
assert_eq!(plaintext, msg);

Run a Committee Node (gRPC)

Each committee member runs a node that holds their key share and serves partial decryption requests:

# Build
cargo build --release -p thresh-node

# Run
THRESH_SHARE_PATH=./keys/shares/share_1.json \
THRESH_PORT=50051 \
THRESH_REGION=us-east-1 \
  ./target/release/thresh-node

The node exposes a gRPC endpoint. Multiple nodes collaborate to decrypt:

service Committee {
  rpc PartialDecrypt(DecryptRequest) returns (DecryptResponse);
  rpc Ping(PingRequest) returns (PingResponse);
  rpc NodeInfo(NodeInfoRequest) returns (NodeInfoResponse);
}

Docker

docker build -t thresh-node -f deployments/Dockerfile.node .
docker run -e THRESH_SHARE_PATH=/keys/share.json \
           -v ./keys:/keys \
           -p 50051:50051 \
           thresh-node

Crypto Primitives

Primitive Algorithm Curve
Secret sharing Shamir's Secret Sharing BLS12-381 scalar field
Encryption ElGamal-style (additive homomorphic) BLS12-381 G1
DKG Pedersen-style (each participant contributes) BLS12-381
Share proofs Schnorr-like NIZK of correct decryption BLS12-381
Hashing BLAKE3

Security properties

  • IND-CPA secure against passive adversaries who observe ciphertexts
  • Threshold security: any t-1 colluding members learn nothing about the plaintext
  • Share unforgeability: decryption shares include NIZK proofs
  • Transcript verifiability: anyone can verify decryption correctness
  • DKG soundness: no participant learns the full secret key (trusted dealer variant also available for testing)

What thresh does NOT protect against

  • t of n collusion: if t or more committee members collude, they can decrypt
  • Denial of service: if > n-t members are down, decryption halts (escape hatch: re-share)
  • Side-channel attacks: implementation is not hardened against timing/power analysis
  • Quantum adversaries: BLS12-381 is not post-quantum secure

Tooling

CLI Commands

Command Description
thresh keygen Generate (t,n)-threshold keypair (Shamir SSS)
thresh encrypt Encrypt a message under the committee public key
thresh decrypt Produce a partial decryption share
thresh combine Combine shares to recover plaintext
thresh dkg init Run a distributed key generation ceremony
thresh dkg verify Verify a DKG transcript

Auditor Commands

Command Description
thresh-auditor verify-epoch Verify all shares in an epoch are correctly formed
thresh-auditor verify-transcript Verify DKG transcript integrity
thresh-auditor audit-batch Batch audit multiple epochs for compliance

Deployment

Docker Compose (3-node committee)

# deployments/docker-compose.yml
services:
  node1:
    build:
      context: .
      dockerfile: deployments/Dockerfile.node
    environment:
      - THRESH_SHARE_PATH=/keys/share_1.json
      - THRESH_PORT=50051
    ports: ["50051:50051"]
    volumes: ["./keys:/keys"]

  node2:
    build:
      context: .
      dockerfile: deployments/Dockerfile.node
    environment:
      - THRESH_SHARE_PATH=/keys/share_2.json
      - THRESH_PORT=50052
    ports: ["50052:50052"]
    volumes: ["./keys:/keys"]

  node3:
    build:
      context: .
      dockerfile: deployments/Dockerfile.node
    environment:
      - THRESH_SHARE_PATH=/keys/share_3.json
      - THRESH_PORT=50053
    ports: ["50053:50053"]
    volumes: ["./keys:/keys"]

Development

# Build everything
cargo build --release

# Run tests
cargo test

# Run benchmarks
cargo bench -p thresh-core

# Build Node.js bindings
cd bindings/ts && npm install && npm run build

# Lint
cargo clippy -- -D warnings

# Format
cargo fmt

Roadmap

  • Shamir secret sharing keygen
  • ElGamal-style threshold encryption
  • Partial decryption with Schnorr proofs
  • Lagrange share combination
  • Pedersen DKG ceremony
  • CLI (keygen, encrypt, decrypt, combine, dkg)
  • gRPC committee node
  • Independent auditor tool
  • Node.js NAPI-RS bindings
  • Python PyO3 bindings
  • Go cgo bindings
  • BLS12-381 production curve (arkworks)
  • Proactive secret sharing (periodic re-sharing)
  • Formal verification with hacspec
  • Post-quantum hybrid mode

License

Apache 2.0 — use it anywhere, modify it, build on it.



GitSync ($GSYNC)

The Private AI Trading Infrastructure for Autonomous Perpetual Markets on Base.

🌐 Website gitsync.trade
📱 App app.gitsync.trade
📄 Whitepaper gitsync.trade/whitepaper
📚 Docs docs.gitsync.trade
💻 GitHub github.com/gitsynctrade
🐦 Twitter x.com/gitsynctrade
📢 Telegram t.me/gitsync

thresh powers the privacy committee in the GitSync perpetual exchange, but the toolkit is fully general-purpose with zero crypto dependencies.

About

Threshold Encryption Toolkit — encrypt data so no single key can decrypt it. Decryption requires t of n committee members.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors