github.com/consensys/gnark-crypto@v0.14.0/ecc/bls12-378/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  	"hash"
    26  	"io"
    27  	"math/big"
    28  
    29  	"github.com/consensys/gnark-crypto/ecc/bls12-378"
    30  	"github.com/consensys/gnark-crypto/ecc/bls12-378/fp"
    31  	"github.com/consensys/gnark-crypto/ecc/bls12-378/fr"
    32  	"github.com/consensys/gnark-crypto/signature"
    33  )
    34  
    35  const (
    36  	sizeFr         = fr.Bytes
    37  	sizeFrBits     = fr.Bits
    38  	sizeFp         = fp.Bytes
    39  	sizePublicKey  = sizeFp
    40  	sizePrivateKey = sizeFr + sizePublicKey
    41  	sizeSignature  = 2 * sizeFr
    42  )
    43  
    44  var order = fr.Modulus()
    45  
    46  // PublicKey represents an ECDSA public key
    47  type PublicKey struct {
    48  	A bls12378.G1Affine
    49  }
    50  
    51  // PrivateKey represents an ECDSA private key
    52  type PrivateKey struct {
    53  	PublicKey PublicKey
    54  	scalar    [sizeFr]byte // secret scalar, in big Endian
    55  }
    56  
    57  // Signature represents an ECDSA signature
    58  type Signature struct {
    59  	R, S [sizeFr]byte
    60  }
    61  
    62  var one = new(big.Int).SetInt64(1)
    63  
    64  // randFieldElement returns a random element of the order of the given
    65  // curve using the procedure given in FIPS 186-4, Appendix B.5.1.
    66  func randFieldElement(rand io.Reader) (k *big.Int, err error) {
    67  	b := make([]byte, fr.Bits/8+8)
    68  	_, err = io.ReadFull(rand, b)
    69  	if err != nil {
    70  		return
    71  	}
    72  
    73  	k = new(big.Int).SetBytes(b)
    74  	n := new(big.Int).Sub(order, one)
    75  	k.Mod(k, n)
    76  	k.Add(k, one)
    77  	return
    78  }
    79  
    80  // GenerateKey generates a public and private key pair.
    81  func GenerateKey(rand io.Reader) (*PrivateKey, error) {
    82  
    83  	k, err := randFieldElement(rand)
    84  	if err != nil {
    85  		return nil, err
    86  
    87  	}
    88  	_, _, g, _ := bls12378.Generators()
    89  
    90  	privateKey := new(PrivateKey)
    91  	k.FillBytes(privateKey.scalar[:sizeFr])
    92  	privateKey.PublicKey.A.ScalarMultiplication(&g, k)
    93  	return privateKey, nil
    94  }
    95  
    96  // HashToInt converts a hash value to an integer. Per FIPS 186-4, Section 6.4,
    97  // we use the left-most bits of the hash to match the bit-length of the order of
    98  // the curve. This also performs Step 5 of SEC 1, Version 2.0, Section 4.1.3.
    99  func HashToInt(hash []byte) *big.Int {
   100  	if len(hash) > sizeFr {
   101  		hash = hash[:sizeFr]
   102  	}
   103  	ret := new(big.Int).SetBytes(hash)
   104  	excess := ret.BitLen() - sizeFrBits
   105  	if excess > 0 {
   106  		ret.Rsh(ret, uint(excess))
   107  	}
   108  	return ret
   109  }
   110  
   111  type zr struct{}
   112  
   113  // Read replaces the contents of dst with zeros. It is safe for concurrent use.
   114  func (zr) Read(dst []byte) (n int, err error) {
   115  	for i := range dst {
   116  		dst[i] = 0
   117  	}
   118  	return len(dst), nil
   119  }
   120  
   121  var zeroReader = zr{}
   122  
   123  const (
   124  	aesIV = "gnark-crypto IV." // must be 16 chars (equal block size)
   125  )
   126  
   127  func nonce(privateKey *PrivateKey, hash []byte) (csprng *cipher.StreamReader, err error) {
   128  	// This implementation derives the nonce from an AES-CTR CSPRNG keyed by:
   129  	//
   130  	//    SHA2-512(privateKey.scalar ∥ entropy ∥ hash)[:32]
   131  	//
   132  	// The CSPRNG key is indifferentiable from a random oracle as shown in
   133  	// [Coron], the AES-CTR stream is indifferentiable from a random oracle
   134  	// under standard cryptographic assumptions (see [Larsson] for examples).
   135  	//
   136  	// [Coron]: https://cs.nyu.edu/~dodis/ps/merkle.pdf
   137  	// [Larsson]: https://web.archive.org/web/20040719170906/https://www.nada.kth.se/kurser/kth/2D1441/semteo03/lecturenotes/assump.pdf
   138  
   139  	// Get 256 bits of entropy from rand.
   140  	entropy := make([]byte, 32)
   141  	_, err = io.ReadFull(rand.Reader, entropy)
   142  	if err != nil {
   143  		return
   144  
   145  	}
   146  
   147  	// Initialize an SHA-512 hash context; digest...
   148  	md := sha512.New()
   149  	md.Write(privateKey.scalar[:sizeFr]) // the private key,
   150  	md.Write(entropy)                    // the entropy,
   151  	md.Write(hash)                       // and the input hash;
   152  	key := md.Sum(nil)[:32]              // and compute ChopMD-256(SHA-512),
   153  	// which is an indifferentiable MAC.
   154  
   155  	// Create an AES-CTR instance to use as a CSPRNG.
   156  	block, _ := aes.NewCipher(key)
   157  
   158  	// Create a CSPRNG that xors a stream of zeros with
   159  	// the output of the AES-CTR instance.
   160  	csprng = &cipher.StreamReader{
   161  		R: zeroReader,
   162  		S: cipher.NewCTR(block, []byte(aesIV)),
   163  	}
   164  
   165  	return csprng, err
   166  }
   167  
   168  // Equal compares 2 public keys
   169  func (pub *PublicKey) Equal(x signature.PublicKey) bool {
   170  	xx, ok := x.(*PublicKey)
   171  	if !ok {
   172  		return false
   173  	}
   174  	bpk := pub.Bytes()
   175  	bxx := xx.Bytes()
   176  	return subtle.ConstantTimeCompare(bpk, bxx) == 1
   177  }
   178  
   179  // Public returns the public key associated to the private key.
   180  func (privKey *PrivateKey) Public() signature.PublicKey {
   181  	var pub PublicKey
   182  	pub.A.Set(&privKey.PublicKey.A)
   183  	return &pub
   184  }
   185  
   186  // Sign performs the ECDSA signature
   187  //
   188  // k ← 𝔽r (random)
   189  // P = k ⋅ g1Gen
   190  // r = x_P (mod order)
   191  // s = k⁻¹ . (m + sk ⋅ r)
   192  // signature = {r, s}
   193  //
   194  // SEC 1, Version 2.0, Section 4.1.3
   195  func (privKey *PrivateKey) Sign(message []byte, hFunc hash.Hash) ([]byte, error) {
   196  	scalar, r, s, kInv := new(big.Int), new(big.Int), new(big.Int), new(big.Int)
   197  	scalar.SetBytes(privKey.scalar[:sizeFr])
   198  	for {
   199  		for {
   200  			csprng, err := nonce(privKey, message)
   201  			if err != nil {
   202  				return nil, err
   203  			}
   204  			k, err := randFieldElement(csprng)
   205  			if err != nil {
   206  				return nil, err
   207  			}
   208  
   209  			var P bls12378.G1Affine
   210  			P.ScalarMultiplicationBase(k)
   211  			kInv.ModInverse(k, order)
   212  
   213  			P.X.BigInt(r)
   214  
   215  			r.Mod(r, order)
   216  			if r.Sign() != 0 {
   217  				break
   218  			}
   219  		}
   220  		s.Mul(r, scalar)
   221  
   222  		var m *big.Int
   223  		if hFunc != nil {
   224  			// compute the hash of the message as an integer
   225  			dataToHash := make([]byte, len(message))
   226  			copy(dataToHash[:], message[:])
   227  			hFunc.Reset()
   228  			_, err := hFunc.Write(dataToHash[:])
   229  			if err != nil {
   230  				return nil, err
   231  			}
   232  			hramBin := hFunc.Sum(nil)
   233  			m = HashToInt(hramBin)
   234  		} else {
   235  			m = HashToInt(message)
   236  		}
   237  
   238  		s.Add(m, s).
   239  			Mul(kInv, s).
   240  			Mod(s, order) // order != 0
   241  		if s.Sign() != 0 {
   242  			break
   243  		}
   244  	}
   245  
   246  	var sig Signature
   247  	r.FillBytes(sig.R[:sizeFr])
   248  	s.FillBytes(sig.S[:sizeFr])
   249  
   250  	return sig.Bytes(), nil
   251  }
   252  
   253  // Verify validates the ECDSA signature
   254  //
   255  // R ?= (s⁻¹ ⋅ m ⋅ Base + s⁻¹ ⋅ R ⋅ publiKey)_x
   256  //
   257  // SEC 1, Version 2.0, Section 4.1.4
   258  func (publicKey *PublicKey) Verify(sigBin, message []byte, hFunc hash.Hash) (bool, error) {
   259  
   260  	// Deserialize the signature
   261  	var sig Signature
   262  	if _, err := sig.SetBytes(sigBin); err != nil {
   263  		return false, err
   264  	}
   265  
   266  	r, s := new(big.Int), new(big.Int)
   267  	r.SetBytes(sig.R[:sizeFr])
   268  	s.SetBytes(sig.S[:sizeFr])
   269  
   270  	sInv := new(big.Int).ModInverse(s, order)
   271  
   272  	var m *big.Int
   273  	if hFunc != nil {
   274  		// compute the hash of the message as an integer
   275  		dataToHash := make([]byte, len(message))
   276  		copy(dataToHash[:], message[:])
   277  		hFunc.Reset()
   278  		_, err := hFunc.Write(dataToHash[:])
   279  		if err != nil {
   280  			return false, err
   281  		}
   282  		hramBin := hFunc.Sum(nil)
   283  		m = HashToInt(hramBin)
   284  	} else {
   285  		m = HashToInt(message)
   286  	}
   287  
   288  	u1 := new(big.Int).Mul(m, sInv)
   289  	u1.Mod(u1, order)
   290  	u2 := new(big.Int).Mul(r, sInv)
   291  	u2.Mod(u2, order)
   292  	var U bls12378.G1Jac
   293  	U.JointScalarMultiplicationBase(&publicKey.A, u1, u2)
   294  
   295  	var z big.Int
   296  	U.Z.Square(&U.Z).
   297  		Inverse(&U.Z).
   298  		Mul(&U.Z, &U.X).
   299  		BigInt(&z)
   300  
   301  	z.Mod(&z, order)
   302  
   303  	return z.Cmp(r) == 0, nil
   304  
   305  }