github.com/consensys/gnark-crypto@v0.14.0/ecc/bls12-381/bandersnatch/eddsa/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 eddsa 18 19 import ( 20 "crypto/subtle" 21 "errors" 22 "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" 23 "github.com/consensys/gnark-crypto/ecc/bls12-381/twistededwards" 24 "io" 25 "math/big" 26 ) 27 28 // cf point.go (ugly copy) 29 const mUnmask = 0x7f 30 31 var errWrongSize = errors.New("wrong size buffer") 32 var errSBiggerThanRMod = errors.New("s >= r_mod") 33 var errRBiggerThanPMod = errors.New("r >= p_mod") 34 var errZero = errors.New("zero value") 35 36 // Bytes returns the binary representation of the public key 37 // follows https://tools.ietf.org/html/rfc8032#section-3.1 38 // and returns a compressed representation of the point (x,y) 39 // 40 // x, y are the coordinates of the point 41 // on the twisted Edwards as big endian integers. 42 // compressed representation store x with a parity bit to recompute y 43 func (pk *PublicKey) Bytes() []byte { 44 var res [sizePublicKey]byte 45 pkBin := pk.A.Bytes() 46 subtle.ConstantTimeCopy(1, res[:sizeFr], pkBin[:]) 47 return res[:] 48 } 49 50 // SetBytes sets p from binary representation in buf. 51 // buf represents a public key as x||y where x, y are 52 // interpreted as big endian binary numbers corresponding 53 // to the coordinates of a point on the twisted Edwards. 54 // It returns the number of bytes read from the buffer. 55 func (pk *PublicKey) SetBytes(buf []byte) (int, error) { 56 n := 0 57 if len(buf) < sizePublicKey { 58 return n, io.ErrShortBuffer 59 } 60 if _, err := pk.A.SetBytes(buf[:sizeFr]); err != nil { 61 return 0, err 62 } 63 n += sizeFr 64 if !pk.A.IsOnCurve() { 65 return n, errNotOnCurve 66 } 67 return n, nil 68 } 69 70 // Bytes returns the binary representation of pk, 71 // as byte array publicKey||scalar||randSrc 72 // where publicKey is as publicKey.Bytes(), and 73 // scalar is in big endian, of size sizeFr. 74 func (privKey *PrivateKey) Bytes() []byte { 75 var res [sizePrivateKey]byte 76 pubkBin := privKey.PublicKey.A.Bytes() 77 subtle.ConstantTimeCopy(1, res[:sizeFr], pubkBin[:]) 78 subtle.ConstantTimeCopy(1, res[sizeFr:2*sizeFr], privKey.scalar[:]) 79 subtle.ConstantTimeCopy(1, res[2*sizeFr:], privKey.randSrc[:]) 80 return res[:] 81 } 82 83 // SetBytes sets pk from buf, where buf is interpreted 84 // as publicKey||scalar||randSrc 85 // where publicKey is as publicKey.Bytes(), and 86 // scalar is in big endian, of size sizeFr. 87 // It returns the number byte read. 88 func (privKey *PrivateKey) SetBytes(buf []byte) (int, error) { 89 n := 0 90 if len(buf) < sizePrivateKey { 91 return n, io.ErrShortBuffer 92 } 93 if _, err := privKey.PublicKey.A.SetBytes(buf[:sizeFr]); err != nil { 94 return 0, err 95 } 96 n += sizeFr 97 if !privKey.PublicKey.A.IsOnCurve() { 98 return n, errNotOnCurve 99 } 100 subtle.ConstantTimeCopy(1, privKey.scalar[:], buf[sizeFr:2*sizeFr]) 101 n += sizeFr 102 subtle.ConstantTimeCopy(1, privKey.randSrc[:], buf[2*sizeFr:]) 103 n += sizeFr 104 return n, nil 105 } 106 107 // Bytes returns the binary representation of sig 108 // as a byte array of size 3*sizeFr x||y||s where 109 // - x, y are the coordinates of a point on the twisted 110 // Edwards represented in big endian 111 // - s=r+h(r,a,m) mod l, the Hasse bound guarantees that 112 // s is smaller than sizeFr (in particular it is supposed 113 // s is NOT blinded) 114 func (sig *Signature) Bytes() []byte { 115 var res [sizeSignature]byte 116 sigRBin := sig.R.Bytes() 117 subtle.ConstantTimeCopy(1, res[:sizeFr], sigRBin[:]) 118 subtle.ConstantTimeCopy(1, res[sizeFr:], sig.S[:]) 119 return res[:] 120 } 121 122 // SetBytes sets sig from a buffer in binary. 123 // buf is read interpreted as x||y||s where 124 // - x,y are the coordinates of a point on the twisted 125 // Edwards represented in big endian 126 // - s=r+h(r,a,m) mod l, the Hasse bound guarantees that 127 // s is smaller than sizeFr (in particular it is supposed 128 // s is NOT blinded) 129 // 130 // It returns the number of bytes read from buf. 131 func (sig *Signature) SetBytes(buf []byte) (int, error) { 132 n := 0 133 if len(buf) != sizeSignature { 134 return n, errWrongSize 135 } 136 137 // R < P_mod (to avoid malleability) 138 // P_mod = field of def of the twisted Edwards = Fr snark field 139 fpMod := fr.Modulus() 140 zero := big.NewInt(0) 141 bufBigInt := new(big.Int) 142 bufCopy := make([]byte, fr.Bytes) 143 for i := 0; i < sizeFr; i++ { 144 bufCopy[sizeFr-1-i] = buf[i] 145 } 146 bufCopy[0] &= mUnmask 147 bufBigInt.SetBytes(bufCopy) 148 if bufBigInt.Cmp(zero) == 0 { 149 return 0, errZero 150 } 151 if bufBigInt.Cmp(fpMod) != -1 { 152 return 0, errRBiggerThanPMod 153 } 154 155 // S < R_mod (to avoid malleability) 156 // R_mod is the relevant group size of the twisted Edwards NOT the fr snark field so it's supposedly smaller 157 bufBigInt.SetBytes(buf[sizeFr : 2*sizeFr]) 158 if bufBigInt.Cmp(zero) == 0 { 159 return 0, errZero 160 } 161 cp := twistededwards.GetEdwardsCurve() 162 if bufBigInt.Cmp(&cp.Order) != -1 { 163 return 0, errSBiggerThanRMod 164 } 165 166 // deserialisation 167 if _, err := sig.R.SetBytes(buf[:sizeFr]); err != nil { 168 return 0, err 169 } 170 n += sizeFr 171 if !sig.R.IsOnCurve() { 172 return n, errNotOnCurve 173 } 174 subtle.ConstantTimeCopy(1, sig.S[:], buf[sizeFr:2*sizeFr]) 175 n += sizeFr 176 return n, nil 177 }