go-circom-prover-verifier/prover.go
prover.goRaw
1package gocircomprover
2
3import (
4 "crypto/rand"
5 "math/big"
6
7 bn256 "github.com/ethereum/go-ethereum/crypto/bn256/cloudflare"
8)
9
10type Proof struct {
11 A *bn256.G1
12 B *bn256.G2
13 C *bn256.G1
14}
15
16type ProvingKey struct {
17 A []*bn256.G1
18 B2 []*bn256.G2
19 B1 []*bn256.G1
20 C []*bn256.G1
21 NVars int
22 NPublic int
23 VkAlpha1 *bn256.G1
24 VkDelta1 *bn256.G1
25 VkBeta1 *bn256.G1
26 VkBeta2 *bn256.G2
27 VkDelta2 *bn256.G2
28 HExps []*bn256.G1
29 DomainSize int
30 PolsA []map[int]*big.Int
31 PolsB []map[int]*big.Int
32 PolsC []map[int]*big.Int
33}
34
35type Witness []*big.Int
36
37var R, _ = new(big.Int).SetString("21888242871839275222246405745257275088548364400416034343698204186575808495617", 10)
38
39func RandBigInt() (*big.Int, error) {
40 maxbits := R.BitLen()
41 b := make([]byte, (maxbits/8)-1)
42 _, err := rand.Read(b)
43 if err != nil {
44 return nil, err
45 }
46 r := new(big.Int).SetBytes(b)
47 rq := new(big.Int).Mod(r, R)
48
49 return rq, nil
50}
51
52func Prove(pk *ProvingKey, w Witness) (*Proof, []*big.Int, error) {
53 var proof Proof
54
55 r, err := RandBigInt()
56 if err != nil {
57 return nil, nil, err
58 }
59 s, err := RandBigInt()
60 if err != nil {
61 return nil, nil, err
62 }
63
64 proof.A = new(bn256.G1).ScalarBaseMult(big.NewInt(0))
65 proof.B = new(bn256.G2).ScalarBaseMult(big.NewInt(0))
66 proof.C = new(bn256.G1).ScalarBaseMult(big.NewInt(0))
67 proofBG1 := new(bn256.G1).ScalarBaseMult(big.NewInt(0))
68
69 for i := 0; i < pk.NVars; i++ {
70 proof.A = new(bn256.G1).Add(proof.A, new(bn256.G1).ScalarMult(pk.A[i], w[i]))
71 proof.B = new(bn256.G2).Add(proof.B, new(bn256.G2).ScalarMult(pk.B2[i], w[i]))
72 proofBG1 = new(bn256.G1).Add(proofBG1, new(bn256.G1).ScalarMult(pk.B1[i], w[i]))
73 }
74
75 for i := pk.NPublic + 1; i < pk.NVars; i++ {
76 proof.C = new(bn256.G1).Add(proof.C, new(bn256.G1).ScalarMult(pk.C[i], w[i]))
77 }
78
79 proof.A = new(bn256.G1).Add(proof.A, pk.VkAlpha1)
80 proof.A = new(bn256.G1).Add(proof.A, new(bn256.G1).ScalarMult(pk.VkDelta1, r))
81
82 proof.B = new(bn256.G2).Add(proof.B, pk.VkBeta2)
83 proof.B = new(bn256.G2).Add(proof.B, new(bn256.G2).ScalarMult(pk.VkDelta2, s))
84
85 proofBG1 = new(bn256.G1).Add(proofBG1, pk.VkBeta1)
86 proofBG1 = new(bn256.G1).Add(proofBG1, new(bn256.G1).ScalarMult(pk.VkDelta1, s))
87
88 // TODO
89 // h := calculateH(pk, w)
90 h := []*big.Int{} // TMP
91
92 for i := 0; i < len(h); i++ {
93 proof.C = new(bn256.G1).Add(proof.C, new(bn256.G1).ScalarMult(pk.HExps[i], h[i]))
94 }
95 proof.C = new(bn256.G1).Add(proof.C, new(bn256.G1).ScalarMult(proof.A, s))
96 proof.C = new(bn256.G1).Add(proof.C, new(bn256.G1).ScalarMult(proofBG1, r))
97 rsneg := new(big.Int).Mod(new(big.Int).Neg(new(big.Int).Mul(r, s)), R) // FAdd & FMul
98 proof.C = new(bn256.G1).Add(proof.C, new(bn256.G1).ScalarMult(pk.VkDelta1, rsneg))
99
100 pubSignals := w[1 : pk.NPublic+1]
101
102 return &proof, pubSignals, nil
103}