github.com/consensys/gnark-crypto@v0.14.0/ecc/secp256k1/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 // FOO 16 17 package secp256k1 18 19 import ( 20 "errors" 21 "io" 22 23 "github.com/consensys/gnark-crypto/ecc/secp256k1/fp" 24 ) 25 26 // SizeOfG1AffineCompressed represents the size in bytes that a G1Affine need in binary form, compressed 27 const SizeOfG1AffineCompressed = 32 28 29 // SizeOfG1AffineUncompressed represents the size in bytes that a G1Affine need in binary form, uncompressed 30 const SizeOfG1AffineUncompressed = SizeOfG1AffineCompressed * 2 31 32 // RawBytes returns binary representation of p (stores X and Y coordinate) 33 func (p *G1Affine) RawBytes() (res [SizeOfG1AffineUncompressed]byte) { 34 35 // not compressed 36 // we store the Y coordinate 37 fp.BigEndian.PutElement((*[fp.Bytes]byte)(res[32:32+fp.Bytes]), p.Y) 38 39 // we store the X coordinate 40 fp.BigEndian.PutElement((*[fp.Bytes]byte)(res[0:0+fp.Bytes]), p.X) 41 42 return 43 } 44 45 // SetBytes sets p from binary representation in buf and returns number of consumed bytes 46 // 47 // bytes in buf must match RawBytes() 48 // 49 // if buf is too short io.ErrShortBuffer is returned 50 // 51 // this check if the resulting point is on the curve and in the correct subgroup 52 func (p *G1Affine) SetBytes(buf []byte) (int, error) { 53 return p.setBytes(buf, true) 54 } 55 56 // we store both X and Y and there is no spare bit for flagging 57 func (p *G1Affine) setBytes(buf []byte, subGroupCheck bool) (int, error) { 58 if len(buf) < SizeOfG1AffineCompressed { 59 return 0, io.ErrShortBuffer 60 } 61 62 // uncompressed point 63 // read X and Y coordinates 64 if err := p.X.SetBytesCanonical(buf[:fp.Bytes]); err != nil { 65 return 0, err 66 } 67 if err := p.Y.SetBytesCanonical(buf[fp.Bytes : fp.Bytes*2]); err != nil { 68 return 0, err 69 } 70 71 // subgroup check 72 if subGroupCheck && !p.IsInSubGroup() { 73 return 0, errors.New("invalid point: subgroup check failed") 74 } 75 76 return SizeOfG1AffineUncompressed, nil 77 78 }