github.com/zntrio/harp/v2@v2.0.9/pkg/sdk/security/crypto/deterministicecdsa/ecdsa.go (about)

     1  package deterministicecdsa
     2  
     3  // Copied from https://github.com/golang/go/blob/1e9ff255a130200fcc4ec5e911d28181fce947d5/src/crypto/ecdsa/ecdsa.go
     4  
     5  import (
     6  	"crypto/ecdsa"
     7  	"crypto/elliptic"
     8  	"io"
     9  	"math/big"
    10  )
    11  
    12  var one = new(big.Int).SetInt64(1)
    13  
    14  // randFieldElement returns a random element of the order of the given
    15  // curve using the procedure given in FIPS 186-4, Appendix B.5.1.
    16  func randFieldElement(c elliptic.Curve, rand io.Reader) (k *big.Int, err error) {
    17  	params := c.Params()
    18  	// Note that for P-521 this will actually be 63 bits more than the order, as
    19  	// division rounds down, but the extra bit is inconsequential.
    20  	b := make([]byte, params.N.BitLen()/8+8)
    21  	_, err = io.ReadFull(rand, b)
    22  	if err != nil {
    23  		return
    24  	}
    25  
    26  	k = new(big.Int).SetBytes(b)
    27  	n := new(big.Int).Sub(params.N, one)
    28  	k.Mod(k, n)
    29  	k.Add(k, one)
    30  	return
    31  }
    32  
    33  // GenerateKey generates a public and private key pair.
    34  func GenerateKey(c elliptic.Curve, rand io.Reader) (*ecdsa.PrivateKey, error) {
    35  	k, err := randFieldElement(c, rand)
    36  	if err != nil {
    37  		return nil, err
    38  	}
    39  
    40  	priv := new(ecdsa.PrivateKey)
    41  	priv.PublicKey.Curve = c
    42  	priv.D = k
    43  	priv.PublicKey.X, priv.PublicKey.Y = c.ScalarBaseMult(k.Bytes())
    44  	return priv, nil
    45  }