mirror of
https://github.com/arnaucube/go-circom-prover-verifier.git
synced 2026-02-07 03:16:46 +01:00
refactor in sub packages
This commit is contained in:
498
parsers/parsers.go
Normal file
498
parsers/parsers.go
Normal file
@@ -0,0 +1,498 @@
|
||||
package parsers
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
bn256 "github.com/ethereum/go-ethereum/crypto/bn256/cloudflare"
|
||||
"github.com/iden3/go-circom-prover-verifier/types"
|
||||
)
|
||||
|
||||
// PkString is the equivalent to the Pk struct in string representation, containing the ProvingKey
|
||||
type PkString struct {
|
||||
A [][]string `json:"A"`
|
||||
B2 [][][]string `json:"B2"`
|
||||
B1 [][]string `json:"B1"`
|
||||
C [][]string `json:"C"`
|
||||
NVars int `json:"nVars"`
|
||||
NPublic int `json:"nPublic"`
|
||||
VkAlpha1 []string `json:"vk_alfa_1"`
|
||||
VkDelta1 []string `json:"vk_delta_1"`
|
||||
VkBeta1 []string `json:"vk_beta_1"`
|
||||
VkBeta2 [][]string `json:"vk_beta_2"`
|
||||
VkDelta2 [][]string `json:"vk_delta_2"`
|
||||
HExps [][]string `json:"hExps"`
|
||||
DomainSize int `json:"domainSize"`
|
||||
PolsA []map[string]string `json:"polsA"`
|
||||
PolsB []map[string]string `json:"polsB"`
|
||||
PolsC []map[string]string `json:"polsC"`
|
||||
}
|
||||
|
||||
// WitnessString contains the Witness in string representation
|
||||
type WitnessString []string
|
||||
|
||||
// ProofString is the equivalent to the Proof struct in string representation
|
||||
type ProofString struct {
|
||||
A []string `json:"pi_a"`
|
||||
B [][]string `json:"pi_b"`
|
||||
C []string `json:"pi_c"`
|
||||
Protocol string `json:"protocol"`
|
||||
}
|
||||
|
||||
// VkString is the Verification Key data structure in string format (from json)
|
||||
type VkString struct {
|
||||
Alpha []string `json:"vk_alfa_1"`
|
||||
Beta [][]string `json:"vk_beta_2"`
|
||||
Gamma [][]string `json:"vk_gamma_2"`
|
||||
Delta [][]string `json:"vk_delta_2"`
|
||||
IC [][]string `json:"IC"`
|
||||
}
|
||||
|
||||
// ParseWitness parses the json []byte data into the Witness struct
|
||||
func ParseWitness(wJson []byte) (types.Witness, error) {
|
||||
var ws WitnessString
|
||||
err := json.Unmarshal(wJson, &ws)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var w types.Witness
|
||||
for i := 0; i < len(ws); i++ {
|
||||
bi, err := stringToBigInt(ws[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
w = append(w, bi)
|
||||
}
|
||||
return w, nil
|
||||
}
|
||||
|
||||
// ParsePk parses the json []byte data into the Pk struct
|
||||
func ParsePk(pkJson []byte) (*types.Pk, error) {
|
||||
var pkStr PkString
|
||||
err := json.Unmarshal(pkJson, &pkStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pk, err := pkStringToPk(pkStr)
|
||||
return pk, err
|
||||
}
|
||||
|
||||
func pkStringToPk(ps PkString) (*types.Pk, error) {
|
||||
var p types.Pk
|
||||
var err error
|
||||
|
||||
p.A, err = arrayStringToG1(ps.A)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.B2, err = arrayStringToG2(ps.B2)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.B1, err = arrayStringToG1(ps.B1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.C, err = arrayStringToG1(ps.C)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p.NVars = ps.NVars
|
||||
p.NPublic = ps.NPublic
|
||||
|
||||
p.VkAlpha1, err = stringToG1(ps.VkAlpha1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p.VkDelta1, err = stringToG1(ps.VkDelta1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p.VkBeta1, err = stringToG1(ps.VkBeta1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.VkBeta2, err = stringToG2(ps.VkBeta2)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.VkDelta2, err = stringToG2(ps.VkDelta2)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p.HExps, err = arrayStringToG1(ps.HExps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p.DomainSize = ps.DomainSize
|
||||
|
||||
p.PolsA, err = polsStringToBigInt(ps.PolsA)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.PolsB, err = polsStringToBigInt(ps.PolsB)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.PolsC, err = polsStringToBigInt(ps.PolsC)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &p, nil
|
||||
}
|
||||
|
||||
func proofStringToProof(pr ProofString) (*types.Proof, error) {
|
||||
var p types.Proof
|
||||
var err error
|
||||
p.A, err = stringToG1(pr.A)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p.B, err = stringToG2(pr.B)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p.C, err = stringToG1(pr.C)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &p, nil
|
||||
}
|
||||
|
||||
// ParseProof takes a json []byte and outputs the *Proof struct
|
||||
func ParseProof(pj []byte) (*types.Proof, error) {
|
||||
var pr ProofString
|
||||
err := json.Unmarshal(pj, &pr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p, err := proofStringToProof(pr)
|
||||
return p, err
|
||||
}
|
||||
|
||||
// ParsePublicSignals takes a json []byte and outputs the []*big.Int struct
|
||||
func ParsePublicSignals(pj []byte) ([]*big.Int, error) {
|
||||
var pr []string
|
||||
err := json.Unmarshal(pj, &pr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var public []*big.Int
|
||||
for _, s := range pr {
|
||||
sb, err := stringToBigInt(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
public = append(public, sb)
|
||||
}
|
||||
return public, nil
|
||||
}
|
||||
|
||||
// ParseVk takes a json []byte and outputs the *Vk struct
|
||||
func ParseVk(vj []byte) (*types.Vk, error) {
|
||||
var vr VkString
|
||||
err := json.Unmarshal(vj, &vr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
v, err := vkStringToVk(vr)
|
||||
return v, err
|
||||
}
|
||||
|
||||
func vkStringToVk(vr VkString) (*types.Vk, error) {
|
||||
var v types.Vk
|
||||
var err error
|
||||
v.Alpha, err = stringToG1(vr.Alpha)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
v.Beta, err = stringToG2(vr.Beta)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
v.Gamma, err = stringToG2(vr.Gamma)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
v.Delta, err = stringToG2(vr.Delta)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i := 0; i < len(vr.IC); i++ {
|
||||
p, err := stringToG1(vr.IC[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
v.IC = append(v.IC, p)
|
||||
}
|
||||
|
||||
return &v, nil
|
||||
}
|
||||
|
||||
// polsStringToBigInt is for taking string polynomials and converting it to *big.Int polynomials
|
||||
func polsStringToBigInt(s []map[string]string) ([]map[int]*big.Int, error) {
|
||||
var o []map[int]*big.Int
|
||||
for i := 0; i < len(s); i++ {
|
||||
// var oi map[int]*big.Int
|
||||
oi := make(map[int]*big.Int)
|
||||
for j, v := range s[i] {
|
||||
si, err := stringToBigInt(v)
|
||||
if err != nil {
|
||||
return o, err
|
||||
}
|
||||
// oi = append(oi, si)
|
||||
jInt, err := strconv.Atoi(j)
|
||||
if err != nil {
|
||||
return o, err
|
||||
}
|
||||
oi[jInt] = si
|
||||
}
|
||||
o = append(o, oi)
|
||||
}
|
||||
return o, nil
|
||||
}
|
||||
|
||||
// ArrayBigIntToString converts an []*big.Int into []string, used to output the Public Signals
|
||||
func ArrayBigIntToString(bi []*big.Int) []string {
|
||||
var s []string
|
||||
for i := 0; i < len(bi); i++ {
|
||||
s = append(s, bi[i].String())
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func arrayStringToBigInt(s []string) ([]*big.Int, error) {
|
||||
var o []*big.Int
|
||||
for i := 0; i < len(s); i++ {
|
||||
si, err := stringToBigInt(s[i])
|
||||
if err != nil {
|
||||
return o, nil
|
||||
}
|
||||
o = append(o, si)
|
||||
}
|
||||
return o, nil
|
||||
}
|
||||
|
||||
func stringToBigInt(s string) (*big.Int, error) {
|
||||
base := 10
|
||||
if bytes.HasPrefix([]byte(s), []byte("0x")) {
|
||||
base = 16
|
||||
s = strings.TrimPrefix(s, "0x")
|
||||
}
|
||||
n, ok := new(big.Int).SetString(s, base)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("Can not parse string to *big.Int: %s", s)
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func addZPadding(b []byte) []byte {
|
||||
var z [32]byte
|
||||
var r []byte
|
||||
r = append(r, z[len(b):]...) // add padding on the left
|
||||
r = append(r, b...)
|
||||
return r[:32]
|
||||
}
|
||||
|
||||
func stringToBytes(s string) ([]byte, error) {
|
||||
if s == "1" {
|
||||
s = "0"
|
||||
}
|
||||
bi, ok := new(big.Int).SetString(s, 10)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("error parsing bigint stringToBytes")
|
||||
}
|
||||
b := bi.Bytes()
|
||||
if len(b) != 32 {
|
||||
b = addZPadding(b)
|
||||
}
|
||||
return b, nil
|
||||
|
||||
}
|
||||
|
||||
func arrayStringToG1(h [][]string) ([]*bn256.G1, error) {
|
||||
var o []*bn256.G1
|
||||
for i := 0; i < len(h); i++ {
|
||||
hi, err := stringToG1(h[i])
|
||||
if err != nil {
|
||||
return o, err
|
||||
}
|
||||
o = append(o, hi)
|
||||
}
|
||||
return o, nil
|
||||
}
|
||||
|
||||
func arrayStringToG2(h [][][]string) ([]*bn256.G2, error) {
|
||||
var o []*bn256.G2
|
||||
for i := 0; i < len(h); i++ {
|
||||
hi, err := stringToG2(h[i])
|
||||
if err != nil {
|
||||
return o, err
|
||||
}
|
||||
o = append(o, hi)
|
||||
}
|
||||
return o, nil
|
||||
}
|
||||
|
||||
func stringToG1(h []string) (*bn256.G1, error) {
|
||||
if len(h) <= 2 {
|
||||
return nil, fmt.Errorf("not enought data for stringToG1")
|
||||
}
|
||||
h = h[:2]
|
||||
hexa := false
|
||||
if len(h[0]) > 1 {
|
||||
if "0x" == h[0][:2] {
|
||||
hexa = true
|
||||
}
|
||||
}
|
||||
in := ""
|
||||
|
||||
var b []byte
|
||||
var err error
|
||||
if hexa {
|
||||
for i := range h {
|
||||
in += strings.TrimPrefix(h[i], "0x")
|
||||
}
|
||||
b, err = hex.DecodeString(in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
// TODO TMP
|
||||
// TODO use stringToBytes()
|
||||
if h[0] == "1" {
|
||||
h[0] = "0"
|
||||
}
|
||||
if h[1] == "1" {
|
||||
h[1] = "0"
|
||||
}
|
||||
bi0, ok := new(big.Int).SetString(h[0], 10)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("error parsing stringToG1")
|
||||
}
|
||||
bi1, ok := new(big.Int).SetString(h[1], 10)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("error parsing stringToG1")
|
||||
}
|
||||
b0 := bi0.Bytes()
|
||||
b1 := bi1.Bytes()
|
||||
if len(b0) != 32 {
|
||||
b0 = addZPadding(b0)
|
||||
}
|
||||
if len(b1) != 32 {
|
||||
b1 = addZPadding(b1)
|
||||
}
|
||||
|
||||
b = append(b, b0...)
|
||||
b = append(b, b1...)
|
||||
}
|
||||
p := new(bn256.G1)
|
||||
_, err = p.Unmarshal(b)
|
||||
|
||||
return p, err
|
||||
}
|
||||
|
||||
func stringToG2(h [][]string) (*bn256.G2, error) {
|
||||
if len(h) <= 2 {
|
||||
return nil, fmt.Errorf("not enought data for stringToG2")
|
||||
}
|
||||
h = h[:2]
|
||||
hexa := false
|
||||
if len(h[0][0]) > 1 {
|
||||
if "0x" == h[0][0][:2] {
|
||||
hexa = true
|
||||
}
|
||||
}
|
||||
in := ""
|
||||
var b []byte
|
||||
var err error
|
||||
if hexa {
|
||||
for i := 0; i < len(h); i++ {
|
||||
for j := 0; j < len(h[i]); j++ {
|
||||
in += strings.TrimPrefix(h[i][j], "0x")
|
||||
}
|
||||
}
|
||||
b, err = hex.DecodeString(in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
// TODO TMP
|
||||
bH, err := stringToBytes(h[0][1])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = append(b, bH...)
|
||||
bH, err = stringToBytes(h[0][0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = append(b, bH...)
|
||||
bH, err = stringToBytes(h[1][1])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = append(b, bH...)
|
||||
bH, err = stringToBytes(h[1][0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = append(b, bH...)
|
||||
}
|
||||
|
||||
p := new(bn256.G2)
|
||||
_, err = p.Unmarshal(b)
|
||||
return p, err
|
||||
}
|
||||
|
||||
// ProofToJson outputs the Proof i Json format
|
||||
func ProofToJson(p *types.Proof) ([]byte, error) {
|
||||
var ps ProofString
|
||||
ps.A = make([]string, 3)
|
||||
ps.B = make([][]string, 3)
|
||||
ps.B[0] = make([]string, 2)
|
||||
ps.B[1] = make([]string, 2)
|
||||
ps.B[2] = make([]string, 2)
|
||||
ps.C = make([]string, 3)
|
||||
|
||||
a := p.A.Marshal()
|
||||
ps.A[0] = new(big.Int).SetBytes(a[:32]).String()
|
||||
ps.A[1] = new(big.Int).SetBytes(a[32:64]).String()
|
||||
ps.A[2] = "1"
|
||||
|
||||
b := p.B.Marshal()
|
||||
ps.B[0][1] = new(big.Int).SetBytes(b[:32]).String()
|
||||
ps.B[0][0] = new(big.Int).SetBytes(b[32:64]).String()
|
||||
ps.B[1][1] = new(big.Int).SetBytes(b[64:96]).String()
|
||||
ps.B[1][0] = new(big.Int).SetBytes(b[96:128]).String()
|
||||
ps.B[2][0] = "1"
|
||||
ps.B[2][1] = "0"
|
||||
|
||||
c := p.C.Marshal()
|
||||
ps.C[0] = new(big.Int).SetBytes(c[:32]).String()
|
||||
ps.C[1] = new(big.Int).SetBytes(c[32:64]).String()
|
||||
ps.C[2] = "1"
|
||||
|
||||
ps.Protocol = "groth"
|
||||
|
||||
return json.Marshal(ps)
|
||||
}
|
||||
145
parsers/parsers_test.go
Normal file
145
parsers/parsers_test.go
Normal file
@@ -0,0 +1,145 @@
|
||||
package parsers
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestParseArrayG1(t *testing.T) {
|
||||
aS := [][]string{
|
||||
{
|
||||
"16145916318196730299582072104388453231952213805668281741813587224450782397538",
|
||||
"4434505318477484327659527264104806919103674231447634885054368605283938696207",
|
||||
"1",
|
||||
},
|
||||
{
|
||||
"10618406967550056457559358662746625591602641004174976323307214433994084907915",
|
||||
"1843236360452735081347085412539192450068665510574800388201121698908391533923",
|
||||
"1",
|
||||
},
|
||||
{
|
||||
"1208972877970123411566574123860641832032384890981476033353526096830198333194",
|
||||
"777503551507025252294438107100944741641946695980350712141258191590862204805",
|
||||
"1",
|
||||
},
|
||||
{
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
},
|
||||
}
|
||||
|
||||
a, err := arrayStringToG1(aS)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "bn256.G1(23b243c928ce40c4cc2dad366e9f61723aef65866e1c66f42a08697f2f030462, 09cdd7500688fb487ec9f27b5a732d68fa0f3ddca5c2c790e330fdfb03b77c0f)", a[0].String())
|
||||
assert.Equal(t, "bn256.G1(1779ce2c586b5fc523e72e755d969a63473052aaad7c11eb5bf0ecdcfdfefb8b, 04133c1c74206dace57cd3d76ce59be381bbf08f51a5b3edc2b0c183d43eed63)", a[1].String())
|
||||
assert.Equal(t, "bn256.G1(02ac4120598d2f2bb81bc09b8df596403360577b0c5ff52485d1ef2200f23f0a, 01b80d298de75f867d6484c55c3da02c042bb4eb9a1734d3386786aaa669af85)", a[2].String())
|
||||
assert.Equal(t, "bn256.G1(0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000001)", a[3].String())
|
||||
}
|
||||
|
||||
func TestParseG2(t *testing.T) {
|
||||
aS := [][]string{
|
||||
{
|
||||
"9283666785342556550467669770956850930982548182701254051508520248901282197973",
|
||||
"11369378229277445316894458966429873744779877313900506577160370623273013178252",
|
||||
},
|
||||
{
|
||||
"10625777544326349817513295021482494426101347915428005055375725845993157551870",
|
||||
"21401790227434807639472120486932615400751346915707967674912972446672152512583",
|
||||
},
|
||||
{
|
||||
"1",
|
||||
"0",
|
||||
},
|
||||
}
|
||||
|
||||
a, err := stringToG2(aS)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "bn256.G2((1922d70c934543aa655ec3277f7fa10a25ec973a4f001a7c54ce4954b4916f8c, 14865e836947c42cf35b47d30e06535fff9dab319c4296e28afde368960671d5), (2f50fbe77925b0a9d718c9ab38638bafa7c65f43f0d09035e518df97ad294847, 177dfa1a3b8627faf0425d9511bcb4c6ca986ea05e3803b5c643c35b94a7e6fe))", a.String())
|
||||
|
||||
aS = [][]string{
|
||||
{
|
||||
"13973091636763944887728510851169742544309374663995476311690518173988838518856",
|
||||
"12903946180439304546475897520537621821375470264150438270817301786763517825250",
|
||||
},
|
||||
{
|
||||
"370374369234123593044872519351942112043402224488849374153134091815693350697",
|
||||
"17423079115073430837335625309232513526393852743032331213038909731579295753224",
|
||||
},
|
||||
{
|
||||
"1",
|
||||
"0",
|
||||
},
|
||||
}
|
||||
a, err = stringToG2(aS)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "bn256.G2((1c875fed67fff3b35f115b03706ec45f281b5f6cc71a99107240e09fce4910e2, 1ee47d566e9a099626b9860bcd96f6d4a1ed65f115d3efa8e05e5f42cc793048), (26851d022ce9961df65a430811824aaf3118710ac03b0614a50c05ee27d8e408, 00d19fdce25b0d78fb317a5f1789823b7ed76274b0d1be9c685792c73b347729))", a.String())
|
||||
}
|
||||
|
||||
func TestParseArrayG2(t *testing.T) {
|
||||
aS := [][][]string{
|
||||
{
|
||||
{
|
||||
"0",
|
||||
"0",
|
||||
},
|
||||
{
|
||||
"1",
|
||||
"0",
|
||||
},
|
||||
{
|
||||
"0",
|
||||
"0",
|
||||
},
|
||||
},
|
||||
{
|
||||
{
|
||||
"0",
|
||||
"0",
|
||||
},
|
||||
{
|
||||
"1",
|
||||
"0",
|
||||
},
|
||||
{
|
||||
"0",
|
||||
"0",
|
||||
},
|
||||
},
|
||||
{
|
||||
{
|
||||
"0",
|
||||
"0",
|
||||
},
|
||||
{
|
||||
"1",
|
||||
"0",
|
||||
},
|
||||
{
|
||||
"0",
|
||||
"0",
|
||||
},
|
||||
},
|
||||
{
|
||||
{
|
||||
"9283666785342556550467669770956850930982548182701254051508520248901282197973",
|
||||
"11369378229277445316894458966429873744779877313900506577160370623273013178252",
|
||||
},
|
||||
{
|
||||
"10625777544326349817513295021482494426101347915428005055375725845993157551870",
|
||||
"21401790227434807639472120486932615400751346915707967674912972446672152512583",
|
||||
},
|
||||
{
|
||||
"1",
|
||||
"0",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
a, err := arrayStringToG2(aS)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "bn256.G2((0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000), (0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000001))", a[0].String())
|
||||
assert.Equal(t, "bn256.G2((1922d70c934543aa655ec3277f7fa10a25ec973a4f001a7c54ce4954b4916f8c, 14865e836947c42cf35b47d30e06535fff9dab319c4296e28afde368960671d5), (2f50fbe77925b0a9d718c9ab38638bafa7c65f43f0d09035e518df97ad294847, 177dfa1a3b8627faf0425d9511bcb4c6ca986ea05e3803b5c643c35b94a7e6fe))", a[3].String())
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user