mirror of
https://github.com/arnaucube/sonobe.git
synced 2026-01-09 15:31:29 +01:00
Onchain decider circuit for Protogalaxy (#145)
* Move r1cs and ccs to standalone folders * Simplify type bounds of SparseMatrixVar * Implement `EquivalenceGadget` trait for `FpVar` and `NonNativeUintVar`. Together with the existing `MatrixGadget` and `VectorGadget`, we can now use the same logic for checking R1CS satisfiability of `R1CSVar` both natively and non-natively. * Simplify trait bounds * Implement `ArithGadget` for `R1CSMatricesVar` and `CCSMatricesVar` * `PedersenGadget::commit` now takes slices as input * Structs for proofs and auxiliary values in protogalaxy * `u` in LCCCS should be `z[0]` * `Inputize` trait * Generic decider circuits * Verifier should check the commitments in committed instances * Update the comments according to the new docs * Fix examples * Add `DeciderEnabledNIFS::fold_group_elements_native` to wrap code for folding commitments * Fix incorrect endian * Format * Get rid of `unwrap` when possible
This commit is contained in:
@@ -63,9 +63,8 @@ contract NovaDecider is Groth16Verifier, KZG10Verifier {
|
||||
// inputs are grouped to prevent errors due stack too deep
|
||||
uint256[{{ 1 + z_len * 2 }}] calldata i_z0_zi, // [i, z0, zi] where |z0| == |zi|
|
||||
uint256[4] calldata U_i_cmW_U_i_cmE, // [U_i_cmW[2], U_i_cmE[2]]
|
||||
uint256[3] calldata U_i_u_u_i_u_r, // [U_i_u, u_i_u, r]
|
||||
uint256[4] calldata U_i_x_u_i_cmW, // [U_i_x[2], u_i_cmW[2]]
|
||||
uint256[4] calldata u_i_x_cmT, // [u_i_x[2], cmT[2]]
|
||||
uint256[2] calldata u_i_cmW, // [u_i_cmW[2]]
|
||||
uint256[3] calldata cmT_r, // [cmT[2], r]
|
||||
uint256[2] calldata pA, // groth16
|
||||
uint256[2][2] calldata pB, // groth16
|
||||
uint256[2] calldata pC, // groth16
|
||||
@@ -85,75 +84,63 @@ contract NovaDecider is Groth16Verifier, KZG10Verifier {
|
||||
public_inputs[2 + i] = i_z0_zi[1 + i];
|
||||
}
|
||||
|
||||
{
|
||||
// U_i.u + r * u_i.u
|
||||
uint256 u = rlc(U_i_u_u_i_u_r[0], U_i_u_u_i_u_r[2], U_i_u_u_i_u_r[1]);
|
||||
// U_i.x + r * u_i.x
|
||||
uint256 x0 = rlc(U_i_x_u_i_cmW[0], U_i_u_u_i_u_r[2], u_i_x_cmT[0]);
|
||||
uint256 x1 = rlc(U_i_x_u_i_cmW[1], U_i_u_u_i_u_r[2], u_i_x_cmT[1]);
|
||||
|
||||
public_inputs[{{ z_len * 2 + 2 }}] = u;
|
||||
public_inputs[{{ z_len * 2 + 3 }}] = x0;
|
||||
public_inputs[{{ z_len * 2 + 4 }}] = x1;
|
||||
}
|
||||
|
||||
{
|
||||
// U_i.cmE + r * u_i.cmT
|
||||
uint256[2] memory mulScalarPoint = super.mulScalar([u_i_x_cmT[2], u_i_x_cmT[3]], U_i_u_u_i_u_r[2]);
|
||||
uint256[2] memory cmE = super.add([U_i_cmW_U_i_cmE[2], U_i_cmW_U_i_cmE[3]], mulScalarPoint);
|
||||
|
||||
{
|
||||
uint256[{{num_limbs}}] memory cmE_x_limbs = LimbsDecomposition.decompose(cmE[0]);
|
||||
uint256[{{num_limbs}}] memory cmE_y_limbs = LimbsDecomposition.decompose(cmE[1]);
|
||||
|
||||
for (uint8 k = 0; k < {{num_limbs}}; k++) {
|
||||
public_inputs[{{ z_len * 2 + 5 }} + k] = cmE_x_limbs[k];
|
||||
public_inputs[{{ z_len * 2 + 5 + num_limbs }} + k] = cmE_y_limbs[k];
|
||||
}
|
||||
}
|
||||
|
||||
require(this.check(cmE, kzg_proof[1], challenge_W_challenge_E_kzg_evals[1], challenge_W_challenge_E_kzg_evals[3]), "KZG: verifying proof for challenge E failed");
|
||||
}
|
||||
|
||||
{
|
||||
// U_i.cmW + r * u_i.cmW
|
||||
uint256[2] memory mulScalarPoint = super.mulScalar([U_i_x_u_i_cmW[2], U_i_x_u_i_cmW[3]], U_i_u_u_i_u_r[2]);
|
||||
uint256[2] memory mulScalarPoint = super.mulScalar([u_i_cmW[0], u_i_cmW[1]], cmT_r[2]);
|
||||
uint256[2] memory cmW = super.add([U_i_cmW_U_i_cmE[0], U_i_cmW_U_i_cmE[1]], mulScalarPoint);
|
||||
|
||||
|
||||
{
|
||||
uint256[{{num_limbs}}] memory cmW_x_limbs = LimbsDecomposition.decompose(cmW[0]);
|
||||
uint256[{{num_limbs}}] memory cmW_y_limbs = LimbsDecomposition.decompose(cmW[1]);
|
||||
|
||||
for (uint8 k = 0; k < {{num_limbs}}; k++) {
|
||||
public_inputs[{{ z_len * 2 + 5 + num_limbs * 2 }} + k] = cmW_x_limbs[k];
|
||||
public_inputs[{{ z_len * 2 + 5 + num_limbs * 3 }} + k] = cmW_y_limbs[k];
|
||||
public_inputs[{{ z_len * 2 + 2 }} + k] = cmW_x_limbs[k];
|
||||
public_inputs[{{ z_len * 2 + 2 + num_limbs }} + k] = cmW_y_limbs[k];
|
||||
}
|
||||
}
|
||||
|
||||
require(this.check(cmW, kzg_proof[0], challenge_W_challenge_E_kzg_evals[0], challenge_W_challenge_E_kzg_evals[2]), "KZG: verifying proof for challenge W failed");
|
||||
}
|
||||
|
||||
{
|
||||
// U_i.cmE + r * cmT
|
||||
uint256[2] memory mulScalarPoint = super.mulScalar([cmT_r[0], cmT_r[1]], cmT_r[2]);
|
||||
uint256[2] memory cmE = super.add([U_i_cmW_U_i_cmE[2], U_i_cmW_U_i_cmE[3]], mulScalarPoint);
|
||||
|
||||
{
|
||||
uint256[{{num_limbs}}] memory cmE_x_limbs = LimbsDecomposition.decompose(cmE[0]);
|
||||
uint256[{{num_limbs}}] memory cmE_y_limbs = LimbsDecomposition.decompose(cmE[1]);
|
||||
|
||||
for (uint8 k = 0; k < {{num_limbs}}; k++) {
|
||||
public_inputs[{{ z_len * 2 + 2 + num_limbs * 2 }} + k] = cmE_x_limbs[k];
|
||||
public_inputs[{{ z_len * 2 + 2 + num_limbs * 3 }} + k] = cmE_y_limbs[k];
|
||||
}
|
||||
}
|
||||
|
||||
require(this.check(cmE, kzg_proof[1], challenge_W_challenge_E_kzg_evals[1], challenge_W_challenge_E_kzg_evals[3]), "KZG: verifying proof for challenge E failed");
|
||||
}
|
||||
|
||||
{
|
||||
// add challenges
|
||||
public_inputs[{{ z_len * 2 + 5 + num_limbs * 4 }}] = challenge_W_challenge_E_kzg_evals[0];
|
||||
public_inputs[{{ z_len * 2 + 5 + num_limbs * 4 + 1 }}] = challenge_W_challenge_E_kzg_evals[1];
|
||||
public_inputs[{{ z_len * 2 + 5 + num_limbs * 4 + 2 }}] = challenge_W_challenge_E_kzg_evals[2];
|
||||
public_inputs[{{ z_len * 2 + 5 + num_limbs * 4 + 3 }}] = challenge_W_challenge_E_kzg_evals[3];
|
||||
|
||||
public_inputs[{{ z_len * 2 + 2 + num_limbs * 4 }}] = challenge_W_challenge_E_kzg_evals[0];
|
||||
public_inputs[{{ z_len * 2 + 2 + num_limbs * 4 + 1 }}] = challenge_W_challenge_E_kzg_evals[1];
|
||||
public_inputs[{{ z_len * 2 + 2 + num_limbs * 4 + 2 }}] = challenge_W_challenge_E_kzg_evals[2];
|
||||
public_inputs[{{ z_len * 2 + 2 + num_limbs * 4 + 3 }}] = challenge_W_challenge_E_kzg_evals[3];
|
||||
|
||||
uint256[{{num_limbs}}] memory cmT_x_limbs;
|
||||
uint256[{{num_limbs}}] memory cmT_y_limbs;
|
||||
|
||||
cmT_x_limbs = LimbsDecomposition.decompose(u_i_x_cmT[2]);
|
||||
cmT_y_limbs = LimbsDecomposition.decompose(u_i_x_cmT[3]);
|
||||
cmT_x_limbs = LimbsDecomposition.decompose(cmT_r[0]);
|
||||
cmT_y_limbs = LimbsDecomposition.decompose(cmT_r[1]);
|
||||
|
||||
for (uint8 k = 0; k < {{num_limbs}}; k++) {
|
||||
public_inputs[{{ z_len * 2 + 5 + num_limbs * 4 }} + 4 + k] = cmT_x_limbs[k];
|
||||
public_inputs[{{ z_len * 2 + 5 + num_limbs * 5}} + 4 + k] = cmT_y_limbs[k];
|
||||
public_inputs[{{ z_len * 2 + 2 + num_limbs * 4 }} + 4 + k] = cmT_x_limbs[k];
|
||||
public_inputs[{{ z_len * 2 + 2 + num_limbs * 5 }} + 4 + k] = cmT_y_limbs[k];
|
||||
}
|
||||
|
||||
// last element of the groth16 proof's public inputs is `r`
|
||||
public_inputs[{{ public_inputs_len - 2 }}] = U_i_u_u_i_u_r[2];
|
||||
|
||||
public_inputs[{{ public_inputs_len - 2 }}] = cmT_r[2];
|
||||
|
||||
bool success_g16 = this.verifyProof(pA, pB, pC, public_inputs);
|
||||
require(success_g16 == true, "Groth16: verifying proof failed");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user