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