/ GrothExamples / src / multiplication_proof.jl
multiplication_proof.jl
  1  """
  2  End-to-end example: Groth16 proof for r = x * y * z * u
  3  
  4  This example demonstrates the complete workflow:
  5  1. Create R1CS for the computation
  6  2. Convert R1CS to QAP
  7  3. Generate trusted setup
  8  4. Create a proof
  9  5. Verify the proof
 10  """
 11  
 12  # Add the parent directory to the load path
 13  push!(LOAD_PATH, dirname(@__DIR__))
 14  
 15  using GrothAlgebra
 16  using GrothCurves
 17  using GrothProofs
 18  
 19  function main()
 20      println("=" ^ 60)
 21      println("Groth16 Proof System Example: r = x * y * z * u")
 22      println("=" ^ 60)
 23      
 24      # Step 1: Create the R1CS
 25      println("\n1. Creating R1CS for r = x * y * z * u")
 26      println("   Variables: [1, r, x, y, z, u, v1, v2]")
 27      println("   Constraints:")
 28      println("   - v1 = x * y")
 29      println("   - v2 = z * u")
 30      println("   - r = v1 * v2")
 31      
 32      r1cs = create_r1cs_example_multiplication()
 33      println("   ✓ R1CS created with $(r1cs.num_constraints) constraints and $(r1cs.num_vars) variables")
 34      
 35      # Step 2: Create a witness with specific values
 36      x, y, z, u = 3, 5, 7, 11
 37      println("\n2. Creating witness with values:")
 38      println("   x = $x, y = $y, z = $z, u = $u")
 39      
 40      witness = create_witness_multiplication(x, y, z, u)
 41      r = x * y * z * u
 42      println("   Expected result: r = $r")
 43      
 44      # Verify the witness satisfies the R1CS
 45      if is_satisfied(r1cs, witness)
 46          println("   ✓ Witness satisfies R1CS constraints")
 47      else
 48          println("   ✗ Witness does NOT satisfy R1CS constraints")
 49          return
 50      end
 51      
 52      # Step 3: Convert R1CS to QAP
 53      println("\n3. Converting R1CS to QAP")
 54      qap = r1cs_to_qap(r1cs)
 55      println("   ✓ QAP created with degree-$(degree(qap.t)) target polynomial")
 56      println("   Evaluation domain points: $(qap.points)")
 57      println("   Coset offset for FFTs: $(coset_offset(qap.coset_domain))")
 58      
 59      # Step 4: Generate production-style keys (CRS)
 60      println("\n4. Generating Groth16 keys (CRS)")
 61      keypair = setup_full(qap)
 62      println("   ✓ Keys generated (ProvingKey + VerificationKey)")
 63      
 64      # Step 5: Generate proof
 65      println("\n5. Generating Groth16 proof")
 66      proof = prove_full(keypair.pk, qap, witness)
 67      println("   ✓ Proof generated:")
 68      println("   - [A]₁ ∈ G1")
 69      println("   - [B]₂ ∈ G2")
 70      println("   - [C]₁ ∈ G1")
 71      
 72      # Show proof elements in affine coordinates
 73      A_affine = to_affine(proof.A)
 74      C_affine = to_affine(proof.C)
 75      println("\n   Proof elements (affine coordinates):")
 76      println("   A.x = $(A_affine[1].value)")
 77      println("   A.y = $(A_affine[2].value)")
 78      println("   C.x = $(C_affine[1].value)")
 79      println("   C.y = $(C_affine[2].value)")
 80      
 81      # Step 6: Verify proof
 82      println("\n6. Verifying proof")
 83      
 84      # Extract public inputs (first 6 elements of witness: 1, r, x, y, z, u)
 85      public_inputs = witness.values[1:r1cs.num_public]
 86      
 87      # Verify using pairing check
 88      println("   Checking pairing equation: e(A,B) = e(α,β) · e(vk_x,γ) · e(C,δ)")
 89      is_valid = verify_full(keypair.vk, proof, public_inputs)
 90      
 91      if is_valid
 92          println("   ✓ Proof is VALID!")
 93      else
 94          println("   ✗ Proof is INVALID!")
 95      end
 96      
 97      # Additional verification details
 98      println("\n7. Verification Summary")
 99      println("   Public inputs verified:")
100      println("   - r = $(witness.values[2].value)")
101      println("   - x = $(witness.values[3].value)")
102      println("   - y = $(witness.values[4].value)")
103      println("   - z = $(witness.values[5].value)")
104      println("   - u = $(witness.values[6].value)")
105      println("   Private witnesses (not revealed to verifier):")
106      println("   - v1 = $(witness.values[7].value) (= x*y)")
107      println("   - v2 = $(witness.values[8].value) (= z*u)")
108      
109      println("\n" * "=" ^ 60)
110      println("Example completed successfully!")
111      println("=" ^ 60)
112  end
113  
114  # Run the example
115  main()