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.

233 lines
4.7 KiB

  1. package bellmanverifier
  2. import (
  3. "bytes"
  4. "encoding/hex"
  5. "encoding/json"
  6. "fmt"
  7. "math/big"
  8. "strings"
  9. bn256 "github.com/ethereum/go-ethereum/crypto/bn256/cloudflare"
  10. )
  11. var q *big.Int
  12. func init() {
  13. var err error
  14. q, err = stringToBigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617")
  15. if err != nil {
  16. panic(err)
  17. }
  18. }
  19. // Vk is the Verification Key data structure
  20. type Vk struct {
  21. Alpha *bn256.G1
  22. Beta *bn256.G2
  23. Gamma *bn256.G2
  24. Delta *bn256.G2
  25. GammaABC []*bn256.G1
  26. }
  27. // VkRaw is the Verification Key data structure in string format (from json)
  28. type VkRaw struct {
  29. Alpha []string `json:"alpha_g1"`
  30. Beta [][]string `json:"beta_g2"`
  31. Gamma [][]string `json:"gamma_g2"`
  32. Delta [][]string `json:"delta_g2"`
  33. GammaABC [][]string `json:"ic"`
  34. }
  35. // Proof is the Groth16 Proof data structure
  36. type Proof struct {
  37. A *bn256.G1
  38. B *bn256.G2
  39. C *bn256.G1
  40. }
  41. // ProofRaw is the Groth16 Proof data structure in string format (from json)
  42. type ProofRaw struct {
  43. A []string `json:"a"`
  44. B [][]string `json:"b"`
  45. C []string `json:"c"`
  46. Inputs []string `json:"inputs"`
  47. }
  48. func hexToG1(h []string) (*bn256.G1, error) {
  49. in := ""
  50. for i := range h {
  51. in += strings.TrimPrefix(h[i], "0x")
  52. }
  53. b, err := hex.DecodeString(in)
  54. if err != nil {
  55. return nil, err
  56. }
  57. p := new(bn256.G1)
  58. _, err = p.Unmarshal(b)
  59. return p, err
  60. }
  61. func hexToG2Regular(h [][]string) (*bn256.G2, error) {
  62. in := ""
  63. for i := 0; i < len(h); i++ {
  64. for j := 0; j < len(h[i]); j++ {
  65. in += strings.TrimPrefix(h[i][j], "0x")
  66. }
  67. }
  68. b, err := hex.DecodeString(in)
  69. if err != nil {
  70. return nil, err
  71. }
  72. p := new(bn256.G2)
  73. _, err = p.Unmarshal(b)
  74. return p, err
  75. }
  76. func hexToG2(h [][]string) (*bn256.G2, error) {
  77. in := ""
  78. in += strings.TrimPrefix(h[0][1], "0x") // note that values are switched
  79. in += strings.TrimPrefix(h[0][0], "0x")
  80. in += strings.TrimPrefix(h[1][1], "0x")
  81. in += strings.TrimPrefix(h[1][0], "0x")
  82. b, err := hex.DecodeString(in)
  83. if err != nil {
  84. return nil, err
  85. }
  86. p := new(bn256.G2)
  87. _, err = p.Unmarshal(b)
  88. return p, err
  89. }
  90. func stringToBigInt(s string) (*big.Int, error) {
  91. base := 10
  92. if bytes.HasPrefix([]byte(s), []byte("0x")) {
  93. base = 16
  94. s = strings.TrimPrefix(s, "0x")
  95. }
  96. n, ok := new(big.Int).SetString(s, base)
  97. if !ok {
  98. return nil, fmt.Errorf("Can not parse string to *big.Int: %s", s)
  99. }
  100. return n, nil
  101. }
  102. // ParsePublicRaw takes a json []byte and outputs the []*big.Int struct
  103. func ParsePublicRaw(pj []byte) ([]*big.Int, error) {
  104. var pr []string
  105. err := json.Unmarshal(pj, &pr)
  106. if err != nil {
  107. return nil, err
  108. }
  109. var public []*big.Int
  110. for _, s := range pr {
  111. sb, err := stringToBigInt(s)
  112. if err != nil {
  113. return nil, err
  114. }
  115. public = append(public, sb)
  116. }
  117. return public, nil
  118. }
  119. // ParseVkRaw takes a json []byte and outputs the *Vk struct
  120. func ParseVkRaw(vj []byte) (*Vk, error) {
  121. var vr VkRaw
  122. err := json.Unmarshal(vj, &vr)
  123. if err != nil {
  124. return nil, err
  125. }
  126. v, err := vkRawToVk(vr)
  127. return v, err
  128. }
  129. // ParseProofRaw takes a json []byte and outputs the *Proof struct
  130. func ParseProofRaw(pj []byte) (*Proof, error) {
  131. var pr ProofRaw
  132. err := json.Unmarshal(pj, &pr)
  133. if err != nil {
  134. return nil, err
  135. }
  136. p, err := proofRawToProof(pr)
  137. return p, err
  138. }
  139. func vkRawToVk(vr VkRaw) (*Vk, error) {
  140. var v Vk
  141. var err error
  142. v.Alpha, err = hexToG1(vr.Alpha)
  143. if err != nil {
  144. return nil, err
  145. }
  146. v.Beta, err = hexToG2(vr.Beta)
  147. if err != nil {
  148. return nil, err
  149. }
  150. v.Gamma, err = hexToG2(vr.Gamma)
  151. if err != nil {
  152. return nil, err
  153. }
  154. v.Delta, err = hexToG2(vr.Delta)
  155. if err != nil {
  156. return nil, err
  157. }
  158. for i := 0; i < len(vr.GammaABC); i++ {
  159. p, err := hexToG1(vr.GammaABC[i])
  160. if err != nil {
  161. return nil, err
  162. }
  163. v.GammaABC = append(v.GammaABC, p)
  164. }
  165. return &v, nil
  166. }
  167. func proofRawToProof(pr ProofRaw) (*Proof, error) {
  168. var p Proof
  169. var err error
  170. p.A, err = hexToG1(pr.A)
  171. if err != nil {
  172. return nil, err
  173. }
  174. p.B, err = hexToG2(pr.B)
  175. if err != nil {
  176. return nil, err
  177. }
  178. p.C, err = hexToG1(pr.C)
  179. if err != nil {
  180. return nil, err
  181. }
  182. return &p, nil
  183. }
  184. // Verify performs the Groth16 zkSnark verification
  185. func Verify(vk *Vk, proof *Proof, inputs []*big.Int) bool {
  186. if len(inputs)+1 != len(vk.GammaABC) {
  187. fmt.Println("len(inputs)+1 != len(vk.GammaABC)")
  188. return false
  189. }
  190. vkX := new(bn256.G1).ScalarBaseMult(big.NewInt(0))
  191. for i := 0; i < len(inputs); i++ {
  192. // check input inside field
  193. if inputs[0].Cmp(q) != -1 {
  194. return false
  195. }
  196. vkX = new(bn256.G1).Add(vkX, new(bn256.G1).ScalarMult(vk.GammaABC[i+1], inputs[i]))
  197. }
  198. vkX = new(bn256.G1).Add(vkX, vk.GammaABC[0])
  199. g1 := []*bn256.G1{proof.A, vk.Alpha.Neg(vk.Alpha), vkX.Neg(vkX), proof.C.Neg(proof.C)}
  200. g2 := []*bn256.G2{proof.B, vk.Beta, vk.Gamma, vk.Delta}
  201. return bn256.PairingCheck(g1, g2)
  202. }