Everything, Everywhere
Verified Specification | Standardized Formulas | Instant Precision
Secure & Private (Zero Data Retention) Free Access • No Sign-Up
Schoenmakers PVSS Chaum-Pedersen DLEQ Public Non-Interactive Proof

Publicly Verifiable Secret Sharing (PVSS) Studio

Simulate publicly verifiable threshold sharing, non-interactive zero-knowledge proofs of share validity, and public reconstruction.

Master Public Secret (S = g^s)
0x3f9a...81c4
Polynomial Degree: 2 (Quadratic)
Public Proof Verification
100% VALID
DLEQ NIZKs: All 5 Verified
Reconstruction Status
Unreconstructed
Active Quorum: 0 / 3 shares

Participant Encrypted Shares & Chaum-Pedersen DLEQ Proofs

Every encrypted share Y_i is verified against commitments without private keys
Participant Public Key (y_i) Encrypted Share (Y_i = y_i^{s_i}) Public Target (X_i = prod C_j^{i^j}) DLEQ Proof (a_i, b_i, r_i) Public Verification

Feldman-Style Public Commitments (C_j = g^{a_j})

The dealer publishes group commitments for each polynomial coefficient.

Chaum-Pedersen DLEQ NIZK Equation

Relation: Prove log_{y_i}(Y_i) == log_g(X_i)
Commitment: a_i = g^{w_i}, b_i = y_i^{w_i}
Fiat-Shamir: c = H(g, y_i, X_i, Y_i, a_i, b_i)
Response: r_i = w_i - c * s_i mod q
Verifier: a_i == g^{r_i} * X_i^c && b_i == y_i^{r_i} * Y_i^c
// pvss_engine.ts
// Publicly Verifiable Secret Sharing (Schoenmakers Scheme)
// 100% Non-Interactive Zero-Knowledge Proofs of Share Validity

export interface PVSSDealerPackage {
  commitments: bigint[]; // C_j = g^{a_j}
  encryptedShares: bigint[]; // Y_i = y_i^{s_i}
  proofs: { a: bigint; b: bigint; r: bigint; c: bigint }[];
}

export class PVSS {
  private p: bigint; // Field prime
  private q: bigint; // Subgroup order
  private g: bigint; // Generator

  constructor(p: bigint, q: bigint, g: bigint) {
    this.p = p; this.q = q; this.g = g;
  }

  // Public verification executable by ANY third party or smart contract
  verifyShare(
    participantIndex: number,
    publicKeyY: bigint,
    encryptedShareY: bigint,
    commitmentsC: bigint[],
    proof: { a: bigint; b: bigint; r: bigint; c: bigint }
  ): boolean {
    const i = BigInt(participantIndex);
    
    // 1. Compute expected public share value X_i = prod_{j=0}^{t-1} C_j^{i^j} mod p
    let X_i = 1n;
    let iPow = 1n;
    for (const C_j of commitmentsC) {
      const term = this.modExp(C_j, iPow, this.p);
      X_i = (X_i * term) % this.p;
      iPow = (iPow * i) % this.q;
    }

    // 2. Verify Chaum-Pedersen DLEQ Equations:
    // a_i == g^{r_i} * X_i^c mod p
    const checkA = (this.modExp(this.g, proof.r, this.p) * this.modExp(X_i, proof.c, this.p)) % this.p;
    if (checkA !== proof.a) return false;

    // b_i == y_i^{r_i} * Y_i^c mod p
    const checkB = (this.modExp(publicKeyY, proof.r, this.p) * this.modExp(encryptedShareY, proof.c, this.p)) % this.p;
    return checkB === proof.b;
  }

  private modExp(base: bigint, exp: bigint, mod: bigint): bigint {
    let res = 1n;
    base = base % mod;
    let e = exp;
    while (e > 0n) {
      if (e & 1n) res = (res * base) % mod;
      base = (base * base) % mod;
      e >>= 1n;
    }
    return res;
  }
}
Sponsored Utility
While You're Here
Sponsored Recommendations
Advertisement