github.com/zhiqiangxu/util@v0.0.0-20230112053021-0a7aee056cd5/crypto/vrf/p256/p256.go (about)

     1  // Package p256 implements a verifiable random function using curve p256.
     2  package p256
     3  
     4  import (
     5  	"bytes"
     6  	"crypto/ecdsa"
     7  	"crypto/elliptic"
     8  	"crypto/hmac"
     9  	"crypto/rand"
    10  	"crypto/sha256"
    11  	"crypto/sha512"
    12  	"crypto/x509"
    13  	"encoding/binary"
    14  	"encoding/pem"
    15  	"errors"
    16  	"math/big"
    17  
    18  	"github.com/zhiqiangxu/util/crypto/vrf"
    19  )
    20  
    21  // PublicKey for vrf
    22  type PublicKey struct {
    23  	*ecdsa.PublicKey
    24  }
    25  
    26  // PrivateKey for vrf
    27  type PrivateKey struct {
    28  	*ecdsa.PrivateKey
    29  }
    30  
    31  var (
    32  	curve  = elliptic.P256()
    33  	params = curve.Params()
    34  )
    35  
    36  // H1 hashes m to a curve point
    37  func H1(m []byte) (x, y *big.Int, err error) {
    38  	h := sha512.New()
    39  	var i uint32
    40  	byteLen := (params.BitSize + 7) >> 3
    41  	for x == nil && i < 100 {
    42  		// TODO: Use a NIST specified DRBG.
    43  		h.Reset()
    44  		binary.Write(h, binary.BigEndian, i)
    45  		h.Write(m)
    46  		r := []byte{2} // Set point encoding to "compressed", y=0.
    47  		r = h.Sum(r)
    48  		x, y, err = Unmarshal(curve, r[:byteLen+1])
    49  		i++
    50  	}
    51  	return
    52  }
    53  
    54  var one = big.NewInt(1)
    55  
    56  // H2 hashes m to an integer [1,N-1]
    57  func H2(m []byte) *big.Int {
    58  	// NIST SP 800-90A § A.5.1: Simple discard method.
    59  	byteLen := (params.BitSize + 7) >> 3
    60  	h := sha512.New()
    61  	for i := uint32(0); ; i++ {
    62  		// TODO: Use a NIST specified DRBG.
    63  		h.Reset()
    64  		binary.Write(h, binary.BigEndian, i)
    65  		h.Write(m)
    66  		b := h.Sum(nil)
    67  		k := new(big.Int).SetBytes(b[:byteLen])
    68  		if k.Cmp(new(big.Int).Sub(params.N, one)) == -1 {
    69  			return k.Add(k, one)
    70  		}
    71  	}
    72  }
    73  
    74  // Hash converts alpha to beta+proof
    75  func (k PrivateKey) Hash(alpha []byte) (beta [32]byte, proof []byte, err error) {
    76  	r, _, _, err := elliptic.GenerateKey(curve, rand.Reader)
    77  	if err != nil {
    78  		return
    79  	}
    80  
    81  	ri := new(big.Int).SetBytes(r)
    82  
    83  	// H = H1(m)
    84  	Hx, Hy, err := H1(alpha)
    85  	if err != nil {
    86  		return
    87  	}
    88  
    89  	// VRF_k(m) = [k]H
    90  	sHx, sHy := curve.ScalarMult(Hx, Hy, k.D.Bytes())
    91  	vrf := elliptic.Marshal(curve, sHx, sHy) // 65 bytes.
    92  
    93  	// G is the base point
    94  	// s = H2(G, H, [k]G, VRF, [r]G, [r]H)
    95  	rGx, rGy := curve.ScalarBaseMult(r)
    96  	rHx, rHy := curve.ScalarMult(Hx, Hy, r)
    97  	var b bytes.Buffer
    98  	b.Write(elliptic.Marshal(curve, params.Gx, params.Gy))
    99  	b.Write(elliptic.Marshal(curve, Hx, Hy))
   100  	b.Write(elliptic.Marshal(curve, k.PublicKey.X, k.PublicKey.Y))
   101  	b.Write(vrf)
   102  	b.Write(elliptic.Marshal(curve, rGx, rGy))
   103  	b.Write(elliptic.Marshal(curve, rHx, rHy))
   104  	s := H2(b.Bytes())
   105  
   106  	// t = r−s*k mod N
   107  	t := new(big.Int).Sub(ri, new(big.Int).Mul(s, k.D))
   108  	t.Mod(t, params.N)
   109  
   110  	// beta = H(vrf)
   111  	beta = sha256.Sum256(vrf)
   112  
   113  	// Write s, t, and vrf to a proof blob. Also write leading zeros before s and t
   114  	// if needed.
   115  	var buf bytes.Buffer
   116  	buf.Write(make([]byte, 32-len(s.Bytes())))
   117  	buf.Write(s.Bytes())
   118  	buf.Write(make([]byte, 32-len(t.Bytes())))
   119  	buf.Write(t.Bytes())
   120  	buf.Write(vrf)
   121  	proof = buf.Bytes()
   122  
   123  	return
   124  }
   125  
   126  // Public returns the corresponding public key as Verifier.
   127  func (k PrivateKey) Public() vrf.Verifier {
   128  	return PublicKey{PublicKey: &k.PublicKey}
   129  }
   130  
   131  // Verify that beta+proof is generated from m by PrivateKey
   132  func (pk PublicKey) Verify(m, proof []byte, beta [32]byte) (valid bool, err error) {
   133  	// verifier checks that s == H2(m, [t]G + [s]([k]G), [t]H1(m) + [s]VRF_k(m))
   134  	if got, want := len(proof), 64+65; got != want {
   135  		return
   136  	}
   137  
   138  	// Parse proof into s, t, and vrf.
   139  	s := proof[0:32]
   140  	t := proof[32:64]
   141  	vrf := proof[64 : 64+65]
   142  
   143  	uHx, uHy := elliptic.Unmarshal(curve, vrf)
   144  	if uHx == nil {
   145  		return
   146  	}
   147  
   148  	// [t]G + [s]([k]G) = [t+ks]G
   149  	tGx, tGy := curve.ScalarBaseMult(t)
   150  	ksGx, ksGy := curve.ScalarMult(pk.X, pk.Y, s)
   151  	tksGx, tksGy := curve.Add(tGx, tGy, ksGx, ksGy)
   152  
   153  	// H = H1(m)
   154  	// [t]H + [s]VRF = [t+ks]H
   155  	Hx, Hy, err := H1(m)
   156  	if err != nil {
   157  		return
   158  	}
   159  	tHx, tHy := curve.ScalarMult(Hx, Hy, t)
   160  	sHx, sHy := curve.ScalarMult(uHx, uHy, s)
   161  	tksHx, tksHy := curve.Add(tHx, tHy, sHx, sHy)
   162  
   163  	//   H2(G, H, [k]G, VRF, [t]G + [s]([k]G), [t]H + [s]VRF)
   164  	// = H2(G, H, [k]G, VRF, [t+ks]G, [t+ks]H)
   165  	// = H2(G, H, [k]G, VRF, [r]G, [r]H)
   166  	var b bytes.Buffer
   167  	b.Write(elliptic.Marshal(curve, params.Gx, params.Gy))
   168  	b.Write(elliptic.Marshal(curve, Hx, Hy))
   169  	b.Write(elliptic.Marshal(curve, pk.X, pk.Y))
   170  	b.Write(vrf)
   171  	b.Write(elliptic.Marshal(curve, tksGx, tksGy))
   172  	b.Write(elliptic.Marshal(curve, tksHx, tksHy))
   173  	h2 := H2(b.Bytes())
   174  
   175  	// Left pad h2 with zeros if needed. This will ensure that h2 is padded
   176  	// the same way s is.
   177  	var buf bytes.Buffer
   178  	buf.Write(make([]byte, 32-len(h2.Bytes())))
   179  	buf.Write(h2.Bytes())
   180  
   181  	if !hmac.Equal(s, buf.Bytes()) {
   182  		return
   183  	}
   184  
   185  	valid = true
   186  	return
   187  }
   188  
   189  // GeneratePair generates a fresh signer/verifier pair for this VRF
   190  func GeneratePair() (k vrf.Signer, pk vrf.Verifier, err error) {
   191  	key, err := ecdsa.GenerateKey(curve, rand.Reader)
   192  	if err != nil {
   193  		return
   194  	}
   195  
   196  	k, pk = PrivateKey{PrivateKey: key}, PublicKey{PublicKey: &key.PublicKey}
   197  	return
   198  }
   199  
   200  var (
   201  	errPointNotOnCurve = errors.New("point not on curve")
   202  	errNoPEMFound      = errors.New("no pem found")
   203  	errWrongKeyType    = errors.New("wrong key type")
   204  )
   205  
   206  // NewVRFSigner creates a signer object from a private key.
   207  func NewVRFSigner(key *ecdsa.PrivateKey) (k vrf.Signer, err error) {
   208  	if *(key.Params()) != *curve.Params() {
   209  		err = errPointNotOnCurve
   210  		return
   211  	}
   212  	if !curve.IsOnCurve(key.X, key.Y) {
   213  		err = errPointNotOnCurve
   214  		return
   215  	}
   216  	k = PrivateKey{PrivateKey: key}
   217  	return
   218  }
   219  
   220  // NewVRFVerifier creates a verifier object from a public key.
   221  func NewVRFVerifier(pubkey *ecdsa.PublicKey) (pk vrf.Verifier, err error) {
   222  	if *(pubkey.Params()) != *curve.Params() {
   223  		err = errPointNotOnCurve
   224  		return
   225  	}
   226  	if !curve.IsOnCurve(pubkey.X, pubkey.Y) {
   227  		err = errPointNotOnCurve
   228  		return
   229  	}
   230  	pk = PublicKey{PublicKey: pubkey}
   231  	return
   232  }
   233  
   234  // NewVRFSignerFromRawKey returns the private key from a raw private key bytes.
   235  func NewVRFSignerFromRawKey(b []byte) (k vrf.Signer, err error) {
   236  	key, err := x509.ParseECPrivateKey(b)
   237  	if err != nil {
   238  		return
   239  	}
   240  	k, err = NewVRFSigner(key)
   241  	return
   242  }
   243  
   244  // NewVRFSignerFromPEM creates a vrf private key from a PEM data structure.
   245  func NewVRFSignerFromPEM(b []byte) (k vrf.Signer, err error) {
   246  	p, _ := pem.Decode(b)
   247  	if p == nil {
   248  		err = errNoPEMFound
   249  		return
   250  	}
   251  	k, err = NewVRFSignerFromRawKey(p.Bytes)
   252  	return
   253  }
   254  
   255  // NewVRFVerifierFromRawKey returns the public key from a raw public key bytes.
   256  func NewVRFVerifierFromRawKey(b []byte) (pk vrf.Verifier, err error) {
   257  	key, err := x509.ParsePKIXPublicKey(b)
   258  	if err != nil {
   259  		return
   260  	}
   261  	pubkey, ok := key.(*ecdsa.PublicKey)
   262  	if !ok {
   263  		err = errWrongKeyType
   264  		return
   265  	}
   266  	pk, err = NewVRFVerifier(pubkey)
   267  	return
   268  }