github.com/consensys/gnark-crypto@v0.14.0/ecc/bn254/ecdsa/ecdsa.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/aes"
    21  	"crypto/cipher"
    22  	"crypto/rand"
    23  	"crypto/sha512"
    24  	"crypto/subtle"
    25  	"errors"
    26  	"hash"
    27  	"io"
    28  	"math/big"
    29  
    30  	"github.com/consensys/gnark-crypto/ecc/bn254"
    31  	"github.com/consensys/gnark-crypto/ecc/bn254/fp"
    32  	"github.com/consensys/gnark-crypto/ecc/bn254/fr"
    33  	"github.com/consensys/gnark-crypto/signature"
    34  )
    35  
    36  const (
    37  	sizeFr         = fr.Bytes
    38  	sizeFrBits     = fr.Bits
    39  	sizeFp         = fp.Bytes
    40  	sizePublicKey  = sizeFp
    41  	sizePrivateKey = sizeFr + sizePublicKey
    42  	sizeSignature  = 2 * sizeFr
    43  )
    44  
    45  var (
    46  	// ErrNoSqrtR is returned when x^3+ax+b is not a square in the field. This
    47  	// is used for public key recovery and allows to detect if the signature is
    48  	// valid or not.
    49  	ErrNoSqrtR = errors.New("x^3+ax+b is not a square in the field")
    50  )
    51  
    52  var order = fr.Modulus()
    53  
    54  // PublicKey represents an ECDSA public key
    55  type PublicKey struct {
    56  	A bn254.G1Affine
    57  }
    58  
    59  // PrivateKey represents an ECDSA private key
    60  type PrivateKey struct {
    61  	PublicKey PublicKey
    62  	scalar    [sizeFr]byte // secret scalar, in big Endian
    63  }
    64  
    65  // Signature represents an ECDSA signature
    66  type Signature struct {
    67  	R, S [sizeFr]byte
    68  }
    69  
    70  var one = new(big.Int).SetInt64(1)
    71  
    72  // randFieldElement returns a random element of the order of the given
    73  // curve using the procedure given in FIPS 186-4, Appendix B.5.1.
    74  func randFieldElement(rand io.Reader) (k *big.Int, err error) {
    75  	b := make([]byte, fr.Bits/8+8)
    76  	_, err = io.ReadFull(rand, b)
    77  	if err != nil {
    78  		return
    79  	}
    80  
    81  	k = new(big.Int).SetBytes(b)
    82  	n := new(big.Int).Sub(order, one)
    83  	k.Mod(k, n)
    84  	k.Add(k, one)
    85  	return
    86  }
    87  
    88  // GenerateKey generates a public and private key pair.
    89  func GenerateKey(rand io.Reader) (*PrivateKey, error) {
    90  
    91  	k, err := randFieldElement(rand)
    92  	if err != nil {
    93  		return nil, err
    94  
    95  	}
    96  	_, _, g, _ := bn254.Generators()
    97  
    98  	privateKey := new(PrivateKey)
    99  	k.FillBytes(privateKey.scalar[:sizeFr])
   100  	privateKey.PublicKey.A.ScalarMultiplication(&g, k)
   101  	return privateKey, nil
   102  }
   103  
   104  // HashToInt converts a hash value to an integer. Per FIPS 186-4, Section 6.4,
   105  // we use the left-most bits of the hash to match the bit-length of the order of
   106  // the curve. This also performs Step 5 of SEC 1, Version 2.0, Section 4.1.3.
   107  func HashToInt(hash []byte) *big.Int {
   108  	if len(hash) > sizeFr {
   109  		hash = hash[:sizeFr]
   110  	}
   111  	ret := new(big.Int).SetBytes(hash)
   112  	excess := ret.BitLen() - sizeFrBits
   113  	if excess > 0 {
   114  		ret.Rsh(ret, uint(excess))
   115  	}
   116  	return ret
   117  }
   118  
   119  // recoverP recovers the value P (prover commitment) when creating a signature.
   120  // It uses the recovery information v and part of the decomposed signature r. It
   121  // is used internally for recovering the public key.
   122  func recoverP(v uint, r *big.Int) (*bn254.G1Affine, error) {
   123  	if r.Cmp(fr.Modulus()) >= 0 {
   124  		return nil, errors.New("r is larger than modulus")
   125  	}
   126  	if r.Cmp(big.NewInt(0)) <= 0 {
   127  		return nil, errors.New("r is negative")
   128  	}
   129  	x := new(big.Int).Set(r)
   130  	// if x is r or r+N
   131  	xChoice := (v & 2) >> 1
   132  	// if y is y or -y
   133  	yChoice := v & 1
   134  	// decompose limbs into big.Int value
   135  	// conditional +n based on xChoice
   136  	kn := big.NewInt(int64(xChoice))
   137  	kn.Mul(kn, fr.Modulus())
   138  	x.Add(x, kn)
   139  	// y^2 = x^3+ax+b
   140  	a, b := bn254.CurveCoefficients()
   141  	y := new(big.Int).Exp(x, big.NewInt(3), fp.Modulus())
   142  	if !a.IsZero() {
   143  		y.Add(y, new(big.Int).Mul(a.BigInt(new(big.Int)), x))
   144  	}
   145  	y.Add(y, b.BigInt(new(big.Int)))
   146  	y.Mod(y, fp.Modulus())
   147  	// y = sqrt(y^2)
   148  	if y.ModSqrt(y, fp.Modulus()) == nil {
   149  		// there is no square root, return error constant
   150  		return nil, ErrNoSqrtR
   151  	}
   152  	// check that y has same oddity as defined by v
   153  	if y.Bit(0) != yChoice {
   154  		y = y.Sub(fp.Modulus(), y)
   155  	}
   156  	return &bn254.G1Affine{
   157  		X: *new(fp.Element).SetBigInt(x),
   158  		Y: *new(fp.Element).SetBigInt(y),
   159  	}, nil
   160  }
   161  
   162  type zr struct{}
   163  
   164  // Read replaces the contents of dst with zeros. It is safe for concurrent use.
   165  func (zr) Read(dst []byte) (n int, err error) {
   166  	for i := range dst {
   167  		dst[i] = 0
   168  	}
   169  	return len(dst), nil
   170  }
   171  
   172  var zeroReader = zr{}
   173  
   174  const (
   175  	aesIV = "gnark-crypto IV." // must be 16 chars (equal block size)
   176  )
   177  
   178  func nonce(privateKey *PrivateKey, hash []byte) (csprng *cipher.StreamReader, err error) {
   179  	// This implementation derives the nonce from an AES-CTR CSPRNG keyed by:
   180  	//
   181  	//    SHA2-512(privateKey.scalar ∥ entropy ∥ hash)[:32]
   182  	//
   183  	// The CSPRNG key is indifferentiable from a random oracle as shown in
   184  	// [Coron], the AES-CTR stream is indifferentiable from a random oracle
   185  	// under standard cryptographic assumptions (see [Larsson] for examples).
   186  	//
   187  	// [Coron]: https://cs.nyu.edu/~dodis/ps/merkle.pdf
   188  	// [Larsson]: https://web.archive.org/web/20040719170906/https://www.nada.kth.se/kurser/kth/2D1441/semteo03/lecturenotes/assump.pdf
   189  
   190  	// Get 256 bits of entropy from rand.
   191  	entropy := make([]byte, 32)
   192  	_, err = io.ReadFull(rand.Reader, entropy)
   193  	if err != nil {
   194  		return
   195  
   196  	}
   197  
   198  	// Initialize an SHA-512 hash context; digest...
   199  	md := sha512.New()
   200  	md.Write(privateKey.scalar[:sizeFr]) // the private key,
   201  	md.Write(entropy)                    // the entropy,
   202  	md.Write(hash)                       // and the input hash;
   203  	key := md.Sum(nil)[:32]              // and compute ChopMD-256(SHA-512),
   204  	// which is an indifferentiable MAC.
   205  
   206  	// Create an AES-CTR instance to use as a CSPRNG.
   207  	block, _ := aes.NewCipher(key)
   208  
   209  	// Create a CSPRNG that xors a stream of zeros with
   210  	// the output of the AES-CTR instance.
   211  	csprng = &cipher.StreamReader{
   212  		R: zeroReader,
   213  		S: cipher.NewCTR(block, []byte(aesIV)),
   214  	}
   215  
   216  	return csprng, err
   217  }
   218  
   219  // Equal compares 2 public keys
   220  func (pub *PublicKey) Equal(x signature.PublicKey) bool {
   221  	xx, ok := x.(*PublicKey)
   222  	if !ok {
   223  		return false
   224  	}
   225  	bpk := pub.Bytes()
   226  	bxx := xx.Bytes()
   227  	return subtle.ConstantTimeCompare(bpk, bxx) == 1
   228  }
   229  
   230  // Public returns the public key associated to the private key.
   231  func (privKey *PrivateKey) Public() signature.PublicKey {
   232  	var pub PublicKey
   233  	pub.A.Set(&privKey.PublicKey.A)
   234  	return &pub
   235  }
   236  
   237  // SignForRecover performs the ECDSA signature and returns public key recovery information
   238  //
   239  // k ← 𝔽r (random)
   240  // P = k ⋅ g1Gen
   241  // r = x_P (mod order)
   242  // s = k⁻¹ . (m + sk ⋅ r)
   243  // v = (div(x_P, order)<<1) || y_P[-1]
   244  //
   245  // SEC 1, Version 2.0, Section 4.1.3
   246  func (privKey *PrivateKey) SignForRecover(message []byte, hFunc hash.Hash) (v uint, r, s *big.Int, err error) {
   247  	r, s = new(big.Int), new(big.Int)
   248  
   249  	scalar, kInv := new(big.Int), new(big.Int)
   250  	scalar.SetBytes(privKey.scalar[:sizeFr])
   251  	for {
   252  		for {
   253  			csprng, err := nonce(privKey, message)
   254  			if err != nil {
   255  				return 0, nil, nil, err
   256  			}
   257  			k, err := randFieldElement(csprng)
   258  			if err != nil {
   259  				return 0, nil, nil, err
   260  			}
   261  
   262  			var P bn254.G1Affine
   263  			P.ScalarMultiplicationBase(k)
   264  			kInv.ModInverse(k, order)
   265  
   266  			P.X.BigInt(r)
   267  			// set how many times we overflow the scalar field
   268  			v |= (uint(new(big.Int).Div(r, order).Uint64())) << 1
   269  			// set if y is even or odd
   270  			v |= P.Y.BigInt(new(big.Int)).Bit(0)
   271  
   272  			r.Mod(r, order)
   273  			if r.Sign() != 0 {
   274  				break
   275  			}
   276  		}
   277  		s.Mul(r, scalar)
   278  
   279  		var m *big.Int
   280  		if hFunc != nil {
   281  			// compute the hash of the message as an integer
   282  			dataToHash := make([]byte, len(message))
   283  			copy(dataToHash[:], message[:])
   284  			hFunc.Reset()
   285  			_, err := hFunc.Write(dataToHash[:])
   286  			if err != nil {
   287  				return 0, nil, nil, err
   288  			}
   289  			hramBin := hFunc.Sum(nil)
   290  			m = HashToInt(hramBin)
   291  		} else {
   292  			m = HashToInt(message)
   293  		}
   294  
   295  		s.Add(m, s).
   296  			Mul(kInv, s).
   297  			Mod(s, order) // order != 0
   298  		if s.Sign() != 0 {
   299  			break
   300  		}
   301  	}
   302  
   303  	return v, r, s, nil
   304  }
   305  
   306  // Sign performs the ECDSA signature
   307  //
   308  // k ← 𝔽r (random)
   309  // P = k ⋅ g1Gen
   310  // r = x_P (mod order)
   311  // s = k⁻¹ . (m + sk ⋅ r)
   312  // signature = {r, s}
   313  //
   314  // SEC 1, Version 2.0, Section 4.1.3
   315  func (privKey *PrivateKey) Sign(message []byte, hFunc hash.Hash) ([]byte, error) {
   316  	_, r, s, err := privKey.SignForRecover(message, hFunc)
   317  	if err != nil {
   318  		return nil, err
   319  	}
   320  	var sig Signature
   321  	r.FillBytes(sig.R[:sizeFr])
   322  	s.FillBytes(sig.S[:sizeFr])
   323  
   324  	return sig.Bytes(), nil
   325  }
   326  
   327  // Verify validates the ECDSA signature
   328  //
   329  // R ?= (s⁻¹ ⋅ m ⋅ Base + s⁻¹ ⋅ R ⋅ publiKey)_x
   330  //
   331  // SEC 1, Version 2.0, Section 4.1.4
   332  func (publicKey *PublicKey) Verify(sigBin, message []byte, hFunc hash.Hash) (bool, error) {
   333  
   334  	// Deserialize the signature
   335  	var sig Signature
   336  	if _, err := sig.SetBytes(sigBin); err != nil {
   337  		return false, err
   338  	}
   339  
   340  	r, s := new(big.Int), new(big.Int)
   341  	r.SetBytes(sig.R[:sizeFr])
   342  	s.SetBytes(sig.S[:sizeFr])
   343  
   344  	sInv := new(big.Int).ModInverse(s, order)
   345  
   346  	var m *big.Int
   347  	if hFunc != nil {
   348  		// compute the hash of the message as an integer
   349  		dataToHash := make([]byte, len(message))
   350  		copy(dataToHash[:], message[:])
   351  		hFunc.Reset()
   352  		_, err := hFunc.Write(dataToHash[:])
   353  		if err != nil {
   354  			return false, err
   355  		}
   356  		hramBin := hFunc.Sum(nil)
   357  		m = HashToInt(hramBin)
   358  	} else {
   359  		m = HashToInt(message)
   360  	}
   361  
   362  	u1 := new(big.Int).Mul(m, sInv)
   363  	u1.Mod(u1, order)
   364  	u2 := new(big.Int).Mul(r, sInv)
   365  	u2.Mod(u2, order)
   366  	var U bn254.G1Jac
   367  	U.JointScalarMultiplicationBase(&publicKey.A, u1, u2)
   368  
   369  	var z big.Int
   370  	U.Z.Square(&U.Z).
   371  		Inverse(&U.Z).
   372  		Mul(&U.Z, &U.X).
   373  		BigInt(&z)
   374  
   375  	z.Mod(&z, order)
   376  
   377  	return z.Cmp(r) == 0, nil
   378  
   379  }