github.com/consensys/gnark-crypto@v0.14.0/ecc/bn254/marshal.go (about)

     1  // Copyright 2020 Consensys Software Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // Code generated by consensys/gnark-crypto DO NOT EDIT
    16  
    17  package bn254
    18  
    19  import (
    20  	"encoding/binary"
    21  	"errors"
    22  	"io"
    23  	"reflect"
    24  	"sync/atomic"
    25  
    26  	"github.com/consensys/gnark-crypto/ecc/bn254/fp"
    27  	"github.com/consensys/gnark-crypto/ecc/bn254/fr"
    28  	"github.com/consensys/gnark-crypto/ecc/bn254/internal/fptower"
    29  	"github.com/consensys/gnark-crypto/internal/parallel"
    30  )
    31  
    32  // To encode G1Affine and G2Affine points, we mask the most significant bits with these bits to specify without ambiguity
    33  // metadata needed for point (de)compression
    34  // we have less than 3 bits available on the msw, so we can't follow BLS12-381 style encoding.
    35  // the difference is the case where a point is infinity and uncompressed is not flagged
    36  const (
    37  	mMask               byte = 0b11 << 6
    38  	mUncompressed       byte = 0b00 << 6
    39  	mCompressedSmallest byte = 0b10 << 6
    40  	mCompressedLargest  byte = 0b11 << 6
    41  	mCompressedInfinity byte = 0b01 << 6
    42  )
    43  
    44  // SizeOfGT represents the size in bytes that a GT element need in binary form
    45  const SizeOfGT = fptower.SizeOfGT
    46  
    47  var (
    48  	ErrInvalidInfinityEncoding = errors.New("invalid infinity point encoding")
    49  	ErrInvalidEncoding         = errors.New("invalid point encoding")
    50  )
    51  
    52  // Encoder writes bn254 object values to an output stream
    53  type Encoder struct {
    54  	w   io.Writer
    55  	n   int64 // written bytes
    56  	raw bool  // raw vs compressed encoding
    57  }
    58  
    59  // Decoder reads bn254 object values from an inbound stream
    60  type Decoder struct {
    61  	r             io.Reader
    62  	n             int64 // read bytes
    63  	subGroupCheck bool  // default to true
    64  }
    65  
    66  // NewDecoder returns a binary decoder supporting curve bn254 objects in both
    67  // compressed and uncompressed (raw) forms
    68  func NewDecoder(r io.Reader, options ...func(*Decoder)) *Decoder {
    69  	d := &Decoder{r: r, subGroupCheck: true}
    70  
    71  	for _, o := range options {
    72  		o(d)
    73  	}
    74  
    75  	return d
    76  }
    77  
    78  // Decode reads the binary encoding of v from the stream
    79  // type must be *uint64, *fr.Element, *fp.Element, *G1Affine, *G2Affine, *[]G1Affine or *[]G2Affine
    80  func (dec *Decoder) Decode(v interface{}) (err error) {
    81  	rv := reflect.ValueOf(v)
    82  	if v == nil || rv.Kind() != reflect.Ptr || rv.IsNil() || !rv.Elem().CanSet() {
    83  		return errors.New("bn254 decoder: unsupported type, need pointer")
    84  	}
    85  
    86  	// implementation note: code is a bit verbose (abusing code generation), but minimize allocations on the heap
    87  	// in particular, careful attention must be given to usage of Bytes() method on Elements and Points
    88  	// that return an array (not a slice) of bytes. Using this is beneficial to minimize memory allocations
    89  	// in very large (de)serialization upstream in gnark.
    90  	// (but detrimental to code readability here)
    91  
    92  	var read64 int64
    93  	if vf, ok := v.(io.ReaderFrom); ok {
    94  		read64, err = vf.ReadFrom(dec.r)
    95  		dec.n += read64
    96  		return
    97  	}
    98  
    99  	var buf [SizeOfG2AffineUncompressed]byte
   100  	var read int
   101  	var sliceLen uint32
   102  
   103  	switch t := v.(type) {
   104  	case *[][]uint64:
   105  		if sliceLen, err = dec.readUint32(); err != nil {
   106  			return
   107  		}
   108  		*t = make([][]uint64, sliceLen)
   109  
   110  		for i := range *t {
   111  			if sliceLen, err = dec.readUint32(); err != nil {
   112  				return
   113  			}
   114  			(*t)[i] = make([]uint64, sliceLen)
   115  			for j := range (*t)[i] {
   116  				if (*t)[i][j], err = dec.readUint64(); err != nil {
   117  					return
   118  				}
   119  			}
   120  		}
   121  		return
   122  	case *[]uint64:
   123  		if sliceLen, err = dec.readUint32(); err != nil {
   124  			return
   125  		}
   126  		*t = make([]uint64, sliceLen)
   127  		for i := range *t {
   128  			if (*t)[i], err = dec.readUint64(); err != nil {
   129  				return
   130  			}
   131  		}
   132  		return
   133  	case *fr.Element:
   134  		read, err = io.ReadFull(dec.r, buf[:fr.Bytes])
   135  		dec.n += int64(read)
   136  		if err != nil {
   137  			return
   138  		}
   139  		err = t.SetBytesCanonical(buf[:fr.Bytes])
   140  		return
   141  	case *fp.Element:
   142  		read, err = io.ReadFull(dec.r, buf[:fp.Bytes])
   143  		dec.n += int64(read)
   144  		if err != nil {
   145  			return
   146  		}
   147  		err = t.SetBytesCanonical(buf[:fp.Bytes])
   148  		return
   149  	case *[]fr.Element:
   150  		read64, err = (*fr.Vector)(t).ReadFrom(dec.r)
   151  		dec.n += read64
   152  		return
   153  	case *[]fp.Element:
   154  		read64, err = (*fp.Vector)(t).ReadFrom(dec.r)
   155  		dec.n += read64
   156  		return
   157  	case *[][]fr.Element:
   158  		if sliceLen, err = dec.readUint32(); err != nil {
   159  			return
   160  		}
   161  		if len(*t) != int(sliceLen) {
   162  			*t = make([][]fr.Element, sliceLen)
   163  		}
   164  		for i := range *t {
   165  			read64, err = (*fr.Vector)(&(*t)[i]).ReadFrom(dec.r)
   166  			dec.n += read64
   167  		}
   168  		return
   169  	case *G1Affine:
   170  		// we start by reading compressed point size, if metadata tells us it is uncompressed, we read more.
   171  		read, err = io.ReadFull(dec.r, buf[:SizeOfG1AffineCompressed])
   172  		dec.n += int64(read)
   173  		if err != nil {
   174  			return
   175  		}
   176  		nbBytes := SizeOfG1AffineCompressed
   177  
   178  		// most significant byte contains metadata
   179  		if !isCompressed(buf[0]) {
   180  			nbBytes = SizeOfG1AffineUncompressed
   181  			// we read more.
   182  			read, err = io.ReadFull(dec.r, buf[SizeOfG1AffineCompressed:SizeOfG1AffineUncompressed])
   183  			dec.n += int64(read)
   184  			if err != nil {
   185  				return
   186  			}
   187  		}
   188  		_, err = t.setBytes(buf[:nbBytes], dec.subGroupCheck)
   189  		return
   190  	case *G2Affine:
   191  		// we start by reading compressed point size, if metadata tells us it is uncompressed, we read more.
   192  		read, err = io.ReadFull(dec.r, buf[:SizeOfG2AffineCompressed])
   193  		dec.n += int64(read)
   194  		if err != nil {
   195  			return
   196  		}
   197  		nbBytes := SizeOfG2AffineCompressed
   198  
   199  		// most significant byte contains metadata
   200  		if !isCompressed(buf[0]) {
   201  			nbBytes = SizeOfG2AffineUncompressed
   202  			// we read more.
   203  			read, err = io.ReadFull(dec.r, buf[SizeOfG2AffineCompressed:SizeOfG2AffineUncompressed])
   204  			dec.n += int64(read)
   205  			if err != nil {
   206  				return
   207  			}
   208  		}
   209  		_, err = t.setBytes(buf[:nbBytes], dec.subGroupCheck)
   210  		return
   211  	case *[]G1Affine:
   212  		sliceLen, err = dec.readUint32()
   213  		if err != nil {
   214  			return
   215  		}
   216  		if len(*t) != int(sliceLen) || *t == nil {
   217  			*t = make([]G1Affine, sliceLen)
   218  		}
   219  		compressed := make([]bool, sliceLen)
   220  		for i := 0; i < len(*t); i++ {
   221  
   222  			// we start by reading compressed point size, if metadata tells us it is uncompressed, we read more.
   223  			read, err = io.ReadFull(dec.r, buf[:SizeOfG1AffineCompressed])
   224  			dec.n += int64(read)
   225  			if err != nil {
   226  				return
   227  			}
   228  			nbBytes := SizeOfG1AffineCompressed
   229  
   230  			// most significant byte contains metadata
   231  			if !isCompressed(buf[0]) {
   232  				nbBytes = SizeOfG1AffineUncompressed
   233  				// we read more.
   234  				read, err = io.ReadFull(dec.r, buf[SizeOfG1AffineCompressed:SizeOfG1AffineUncompressed])
   235  				dec.n += int64(read)
   236  				if err != nil {
   237  					return
   238  				}
   239  				_, err = (*t)[i].setBytes(buf[:nbBytes], false)
   240  				if err != nil {
   241  					return
   242  				}
   243  			} else {
   244  				var r bool
   245  				if r, err = (*t)[i].unsafeSetCompressedBytes(buf[:nbBytes]); err != nil {
   246  					return
   247  				}
   248  				compressed[i] = !r
   249  			}
   250  		}
   251  		var nbErrs uint64
   252  		parallel.Execute(len(compressed), func(start, end int) {
   253  			for i := start; i < end; i++ {
   254  				if compressed[i] {
   255  					if err := (*t)[i].unsafeComputeY(dec.subGroupCheck); err != nil {
   256  						atomic.AddUint64(&nbErrs, 1)
   257  					}
   258  				} else if dec.subGroupCheck {
   259  					if !(*t)[i].IsInSubGroup() {
   260  						atomic.AddUint64(&nbErrs, 1)
   261  					}
   262  				}
   263  			}
   264  		})
   265  		if nbErrs != 0 {
   266  			return errors.New("point decompression failed")
   267  		}
   268  
   269  		return nil
   270  	case *[]G2Affine:
   271  		sliceLen, err = dec.readUint32()
   272  		if err != nil {
   273  			return
   274  		}
   275  		if len(*t) != int(sliceLen) {
   276  			*t = make([]G2Affine, sliceLen)
   277  		}
   278  		compressed := make([]bool, sliceLen)
   279  		for i := 0; i < len(*t); i++ {
   280  
   281  			// we start by reading compressed point size, if metadata tells us it is uncompressed, we read more.
   282  			read, err = io.ReadFull(dec.r, buf[:SizeOfG2AffineCompressed])
   283  			dec.n += int64(read)
   284  			if err != nil {
   285  				return
   286  			}
   287  			nbBytes := SizeOfG2AffineCompressed
   288  
   289  			// most significant byte contains metadata
   290  			if !isCompressed(buf[0]) {
   291  				nbBytes = SizeOfG2AffineUncompressed
   292  				// we read more.
   293  				read, err = io.ReadFull(dec.r, buf[SizeOfG2AffineCompressed:SizeOfG2AffineUncompressed])
   294  				dec.n += int64(read)
   295  				if err != nil {
   296  					return
   297  				}
   298  				_, err = (*t)[i].setBytes(buf[:nbBytes], false)
   299  				if err != nil {
   300  					return
   301  				}
   302  			} else {
   303  				var r bool
   304  				if r, err = (*t)[i].unsafeSetCompressedBytes(buf[:nbBytes]); err != nil {
   305  					return
   306  				}
   307  				compressed[i] = !r
   308  			}
   309  		}
   310  		var nbErrs uint64
   311  		parallel.Execute(len(compressed), func(start, end int) {
   312  			for i := start; i < end; i++ {
   313  				if compressed[i] {
   314  					if err := (*t)[i].unsafeComputeY(dec.subGroupCheck); err != nil {
   315  						atomic.AddUint64(&nbErrs, 1)
   316  					}
   317  				} else if dec.subGroupCheck {
   318  					if !(*t)[i].IsInSubGroup() {
   319  						atomic.AddUint64(&nbErrs, 1)
   320  					}
   321  				}
   322  			}
   323  		})
   324  		if nbErrs != 0 {
   325  			return errors.New("point decompression failed")
   326  		}
   327  
   328  		return nil
   329  	default:
   330  		n := binary.Size(t)
   331  		if n == -1 {
   332  			return errors.New("bn254 encoder: unsupported type")
   333  		}
   334  		err = binary.Read(dec.r, binary.BigEndian, t)
   335  		if err == nil {
   336  			dec.n += int64(n)
   337  		}
   338  		return
   339  	}
   340  }
   341  
   342  // BytesRead return total bytes read from reader
   343  func (dec *Decoder) BytesRead() int64 {
   344  	return dec.n
   345  }
   346  
   347  func (dec *Decoder) readUint32() (r uint32, err error) {
   348  	var read int
   349  	var buf [4]byte
   350  	read, err = io.ReadFull(dec.r, buf[:4])
   351  	dec.n += int64(read)
   352  	if err != nil {
   353  		return
   354  	}
   355  	r = binary.BigEndian.Uint32(buf[:4])
   356  	return
   357  }
   358  
   359  func (dec *Decoder) readUint64() (r uint64, err error) {
   360  	var read int
   361  	var buf [8]byte
   362  	read, err = io.ReadFull(dec.r, buf[:])
   363  	dec.n += int64(read)
   364  	if err != nil {
   365  		return
   366  	}
   367  	r = binary.BigEndian.Uint64(buf[:])
   368  	return
   369  }
   370  
   371  func isCompressed(msb byte) bool {
   372  	mData := msb & mMask
   373  	return !(mData == mUncompressed)
   374  }
   375  
   376  // NewEncoder returns a binary encoder supporting curve bn254 objects
   377  func NewEncoder(w io.Writer, options ...func(*Encoder)) *Encoder {
   378  	// default settings
   379  	enc := &Encoder{
   380  		w:   w,
   381  		n:   0,
   382  		raw: false,
   383  	}
   384  
   385  	// handle options
   386  	for _, option := range options {
   387  		option(enc)
   388  	}
   389  
   390  	return enc
   391  }
   392  
   393  // Encode writes the binary encoding of v to the stream
   394  // type must be uint64, *fr.Element, *fp.Element, *G1Affine, *G2Affine, []G1Affine or []G2Affine
   395  func (enc *Encoder) Encode(v interface{}) (err error) {
   396  	if enc.raw {
   397  		return enc.encodeRaw(v)
   398  	}
   399  	return enc.encode(v)
   400  }
   401  
   402  // BytesWritten return total bytes written on writer
   403  func (enc *Encoder) BytesWritten() int64 {
   404  	return enc.n
   405  }
   406  
   407  // RawEncoding returns an option to use in NewEncoder(...) which sets raw encoding mode to true
   408  // points will not be compressed using this option
   409  func RawEncoding() func(*Encoder) {
   410  	return func(enc *Encoder) {
   411  		enc.raw = true
   412  	}
   413  }
   414  
   415  // NoSubgroupChecks returns an option to use in NewDecoder(...) which disable subgroup checks on the points
   416  // the decoder will read. Use with caution, as crafted points from an untrusted source can lead to crypto-attacks.
   417  func NoSubgroupChecks() func(*Decoder) {
   418  	return func(dec *Decoder) {
   419  		dec.subGroupCheck = false
   420  	}
   421  }
   422  
   423  // isZeroed checks that the provided bytes are at 0
   424  func isZeroed(firstByte byte, buf []byte) bool {
   425  	if firstByte != 0 {
   426  		return false
   427  	}
   428  	for _, b := range buf {
   429  		if b != 0 {
   430  			return false
   431  		}
   432  	}
   433  	return true
   434  }
   435  
   436  func (enc *Encoder) encode(v interface{}) (err error) {
   437  	rv := reflect.ValueOf(v)
   438  	if v == nil || (rv.Kind() == reflect.Ptr && rv.IsNil()) {
   439  		return errors.New("<no value> encoder: can't encode <nil>")
   440  	}
   441  
   442  	// implementation note: code is a bit verbose (abusing code generation), but minimize allocations on the heap
   443  
   444  	var written64 int64
   445  	if vw, ok := v.(io.WriterTo); ok {
   446  		written64, err = vw.WriteTo(enc.w)
   447  		enc.n += written64
   448  		return
   449  	}
   450  
   451  	var written int
   452  
   453  	switch t := v.(type) {
   454  	case []uint64:
   455  		return enc.writeUint64Slice(t)
   456  	case [][]uint64:
   457  		return enc.writeUint64SliceSlice(t)
   458  	case *fr.Element:
   459  		buf := t.Bytes()
   460  		written, err = enc.w.Write(buf[:])
   461  		enc.n += int64(written)
   462  		return
   463  	case *fp.Element:
   464  		buf := t.Bytes()
   465  		written, err = enc.w.Write(buf[:])
   466  		enc.n += int64(written)
   467  		return
   468  	case *G1Affine:
   469  		buf := t.Bytes()
   470  		written, err = enc.w.Write(buf[:])
   471  		enc.n += int64(written)
   472  		return
   473  	case *G2Affine:
   474  		buf := t.Bytes()
   475  		written, err = enc.w.Write(buf[:])
   476  		enc.n += int64(written)
   477  		return
   478  	case fr.Vector:
   479  		written64, err = t.WriteTo(enc.w)
   480  		enc.n += written64
   481  		return
   482  	case fp.Vector:
   483  		written64, err = t.WriteTo(enc.w)
   484  		enc.n += written64
   485  		return
   486  	case []fr.Element:
   487  		written64, err = (*fr.Vector)(&t).WriteTo(enc.w)
   488  		enc.n += written64
   489  		return
   490  	case []fp.Element:
   491  		written64, err = (*fp.Vector)(&t).WriteTo(enc.w)
   492  		enc.n += written64
   493  		return
   494  	case [][]fr.Element:
   495  		// write slice length
   496  		if err = binary.Write(enc.w, binary.BigEndian, uint32(len(t))); err != nil {
   497  			return
   498  		}
   499  		enc.n += 4
   500  		for i := range t {
   501  			written64, err = (*fr.Vector)(&t[i]).WriteTo(enc.w)
   502  			enc.n += written64
   503  		}
   504  		return
   505  	case []G1Affine:
   506  		// write slice length
   507  		err = binary.Write(enc.w, binary.BigEndian, uint32(len(t)))
   508  		if err != nil {
   509  			return
   510  		}
   511  		enc.n += 4
   512  
   513  		var buf [SizeOfG1AffineCompressed]byte
   514  
   515  		for i := 0; i < len(t); i++ {
   516  			buf = t[i].Bytes()
   517  			written, err = enc.w.Write(buf[:])
   518  			enc.n += int64(written)
   519  			if err != nil {
   520  				return
   521  			}
   522  		}
   523  		return nil
   524  	case []G2Affine:
   525  		// write slice length
   526  		err = binary.Write(enc.w, binary.BigEndian, uint32(len(t)))
   527  		if err != nil {
   528  			return
   529  		}
   530  		enc.n += 4
   531  
   532  		var buf [SizeOfG2AffineCompressed]byte
   533  
   534  		for i := 0; i < len(t); i++ {
   535  			buf = t[i].Bytes()
   536  			written, err = enc.w.Write(buf[:])
   537  			enc.n += int64(written)
   538  			if err != nil {
   539  				return
   540  			}
   541  		}
   542  		return nil
   543  	default:
   544  		n := binary.Size(t)
   545  		if n == -1 {
   546  			return errors.New("<no value> encoder: unsupported type")
   547  		}
   548  		err = binary.Write(enc.w, binary.BigEndian, t)
   549  		enc.n += int64(n)
   550  		return
   551  	}
   552  }
   553  
   554  func (enc *Encoder) encodeRaw(v interface{}) (err error) {
   555  	rv := reflect.ValueOf(v)
   556  	if v == nil || (rv.Kind() == reflect.Ptr && rv.IsNil()) {
   557  		return errors.New("<no value> encoder: can't encode <nil>")
   558  	}
   559  
   560  	// implementation note: code is a bit verbose (abusing code generation), but minimize allocations on the heap
   561  
   562  	var written64 int64
   563  	if vw, ok := v.(io.WriterTo); ok {
   564  		written64, err = vw.WriteTo(enc.w)
   565  		enc.n += written64
   566  		return
   567  	}
   568  
   569  	var written int
   570  
   571  	switch t := v.(type) {
   572  	case []uint64:
   573  		return enc.writeUint64Slice(t)
   574  	case [][]uint64:
   575  		return enc.writeUint64SliceSlice(t)
   576  	case *fr.Element:
   577  		buf := t.Bytes()
   578  		written, err = enc.w.Write(buf[:])
   579  		enc.n += int64(written)
   580  		return
   581  	case *fp.Element:
   582  		buf := t.Bytes()
   583  		written, err = enc.w.Write(buf[:])
   584  		enc.n += int64(written)
   585  		return
   586  	case *G1Affine:
   587  		buf := t.RawBytes()
   588  		written, err = enc.w.Write(buf[:])
   589  		enc.n += int64(written)
   590  		return
   591  	case *G2Affine:
   592  		buf := t.RawBytes()
   593  		written, err = enc.w.Write(buf[:])
   594  		enc.n += int64(written)
   595  		return
   596  	case fr.Vector:
   597  		written64, err = t.WriteTo(enc.w)
   598  		enc.n += written64
   599  		return
   600  	case fp.Vector:
   601  		written64, err = t.WriteTo(enc.w)
   602  		enc.n += written64
   603  		return
   604  	case []fr.Element:
   605  		written64, err = (*fr.Vector)(&t).WriteTo(enc.w)
   606  		enc.n += written64
   607  		return
   608  	case []fp.Element:
   609  		written64, err = (*fp.Vector)(&t).WriteTo(enc.w)
   610  		enc.n += written64
   611  		return
   612  	case [][]fr.Element:
   613  		// write slice length
   614  		if err = binary.Write(enc.w, binary.BigEndian, uint32(len(t))); err != nil {
   615  			return
   616  		}
   617  		enc.n += 4
   618  		for i := range t {
   619  			written64, err = (*fr.Vector)(&t[i]).WriteTo(enc.w)
   620  			enc.n += written64
   621  		}
   622  		return
   623  	case []G1Affine:
   624  		// write slice length
   625  		err = binary.Write(enc.w, binary.BigEndian, uint32(len(t)))
   626  		if err != nil {
   627  			return
   628  		}
   629  		enc.n += 4
   630  
   631  		var buf [SizeOfG1AffineUncompressed]byte
   632  
   633  		for i := 0; i < len(t); i++ {
   634  			buf = t[i].RawBytes()
   635  			written, err = enc.w.Write(buf[:])
   636  			enc.n += int64(written)
   637  			if err != nil {
   638  				return
   639  			}
   640  		}
   641  		return nil
   642  	case []G2Affine:
   643  		// write slice length
   644  		err = binary.Write(enc.w, binary.BigEndian, uint32(len(t)))
   645  		if err != nil {
   646  			return
   647  		}
   648  		enc.n += 4
   649  
   650  		var buf [SizeOfG2AffineUncompressed]byte
   651  
   652  		for i := 0; i < len(t); i++ {
   653  			buf = t[i].RawBytes()
   654  			written, err = enc.w.Write(buf[:])
   655  			enc.n += int64(written)
   656  			if err != nil {
   657  				return
   658  			}
   659  		}
   660  		return nil
   661  	default:
   662  		n := binary.Size(t)
   663  		if n == -1 {
   664  			return errors.New("<no value> encoder: unsupported type")
   665  		}
   666  		err = binary.Write(enc.w, binary.BigEndian, t)
   667  		enc.n += int64(n)
   668  		return
   669  	}
   670  }
   671  
   672  func (enc *Encoder) writeUint64Slice(t []uint64) (err error) {
   673  	if err = enc.writeUint32(uint32(len(t))); err != nil {
   674  		return
   675  	}
   676  	for i := range t {
   677  		if err = enc.writeUint64(t[i]); err != nil {
   678  			return
   679  		}
   680  	}
   681  	return nil
   682  }
   683  
   684  func (enc *Encoder) writeUint64SliceSlice(t [][]uint64) (err error) {
   685  	if err = enc.writeUint32(uint32(len(t))); err != nil {
   686  		return
   687  	}
   688  	for i := range t {
   689  		if err = enc.writeUint32(uint32(len(t[i]))); err != nil {
   690  			return
   691  		}
   692  		for j := range t[i] {
   693  			if err = enc.writeUint64(t[i][j]); err != nil {
   694  				return
   695  			}
   696  		}
   697  	}
   698  	return nil
   699  }
   700  
   701  func (enc *Encoder) writeUint64(a uint64) error {
   702  	var buff [64 / 8]byte
   703  	binary.BigEndian.PutUint64(buff[:], a)
   704  	written, err := enc.w.Write(buff[:])
   705  	enc.n += int64(written)
   706  	return err
   707  }
   708  
   709  func (enc *Encoder) writeUint32(a uint32) error {
   710  	var buff [32 / 8]byte
   711  	binary.BigEndian.PutUint32(buff[:], a)
   712  	written, err := enc.w.Write(buff[:])
   713  	enc.n += int64(written)
   714  	return err
   715  }
   716  
   717  // SizeOfG1AffineCompressed represents the size in bytes that a G1Affine need in binary form, compressed
   718  const SizeOfG1AffineCompressed = 32
   719  
   720  // SizeOfG1AffineUncompressed represents the size in bytes that a G1Affine need in binary form, uncompressed
   721  const SizeOfG1AffineUncompressed = SizeOfG1AffineCompressed * 2
   722  
   723  // Marshal converts p to a byte slice (without point compression)
   724  func (p *G1Affine) Marshal() []byte {
   725  	b := p.RawBytes()
   726  	return b[:]
   727  }
   728  
   729  // Unmarshal is an alias to SetBytes()
   730  func (p *G1Affine) Unmarshal(buf []byte) error {
   731  	_, err := p.SetBytes(buf)
   732  	return err
   733  }
   734  
   735  // Bytes returns binary representation of p
   736  // will store X coordinate in regular form and a parity bit
   737  // as we have less than 3 bits available in our coordinate, we can't follow BLS12-381 style encoding (ZCash/IETF)
   738  //
   739  // we use the 2 most significant bits instead
   740  //
   741  //	00 -> uncompressed
   742  //	10 -> compressed, use smallest lexicographically square root of Y^2
   743  //	11 -> compressed, use largest lexicographically square root of Y^2
   744  //	01 -> compressed infinity point
   745  //	the "uncompressed infinity point" will just have 00 (uncompressed) followed by zeroes (infinity = 0,0 in affine coordinates)
   746  func (p *G1Affine) Bytes() (res [SizeOfG1AffineCompressed]byte) {
   747  
   748  	// check if p is infinity point
   749  	if p.X.IsZero() && p.Y.IsZero() {
   750  		res[0] = mCompressedInfinity
   751  		return
   752  	}
   753  
   754  	msbMask := mCompressedSmallest
   755  	// compressed, we need to know if Y is lexicographically bigger than -Y
   756  	// if p.Y ">" -p.Y
   757  	if p.Y.LexicographicallyLargest() {
   758  		msbMask = mCompressedLargest
   759  	}
   760  
   761  	// we store X  and mask the most significant word with our metadata mask
   762  	fp.BigEndian.PutElement((*[fp.Bytes]byte)(res[0:0+fp.Bytes]), p.X)
   763  
   764  	res[0] |= msbMask
   765  
   766  	return
   767  }
   768  
   769  // RawBytes returns binary representation of p (stores X and Y coordinate)
   770  // see Bytes() for a compressed representation
   771  func (p *G1Affine) RawBytes() (res [SizeOfG1AffineUncompressed]byte) {
   772  
   773  	// check if p is infinity point
   774  	if p.X.IsZero() && p.Y.IsZero() {
   775  
   776  		res[0] = mUncompressed
   777  
   778  		return
   779  	}
   780  
   781  	// not compressed
   782  	// we store the Y coordinate
   783  	fp.BigEndian.PutElement((*[fp.Bytes]byte)(res[32:32+fp.Bytes]), p.Y)
   784  
   785  	// we store X  and mask the most significant word with our metadata mask
   786  	fp.BigEndian.PutElement((*[fp.Bytes]byte)(res[0:0+fp.Bytes]), p.X)
   787  
   788  	res[0] |= mUncompressed
   789  
   790  	return
   791  }
   792  
   793  // SetBytes sets p from binary representation in buf and returns number of consumed bytes
   794  //
   795  // bytes in buf must match either RawBytes() or Bytes() output
   796  //
   797  // if buf is too short io.ErrShortBuffer is returned
   798  //
   799  // if buf contains compressed representation (output from Bytes()) and we're unable to compute
   800  // the Y coordinate (i.e the square root doesn't exist) this function returns an error
   801  //
   802  // this check if the resulting point is on the curve and in the correct subgroup
   803  func (p *G1Affine) SetBytes(buf []byte) (int, error) {
   804  	return p.setBytes(buf, true)
   805  }
   806  
   807  func (p *G1Affine) setBytes(buf []byte, subGroupCheck bool) (int, error) {
   808  	if len(buf) < SizeOfG1AffineCompressed {
   809  		return 0, io.ErrShortBuffer
   810  	}
   811  
   812  	// most significant byte
   813  	mData := buf[0] & mMask
   814  
   815  	// check buffer size
   816  	if mData == mUncompressed {
   817  		if len(buf) < SizeOfG1AffineUncompressed {
   818  			return 0, io.ErrShortBuffer
   819  		}
   820  	}
   821  
   822  	// infinity encoded, we still check that the buffer is full of zeroes.
   823  	if mData == mCompressedInfinity {
   824  		if !isZeroed(buf[0] & ^mMask, buf[1:SizeOfG1AffineCompressed]) {
   825  			return 0, ErrInvalidInfinityEncoding
   826  		}
   827  		p.X.SetZero()
   828  		p.Y.SetZero()
   829  		return SizeOfG1AffineCompressed, nil
   830  	}
   831  
   832  	// uncompressed point
   833  	if mData == mUncompressed {
   834  		// read X and Y coordinates
   835  		if err := p.X.SetBytesCanonical(buf[:fp.Bytes]); err != nil {
   836  			return 0, err
   837  		}
   838  		if err := p.Y.SetBytesCanonical(buf[fp.Bytes : fp.Bytes*2]); err != nil {
   839  			return 0, err
   840  		}
   841  
   842  		// subgroup check
   843  		if subGroupCheck && !p.IsInSubGroup() {
   844  			return 0, errors.New("invalid point: subgroup check failed")
   845  		}
   846  
   847  		return SizeOfG1AffineUncompressed, nil
   848  	}
   849  
   850  	// we have a compressed coordinate
   851  	// we need to
   852  	// 	1. copy the buffer (to keep this method thread safe)
   853  	// 	2. we need to solve the curve equation to compute Y
   854  
   855  	var bufX [fp.Bytes]byte
   856  	copy(bufX[:fp.Bytes], buf[:fp.Bytes])
   857  	bufX[0] &= ^mMask
   858  
   859  	// read X coordinate
   860  	if err := p.X.SetBytesCanonical(bufX[:fp.Bytes]); err != nil {
   861  		return 0, err
   862  	}
   863  
   864  	var YSquared, Y fp.Element
   865  
   866  	YSquared.Square(&p.X).Mul(&YSquared, &p.X)
   867  	YSquared.Add(&YSquared, &bCurveCoeff)
   868  	if Y.Sqrt(&YSquared) == nil {
   869  		return 0, errors.New("invalid compressed coordinate: square root doesn't exist")
   870  	}
   871  
   872  	if Y.LexicographicallyLargest() {
   873  		// Y ">" -Y
   874  		if mData == mCompressedSmallest {
   875  			Y.Neg(&Y)
   876  		}
   877  	} else {
   878  		// Y "<=" -Y
   879  		if mData == mCompressedLargest {
   880  			Y.Neg(&Y)
   881  		}
   882  	}
   883  
   884  	p.Y = Y
   885  
   886  	// subgroup check
   887  	if subGroupCheck && !p.IsInSubGroup() {
   888  		return 0, errors.New("invalid point: subgroup check failed")
   889  	}
   890  
   891  	return SizeOfG1AffineCompressed, nil
   892  }
   893  
   894  // unsafeComputeY called by Decoder when processing slices of compressed point in parallel (step 2)
   895  // it computes the Y coordinate from the already set X coordinate and is compute intensive
   896  func (p *G1Affine) unsafeComputeY(subGroupCheck bool) error {
   897  	// stored in unsafeSetCompressedBytes
   898  
   899  	mData := byte(p.Y[0])
   900  
   901  	// we have a compressed coordinate, we need to solve the curve equation to compute Y
   902  	var YSquared, Y fp.Element
   903  
   904  	YSquared.Square(&p.X).Mul(&YSquared, &p.X)
   905  	YSquared.Add(&YSquared, &bCurveCoeff)
   906  	if Y.Sqrt(&YSquared) == nil {
   907  		return errors.New("invalid compressed coordinate: square root doesn't exist")
   908  	}
   909  
   910  	if Y.LexicographicallyLargest() {
   911  		// Y ">" -Y
   912  		if mData == mCompressedSmallest {
   913  			Y.Neg(&Y)
   914  		}
   915  	} else {
   916  		// Y "<=" -Y
   917  		if mData == mCompressedLargest {
   918  			Y.Neg(&Y)
   919  		}
   920  	}
   921  
   922  	p.Y = Y
   923  
   924  	// subgroup check
   925  	if subGroupCheck && !p.IsInSubGroup() {
   926  		return errors.New("invalid point: subgroup check failed")
   927  	}
   928  
   929  	return nil
   930  }
   931  
   932  // unsafeSetCompressedBytes is called by Decoder when processing slices of compressed point in parallel (step 1)
   933  // assumes buf[:8] mask is set to compressed
   934  // returns true if point is infinity and need no further processing
   935  // it sets X coordinate and uses Y for scratch space to store decompression metadata
   936  func (p *G1Affine) unsafeSetCompressedBytes(buf []byte) (isInfinity bool, err error) {
   937  
   938  	// read the most significant byte
   939  	mData := buf[0] & mMask
   940  
   941  	if mData == mCompressedInfinity {
   942  		isInfinity = true
   943  		if !isZeroed(buf[0] & ^mMask, buf[1:SizeOfG1AffineCompressed]) {
   944  			return isInfinity, ErrInvalidInfinityEncoding
   945  		}
   946  		p.X.SetZero()
   947  		p.Y.SetZero()
   948  		return isInfinity, nil
   949  	}
   950  
   951  	// we need to copy the input buffer (to keep this method thread safe)
   952  	var bufX [fp.Bytes]byte
   953  	copy(bufX[:fp.Bytes], buf[:fp.Bytes])
   954  	bufX[0] &= ^mMask
   955  
   956  	// read X coordinate
   957  	if err := p.X.SetBytesCanonical(bufX[:fp.Bytes]); err != nil {
   958  		return false, err
   959  	}
   960  	// store mData in p.Y[0]
   961  	p.Y[0] = uint64(mData)
   962  
   963  	// recomputing Y will be done asynchronously
   964  	return isInfinity, nil
   965  }
   966  
   967  // SizeOfG2AffineCompressed represents the size in bytes that a G2Affine need in binary form, compressed
   968  const SizeOfG2AffineCompressed = 32 * 2
   969  
   970  // SizeOfG2AffineUncompressed represents the size in bytes that a G2Affine need in binary form, uncompressed
   971  const SizeOfG2AffineUncompressed = SizeOfG2AffineCompressed * 2
   972  
   973  // Marshal converts p to a byte slice (without point compression)
   974  func (p *G2Affine) Marshal() []byte {
   975  	b := p.RawBytes()
   976  	return b[:]
   977  }
   978  
   979  // Unmarshal is an alias to SetBytes()
   980  func (p *G2Affine) Unmarshal(buf []byte) error {
   981  	_, err := p.SetBytes(buf)
   982  	return err
   983  }
   984  
   985  // Bytes returns binary representation of p
   986  // will store X coordinate in regular form and a parity bit
   987  // as we have less than 3 bits available in our coordinate, we can't follow BLS12-381 style encoding (ZCash/IETF)
   988  //
   989  // we use the 2 most significant bits instead
   990  //
   991  //	00 -> uncompressed
   992  //	10 -> compressed, use smallest lexicographically square root of Y^2
   993  //	11 -> compressed, use largest lexicographically square root of Y^2
   994  //	01 -> compressed infinity point
   995  //	the "uncompressed infinity point" will just have 00 (uncompressed) followed by zeroes (infinity = 0,0 in affine coordinates)
   996  func (p *G2Affine) Bytes() (res [SizeOfG2AffineCompressed]byte) {
   997  
   998  	// check if p is infinity point
   999  	if p.X.IsZero() && p.Y.IsZero() {
  1000  		res[0] = mCompressedInfinity
  1001  		return
  1002  	}
  1003  
  1004  	msbMask := mCompressedSmallest
  1005  	// compressed, we need to know if Y is lexicographically bigger than -Y
  1006  	// if p.Y ">" -p.Y
  1007  	if p.Y.LexicographicallyLargest() {
  1008  		msbMask = mCompressedLargest
  1009  	}
  1010  
  1011  	// we store X  and mask the most significant word with our metadata mask
  1012  	// p.X.A1 | p.X.A0
  1013  	fp.BigEndian.PutElement((*[fp.Bytes]byte)(res[32:32+fp.Bytes]), p.X.A0)
  1014  	fp.BigEndian.PutElement((*[fp.Bytes]byte)(res[0:0+fp.Bytes]), p.X.A1)
  1015  
  1016  	res[0] |= msbMask
  1017  
  1018  	return
  1019  }
  1020  
  1021  // RawBytes returns binary representation of p (stores X and Y coordinate)
  1022  // see Bytes() for a compressed representation
  1023  func (p *G2Affine) RawBytes() (res [SizeOfG2AffineUncompressed]byte) {
  1024  
  1025  	// check if p is infinity point
  1026  	if p.X.IsZero() && p.Y.IsZero() {
  1027  
  1028  		res[0] = mUncompressed
  1029  
  1030  		return
  1031  	}
  1032  
  1033  	// not compressed
  1034  	// we store the Y coordinate
  1035  	// p.Y.A1 | p.Y.A0
  1036  	fp.BigEndian.PutElement((*[fp.Bytes]byte)(res[96:96+fp.Bytes]), p.Y.A0)
  1037  	fp.BigEndian.PutElement((*[fp.Bytes]byte)(res[64:64+fp.Bytes]), p.Y.A1)
  1038  
  1039  	// we store X  and mask the most significant word with our metadata mask
  1040  	// p.X.A1 | p.X.A0
  1041  	fp.BigEndian.PutElement((*[fp.Bytes]byte)(res[0:0+fp.Bytes]), p.X.A1)
  1042  	fp.BigEndian.PutElement((*[fp.Bytes]byte)(res[32:32+fp.Bytes]), p.X.A0)
  1043  
  1044  	res[0] |= mUncompressed
  1045  
  1046  	return
  1047  }
  1048  
  1049  // SetBytes sets p from binary representation in buf and returns number of consumed bytes
  1050  //
  1051  // bytes in buf must match either RawBytes() or Bytes() output
  1052  //
  1053  // if buf is too short io.ErrShortBuffer is returned
  1054  //
  1055  // if buf contains compressed representation (output from Bytes()) and we're unable to compute
  1056  // the Y coordinate (i.e the square root doesn't exist) this function returns an error
  1057  //
  1058  // this check if the resulting point is on the curve and in the correct subgroup
  1059  func (p *G2Affine) SetBytes(buf []byte) (int, error) {
  1060  	return p.setBytes(buf, true)
  1061  }
  1062  
  1063  func (p *G2Affine) setBytes(buf []byte, subGroupCheck bool) (int, error) {
  1064  	if len(buf) < SizeOfG2AffineCompressed {
  1065  		return 0, io.ErrShortBuffer
  1066  	}
  1067  
  1068  	// most significant byte
  1069  	mData := buf[0] & mMask
  1070  
  1071  	// check buffer size
  1072  	if mData == mUncompressed {
  1073  		if len(buf) < SizeOfG2AffineUncompressed {
  1074  			return 0, io.ErrShortBuffer
  1075  		}
  1076  	}
  1077  
  1078  	// infinity encoded, we still check that the buffer is full of zeroes.
  1079  	if mData == mCompressedInfinity {
  1080  		if !isZeroed(buf[0] & ^mMask, buf[1:SizeOfG2AffineCompressed]) {
  1081  			return 0, ErrInvalidInfinityEncoding
  1082  		}
  1083  		p.X.SetZero()
  1084  		p.Y.SetZero()
  1085  		return SizeOfG2AffineCompressed, nil
  1086  	}
  1087  
  1088  	// uncompressed point
  1089  	if mData == mUncompressed {
  1090  		// read X and Y coordinates
  1091  		// p.X.A1 | p.X.A0
  1092  		if err := p.X.A1.SetBytesCanonical(buf[:fp.Bytes]); err != nil {
  1093  			return 0, err
  1094  		}
  1095  		if err := p.X.A0.SetBytesCanonical(buf[fp.Bytes : fp.Bytes*2]); err != nil {
  1096  			return 0, err
  1097  		}
  1098  		// p.Y.A1 | p.Y.A0
  1099  		if err := p.Y.A1.SetBytesCanonical(buf[fp.Bytes*2 : fp.Bytes*3]); err != nil {
  1100  			return 0, err
  1101  		}
  1102  		if err := p.Y.A0.SetBytesCanonical(buf[fp.Bytes*3 : fp.Bytes*4]); err != nil {
  1103  			return 0, err
  1104  		}
  1105  
  1106  		// subgroup check
  1107  		if subGroupCheck && !p.IsInSubGroup() {
  1108  			return 0, errors.New("invalid point: subgroup check failed")
  1109  		}
  1110  
  1111  		return SizeOfG2AffineUncompressed, nil
  1112  	}
  1113  
  1114  	// we have a compressed coordinate
  1115  	// we need to
  1116  	// 	1. copy the buffer (to keep this method thread safe)
  1117  	// 	2. we need to solve the curve equation to compute Y
  1118  
  1119  	var bufX [fp.Bytes]byte
  1120  	copy(bufX[:fp.Bytes], buf[:fp.Bytes])
  1121  	bufX[0] &= ^mMask
  1122  
  1123  	// read X coordinate
  1124  	// p.X.A1 | p.X.A0
  1125  	if err := p.X.A1.SetBytesCanonical(bufX[:fp.Bytes]); err != nil {
  1126  		return 0, err
  1127  	}
  1128  	if err := p.X.A0.SetBytesCanonical(buf[fp.Bytes : fp.Bytes*2]); err != nil {
  1129  		return 0, err
  1130  	}
  1131  
  1132  	var YSquared, Y fptower.E2
  1133  
  1134  	YSquared.Square(&p.X).Mul(&YSquared, &p.X)
  1135  	YSquared.Add(&YSquared, &bTwistCurveCoeff)
  1136  	if YSquared.Legendre() == -1 {
  1137  		return 0, errors.New("invalid compressed coordinate: square root doesn't exist")
  1138  	}
  1139  	Y.Sqrt(&YSquared)
  1140  
  1141  	if Y.LexicographicallyLargest() {
  1142  		// Y ">" -Y
  1143  		if mData == mCompressedSmallest {
  1144  			Y.Neg(&Y)
  1145  		}
  1146  	} else {
  1147  		// Y "<=" -Y
  1148  		if mData == mCompressedLargest {
  1149  			Y.Neg(&Y)
  1150  		}
  1151  	}
  1152  
  1153  	p.Y = Y
  1154  
  1155  	// subgroup check
  1156  	if subGroupCheck && !p.IsInSubGroup() {
  1157  		return 0, errors.New("invalid point: subgroup check failed")
  1158  	}
  1159  
  1160  	return SizeOfG2AffineCompressed, nil
  1161  }
  1162  
  1163  // unsafeComputeY called by Decoder when processing slices of compressed point in parallel (step 2)
  1164  // it computes the Y coordinate from the already set X coordinate and is compute intensive
  1165  func (p *G2Affine) unsafeComputeY(subGroupCheck bool) error {
  1166  	// stored in unsafeSetCompressedBytes
  1167  
  1168  	mData := byte(p.Y.A0[0])
  1169  
  1170  	// we have a compressed coordinate, we need to solve the curve equation to compute Y
  1171  	var YSquared, Y fptower.E2
  1172  
  1173  	YSquared.Square(&p.X).Mul(&YSquared, &p.X)
  1174  	YSquared.Add(&YSquared, &bTwistCurveCoeff)
  1175  	if YSquared.Legendre() == -1 {
  1176  		return errors.New("invalid compressed coordinate: square root doesn't exist")
  1177  	}
  1178  	Y.Sqrt(&YSquared)
  1179  
  1180  	if Y.LexicographicallyLargest() {
  1181  		// Y ">" -Y
  1182  		if mData == mCompressedSmallest {
  1183  			Y.Neg(&Y)
  1184  		}
  1185  	} else {
  1186  		// Y "<=" -Y
  1187  		if mData == mCompressedLargest {
  1188  			Y.Neg(&Y)
  1189  		}
  1190  	}
  1191  
  1192  	p.Y = Y
  1193  
  1194  	// subgroup check
  1195  	if subGroupCheck && !p.IsInSubGroup() {
  1196  		return errors.New("invalid point: subgroup check failed")
  1197  	}
  1198  
  1199  	return nil
  1200  }
  1201  
  1202  // unsafeSetCompressedBytes is called by Decoder when processing slices of compressed point in parallel (step 1)
  1203  // assumes buf[:8] mask is set to compressed
  1204  // returns true if point is infinity and need no further processing
  1205  // it sets X coordinate and uses Y for scratch space to store decompression metadata
  1206  func (p *G2Affine) unsafeSetCompressedBytes(buf []byte) (isInfinity bool, err error) {
  1207  
  1208  	// read the most significant byte
  1209  	mData := buf[0] & mMask
  1210  
  1211  	if mData == mCompressedInfinity {
  1212  		isInfinity = true
  1213  		if !isZeroed(buf[0] & ^mMask, buf[1:SizeOfG2AffineCompressed]) {
  1214  			return isInfinity, ErrInvalidInfinityEncoding
  1215  		}
  1216  		p.X.SetZero()
  1217  		p.Y.SetZero()
  1218  		return isInfinity, nil
  1219  	}
  1220  
  1221  	// we need to copy the input buffer (to keep this method thread safe)
  1222  	var bufX [fp.Bytes]byte
  1223  	copy(bufX[:fp.Bytes], buf[:fp.Bytes])
  1224  	bufX[0] &= ^mMask
  1225  
  1226  	// read X coordinate
  1227  	// p.X.A1 | p.X.A0
  1228  	if err := p.X.A1.SetBytesCanonical(bufX[:fp.Bytes]); err != nil {
  1229  		return false, err
  1230  	}
  1231  	if err := p.X.A0.SetBytesCanonical(buf[fp.Bytes : fp.Bytes*2]); err != nil {
  1232  		return false, err
  1233  	}
  1234  
  1235  	// store mData in p.Y.A0[0]
  1236  	p.Y.A0[0] = uint64(mData)
  1237  
  1238  	// recomputing Y will be done asynchronously
  1239  	return isInfinity, nil
  1240  }