github.com/consensys/gnark-crypto@v0.14.0/internal/generator/ecdsa/template/marshal.go.tmpl (about) 1 import ( 2 "crypto/subtle" 3 "io" 4 "errors" 5 "math/big" 6 "github.com/consensys/gnark-crypto/ecc/{{ .Name }}/fr" 7 {{- if or (eq .Name "secp256k1") (eq .Name "bn254") (eq .Name "stark-curve") }} 8 9 "github.com/consensys/gnark-crypto/ecc/{{ .Name }}" 10 {{- end }} 11 ) 12 13 var errWrongSize = errors.New("wrong size buffer") 14 var errRBiggerThanRMod = errors.New("r >= r_mod") 15 var errSBiggerThanRMod = errors.New("s >= r_mod") 16 var errZero = errors.New("zero value") 17 18 // Bytes returns the binary representation of the public key 19 // follows https://tools.ietf.org/html/rfc8032#section-3.1 20 // and returns a compressed representation of the point (x,y) 21 // 22 // x, y are the coordinates of the point 23 // on the curve as big endian integers. 24 // compressed representation store x with a parity bit to recompute y 25 func (pk *PublicKey) Bytes() []byte { 26 var res [sizePublicKey]byte 27 {{- if eq .Name "secp256k1"}} 28 pkBin := pk.A.RawBytes() 29 {{- else}} 30 pkBin := pk.A.Bytes() 31 {{- end}} 32 subtle.ConstantTimeCopy(1, res[:sizePublicKey], pkBin[:]) 33 return res[:] 34 } 35 36 // SetBytes sets p from binary representation in buf. 37 // buf represents a public key as x||y where x, y are 38 // interpreted as big endian binary numbers corresponding 39 // to the coordinates of a point on the curve. 40 // It returns the number of bytes read from the buffer. 41 func (pk *PublicKey) SetBytes(buf []byte) (int, error) { 42 n := 0 43 if len(buf) < sizePublicKey { 44 return n, io.ErrShortBuffer 45 } 46 if _, err := pk.A.SetBytes(buf[:sizePublicKey]); err != nil { 47 return 0, err 48 } 49 n += sizeFp 50 return n, nil 51 } 52 53 {{- if or (eq .Name "secp256k1") (eq .Name "bn254") (eq .Name "stark-curve") }} 54 // RecoverFrom recovers the public key from the message msg, recovery 55 // information v and decompose signature {r,s}. If recovery succeeded, the 56 // methods sets the current public key to the recovered value. Otherwise returns 57 // error and leaves current public key unchanged. 58 func (pk *PublicKey) RecoverFrom(msg []byte, v uint, r, s *big.Int) error { 59 if s.Cmp(fr.Modulus()) >= 0 { 60 return errors.New("s is larger than modulus") 61 } 62 if s.Cmp(big.NewInt(0)) <= 0 { 63 return errors.New("s is negative") 64 } 65 P, err := recoverP(v, r) 66 if err != nil { 67 return err 68 } 69 z := HashToInt(msg) 70 rinv := new(big.Int).ModInverse(r, fr.Modulus()) 71 u1 := new(big.Int).Mul(z, rinv) 72 u1.Neg(u1) 73 u1.Mod(u1, fr.Modulus()) 74 u2 := new(big.Int).Mul(s, rinv) 75 u2.Mod(u2, fr.Modulus()) 76 var Q {{ .CurvePackage }}.G1Jac 77 Q.JointScalarMultiplicationBase(P, u1, u2) 78 pk.A.FromJacobian(&Q) 79 return nil 80 } 81 {{- end }} 82 83 // Bytes returns the binary representation of pk, 84 // as byte array publicKey||scalar 85 // where publicKey is as publicKey.Bytes(), and 86 // scalar is in big endian, of size sizeFr. 87 func (privKey *PrivateKey) Bytes() []byte { 88 var res [sizePrivateKey]byte 89 {{- if eq .Name "secp256k1"}} 90 pubkBin := privKey.PublicKey.A.RawBytes() 91 {{- else}} 92 pubkBin := privKey.PublicKey.A.Bytes() 93 {{- end}} 94 subtle.ConstantTimeCopy(1, res[:sizePublicKey], pubkBin[:]) 95 subtle.ConstantTimeCopy(1, res[sizePublicKey:sizePrivateKey], privKey.scalar[:]) 96 return res[:] 97 } 98 99 // SetBytes sets pk from buf, where buf is interpreted 100 // as publicKey||scalar 101 // where publicKey is as publicKey.Bytes(), and 102 // scalar is in big endian, of size sizeFr. 103 // It returns the number byte read. 104 func (privKey *PrivateKey) SetBytes(buf []byte) (int, error) { 105 n := 0 106 if len(buf) < sizePrivateKey { 107 return n, io.ErrShortBuffer 108 } 109 if _, err := privKey.PublicKey.A.SetBytes(buf[:sizePublicKey]); err != nil { 110 return 0, err 111 } 112 n += sizePublicKey 113 subtle.ConstantTimeCopy(1, privKey.scalar[:], buf[sizePublicKey:sizePrivateKey]) 114 n += sizeFr 115 return n, nil 116 } 117 118 // Bytes returns the binary representation of sig 119 // as a byte array of size 2*sizeFr r||s 120 func (sig *Signature) Bytes() []byte { 121 var res [sizeSignature]byte 122 subtle.ConstantTimeCopy(1, res[:sizeFr], sig.R[:]) 123 subtle.ConstantTimeCopy(1, res[sizeFr:], sig.S[:]) 124 return res[:] 125 } 126 127 // SetBytes sets sig from a buffer in binary. 128 // buf is read interpreted as r||s 129 // It returns the number of bytes read from buf. 130 func (sig *Signature) SetBytes(buf []byte) (int, error) { 131 n := 0 132 if len(buf) != sizeSignature { 133 return n, errWrongSize 134 } 135 136 // S, R < R_mod (to avoid malleability) 137 frMod := fr.Modulus() 138 zero := big.NewInt(0) 139 bufBigInt := new(big.Int) 140 bufBigInt.SetBytes(buf[:sizeFr]) 141 if bufBigInt.Cmp(zero) == 0 { 142 return 0, errZero 143 } 144 if bufBigInt.Cmp(frMod) != -1 { 145 return 0, errRBiggerThanRMod 146 } 147 bufBigInt.SetBytes(buf[sizeFr : 2*sizeFr]) 148 if bufBigInt.Cmp(zero) == 0 { 149 return 0, errZero 150 } 151 if bufBigInt.Cmp(frMod) != -1 { 152 return 0, errSBiggerThanRMod 153 } 154 155 subtle.ConstantTimeCopy(1, sig.R[:], buf[:sizeFr]) 156 n += sizeFr 157 subtle.ConstantTimeCopy(1, sig.S[:], buf[sizeFr:2*sizeFr]) 158 n += sizeFr 159 return n, nil 160 }