Toxic waste is the secret setup randomness and derived data used to create a cryptographic common reference string (CRS). It must be lost after setup: if an adversary learns it, they could create a proof using arbitrary inputs. In a pairing-based SNARK flow, the CRS retains elliptic-curve points derived from these values rather than exposing the values themselves. section 19.5.3 section 19.7
The initial toxic values are random field elements α, β, γ, δ, and z. Further toxic intermediates include evaluations such as l_i(z) and t(z), plus the sequence of powers z^i through the gate count. These values drive construction of hidden θ_i values, which are split between statement variables using γ and witness variables using δ. section 19.5.1 section 19.5.3
CRS creation uses toxic values in a staged computation:
- Sample α, β, γ, δ, and z within the torsion-value field. section 19.5.3
- Generate z^0 through z^(n−1) by starting at 1 and repeatedly multiplying by z. section 19.5.3
- Evaluate QAP polynomials at z and combine them with α and β to compute θ_i. section 19.5.3
- Divide statement-side θ_i values by γ, witness-side values by δ, and compute t(z)/δ. section 19.5.3
- Convert the secret scalars into G1 and G2 elliptic-curve points and save those points in the CRS. section 19.5.3
Generating powers of z
For n gates, allocate n field elements, set zpow[0] to 1, then compute each later entry as zpow[i−1] · z. The resulting z^i values are toxic waste while they are available as scalars, but scalar multiplication turns them into CRS points such as z^iG. section 19.5.3
The security boundary is operational rather than merely mathematical: prover and verifier receive and use the CRS, while the setup values must not remain known to either party. The verifier checks a proof with public statement information and CRS points; the prover uses statement and witness values to form the proof. section 19.7
Listing 19.16 Generating powers of \(z^i\)
zpow = (mpz_t*)malloc(sizeof(mpz_t)*n); #1
for(i=0; i<n; i++)
mpz_init(zpow[i]); #2
mpz_set_ui(zpow[0], 1); #3
for(i=1; i<n; i++) #4
mmul(zpow[i], zpow[i - 1], z); #4
This routine makes the toxic z-power sequence explicit: initialize the first power to 1, then multiply by z once per entry. section 19.5.3
