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