arnaucube
arnaucube/go-circom-prover-verifierPublic Self-hosted repository
go-circom-prover-verifier/parsers/parsers.go
parsers/parsers.goRaw
   1package parsers
   2
   3import (
   4	"bufio"
   5	"bytes"
   6	"encoding/binary"
   7	"encoding/hex"
   8	"encoding/json"
   9	"fmt"
  10	"io"
  11	"math/big"
  12	"os"
  13	"strconv"
  14	"strings"
  15
  16	bn256 "github.com/ethereum/go-ethereum/crypto/bn256/cloudflare"
  17	"github.com/iden3/go-circom-prover-verifier/types"
  18)
  19
  20// PkString is the equivalent to the Pk struct in string representation, containing the ProvingKey
  21type PkString struct {
  22	A          [][]string          `json:"A"`
  23	B2         [][][]string        `json:"B2"`
  24	B1         [][]string          `json:"B1"`
  25	C          [][]string          `json:"C"`
  26	NVars      int                 `json:"nVars"`
  27	NPublic    int                 `json:"nPublic"`
  28	VkAlpha1   []string            `json:"vk_alfa_1"`
  29	VkDelta1   []string            `json:"vk_delta_1"`
  30	VkBeta1    []string            `json:"vk_beta_1"`
  31	VkBeta2    [][]string          `json:"vk_beta_2"`
  32	VkDelta2   [][]string          `json:"vk_delta_2"`
  33	HExps      [][]string          `json:"hExps"`
  34	DomainSize int                 `json:"domainSize"`
  35	PolsA      []map[string]string `json:"polsA"`
  36	PolsB      []map[string]string `json:"polsB"`
  37}
  38
  39// WitnessString contains the Witness in string representation
  40type WitnessString []string
  41
  42// ProofString is the equivalent to the Proof struct in string representation
  43type ProofString struct {
  44	A        []string   `json:"pi_a"`
  45	B        [][]string `json:"pi_b"`
  46	C        []string   `json:"pi_c"`
  47	Protocol string     `json:"protocol"`
  48}
  49
  50// VkString is the Verification Key data structure in string format (from json)
  51type VkString struct {
  52	Alpha []string   `json:"vk_alfa_1"`
  53	Beta  [][]string `json:"vk_beta_2"`
  54	Gamma [][]string `json:"vk_gamma_2"`
  55	Delta [][]string `json:"vk_delta_2"`
  56	IC    [][]string `json:"IC"`
  57}
  58
  59// ParseWitness parses the json []byte data into the Witness struct
  60func ParseWitness(wJson []byte) (types.Witness, error) {
  61	var ws WitnessString
  62	err := json.Unmarshal(wJson, &ws)
  63	if err != nil {
  64		return nil, err
  65	}
  66
  67	var w types.Witness
  68	for i := 0; i < len(ws); i++ {
  69		bi, err := stringToBigInt(ws[i])
  70		if err != nil {
  71			return nil, err
  72		}
  73		w = append(w, bi)
  74	}
  75	return w, nil
  76}
  77
  78// ParsePk parses the json []byte data into the Pk struct
  79func ParsePk(pkJson []byte) (*types.Pk, error) {
  80	var pkStr PkString
  81	err := json.Unmarshal(pkJson, &pkStr)
  82	if err != nil {
  83		return nil, err
  84	}
  85	pk, err := pkStringToPk(pkStr)
  86	return pk, err
  87}
  88
  89func pkStringToPk(ps PkString) (*types.Pk, error) {
  90	var p types.Pk
  91	var err error
  92
  93	p.A, err = arrayStringToG1(ps.A)
  94	if err != nil {
  95		return nil, err
  96	}
  97	p.B2, err = arrayStringToG2(ps.B2)
  98	if err != nil {
  99		return nil, err
 100	}
 101	p.B1, err = arrayStringToG1(ps.B1)
 102	if err != nil {
 103		return nil, err
 104	}
 105	p.C, err = arrayStringToG1(ps.C)
 106	if err != nil {
 107		return nil, err
 108	}
 109
 110	p.NVars = ps.NVars
 111	p.NPublic = ps.NPublic
 112
 113	p.VkAlpha1, err = stringToG1(ps.VkAlpha1)
 114	if err != nil {
 115		return nil, err
 116	}
 117
 118	p.VkDelta1, err = stringToG1(ps.VkDelta1)
 119	if err != nil {
 120		return nil, err
 121	}
 122
 123	p.VkBeta1, err = stringToG1(ps.VkBeta1)
 124	if err != nil {
 125		return nil, err
 126	}
 127	p.VkBeta2, err = stringToG2(ps.VkBeta2)
 128	if err != nil {
 129		return nil, err
 130	}
 131	p.VkDelta2, err = stringToG2(ps.VkDelta2)
 132	if err != nil {
 133		return nil, err
 134	}
 135
 136	p.HExps, err = arrayStringToG1(ps.HExps)
 137	if err != nil {
 138		return nil, err
 139	}
 140
 141	p.DomainSize = ps.DomainSize
 142
 143	p.PolsA, err = polsStringToBigInt(ps.PolsA)
 144	if err != nil {
 145		return nil, err
 146	}
 147	p.PolsB, err = polsStringToBigInt(ps.PolsB)
 148	if err != nil {
 149		return nil, err
 150	}
 151
 152	return &p, nil
 153}
 154
 155func proofStringToProof(pr ProofString) (*types.Proof, error) {
 156	var p types.Proof
 157	var err error
 158	p.A, err = stringToG1(pr.A)
 159	if err != nil {
 160		return nil, err
 161	}
 162
 163	p.B, err = stringToG2(pr.B)
 164	if err != nil {
 165		return nil, err
 166	}
 167
 168	p.C, err = stringToG1(pr.C)
 169	if err != nil {
 170		return nil, err
 171	}
 172
 173	return &p, nil
 174}
 175
 176// ParseProof takes a json []byte and outputs the *Proof struct
 177func ParseProof(pj []byte) (*types.Proof, error) {
 178	var pr ProofString
 179	err := json.Unmarshal(pj, &pr)
 180	if err != nil {
 181		return nil, err
 182	}
 183	p, err := proofStringToProof(pr)
 184	return p, err
 185}
 186
 187// ParsePublicSignals takes a json []byte and outputs the []*big.Int struct
 188func ParsePublicSignals(pj []byte) ([]*big.Int, error) {
 189	var pr []string
 190	err := json.Unmarshal(pj, &pr)
 191	if err != nil {
 192		return nil, err
 193	}
 194	var public []*big.Int
 195	for _, s := range pr {
 196		sb, err := stringToBigInt(s)
 197		if err != nil {
 198			return nil, err
 199		}
 200		public = append(public, sb)
 201	}
 202	return public, nil
 203}
 204
 205// ParseVk takes a json []byte and outputs the *Vk struct
 206func ParseVk(vj []byte) (*types.Vk, error) {
 207	var vr VkString
 208	err := json.Unmarshal(vj, &vr)
 209	if err != nil {
 210		return nil, err
 211	}
 212	v, err := vkStringToVk(vr)
 213	return v, err
 214}
 215
 216func vkStringToVk(vr VkString) (*types.Vk, error) {
 217	var v types.Vk
 218	var err error
 219	v.Alpha, err = stringToG1(vr.Alpha)
 220	if err != nil {
 221		return nil, err
 222	}
 223
 224	v.Beta, err = stringToG2(vr.Beta)
 225	if err != nil {
 226		return nil, err
 227	}
 228
 229	v.Gamma, err = stringToG2(vr.Gamma)
 230	if err != nil {
 231		return nil, err
 232	}
 233
 234	v.Delta, err = stringToG2(vr.Delta)
 235	if err != nil {
 236		return nil, err
 237	}
 238
 239	for i := 0; i < len(vr.IC); i++ {
 240		p, err := stringToG1(vr.IC[i])
 241		if err != nil {
 242			return nil, err
 243		}
 244		v.IC = append(v.IC, p)
 245	}
 246
 247	return &v, nil
 248}
 249
 250// polsStringToBigInt is for taking string polynomials and converting it to *big.Int polynomials
 251func polsStringToBigInt(s []map[string]string) ([]map[int]*big.Int, error) {
 252	var o []map[int]*big.Int
 253	for i := 0; i < len(s); i++ {
 254		// var oi map[int]*big.Int
 255		oi := make(map[int]*big.Int)
 256		for j, v := range s[i] {
 257			si, err := stringToBigInt(v)
 258			if err != nil {
 259				return o, err
 260			}
 261			// oi = append(oi, si)
 262			jInt, err := strconv.Atoi(j)
 263			if err != nil {
 264				return o, err
 265			}
 266			oi[jInt] = si
 267		}
 268		o = append(o, oi)
 269	}
 270	return o, nil
 271}
 272
 273// ArrayBigIntToString converts an []*big.Int into []string, used to output the Public Signals
 274func ArrayBigIntToString(bi []*big.Int) []string {
 275	var s []string
 276	for i := 0; i < len(bi); i++ {
 277		s = append(s, bi[i].String())
 278	}
 279	return s
 280}
 281
 282func arrayStringToBigInt(s []string) ([]*big.Int, error) {
 283	var o []*big.Int
 284	for i := 0; i < len(s); i++ {
 285		si, err := stringToBigInt(s[i])
 286		if err != nil {
 287			return o, nil
 288		}
 289		o = append(o, si)
 290	}
 291	return o, nil
 292}
 293
 294func stringToBigInt(s string) (*big.Int, error) {
 295	base := 10
 296	if bytes.HasPrefix([]byte(s), []byte("0x")) {
 297		base = 16
 298		s = strings.TrimPrefix(s, "0x")
 299	}
 300	n, ok := new(big.Int).SetString(s, base)
 301	if !ok {
 302		return nil, fmt.Errorf("Can not parse string to *big.Int: %s", s)
 303	}
 304	return n, nil
 305}
 306
 307func addPadding32(b []byte) []byte {
 308	if len(b) != 32 {
 309		b = addZPadding(b)
 310	}
 311	return b
 312}
 313
 314func addZPadding(b []byte) []byte {
 315	var z [32]byte
 316	var r []byte
 317	r = append(r, z[len(b):]...) // add padding on the left
 318	r = append(r, b...)
 319	return r[:32]
 320}
 321
 322func stringToBytes(s string) ([]byte, error) {
 323	if s == "1" {
 324		s = "0"
 325	}
 326	bi, ok := new(big.Int).SetString(s, 10)
 327	if !ok {
 328		return nil, fmt.Errorf("error parsing bigint stringToBytes")
 329	}
 330	b := bi.Bytes()
 331	if len(b) != 32 {
 332		b = addZPadding(b)
 333	}
 334	return b, nil
 335
 336}
 337
 338func arrayStringToG1(h [][]string) ([]*bn256.G1, error) {
 339	var o []*bn256.G1
 340	for i := 0; i < len(h); i++ {
 341		hi, err := stringToG1(h[i])
 342		if err != nil {
 343			return o, err
 344		}
 345		o = append(o, hi)
 346	}
 347	return o, nil
 348}
 349
 350func arrayStringToG2(h [][][]string) ([]*bn256.G2, error) {
 351	var o []*bn256.G2
 352	for i := 0; i < len(h); i++ {
 353		hi, err := stringToG2(h[i])
 354		if err != nil {
 355			return o, err
 356		}
 357		o = append(o, hi)
 358	}
 359	return o, nil
 360}
 361
 362func stringToG1(h []string) (*bn256.G1, error) {
 363	if len(h) <= 2 {
 364		return nil, fmt.Errorf("not enought data for stringToG1")
 365	}
 366	h = h[:2]
 367	hexa := false
 368	if len(h[0]) > 1 {
 369		if "0x" == h[0][:2] {
 370			hexa = true
 371		}
 372	}
 373	in := ""
 374
 375	var b []byte
 376	var err error
 377	if hexa {
 378		for i := range h {
 379			in += strings.TrimPrefix(h[i], "0x")
 380		}
 381		b, err = hex.DecodeString(in)
 382		if err != nil {
 383			return nil, err
 384		}
 385	} else {
 386		// TODO TMP
 387		// TODO use stringToBytes()
 388		if h[0] == "1" {
 389			h[0] = "0"
 390		}
 391		if h[1] == "1" {
 392			h[1] = "0"
 393		}
 394		bi0, ok := new(big.Int).SetString(h[0], 10)
 395		if !ok {
 396			return nil, fmt.Errorf("error parsing stringToG1")
 397		}
 398		bi1, ok := new(big.Int).SetString(h[1], 10)
 399		if !ok {
 400			return nil, fmt.Errorf("error parsing stringToG1")
 401		}
 402		b0 := bi0.Bytes()
 403		b1 := bi1.Bytes()
 404		if len(b0) != 32 {
 405			b0 = addZPadding(b0)
 406		}
 407		if len(b1) != 32 {
 408			b1 = addZPadding(b1)
 409		}
 410
 411		b = append(b, b0...)
 412		b = append(b, b1...)
 413	}
 414	p := new(bn256.G1)
 415	_, err = p.Unmarshal(b)
 416
 417	return p, err
 418}
 419
 420func stringToG2(h [][]string) (*bn256.G2, error) {
 421	if len(h) <= 2 {
 422		return nil, fmt.Errorf("not enought data for stringToG2")
 423	}
 424	h = h[:2]
 425	hexa := false
 426	if len(h[0][0]) > 1 {
 427		if "0x" == h[0][0][:2] {
 428			hexa = true
 429		}
 430	}
 431	in := ""
 432	var b []byte
 433	var err error
 434	if hexa {
 435		for i := 0; i < len(h); i++ {
 436			for j := 0; j < len(h[i]); j++ {
 437				in += strings.TrimPrefix(h[i][j], "0x")
 438			}
 439		}
 440		b, err = hex.DecodeString(in)
 441		if err != nil {
 442			return nil, err
 443		}
 444	} else {
 445		// TODO TMP
 446		bH, err := stringToBytes(h[0][1])
 447		if err != nil {
 448			return nil, err
 449		}
 450		b = append(b, bH...)
 451		bH, err = stringToBytes(h[0][0])
 452		if err != nil {
 453			return nil, err
 454		}
 455		b = append(b, bH...)
 456		bH, err = stringToBytes(h[1][1])
 457		if err != nil {
 458			return nil, err
 459		}
 460		b = append(b, bH...)
 461		bH, err = stringToBytes(h[1][0])
 462		if err != nil {
 463			return nil, err
 464		}
 465		b = append(b, bH...)
 466	}
 467
 468	p := new(bn256.G2)
 469	_, err = p.Unmarshal(b)
 470	return p, err
 471}
 472
 473// ProofStringToSmartContractFormat converts the ProofString to a ProofString in the SmartContract format in a ProofString structure
 474func ProofStringToSmartContractFormat(s ProofString) ProofString {
 475	var rs ProofString
 476	rs.A = make([]string, 2)
 477	rs.B = make([][]string, 2)
 478	rs.B[0] = make([]string, 2)
 479	rs.B[1] = make([]string, 2)
 480	rs.C = make([]string, 2)
 481
 482	rs.A[0] = s.A[0]
 483	rs.A[1] = s.A[1]
 484	rs.B[0][0] = s.B[0][1]
 485	rs.B[0][1] = s.B[0][0]
 486	rs.B[1][0] = s.B[1][1]
 487	rs.B[1][1] = s.B[1][0]
 488	rs.C[0] = s.C[0]
 489	rs.C[1] = s.C[1]
 490	rs.Protocol = s.Protocol
 491	return rs
 492}
 493
 494// ProofToSmartContractFormat converts the *types.Proof to a ProofString in the SmartContract format in a ProofString structure
 495func ProofToSmartContractFormat(p *types.Proof) ProofString {
 496	s := ProofToString(p)
 497	return ProofStringToSmartContractFormat(s)
 498}
 499
 500// ProofToString converts the Proof to ProofString
 501func ProofToString(p *types.Proof) ProofString {
 502	var ps ProofString
 503	ps.A = make([]string, 3)
 504	ps.B = make([][]string, 3)
 505	ps.B[0] = make([]string, 2)
 506	ps.B[1] = make([]string, 2)
 507	ps.B[2] = make([]string, 2)
 508	ps.C = make([]string, 3)
 509
 510	a := p.A.Marshal()
 511	ps.A[0] = new(big.Int).SetBytes(a[:32]).String()
 512	ps.A[1] = new(big.Int).SetBytes(a[32:64]).String()
 513	ps.A[2] = "1"
 514
 515	b := p.B.Marshal()
 516	ps.B[0][1] = new(big.Int).SetBytes(b[:32]).String()
 517	ps.B[0][0] = new(big.Int).SetBytes(b[32:64]).String()
 518	ps.B[1][1] = new(big.Int).SetBytes(b[64:96]).String()
 519	ps.B[1][0] = new(big.Int).SetBytes(b[96:128]).String()
 520	ps.B[2][0] = "1"
 521	ps.B[2][1] = "0"
 522
 523	c := p.C.Marshal()
 524	ps.C[0] = new(big.Int).SetBytes(c[:32]).String()
 525	ps.C[1] = new(big.Int).SetBytes(c[32:64]).String()
 526	ps.C[2] = "1"
 527
 528	ps.Protocol = "groth"
 529
 530	return ps
 531}
 532
 533// ProofToJson outputs the Proof i Json format
 534func ProofToJson(p *types.Proof) ([]byte, error) {
 535	ps := ProofToString(p)
 536	return json.Marshal(ps)
 537}
 538
 539// ProofToHex converts the Proof to ProofString with hexadecimal strings
 540func ProofToHex(p *types.Proof) ProofString {
 541	var ps ProofString
 542	ps.A = make([]string, 3)
 543	ps.B = make([][]string, 3)
 544	ps.B[0] = make([]string, 2)
 545	ps.B[1] = make([]string, 2)
 546	ps.B[2] = make([]string, 2)
 547	ps.C = make([]string, 3)
 548
 549	a := p.A.Marshal()
 550	ps.A[0] = "0x" + hex.EncodeToString(new(big.Int).SetBytes(a[:32]).Bytes())
 551	ps.A[1] = "0x" + hex.EncodeToString(new(big.Int).SetBytes(a[32:64]).Bytes())
 552	ps.A[2] = "1"
 553
 554	b := p.B.Marshal()
 555	ps.B[0][1] = "0x" + hex.EncodeToString(new(big.Int).SetBytes(b[:32]).Bytes())
 556	ps.B[0][0] = "0x" + hex.EncodeToString(new(big.Int).SetBytes(b[32:64]).Bytes())
 557	ps.B[1][1] = "0x" + hex.EncodeToString(new(big.Int).SetBytes(b[64:96]).Bytes())
 558	ps.B[1][0] = "0x" + hex.EncodeToString(new(big.Int).SetBytes(b[96:128]).Bytes())
 559	ps.B[2][0] = "1"
 560	ps.B[2][1] = "0"
 561
 562	c := p.C.Marshal()
 563	ps.C[0] = "0x" + hex.EncodeToString(new(big.Int).SetBytes(c[:32]).Bytes())
 564	ps.C[1] = "0x" + hex.EncodeToString(new(big.Int).SetBytes(c[32:64]).Bytes())
 565	ps.C[2] = "1"
 566
 567	ps.Protocol = "groth"
 568
 569	return ps
 570}
 571
 572// ProofToJsonHex outputs the Proof i Json format with hexadecimal strings
 573func ProofToJsonHex(p *types.Proof) ([]byte, error) {
 574	ps := ProofToHex(p)
 575	return json.Marshal(ps)
 576}
 577
 578// ParseWitnessBin parses binary file representation of the Witness into the Witness struct
 579func ParseWitnessBin(f *os.File) (types.Witness, error) {
 580	var w types.Witness
 581	r := bufio.NewReader(f)
 582	for {
 583		b := make([]byte, 32)
 584		n, err := r.Read(b)
 585		if err == io.EOF {
 586			return w, nil
 587		} else if err != nil {
 588			return nil, err
 589		}
 590		if n != 32 {
 591			return nil, fmt.Errorf("error on value format, expected 32 bytes, got %v", n)
 592		}
 593		w = append(w, new(big.Int).SetBytes(swapEndianness(b[0:32])))
 594	}
 595}
 596
 597// swapEndianness swaps the order of the bytes in the slice.
 598func swapEndianness(b []byte) []byte {
 599	o := make([]byte, len(b))
 600	for i := range b {
 601		o[len(b)-1-i] = b[i]
 602	}
 603	return o
 604}
 605
 606func readNBytes(r io.Reader, n int) ([]byte, error) {
 607	b := make([]byte, n)
 608	_, err := io.ReadFull(r, b)
 609	if err != nil {
 610		return b, err
 611	}
 612	return b, nil
 613}
 614
 615// ParsePkBin parses binary file representation of the ProvingKey into the ProvingKey struct
 616func ParsePkBin(f *os.File) (*types.Pk, error) {
 617	o := 0
 618	var pk types.Pk
 619	r := bufio.NewReader(f)
 620
 621	b, err := readNBytes(r, 12)
 622	if err != nil {
 623		return nil, err
 624	}
 625	pk.NVars = int(binary.LittleEndian.Uint32(b[:4]))
 626	pk.NPublic = int(binary.LittleEndian.Uint32(b[4:8]))
 627	pk.DomainSize = int(binary.LittleEndian.Uint32(b[8:12]))
 628	o += 12
 629
 630	b, err = readNBytes(r, 8)
 631	if err != nil {
 632		return nil, err
 633	}
 634	pPolsA := int(binary.LittleEndian.Uint32(b[:4]))
 635	pPolsB := int(binary.LittleEndian.Uint32(b[4:8]))
 636	o += 8
 637
 638	b, err = readNBytes(r, 20)
 639	if err != nil {
 640		return nil, err
 641	}
 642	pPointsA := int(binary.LittleEndian.Uint32(b[:4]))
 643	pPointsB1 := int(binary.LittleEndian.Uint32(b[4:8]))
 644	pPointsB2 := int(binary.LittleEndian.Uint32(b[8:12]))
 645	pPointsC := int(binary.LittleEndian.Uint32(b[12:16]))
 646	pPointsHExps := int(binary.LittleEndian.Uint32(b[16:20]))
 647	o += 20
 648
 649	b, err = readNBytes(r, 64)
 650	if err != nil {
 651		return nil, err
 652	}
 653	pk.VkAlpha1 = new(bn256.G1)
 654	_, err = pk.VkAlpha1.Unmarshal(fromMont1Q(b))
 655	if err != nil {
 656		return nil, err
 657	}
 658
 659	b, err = readNBytes(r, 64)
 660	if err != nil {
 661		return nil, err
 662	}
 663	pk.VkBeta1 = new(bn256.G1)
 664	_, err = pk.VkBeta1.Unmarshal(fromMont1Q(b))
 665	if err != nil {
 666		return nil, err
 667	}
 668
 669	b, err = readNBytes(r, 64)
 670	if err != nil {
 671		return nil, err
 672	}
 673	pk.VkDelta1 = new(bn256.G1)
 674	_, err = pk.VkDelta1.Unmarshal(fromMont1Q(b))
 675	if err != nil {
 676		return nil, err
 677	}
 678	b, err = readNBytes(r, 128)
 679	if err != nil {
 680		return nil, err
 681	}
 682	pk.VkBeta2 = new(bn256.G2)
 683	_, err = pk.VkBeta2.Unmarshal(fromMont2Q(b))
 684	if err != nil {
 685		return nil, err
 686	}
 687	b, err = readNBytes(r, 128)
 688	if err != nil {
 689		return nil, err
 690	}
 691	pk.VkDelta2 = new(bn256.G2)
 692	_, err = pk.VkDelta2.Unmarshal(fromMont2Q(b))
 693	if err != nil {
 694		return nil, err
 695	}
 696	o += 448
 697	if o != pPolsA {
 698		return nil, fmt.Errorf("Unexpected offset, expected: %v, actual: %v", pPolsA, o)
 699	}
 700
 701	// PolsA
 702	for i := 0; i < pk.NVars; i++ {
 703		b, err = readNBytes(r, 4)
 704		if err != nil {
 705			return nil, err
 706		}
 707		keysLength := int(binary.LittleEndian.Uint32(b[:4]))
 708		o += 4
 709		polsMap := make(map[int]*big.Int)
 710		for j := 0; j < keysLength; j++ {
 711			bK, err := readNBytes(r, 4)
 712			if err != nil {
 713				return nil, err
 714			}
 715			key := int(binary.LittleEndian.Uint32(bK[:4]))
 716			o += 4
 717
 718			b, err := readNBytes(r, 32)
 719			if err != nil {
 720				return nil, err
 721			}
 722			polsMap[key] = new(big.Int).SetBytes(fromMont1R(b[:32]))
 723			o += 32
 724		}
 725		pk.PolsA = append(pk.PolsA, polsMap)
 726	}
 727	if o != pPolsB {
 728		return nil, fmt.Errorf("Unexpected offset, expected: %v, actual: %v", pPolsB, o)
 729	}
 730	// PolsB
 731	for i := 0; i < pk.NVars; i++ {
 732		b, err = readNBytes(r, 4)
 733		if err != nil {
 734			return nil, err
 735		}
 736		keysLength := int(binary.LittleEndian.Uint32(b[:4]))
 737		o += 4
 738		polsMap := make(map[int]*big.Int)
 739		for j := 0; j < keysLength; j++ {
 740			bK, err := readNBytes(r, 4)
 741			if err != nil {
 742				return nil, err
 743			}
 744			key := int(binary.LittleEndian.Uint32(bK[:4]))
 745			o += 4
 746
 747			b, err := readNBytes(r, 32)
 748			if err != nil {
 749				return nil, err
 750			}
 751			polsMap[key] = new(big.Int).SetBytes(fromMont1R(b[:32]))
 752			o += 32
 753		}
 754		pk.PolsB = append(pk.PolsB, polsMap)
 755	}
 756	if o != pPointsA {
 757		return nil, fmt.Errorf("Unexpected offset, expected: %v, actual: %v", pPointsA, o)
 758	}
 759	// A
 760	for i := 0; i < pk.NVars; i++ {
 761		b, err = readNBytes(r, 64)
 762		if err != nil {
 763			return nil, err
 764		}
 765		p1 := new(bn256.G1)
 766		_, err = p1.Unmarshal(fromMont1Q(b))
 767		if err != nil {
 768			return nil, err
 769		}
 770		pk.A = append(pk.A, p1)
 771		o += 64
 772	}
 773	if o != pPointsB1 {
 774		return nil, fmt.Errorf("Unexpected offset, expected: %v, actual: %v", pPointsB1, o)
 775	}
 776	// B1
 777	for i := 0; i < pk.NVars; i++ {
 778		b, err = readNBytes(r, 64)
 779		if err != nil {
 780			return nil, err
 781		}
 782		p1 := new(bn256.G1)
 783		_, err = p1.Unmarshal(fromMont1Q(b))
 784		if err != nil {
 785			return nil, err
 786		}
 787		pk.B1 = append(pk.B1, p1)
 788		o += 64
 789	}
 790	if o != pPointsB2 {
 791		return nil, fmt.Errorf("Unexpected offset, expected: %v, actual: %v", pPointsB2, o)
 792	}
 793	// B2
 794	for i := 0; i < pk.NVars; i++ {
 795		b, err = readNBytes(r, 128)
 796		if err != nil {
 797			return nil, err
 798		}
 799		p2 := new(bn256.G2)
 800		_, err = p2.Unmarshal(fromMont2Q(b))
 801		if err != nil {
 802			return nil, err
 803		}
 804		pk.B2 = append(pk.B2, p2)
 805		o += 128
 806	}
 807	if o != pPointsC {
 808		return nil, fmt.Errorf("Unexpected offset, expected: %v, actual: %v", pPointsC, o)
 809	}
 810	// C
 811	zb := make([]byte, 64)
 812	z := new(bn256.G1)
 813	_, err = z.Unmarshal(zb)
 814	if err != nil {
 815		return nil, err
 816	}
 817	pk.C = append(pk.C, z) // circom behaviour (3x null==["0", "0", "0"])
 818	pk.C = append(pk.C, z)
 819	pk.C = append(pk.C, z)
 820	for i := pk.NPublic + 1; i < pk.NVars; i++ {
 821		b, err = readNBytes(r, 64)
 822		if err != nil {
 823			return nil, err
 824		}
 825		p1 := new(bn256.G1)
 826		_, err = p1.Unmarshal(fromMont1Q(b))
 827		if err != nil {
 828			return nil, err
 829		}
 830		pk.C = append(pk.C, p1)
 831		o += 64
 832	}
 833	if o != pPointsHExps {
 834		return nil, fmt.Errorf("Unexpected offset, expected: %v, actual: %v", pPointsHExps, o)
 835	}
 836	// HExps
 837	for i := 0; i < pk.DomainSize; i++ {
 838		b, err = readNBytes(r, 64)
 839		if err != nil {
 840			return nil, err
 841		}
 842		p1 := new(bn256.G1)
 843		_, err = p1.Unmarshal(fromMont1Q(b))
 844		if err != nil {
 845			return nil, err
 846		}
 847		pk.HExps = append(pk.HExps, p1)
 848	}
 849	return &pk, nil
 850}
 851
 852func fromMont1Q(m []byte) []byte {
 853	a := new(big.Int).SetBytes(swapEndianness(m[:32]))
 854	b := new(big.Int).SetBytes(swapEndianness(m[32:64]))
 855
 856	x := coordFromMont(a, types.Q)
 857	y := coordFromMont(b, types.Q)
 858	if bytes.Equal(x.Bytes(), big.NewInt(1).Bytes()) {
 859		x = big.NewInt(0)
 860	}
 861	if bytes.Equal(y.Bytes(), big.NewInt(1).Bytes()) {
 862		y = big.NewInt(0)
 863	}
 864
 865	xBytes := x.Bytes()
 866	yBytes := y.Bytes()
 867	if len(xBytes) != 32 {
 868		xBytes = addZPadding(xBytes)
 869	}
 870	if len(yBytes) != 32 {
 871		yBytes = addZPadding(yBytes)
 872	}
 873
 874	var p []byte
 875	p = append(p, xBytes...)
 876	p = append(p, yBytes...)
 877
 878	return p
 879}
 880
 881func fromMont2Q(m []byte) []byte {
 882	a := new(big.Int).SetBytes(swapEndianness(m[:32]))
 883	b := new(big.Int).SetBytes(swapEndianness(m[32:64]))
 884	c := new(big.Int).SetBytes(swapEndianness(m[64:96]))
 885	d := new(big.Int).SetBytes(swapEndianness(m[96:128]))
 886
 887	x := coordFromMont(a, types.Q)
 888	y := coordFromMont(b, types.Q)
 889	z := coordFromMont(c, types.Q)
 890	t := coordFromMont(d, types.Q)
 891
 892	if bytes.Equal(x.Bytes(), big.NewInt(1).Bytes()) {
 893		x = big.NewInt(0)
 894	}
 895	if bytes.Equal(y.Bytes(), big.NewInt(1).Bytes()) {
 896		y = big.NewInt(0)
 897	}
 898	if bytes.Equal(z.Bytes(), big.NewInt(1).Bytes()) {
 899		z = big.NewInt(0)
 900	}
 901	if bytes.Equal(t.Bytes(), big.NewInt(1).Bytes()) {
 902		t = big.NewInt(0)
 903	}
 904
 905	xBytes := x.Bytes()
 906	yBytes := y.Bytes()
 907	zBytes := z.Bytes()
 908	tBytes := t.Bytes()
 909	if len(xBytes) != 32 {
 910		xBytes = addZPadding(xBytes)
 911	}
 912	if len(yBytes) != 32 {
 913		yBytes = addZPadding(yBytes)
 914	}
 915	if len(zBytes) != 32 {
 916		zBytes = addZPadding(zBytes)
 917	}
 918	if len(tBytes) != 32 {
 919		tBytes = addZPadding(tBytes)
 920	}
 921
 922	var p []byte
 923	p = append(p, yBytes...) // swap
 924	p = append(p, xBytes...)
 925	p = append(p, tBytes...)
 926	p = append(p, zBytes...)
 927
 928	return p
 929}
 930
 931func fromMont1R(m []byte) []byte {
 932	a := new(big.Int).SetBytes(swapEndianness(m[:32]))
 933
 934	x := coordFromMont(a, types.R)
 935
 936	return x.Bytes()
 937}
 938
 939func fromMont2R(m []byte) []byte {
 940	a := new(big.Int).SetBytes(swapEndianness(m[:32]))
 941	b := new(big.Int).SetBytes(swapEndianness(m[32:64]))
 942	c := new(big.Int).SetBytes(swapEndianness(m[64:96]))
 943	d := new(big.Int).SetBytes(swapEndianness(m[96:128]))
 944
 945	x := coordFromMont(a, types.R)
 946	y := coordFromMont(b, types.R)
 947	z := coordFromMont(c, types.R)
 948	t := coordFromMont(d, types.R)
 949
 950	var p []byte
 951	p = append(p, y.Bytes()...) // swap
 952	p = append(p, x.Bytes()...)
 953	p = append(p, t.Bytes()...)
 954	p = append(p, z.Bytes()...)
 955
 956	return p
 957}
 958
 959func coordFromMont(u, q *big.Int) *big.Int {
 960	return new(big.Int).Mod(
 961		new(big.Int).Mul(
 962			u,
 963			new(big.Int).ModInverse(
 964				new(big.Int).Lsh(big.NewInt(1), 256),
 965				q,
 966			),
 967		),
 968		q,
 969	)
 970}
 971
 972// PkToGoBin converts the ProvingKey (*types.Pk) into binary format defined by
 973// go-circom-prover-verifier.  PkGoBin is a own go-circom-prover-verifier
 974// binary format that allows to go faster when parsing.
 975func PkToGoBin(pk *types.Pk) ([]byte, error) {
 976	var r []byte
 977	o := 0
 978	var b [4]byte
 979	binary.LittleEndian.PutUint32(b[:], uint32(pk.NVars))
 980	r = append(r, b[:]...)
 981
 982	binary.LittleEndian.PutUint32(b[:], uint32(pk.NPublic))
 983	r = append(r, b[:]...)
 984
 985	binary.LittleEndian.PutUint32(b[:], uint32(pk.DomainSize))
 986	r = append(r, b[:]...)
 987	o += 12
 988
 989	// reserve space for pols (A, B) pos
 990	b = [4]byte{}
 991	r = append(r, b[:]...) // 12:16
 992	r = append(r, b[:]...) // 16:20
 993	o += 8
 994	// reserve space for points (A, B1, B2, C, HExps) pos
 995	r = append(r, b[:]...) // 20:24
 996	r = append(r, b[:]...) // 24
 997	r = append(r, b[:]...) // 28
 998	r = append(r, b[:]...) // 32
 999	r = append(r, b[:]...) // 36:40
1000	o += 20
1001
1002	pb1 := pk.VkAlpha1.Marshal()
1003	r = append(r, pb1[:]...)
1004	pb1 = pk.VkBeta1.Marshal()
1005	r = append(r, pb1[:]...)
1006	pb1 = pk.VkDelta1.Marshal()
1007	r = append(r, pb1[:]...)
1008	pb2 := pk.VkBeta2.Marshal()
1009	r = append(r, pb2[:]...)
1010	pb2 = pk.VkDelta2.Marshal()
1011	r = append(r, pb2[:]...)
1012	o += 448
1013
1014	// polsA
1015	binary.LittleEndian.PutUint32(r[12:16], uint32(o))
1016	for i := 0; i < pk.NVars; i++ {
1017		binary.LittleEndian.PutUint32(b[:], uint32(len(pk.PolsA[i])))
1018		r = append(r, b[:]...)
1019		o += 4
1020		for j, v := range pk.PolsA[i] {
1021			binary.LittleEndian.PutUint32(b[:], uint32(j))
1022			r = append(r, b[:]...)
1023			r = append(r, addPadding32(v.Bytes())...)
1024			o += 32 + 4
1025		}
1026	}
1027	// polsB
1028	binary.LittleEndian.PutUint32(r[16:20], uint32(o))
1029	for i := 0; i < pk.NVars; i++ {
1030		binary.LittleEndian.PutUint32(b[:], uint32(len(pk.PolsB[i])))
1031		r = append(r, b[:]...)
1032		o += 4
1033		for j, v := range pk.PolsB[i] {
1034			binary.LittleEndian.PutUint32(b[:], uint32(j))
1035			r = append(r, b[:]...)
1036			r = append(r, addPadding32(v.Bytes())...)
1037			o += 32 + 4
1038		}
1039	}
1040	// A
1041	binary.LittleEndian.PutUint32(r[20:24], uint32(o))
1042	for i := 0; i < pk.NVars; i++ {
1043		pb1 = pk.A[i].Marshal()
1044		r = append(r, pb1[:]...)
1045		o += 64
1046	}
1047	// B1
1048	binary.LittleEndian.PutUint32(r[24:28], uint32(o))
1049	for i := 0; i < pk.NVars; i++ {
1050		pb1 = pk.B1[i].Marshal()
1051		r = append(r, pb1[:]...)
1052		o += 64
1053	}
1054	// B2
1055	binary.LittleEndian.PutUint32(r[28:32], uint32(o))
1056	for i := 0; i < pk.NVars; i++ {
1057		pb2 = pk.B2[i].Marshal()
1058		r = append(r, pb2[:]...)
1059		o += 128
1060	}
1061	// C
1062	binary.LittleEndian.PutUint32(r[32:36], uint32(o))
1063	for i := pk.NPublic + 1; i < pk.NVars; i++ {
1064		pb1 = pk.C[i].Marshal()
1065		r = append(r, pb1[:]...)
1066		o += 64
1067	}
1068	// HExps
1069	binary.LittleEndian.PutUint32(r[36:40], uint32(o))
1070	for i := 0; i < pk.DomainSize+1; i++ {
1071		pb1 = pk.HExps[i].Marshal()
1072		r = append(r, pb1[:]...)
1073		o += 64
1074	}
1075
1076	return r[:], nil
1077}
1078
1079// ParsePkGoBin parses go-circom-prover-verifier binary file representation of
1080// the ProvingKey into ProvingKey struct (*types.Pk).  PkGoBin is a own
1081// go-circom-prover-verifier binary format that allows to go faster when
1082// parsing.
1083func ParsePkGoBin(f *os.File) (*types.Pk, error) {
1084	o := 0
1085	var pk types.Pk
1086	r := bufio.NewReader(f)
1087
1088	b, err := readNBytes(r, 12)
1089	if err != nil {
1090		return nil, err
1091	}
1092	pk.NVars = int(binary.LittleEndian.Uint32(b[:4]))
1093	pk.NPublic = int(binary.LittleEndian.Uint32(b[4:8]))
1094	pk.DomainSize = int(binary.LittleEndian.Uint32(b[8:12]))
1095	o += 12
1096
1097	b, err = readNBytes(r, 8)
1098	if err != nil {
1099		return nil, err
1100	}
1101	pPolsA := int(binary.LittleEndian.Uint32(b[:4]))
1102	pPolsB := int(binary.LittleEndian.Uint32(b[4:8]))
1103	o += 8
1104
1105	b, err = readNBytes(r, 20)
1106	if err != nil {
1107		return nil, err
1108	}
1109	pPointsA := int(binary.LittleEndian.Uint32(b[:4]))
1110	pPointsB1 := int(binary.LittleEndian.Uint32(b[4:8]))
1111	pPointsB2 := int(binary.LittleEndian.Uint32(b[8:12]))
1112	pPointsC := int(binary.LittleEndian.Uint32(b[12:16]))
1113	pPointsHExps := int(binary.LittleEndian.Uint32(b[16:20]))
1114	o += 20
1115
1116	b, err = readNBytes(r, 64)
1117	if err != nil {
1118		return nil, err
1119	}
1120	pk.VkAlpha1 = new(bn256.G1)
1121	_, err = pk.VkAlpha1.Unmarshal(b)
1122	if err != nil {
1123		return &pk, err
1124	}
1125	b, err = readNBytes(r, 64)
1126	if err != nil {
1127		return nil, err
1128	}
1129	pk.VkBeta1 = new(bn256.G1)
1130	_, err = pk.VkBeta1.Unmarshal(b)
1131	if err != nil {
1132		return &pk, err
1133	}
1134	b, err = readNBytes(r, 64)
1135	if err != nil {
1136		return nil, err
1137	}
1138	pk.VkDelta1 = new(bn256.G1)
1139	_, err = pk.VkDelta1.Unmarshal(b)
1140	if err != nil {
1141		return &pk, err
1142	}
1143	b, err = readNBytes(r, 128)
1144	if err != nil {
1145		return nil, err
1146	}
1147	pk.VkBeta2 = new(bn256.G2)
1148	_, err = pk.VkBeta2.Unmarshal(b)
1149	if err != nil {
1150		return &pk, err
1151	}
1152	b, err = readNBytes(r, 128)
1153	if err != nil {
1154		return nil, err
1155	}
1156	pk.VkDelta2 = new(bn256.G2)
1157	_, err = pk.VkDelta2.Unmarshal(b)
1158	if err != nil {
1159		return &pk, err
1160	}
1161	o += 448
1162	if o != pPolsA {
1163		return nil, fmt.Errorf("Unexpected offset, expected: %v, actual: %v", pPolsA, o)
1164	}
1165
1166	// PolsA
1167	for i := 0; i < pk.NVars; i++ {
1168		b, err = readNBytes(r, 4)
1169		if err != nil {
1170			return nil, err
1171		}
1172		keysLength := int(binary.LittleEndian.Uint32(b[:4]))
1173		o += 4
1174		polsMap := make(map[int]*big.Int)
1175		for j := 0; j < keysLength; j++ {
1176			bK, err := readNBytes(r, 4)
1177			if err != nil {
1178				return nil, err
1179			}
1180			key := int(binary.LittleEndian.Uint32(bK[:4]))
1181			o += 4
1182
1183			b, err := readNBytes(r, 32)
1184			if err != nil {
1185				return nil, err
1186			}
1187			polsMap[key] = new(big.Int).SetBytes(b[:32])
1188			o += 32
1189		}
1190		pk.PolsA = append(pk.PolsA, polsMap)
1191	}
1192	if o != pPolsB {
1193		return nil, fmt.Errorf("Unexpected offset, expected: %v, actual: %v", pPolsB, o)
1194	}
1195	// PolsB
1196	for i := 0; i < pk.NVars; i++ {
1197		b, err = readNBytes(r, 4)
1198		if err != nil {
1199			return nil, err
1200		}
1201		keysLength := int(binary.LittleEndian.Uint32(b[:4]))
1202		o += 4
1203		polsMap := make(map[int]*big.Int)
1204		for j := 0; j < keysLength; j++ {
1205			bK, err := readNBytes(r, 4)
1206			if err != nil {
1207				return nil, err
1208			}
1209			key := int(binary.LittleEndian.Uint32(bK[:4]))
1210			o += 4
1211
1212			b, err := readNBytes(r, 32)
1213			if err != nil {
1214				return nil, err
1215			}
1216			polsMap[key] = new(big.Int).SetBytes(b[:32])
1217			o += 32
1218		}
1219		pk.PolsB = append(pk.PolsB, polsMap)
1220	}
1221	if o != pPointsA {
1222		return nil, fmt.Errorf("Unexpected offset, expected: %v, actual: %v", pPointsA, o)
1223	}
1224	// A
1225	for i := 0; i < pk.NVars; i++ {
1226		b, err = readNBytes(r, 64)
1227		if err != nil {
1228			return nil, err
1229		}
1230		p1 := new(bn256.G1)
1231		_, err = p1.Unmarshal(b)
1232		if err != nil {
1233			return nil, err
1234		}
1235		pk.A = append(pk.A, p1)
1236		o += 64
1237	}
1238	if o != pPointsB1 {
1239		return nil, fmt.Errorf("Unexpected offset, expected: %v, actual: %v", pPointsB1, o)
1240	}
1241	// B1
1242	for i := 0; i < pk.NVars; i++ {
1243		b, err = readNBytes(r, 64)
1244		if err != nil {
1245			return nil, err
1246		}
1247		p1 := new(bn256.G1)
1248		_, err = p1.Unmarshal(b)
1249		if err != nil {
1250			return nil, err
1251		}
1252		pk.B1 = append(pk.B1, p1)
1253		o += 64
1254	}
1255	if o != pPointsB2 {
1256		return nil, fmt.Errorf("Unexpected offset, expected: %v, actual: %v", pPointsB2, o)
1257	}
1258	// B2
1259	for i := 0; i < pk.NVars; i++ {
1260		b, err = readNBytes(r, 128)
1261		if err != nil {
1262			return nil, err
1263		}
1264		p2 := new(bn256.G2)
1265		_, err = p2.Unmarshal(b)
1266		if err != nil {
1267			return nil, err
1268		}
1269		pk.B2 = append(pk.B2, p2)
1270		o += 128
1271	}
1272	if o != pPointsC {
1273		return nil, fmt.Errorf("Unexpected offset, expected: %v, actual: %v", pPointsC, o)
1274	}
1275	// C
1276	zb := make([]byte, 64)
1277	z := new(bn256.G1)
1278	_, err = z.Unmarshal(zb)
1279	if err != nil {
1280		return nil, err
1281	}
1282	pk.C = append(pk.C, z)
1283	pk.C = append(pk.C, z)
1284	pk.C = append(pk.C, z)
1285	for i := pk.NPublic + 1; i < pk.NVars; i++ {
1286		b, err = readNBytes(r, 64)
1287		if err != nil {
1288			return nil, err
1289		}
1290		p1 := new(bn256.G1)
1291		_, err = p1.Unmarshal(b)
1292		if err != nil {
1293			return nil, err
1294		}
1295		pk.C = append(pk.C, p1)
1296		o += 64
1297	}
1298	if o != pPointsHExps {
1299		return nil, fmt.Errorf("Unexpected offset, expected: %v, actual: %v", pPointsHExps, o)
1300	}
1301	// HExps
1302	for i := 0; i < pk.DomainSize+1; i++ {
1303		b, err = readNBytes(r, 64)
1304		if err != nil {
1305			return nil, err
1306		}
1307		p1 := new(bn256.G1)
1308		_, err = p1.Unmarshal(b)
1309		if err != nil {
1310			return nil, err
1311		}
1312		pk.HExps = append(pk.HExps, p1)
1313	}
1314
1315	return &pk, nil
1316}