/
build.go
136 lines (115 loc) · 2.97 KB
/
build.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package succinct
import (
"fmt"
"os"
"github.com/consensys/gnark-crypto/ecc"
"github.com/consensys/gnark/backend/groth16"
"github.com/consensys/gnark/constraint"
)
type CircuitBuild struct {
pk groth16.ProvingKey
vk groth16.VerifyingKey
r1cs constraint.ConstraintSystem
}
// Export exports the R1CS, proving key, and verifying key to files.
func (build *CircuitBuild) Export() {
// Make build directory.
err := os.MkdirAll("build", 0755)
if err != nil {
fmt.Printf("Failed to create directory: %v\n", err)
return
}
// Write R1CS.
r1csFile, err := os.Create("build/r1cs.bin")
if err != nil {
fmt.Println("Failed to create file:", err)
return
}
defer r1csFile.Close()
_, err = build.r1cs.WriteTo(r1csFile)
if err != nil {
fmt.Println("Failed to write data:", err)
return
}
// Create the proving key file.
pkFile, err := os.Create("build/pkey.bin")
if err != nil {
fmt.Println("Failed to create file:", err)
return
}
defer pkFile.Close()
// Write proving key.
_, err = build.pk.WriteTo(pkFile)
if err != nil {
fmt.Println("Failed to write data:", err)
return
}
// Write verification key.
vkFile, err := os.Create("build/vkey.bin")
if err != nil {
fmt.Println("Failed to create file:", err)
return
}
defer vkFile.Close()
_, err = build.vk.WriteTo(vkFile)
if err != nil {
fmt.Println("Failed to write data:", err)
return
}
// Write verifier smart contract into a file.
verifierFile, err := os.Create("build/FunctionVerifier.sol")
if err != nil {
fmt.Println("Failed to create file:", err)
return
}
defer verifierFile.Close()
svk := &SuccinctVerifyingKey{VerifyingKey: build.vk}
err = svk.ExportIFunctionVerifierSolidity(verifierFile)
if err != nil {
fmt.Println("Failed to export solidity verifier:", err)
return
}
}
// ImportCircuitBuild imports the R1CS, proving key, and verifying key from files.
func ImportCircuitBuild() (*CircuitBuild, error) {
r1cs := groth16.NewCS(ecc.BN254)
// Read the proving key file.
pkFile, err := os.Open("build/pkey.bin")
if err != nil {
return nil, fmt.Errorf("failed to open file: %w", err)
}
defer pkFile.Close()
// Deserialize the proving key.
pk := groth16.NewProvingKey(ecc.BN254)
_, err = pk.ReadFrom(pkFile)
if err != nil {
return nil, fmt.Errorf("failed to read data: %w", err)
}
vkFile, err := os.Open("build/vkey.bin")
if err != nil {
return nil, fmt.Errorf("failed to open file: %w", err)
}
defer vkFile.Close()
// Deserialize the verifying key.
vk := groth16.NewVerifyingKey(ecc.BN254)
_, err = vk.ReadFrom(vkFile)
if err != nil {
return nil, fmt.Errorf("failed to read data: %w", err)
}
// Read the R1CS file.
r1csFile, err := os.Open("build/r1cs.bin")
if err != nil {
return nil, fmt.Errorf("failed to open file: %w", err)
}
defer r1csFile.Close()
// Deserialize the R1CS.
_, err = r1cs.ReadFrom(r1csFile)
if err != nil {
return nil, fmt.Errorf("failed to read data: %w", err)
}
return &CircuitBuild{
pk: pk,
vk: vk,
r1cs: r1cs,
}, nil
}