You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

324 lines
8.2 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. package main
  2. import (
  3. "bufio"
  4. "bytes"
  5. "encoding/json"
  6. "errors"
  7. "fmt"
  8. "io/ioutil"
  9. "log"
  10. "math/big"
  11. "os"
  12. snark "github.com/mottla/go-snark"
  13. "github.com/mottla/go-snark/circuitcompiler"
  14. "github.com/mottla/go-snark/r1csqap"
  15. "github.com/urfave/cli"
  16. )
  17. func panicErr(err error) {
  18. if err != nil {
  19. panic(err)
  20. }
  21. }
  22. var commands = []cli.Command{
  23. {
  24. Name: "compile",
  25. Aliases: []string{},
  26. Usage: "compile a circuit",
  27. Action: CompileCircuit,
  28. },
  29. {
  30. Name: "trustedsetup",
  31. Aliases: []string{},
  32. Usage: "generate trusted setup for a circuit",
  33. Action: TrustedSetup,
  34. },
  35. {
  36. Name: "genproofs",
  37. Aliases: []string{},
  38. Usage: "generate the snark proofs",
  39. Action: GenerateProofs,
  40. },
  41. {
  42. Name: "verify",
  43. Aliases: []string{},
  44. Usage: "verify the snark proofs",
  45. Action: VerifyProofs,
  46. },
  47. }
  48. func main() {
  49. app := cli.NewApp()
  50. app.Name = "go-snarks-cli"
  51. app.Version = "0.0.1-alpha"
  52. app.Flags = []cli.Flag{
  53. cli.StringFlag{Name: "config"},
  54. }
  55. app.Commands = commands
  56. err := app.Run(os.Args)
  57. if err != nil {
  58. log.Fatal(err)
  59. }
  60. }
  61. func CompileCircuit(context *cli.Context) error {
  62. fmt.Println("cli")
  63. circuitPath := context.Args().Get(0)
  64. // read circuit file
  65. circuitFile, err := os.Open(circuitPath)
  66. panicErr(err)
  67. // parse circuit code
  68. parser := circuitcompiler.NewParser(bufio.NewReader(circuitFile))
  69. circuit, err := parser.Parse()
  70. panicErr(err)
  71. fmt.Println("\ncircuit data:", circuit)
  72. // read privateInputs file
  73. privateInputsFile, err := ioutil.ReadFile("privateInputs.json")
  74. panicErr(err)
  75. // read publicInputs file
  76. publicInputsFile, err := ioutil.ReadFile("publicInputs.json")
  77. panicErr(err)
  78. // parse inputs from inputsFile
  79. var inputs circuitcompiler.Inputs
  80. err = json.Unmarshal([]byte(string(privateInputsFile)), &inputs.Private)
  81. panicErr(err)
  82. err = json.Unmarshal([]byte(string(publicInputsFile)), &inputs.Public)
  83. panicErr(err)
  84. // calculate wittness
  85. w, err := circuit.CalculateWitness(inputs.Private, inputs.Public)
  86. panicErr(err)
  87. fmt.Println("\nwitness", w)
  88. // flat code to R1CS
  89. fmt.Println("\ngenerating R1CS from flat code")
  90. a, b, c := circuit.GenerateR1CS()
  91. fmt.Println("\nR1CS:")
  92. fmt.Println("a:", a)
  93. fmt.Println("b:", b)
  94. fmt.Println("c:", c)
  95. // R1CS to QAP
  96. alphas, betas, gammas, zx := snark.Utils.PF.R1CSToQAP(a, b, c)
  97. fmt.Println("qap")
  98. fmt.Println(alphas)
  99. fmt.Println(betas)
  100. fmt.Println(gammas)
  101. ax, bx, cx, px := snark.Utils.PF.CombinePolynomials(w, alphas, betas, gammas)
  102. hx := snark.Utils.PF.DivisorPolynomial(px, zx)
  103. // hx==px/zx so px==hx*zx
  104. // assert.Equal(t, px, snark.Utils.PF.Mul(hx, zx))
  105. if !r1csqap.BigArraysEqual(px, snark.Utils.PF.Mul(hx, zx)) {
  106. panic(errors.New("px != hx*zx"))
  107. }
  108. // p(x) = a(x) * b(x) - c(x) == h(x) * z(x)
  109. abc := snark.Utils.PF.Sub(snark.Utils.PF.Mul(ax, bx), cx)
  110. // assert.Equal(t, abc, px)
  111. if !r1csqap.BigArraysEqual(abc, px) {
  112. panic(errors.New("abc != px"))
  113. }
  114. hz := snark.Utils.PF.Mul(hx, zx)
  115. if !r1csqap.BigArraysEqual(abc, hz) {
  116. panic(errors.New("abc != hz"))
  117. }
  118. // assert.Equal(t, abc, hz)
  119. div, rem := snark.Utils.PF.Div(px, zx)
  120. if !r1csqap.BigArraysEqual(hx, div) {
  121. panic(errors.New("hx != div"))
  122. }
  123. // assert.Equal(t, hx, div)
  124. // assert.Equal(t, rem, r1csqap.ArrayOfBigZeros(4))
  125. for _, r := range rem {
  126. if !bytes.Equal(r.Bytes(), big.NewInt(int64(0)).Bytes()) {
  127. panic(errors.New("error:error: px/zx rem not equal to zeros"))
  128. }
  129. }
  130. // store circuit to json
  131. jsonData, err := json.Marshal(circuit)
  132. panicErr(err)
  133. // store setup into file
  134. jsonFile, err := os.Create("compiledcircuit.json")
  135. panicErr(err)
  136. defer jsonFile.Close()
  137. jsonFile.Write(jsonData)
  138. jsonFile.Close()
  139. fmt.Println("Compiled Circuit data written to ", jsonFile.Name())
  140. return nil
  141. }
  142. func TrustedSetup(context *cli.Context) error {
  143. // open compiledcircuit.json
  144. compiledcircuitFile, err := ioutil.ReadFile("compiledcircuit.json")
  145. panicErr(err)
  146. var circuit circuitcompiler.Circuit
  147. json.Unmarshal([]byte(string(compiledcircuitFile)), &circuit)
  148. panicErr(err)
  149. // read privateInputs file
  150. privateInputsFile, err := ioutil.ReadFile("privateInputs.json")
  151. panicErr(err)
  152. // read publicInputs file
  153. publicInputsFile, err := ioutil.ReadFile("publicInputs.json")
  154. panicErr(err)
  155. // parse inputs from inputsFile
  156. var inputs circuitcompiler.Inputs
  157. err = json.Unmarshal([]byte(string(privateInputsFile)), &inputs.Private)
  158. panicErr(err)
  159. err = json.Unmarshal([]byte(string(publicInputsFile)), &inputs.Public)
  160. panicErr(err)
  161. // calculate wittness
  162. w, err := circuit.CalculateWitness(inputs.Private, inputs.Public)
  163. panicErr(err)
  164. // R1CS to QAP
  165. alphas, betas, gammas, _ := snark.Utils.PF.R1CSToQAP(circuit.R1CS.A, circuit.R1CS.B, circuit.R1CS.C)
  166. fmt.Println("qap")
  167. fmt.Println(alphas)
  168. fmt.Println(betas)
  169. fmt.Println(gammas)
  170. // calculate trusted setup
  171. setup, err := snark.GenerateTrustedSetup(len(w), circuit, alphas, betas, gammas)
  172. panicErr(err)
  173. fmt.Println("\nt:", setup.Toxic.T)
  174. // remove setup.Toxic
  175. var tsetup snark.Setup
  176. tsetup.Pk = setup.Pk
  177. tsetup.Vk = setup.Vk
  178. tsetup.G1T = setup.G1T
  179. tsetup.G2T = setup.G2T
  180. // store setup to json
  181. jsonData, err := json.Marshal(tsetup)
  182. panicErr(err)
  183. // store setup into file
  184. jsonFile, err := os.Create("trustedsetup.json")
  185. panicErr(err)
  186. defer jsonFile.Close()
  187. jsonFile.Write(jsonData)
  188. jsonFile.Close()
  189. fmt.Println("Trusted Setup data written to ", jsonFile.Name())
  190. return nil
  191. }
  192. func GenerateProofs(context *cli.Context) error {
  193. // open compiledcircuit.json
  194. compiledcircuitFile, err := ioutil.ReadFile("compiledcircuit.json")
  195. panicErr(err)
  196. var circuit circuitcompiler.Circuit
  197. json.Unmarshal([]byte(string(compiledcircuitFile)), &circuit)
  198. panicErr(err)
  199. // open trustedsetup.json
  200. trustedsetupFile, err := ioutil.ReadFile("trustedsetup.json")
  201. panicErr(err)
  202. var trustedsetup snark.Setup
  203. json.Unmarshal([]byte(string(trustedsetupFile)), &trustedsetup)
  204. panicErr(err)
  205. // read privateInputs file
  206. privateInputsFile, err := ioutil.ReadFile("privateInputs.json")
  207. panicErr(err)
  208. // read publicInputs file
  209. publicInputsFile, err := ioutil.ReadFile("publicInputs.json")
  210. panicErr(err)
  211. // parse inputs from inputsFile
  212. var inputs circuitcompiler.Inputs
  213. err = json.Unmarshal([]byte(string(privateInputsFile)), &inputs.Private)
  214. panicErr(err)
  215. err = json.Unmarshal([]byte(string(publicInputsFile)), &inputs.Public)
  216. panicErr(err)
  217. // calculate wittness
  218. w, err := circuit.CalculateWitness(inputs.Private, inputs.Public)
  219. panicErr(err)
  220. fmt.Println("witness", w)
  221. // flat code to R1CS
  222. a := circuit.R1CS.A
  223. b := circuit.R1CS.B
  224. c := circuit.R1CS.C
  225. // R1CS to QAP
  226. alphas, betas, gammas, _ := snark.Utils.PF.R1CSToQAP(a, b, c)
  227. _, _, _, px := snark.Utils.PF.CombinePolynomials(w, alphas, betas, gammas)
  228. hx := snark.Utils.PF.DivisorPolynomial(px, trustedsetup.Pk.Z)
  229. fmt.Println(circuit)
  230. fmt.Println(trustedsetup.G1T)
  231. fmt.Println(hx)
  232. fmt.Println(w)
  233. proof, err := snark.GenerateProofs(circuit, trustedsetup, w, px)
  234. panicErr(err)
  235. fmt.Println("\n proofs:")
  236. fmt.Println(proof)
  237. // store proofs to json
  238. jsonData, err := json.Marshal(proof)
  239. panicErr(err)
  240. // store proof into file
  241. jsonFile, err := os.Create("proofs.json")
  242. panicErr(err)
  243. defer jsonFile.Close()
  244. jsonFile.Write(jsonData)
  245. jsonFile.Close()
  246. fmt.Println("Proofs data written to ", jsonFile.Name())
  247. return nil
  248. }
  249. func VerifyProofs(context *cli.Context) error {
  250. // open proofs.json
  251. proofsFile, err := ioutil.ReadFile("proofs.json")
  252. panicErr(err)
  253. var proof snark.Proof
  254. json.Unmarshal([]byte(string(proofsFile)), &proof)
  255. panicErr(err)
  256. // open compiledcircuit.json
  257. compiledcircuitFile, err := ioutil.ReadFile("compiledcircuit.json")
  258. panicErr(err)
  259. var circuit circuitcompiler.Circuit
  260. json.Unmarshal([]byte(string(compiledcircuitFile)), &circuit)
  261. panicErr(err)
  262. // open trustedsetup.json
  263. trustedsetupFile, err := ioutil.ReadFile("trustedsetup.json")
  264. panicErr(err)
  265. var trustedsetup snark.Setup
  266. json.Unmarshal([]byte(string(trustedsetupFile)), &trustedsetup)
  267. panicErr(err)
  268. // read publicInputs file
  269. publicInputsFile, err := ioutil.ReadFile("publicInputs.json")
  270. panicErr(err)
  271. var publicSignals []*big.Int
  272. err = json.Unmarshal([]byte(string(publicInputsFile)), &publicSignals)
  273. panicErr(err)
  274. verified := snark.VerifyProof(circuit, trustedsetup, proof, publicSignals, true)
  275. if !verified {
  276. fmt.Println("ERROR: proofs not verified")
  277. } else {
  278. fmt.Println("Proofs verified")
  279. }
  280. return nil
  281. }