Interactive SRS math

Why Publish tau G Instead of tau?

Enter a secret tau, choose a real protocol generator, and watch how group elements hide the exponent while preserving the algebra SNARKs need.

Read blog
Step 1

Without G

Publishing raw powers immediately exposes the toxic waste.

tau mod n = 5
tau^2 mod n = 25
tau^3 mod n = 125
Step 2

With G

The SRS publishes locked powers as group elements.

G
tau G
tau^2 G
tau^3 G
Step 3

Discrete Log

The visible objects are points or modular group values, not the exponents.

G -> x=0x17f1d3a73197d794...fb3af00adb22c6bb y=0x8b3f481e3aaa0f1a...0caa232946c5e7e1
tau G -> x=0x10e7791fb972fe01...a575af0f18fb13dc y=0x16ba437edcc6551e...fbf0bcd70d67c6e2
tau^2 G -> x=0xcb58c81ae0cae2e9...469035b291e37269 y=0x1678cefdd942f604...bc8f83983a282aff
tau^3 G -> x=0x2681717d96c5d63a...361a4b723c307e2d y=0x37fdcd2dc19f84d3...1debc1c8103024b9
Step 4

Hashes Fail

Hashes can hide values, but they cannot form polynomial evaluations from public powers.

Hash(tau)
Hash(tau^2)
Hash(tau^3)

no useful SNARK algebra
Step 5

Real Setups

Pairing-based setups publish locked powers in G1 and G2. The toxic waste is tau, not the generators.

[G1], [tau G1], [tau^2 G1], ...
[G2], [tau G2], [tau^2 G2], ...
Selected G

Ethereum KZG BLS12-381 G1

KZG commitments and trusted setup powers. This is the closest real-world match for [G, tau G, tau^2 G, ...].

Ecosystem
Ethereum EIP-4844 / KZG
Generator
BLS12-381 G1 generator
Equation
y^2 = x^3 + 4 over Fp
Meaning
Real KZG setup files also include G2 powers for pairing checks.
Public SRS elements

[G, tau G, ... tau^3 G]

TermHidden scalarPublic group element
G1 = 0x1x=0x17f1d3a73197d794...fb3af00adb22c6bb y=0x8b3f481e3aaa0f1a...0caa232946c5e7e1
tau Gtau mod n = 0x5x=0x10e7791fb972fe01...a575af0f18fb13dc y=0x16ba437edcc6551e...fbf0bcd70d67c6e2
tau^2 Gtau^2 mod n = 0x19x=0xcb58c81ae0cae2e9...469035b291e37269 y=0x1678cefdd942f604...bc8f83983a282aff
tau^3 Gtau^3 mod n = 0x7dx=0x2681717d96c5d63a...361a4b723c307e2d y=0x37fdcd2dc19f84d3...1debc1c8103024b9
Algebra preserved

Locked polynomial evaluation

f(x) = 3x^2 + 2x + 1

3(tau^2 G) + 2(tau G) + G
= (3tau^2 + 2tau + 1)G

scalar = 86
match = true
Why hashes fail

Hash outputs do not compose this way

A hash can hide tau, but it does not let the prover form (3tau^2 + 2tau + 1)G from public powers. Group operations preserve the algebra while discrete log hides the scalar.

Source notes

What this selector means

There are many mathematical generators in these groups, but protocols standardize specific base points. This explorer includes common fixed generators from Bitcoin, Ethereum, and Solana contexts, plus the BLS12-381 G1 generator relevant to KZG-style SRS material.

Toy Python demo

Run the SRS commitment script

This uses the exact toy values from the script: MOD = 101, G = 2, TAU = 5, and P(x) = x^2 - 25.

$ python toy_srs_demo.py

Click a button to run the toy setup step by step.
Script

toy_srs_demo.py

# toy_srs_demo.py
# Educational only. NOT cryptographically secure.

MOD = 101   # small prime field
G = 2       # toy generator-like value
TAU = 5     # secret toxic waste, should be destroyed in real setup


def mod(x):
    return x % MOD


def generate_srs(max_power: int):
    """
    Publishes:
      G*tau^0, G*tau^1, G*tau^2, ...
    But does NOT publish tau directly.
    """
    srs = []

    for i in range(max_power + 1):
        tau_power = pow(TAU, i, MOD)
        encoded = mod(G * tau_power)
        srs.append(encoded)

    return srs


def commit_polynomial(coeffs, srs):
    """
    Polynomial:
      f(x) = c0 + c1*x + c2*x^2 + ...

    Commitment using SRS:
      c0*[G] + c1*[tau G] + c2*[tau^2 G] + ...
    """
    commitment = 0

    for i, coeff in enumerate(coeffs):
        commitment += coeff * srs[i]

    return mod(commitment)


# -----------------------------------------
# Setup phase
# -----------------------------------------

srs = generate_srs(max_power=2)

print("Public SRS:")
print("G*tau^0 =", srs[0])
print("G*tau^1 =", srs[1])
print("G*tau^2 =", srs[2])

print("\nSecret tau is NOT published.")
print("For demo only, tau =", TAU)


# -----------------------------------------
# Prove something simple
# -----------------------------------------
# Claim:
#   I know x such that x^2 = 25
#
# Polynomial:
#   P(x) = x^2 - 25
#
# Coefficients:
#   -25 + 0*x + 1*x^2

coeffs = [-25, 0, 1]

proof_commitment = commit_polynomial(coeffs, srs)

print("\nPolynomial:")
print("P(x) = x^2 - 25")

print("\nProof commitment:")
print("Commit(P) =", proof_commitment)


# -----------------------------------------
# Direct check, only for learning
# -----------------------------------------

p_tau = mod((TAU ** 2) - 25)

print("\nDirect hidden check:")
print("P(tau) =", p_tau)

if proof_commitment == 0:
    print("\nVerifier accepts: polynomial evaluates to 0 at hidden tau.")
else:
    print("\nVerifier rejects.")


# -----------------------------------------
# Show algebra with SRS
# -----------------------------------------

print("\nExplanation:")
print("SRS[2] - 25*SRS[0] mod 101")
print(f"{srs[2]} - 25*{srs[0]} mod 101 = {proof_commitment}")