github.com/consensys/gnark-crypto@v0.14.0/ecc/bn254/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/bn254/fr"
    23  	"io"
    24  	"math/big"
    25  
    26  	"github.com/consensys/gnark-crypto/ecc/bn254"
    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.Bytes()
    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 bn254.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.Bytes()
   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  }