github.com/igggame/nebulas-go@v2.1.0+incompatible/crypto/keystore/secp256k1/vrf/secp256k1VRF/secp256k1VRF.go (about)

     1  // Copyright 2016 Google Inc. All Rights Reserved.
     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  // Implements a verifiable random function using curve secp256k1.
    16  
    17  package secp256k1VRF
    18  
    19  // Discrete Log based VRF from Appendix A of CONIKS:
    20  // http://www.jbonneau.com/doc/MBBFF15-coniks.pdf
    21  // based on "Unique Ring Signatures, a Practical Construction"
    22  // http://fc13.ifca.ai/proc/5-1.pdf
    23  
    24  import (
    25  	"bytes"
    26  	"crypto"
    27  	"crypto/ecdsa"
    28  	"crypto/hmac"
    29  	"crypto/rand"
    30  	"crypto/sha256"
    31  	"crypto/sha512"
    32  	"encoding/binary"
    33  	"errors"
    34  	"io"
    35  	"math/big"
    36  
    37  	"github.com/nebulasio/go-nebulas/crypto/keystore/secp256k1"
    38  	"github.com/nebulasio/go-nebulas/crypto/keystore/secp256k1/bitelliptic"
    39  
    40  	"github.com/nebulasio/go-nebulas/crypto/keystore/secp256k1/vrf"
    41  )
    42  
    43  var (
    44  	curve  = bitelliptic.S256()
    45  	params = curve.Params()
    46  
    47  	// ErrPointNotOnCurve occurs when a public key is not on the curve.
    48  	ErrPointNotOnCurve = errors.New("point is not on the P256 curve")
    49  	// ErrWrongKeyType occurs when a key is not an ECDSA key.
    50  	ErrWrongKeyType = errors.New("not an ECDSA key")
    51  	// ErrNoPEMFound occurs when attempting to parse a non PEM data structure.
    52  	ErrNoPEMFound = errors.New("no PEM block found")
    53  	// ErrInvalidVRF occurs when the VRF does not validate.
    54  	ErrInvalidVRF = errors.New("invalid VRF proof")
    55  	// ErrEvaluateFailed fail
    56  	ErrEvaluateFailed = errors.New("failed to evaluate VRF")
    57  )
    58  
    59  // PublicKey holds a public VRF key.
    60  type PublicKey struct {
    61  	*ecdsa.PublicKey
    62  }
    63  
    64  // PrivateKey holds a private VRF key.
    65  type PrivateKey struct {
    66  	*ecdsa.PrivateKey
    67  }
    68  
    69  // GenerateKey generates a fresh keypair for this VRF
    70  func GenerateKey() (vrf.PrivateKey, vrf.PublicKey) {
    71  	key, err := ecdsa.GenerateKey(curve, rand.Reader)
    72  	if err != nil {
    73  		return nil, nil
    74  	}
    75  
    76  	return &PrivateKey{key}, &PublicKey{&key.PublicKey}
    77  }
    78  
    79  // H1 hashes m to a curve point
    80  func H1(m []byte) (x, y *big.Int) {
    81  	h := sha512.New()
    82  	var i uint32
    83  	byteLen := (params.BitSize + 7) >> 3
    84  	for x == nil && i < 100 {
    85  		// TODO: Use a NIST specified DRBG.
    86  		h.Reset()
    87  		binary.Write(h, binary.BigEndian, i)
    88  		h.Write(m)
    89  		r := []byte{2} // Set point encoding to "compressed", y=0.
    90  		r = h.Sum(r)
    91  		x, y = Unmarshal(curve, r[:byteLen+1])
    92  		i++
    93  	}
    94  	return
    95  }
    96  
    97  var one = big.NewInt(1)
    98  
    99  // H2 hashes to an integer [1,N-1]
   100  func H2(m []byte) *big.Int {
   101  	// NIST SP 800-90A § A.5.1: Simple discard method.
   102  	byteLen := (params.BitSize + 7) >> 3
   103  	h := sha512.New()
   104  	for i := uint32(0); ; i++ {
   105  		// TODO: Use a NIST specified DRBG.
   106  		h.Reset()
   107  		binary.Write(h, binary.BigEndian, i)
   108  		h.Write(m)
   109  		b := h.Sum(nil)
   110  		k := new(big.Int).SetBytes(b[:byteLen])
   111  		if k.Cmp(new(big.Int).Sub(params.N, one)) == -1 {
   112  			return k.Add(k, one)
   113  		}
   114  	}
   115  }
   116  
   117  // Evaluate returns the verifiable unpredictable function evaluated at m
   118  func (k PrivateKey) Evaluate(m []byte) (index [32]byte, proof []byte) {
   119  	nilIndex := [32]byte{}
   120  	// Prover chooses r <-- [1,N-1]
   121  	r, _, _, err := generateKeyFromCurve(curve, rand.Reader)
   122  	if err != nil {
   123  		return nilIndex, nil
   124  	}
   125  	ri := new(big.Int).SetBytes(r)
   126  
   127  	// H = H1(m)
   128  	Hx, Hy := H1(m)
   129  
   130  	// VRF_k(m) = [k]H
   131  	sHx, sHy := curve.ScalarMult(Hx, Hy, k.D.Bytes())
   132  
   133  	// vrf := elliptic.Marshal(curve, sHx, sHy) // 65 bytes.
   134  	vrf := curve.Marshal(sHx, sHy) // 65 bytes.
   135  
   136  	// G is the base point
   137  	// s = H2(G, H, [k]G, VRF, [r]G, [r]H)
   138  	rGx, rGy := curve.ScalarBaseMult(r)
   139  	rHx, rHy := curve.ScalarMult(Hx, Hy, r)
   140  	var b bytes.Buffer
   141  	b.Write(curve.Marshal(params.Gx, params.Gy))
   142  	b.Write(curve.Marshal(Hx, Hy))
   143  	b.Write(curve.Marshal(k.PublicKey.X, k.PublicKey.Y))
   144  	b.Write(vrf)
   145  	b.Write(curve.Marshal(rGx, rGy))
   146  	b.Write(curve.Marshal(rHx, rHy))
   147  	s := H2(b.Bytes())
   148  
   149  	// t = r−s*k mod N
   150  	t := new(big.Int).Sub(ri, new(big.Int).Mul(s, k.D))
   151  	t.Mod(t, params.N)
   152  
   153  	// Index = H(vrf)
   154  	index = sha256.Sum256(vrf)
   155  
   156  	// Write s, t, and vrf to a proof blob. Also write leading zeros before s and t
   157  	// if needed.
   158  	var buf bytes.Buffer
   159  	buf.Write(make([]byte, 32-len(s.Bytes())))
   160  	buf.Write(s.Bytes())
   161  	buf.Write(make([]byte, 32-len(t.Bytes())))
   162  	buf.Write(t.Bytes())
   163  	buf.Write(vrf)
   164  
   165  	return index, buf.Bytes()
   166  }
   167  
   168  // ProofToHash asserts that proof is correct for m and outputs index.
   169  func (pk *PublicKey) ProofToHash(m, proof []byte) (index [32]byte, err error) {
   170  	nilIndex := [32]byte{}
   171  	// verifier checks that s == H2(m, [t]G + [s]([k]G), [t]H1(m) + [s]VRF_k(m))
   172  	if got, want := len(proof), 64+65; got != want {
   173  		return nilIndex, ErrInvalidVRF
   174  	}
   175  
   176  	// Parse proof into s, t, and vrf.
   177  	s := proof[0:32]
   178  	t := proof[32:64]
   179  	vrf := proof[64 : 64+65]
   180  
   181  	// uHx, uHy := elliptic.Unmarshal(curve, vrf)
   182  	uHx, uHy := curve.Unmarshal(vrf) //////???
   183  	if uHx == nil {
   184  		return nilIndex, ErrInvalidVRF
   185  	}
   186  
   187  	// [t]G + [s]([k]G) = [t+ks]G
   188  	tGx, tGy := curve.ScalarBaseMult(t)
   189  	ksGx, ksGy := curve.ScalarMult(pk.X, pk.Y, s)
   190  	tksGx, tksGy := curve.Add(tGx, tGy, ksGx, ksGy)
   191  
   192  	// H = H1(m)
   193  	// [t]H + [s]VRF = [t+ks]H
   194  	Hx, Hy := H1(m)
   195  	tHx, tHy := curve.ScalarMult(Hx, Hy, t)
   196  	sHx, sHy := curve.ScalarMult(uHx, uHy, s)
   197  	tksHx, tksHy := curve.Add(tHx, tHy, sHx, sHy)
   198  
   199  	//   H2(G, H, [k]G, VRF, [t]G + [s]([k]G), [t]H + [s]VRF)
   200  	// = H2(G, H, [k]G, VRF, [t+ks]G, [t+ks]H)
   201  	// = H2(G, H, [k]G, VRF, [r]G, [r]H)
   202  	var b bytes.Buffer
   203  	b.Write(curve.Marshal(params.Gx, params.Gy))
   204  	b.Write(curve.Marshal(Hx, Hy))
   205  	b.Write(curve.Marshal(pk.X, pk.Y))
   206  	b.Write(vrf)
   207  	b.Write(curve.Marshal(tksGx, tksGy))
   208  	b.Write(curve.Marshal(tksHx, tksHy))
   209  	h2 := H2(b.Bytes())
   210  
   211  	// Left pad h2 with zeros if needed. This will ensure that h2 is padded
   212  	// the same way s is.
   213  	var buf bytes.Buffer
   214  	buf.Write(make([]byte, 32-len(h2.Bytes())))
   215  	buf.Write(h2.Bytes())
   216  
   217  	if !hmac.Equal(s, buf.Bytes()) {
   218  		return nilIndex, ErrInvalidVRF
   219  	}
   220  	return sha256.Sum256(vrf), nil
   221  }
   222  
   223  // NewFromWrappedKey creates a VRF signer object from an encrypted private key.
   224  // The opaque private key must resolve to an `ecdsa.PrivateKey` in order to work.
   225  // func NewFromWrappedKey(ctx context.Context, wrapped proto.Message) (vrf.PrivateKey, error) {
   226  // 	// Unwrap.
   227  // 	signer, err := keys.NewSigner(ctx, wrapped)
   228  // 	if err != nil {
   229  // 		return nil, err
   230  // 	}
   231  
   232  // 	switch key := signer.(type) {
   233  // 	case *ecdsa.PrivateKey:
   234  // 		return NewVRFSigner(key)
   235  // 	default:
   236  // 		return nil, fmt.Errorf("NewSigner().type: %T, want ecdsa.PrivateKey", key)
   237  // 	}
   238  // }
   239  
   240  // NewVRFSigner creates a signer object from a private key.
   241  func NewVRFSigner(key *ecdsa.PrivateKey) (vrf.PrivateKey, error) {
   242  	if *(key.Params()) != *curve.Params() {
   243  		return nil, ErrPointNotOnCurve
   244  	}
   245  	if !curve.IsOnCurve(key.X, key.Y) {
   246  		return nil, ErrPointNotOnCurve
   247  	}
   248  	return &PrivateKey{key}, nil
   249  }
   250  
   251  // Public returns the corresponding public key as bytes.
   252  func (k PrivateKey) Public() crypto.PublicKey {
   253  	return &k.PublicKey
   254  }
   255  
   256  // NewVRFVerifier creates a verifier object from a public key.
   257  func NewVRFVerifier(pubkey *ecdsa.PublicKey) (vrf.PublicKey, error) {
   258  	if *(pubkey.Params()) != *curve.Params() {
   259  		return nil, ErrPointNotOnCurve
   260  	}
   261  	if !curve.IsOnCurve(pubkey.X, pubkey.Y) {
   262  		return nil, ErrPointNotOnCurve
   263  	}
   264  	return &PublicKey{pubkey}, nil
   265  }
   266  
   267  // NewVRFSignerFromPEM creates a vrf private key from a PEM data structure.
   268  // func NewVRFSignerFromPEM(b []byte) (vrf.PrivateKey, error) {
   269  // 	p, _ := pem.Decode(b)
   270  // 	if p == nil {
   271  // 		return nil, ErrNoPEMFound
   272  // 	}
   273  // 	return NewVRFSignerFromRawKey(p.Bytes)
   274  // }
   275  
   276  // NewVRFSignerFromRawKey returns the private key from a raw private key bytes.
   277  func NewVRFSignerFromRawKey(b []byte) (vrf.PrivateKey, error) {
   278  	k, err := secp256k1.ToECDSAPrivateKey(b)
   279  	if err != nil {
   280  		return nil, err
   281  	}
   282  	return NewVRFSigner(k)
   283  }
   284  
   285  // NewVRFVerifierFromPEM creates a vrf public key from a PEM data structure.
   286  // func NewVRFVerifierFromPEM(b []byte) (vrf.PublicKey, error) {
   287  // 	p, _ := pem.Decode(b)
   288  // 	if p == nil {
   289  // 		return nil, ErrNoPEMFound
   290  // 	}
   291  // 	return NewVRFVerifierFromRawKey(p.Bytes)
   292  // }
   293  
   294  // NewVRFVerifierFromRawKey returns the public key from a raw public key bytes.
   295  func NewVRFVerifierFromRawKey(b []byte) (vrf.PublicKey, error) {
   296  	k, err := secp256k1.ToECDSAPublicKey(b)
   297  	if err != nil {
   298  		return nil, err
   299  	}
   300  	return NewVRFVerifier(k)
   301  }
   302  
   303  var mask = []byte{0xff, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f}
   304  
   305  func generateKeyFromCurve(curve *bitelliptic.BitCurve, rand io.Reader) (priv []byte, x, y *big.Int, err error) {
   306  	N := curve.Params().N
   307  	bitSize := N.BitLen()
   308  	byteLen := (bitSize + 7) >> 3
   309  	priv = make([]byte, byteLen)
   310  
   311  	for x == nil {
   312  		_, err = io.ReadFull(rand, priv)
   313  		if err != nil {
   314  			return
   315  		}
   316  		// We have to mask off any excess bits in the case that the size of the
   317  		// underlying field is not a whole number of bytes.
   318  		priv[0] &= mask[bitSize%8]
   319  		// This is because, in tests, rand will return all zeros and we don't
   320  		// want to get the point at infinity and loop forever.
   321  		priv[1] ^= 0x42
   322  
   323  		// If the scalar is out of range, sample another random number.
   324  		if new(big.Int).SetBytes(priv).Cmp(N) >= 0 {
   325  			continue
   326  		}
   327  
   328  		x, y = curve.ScalarBaseMult(priv)
   329  	}
   330  	return
   331  }