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