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