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  }