diff --git a/benchmark.go b/benchmark.go index 7ba592f..320ed8e 100644 --- a/benchmark.go +++ b/benchmark.go @@ -40,7 +40,7 @@ func (circuit *BenchmarkPlonky2VerifierCircuit) Define(api frontend.API) error { return nil } -func compileCircuit(plonky2Circuit string, profileCircuit bool, serialize bool, outputSolidity bool) (constraint.ConstraintSystem, groth16.ProvingKey, groth16.VerifyingKey) { +func compileCircuit(plonky2Circuit string, profileCircuit bool, serialize bool, outputSolidity bool, dummy bool) (constraint.ConstraintSystem, groth16.ProvingKey, groth16.VerifyingKey) { circuit := BenchmarkPlonky2VerifierCircuit{ plonky2CircuitName: plonky2Circuit, } @@ -76,9 +76,17 @@ func compileCircuit(plonky2Circuit string, profileCircuit bool, serialize bool, fR1CS.Close() } */ + var pk groth16.ProvingKey + var vk groth16.VerifyingKey fmt.Println("Running circuit setup", time.Now()) - pk, vk, err := groth16.Setup(r1cs) + if dummy { + fmt.Println("Using dummy setup") + pk, err = groth16.DummySetup(r1cs) + } else { + fmt.Println("Using real setup") + pk, vk, err = groth16.Setup(r1cs) + } if err != nil { fmt.Println(err) os.Exit(1) @@ -132,6 +140,11 @@ func createProof(plonky2Circuit string, r1cs constraint.ConstraintSystem, pk gro fProof.Close() } + if vk == nil { + fmt.Println("vk is nil, means you're using dummy setup and we skip verification step") + return proof + } + fmt.Println("Verifying proof", time.Now()) err = groth16.Verify(proof, vk, publicWitness) if err != nil { @@ -187,6 +200,6 @@ func main() { os.Exit(1) } - r1cs, pk, vk := compileCircuit(*plonky2Circuit, *profileCircuit, *serialize, *outputSolidity) + r1cs, pk, vk := compileCircuit(*plonky2Circuit, *profileCircuit, *serialize, *outputSolidity, true) createProof(*plonky2Circuit, r1cs, pk, vk, *serialize) } diff --git a/goldilocks/base.go b/goldilocks/base.go index c4aff35..14f8ed4 100644 --- a/goldilocks/base.go +++ b/goldilocks/base.go @@ -323,8 +323,18 @@ func (p *GoldilocksApi) RangeCheck(x GoldilocksVariable) { panic(err) } + // We check that this is a valid decomposition of the Goldilock's element and range-check each limb. mostSigBits := result[0] leastSigBits := result[1] + p.api.AssertIsEqual( + p.api.Add( + p.api.Mul(mostSigBits, uint64(math.Pow(2, 32))), + leastSigBits, + ), + x.Limb, + ) + rangeChecker.Check(mostSigBits, 32) + rangeChecker.Check(leastSigBits, 32) // If the most significant bits are all 1, then we need to check that the least significant bits are all zero // in order for element to be less than the Goldilock's modulus.