github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/crypto/key.go (about)

     1  package crypto
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/ecdsa"
     6  	"crypto/elliptic"
     7  	"crypto/hmac"
     8  	"crypto/rand"
     9  	"crypto/sha256"
    10  	"crypto/sha512"
    11  	"encoding/binary"
    12  	"encoding/hex"
    13  	"errors"
    14  	"fmt"
    15  	"math/big"
    16  
    17  	"github.com/sixexorg/magnetic-ring/crypto/secp256k1/bitelliptic"
    18  )
    19  
    20  var (
    21  	curve  = bitelliptic.S256()
    22  	params = curve.Params()
    23  	one    = big.NewInt(1)
    24  
    25  	ErrInvalidVRF    = errors.New("invalid VRF proof")
    26  	ErrInvalidPubkey = errors.New("invalid secp256k1 public key")
    27  )
    28  
    29  // PrivateKey supports evaluating the VRF function.
    30  type PrivateKey interface {
    31  	// Evaluate returns the output of H(f_k(m)) and its proof.
    32  	Evaluate(m []byte) (index [32]byte, proof []byte)
    33  	// Public returns the corresponding public key.
    34  	Public() PublicKey
    35  	// Bytes byte array of private key.
    36  	Bytes() []byte
    37  	// Sign returns the result of the signature for hash.
    38  	Sign(hash []byte) ([]byte, error)
    39  
    40  	Hex() string
    41  }
    42  
    43  // PublicKey supports verifying output from the VRF function.
    44  type PublicKey interface {
    45  	// ProofToHash verifies the NP-proof supplied by Proof and outputs Index.
    46  	ProofToHash(m, proof []byte) (index [32]byte, err error)
    47  	// Verify verify hash with signature and public key.
    48  	Verify(hash, sig []byte) (bool, error)
    49  	// Bytes byte array of public key.
    50  	Bytes() []byte
    51  	Hex() string
    52  }
    53  
    54  // GenerateKey 生成带VRF功能的私钥
    55  func GenerateKey() (PrivateKey, error) {
    56  	priv, err := generateEcdsaKey()
    57  	if err != nil {
    58  		return nil, err
    59  	}
    60  
    61  	return &VrfablePrivateKey{priv}, nil
    62  }
    63  
    64  // ToPrivateKey 将字节数组转换成带VRF功能的私钥
    65  func ToPrivateKey(d []byte) (PrivateKey, error) {
    66  	priv := new(VrfablePrivateKey)
    67  	ecdsaPriv, err := toECDSA(d)
    68  	if err != nil {
    69  		return nil, err
    70  	}
    71  
    72  	priv.PrivateKey = ecdsaPriv
    73  	return priv, nil
    74  }
    75  func HexToPrivateKey(hexStr string) (PrivateKey, error) {
    76  	byteArr, err := hex.DecodeString(hexStr)
    77  	if err != nil {
    78  		return nil, err
    79  	}
    80  	return ToPrivateKey(byteArr)
    81  }
    82  
    83  // UnmarshalPubkey converts bytes to a secp256k1 public key.
    84  func UnmarshalPubkey(pub []byte) (PublicKey, error) {
    85  	x, y := elliptic.Unmarshal(S256(), pub)
    86  	if x == nil {
    87  		return nil, ErrInvalidPubkey
    88  	}
    89  
    90  	pubKey := new(VrfablePublicKey)
    91  	pubKey.PublicKey = &ecdsa.PublicKey{Curve: S256(), X: x, Y: y}
    92  	return pubKey, nil
    93  }
    94  
    95  // PrivateKey holds a private VRF key.
    96  type VrfablePrivateKey struct {
    97  	*ecdsa.PrivateKey
    98  }
    99  
   100  // Evaluate returns the verifiable unpredictable function evaluated at m
   101  func (k *VrfablePrivateKey) Evaluate(m []byte) (index [32]byte, proof []byte) {
   102  	nilIndex := [32]byte{}
   103  	// Prover chooses r <-- [1,N-1]
   104  	r, _, _, err := generateKeyFromCurve(curve, rand.Reader)
   105  	if err != nil {
   106  		return nilIndex, nil
   107  	}
   108  	ri := new(big.Int).SetBytes(r)
   109  
   110  	// H = H1(m)
   111  	Hx, Hy := H1(m)
   112  
   113  	// VRF_k(m) = [k]H
   114  	sHx, sHy := curve.ScalarMult(Hx, Hy, k.D.Bytes())
   115  
   116  	// vrf := elliptic.Marshal(curve, sHx, sHy) // 65 bytes.
   117  	vrf := curve.Marshal(sHx, sHy) // 65 bytes.
   118  
   119  	// G is the base point
   120  	// s = H2(G, H, [k]G, VRF, [r]G, [r]H)
   121  	rGx, rGy := curve.ScalarBaseMult(r)
   122  	rHx, rHy := curve.ScalarMult(Hx, Hy, r)
   123  	var b bytes.Buffer
   124  	b.Write(curve.Marshal(params.Gx, params.Gy))
   125  	b.Write(curve.Marshal(Hx, Hy))
   126  	b.Write(curve.Marshal(k.PublicKey.X, k.PublicKey.Y))
   127  	b.Write(vrf)
   128  	b.Write(curve.Marshal(rGx, rGy))
   129  	b.Write(curve.Marshal(rHx, rHy))
   130  	s := H2(b.Bytes())
   131  
   132  	// t = r−s*k mod N
   133  	t := new(big.Int).Sub(ri, new(big.Int).Mul(s, k.D))
   134  	t.Mod(t, params.N)
   135  
   136  	// Index = H(vrf)
   137  	index = sha256.Sum256(vrf)
   138  
   139  	// Write s, t, and vrf to a proof blob. Also write leading zeros before s and t
   140  	// if needed.
   141  	var buf bytes.Buffer
   142  	buf.Write(make([]byte, 32-len(s.Bytes())))
   143  	buf.Write(s.Bytes())
   144  	buf.Write(make([]byte, 32-len(t.Bytes())))
   145  	buf.Write(t.Bytes())
   146  	buf.Write(vrf)
   147  
   148  	return index, buf.Bytes()
   149  }
   150  
   151  // Public returns the corresponding public key as bytes.
   152  func (k *VrfablePrivateKey) Public() PublicKey {
   153  	return &VrfablePublicKey{&k.PublicKey}
   154  }
   155  
   156  func (k *VrfablePrivateKey) Bytes() []byte {
   157  	priv := k.PrivateKey
   158  	return paddedBigBytes(priv.D, priv.Params().BitSize/8)
   159  }
   160  
   161  func (k *VrfablePrivateKey) Sign(hash []byte) ([]byte, error) {
   162  	return Sign(k.PrivateKey, hash)
   163  }
   164  func (k *VrfablePrivateKey) Hex() string {
   165  	return hex.EncodeToString(k.Bytes())
   166  }
   167  
   168  func (k *VrfablePrivateKey) Clear(hash []byte) ([]byte, error) {
   169  	fmt.Printf("%s\n", k.D)
   170  	return Sign(k.PrivateKey, hash)
   171  }
   172  
   173  // PublicKey holds a public VRF key.
   174  type VrfablePublicKey struct {
   175  	*ecdsa.PublicKey
   176  }
   177  
   178  func (pk *VrfablePublicKey) Verify(hash, sig []byte) (bool, error) {
   179  	return Verify(pk.PublicKey, hash, sig)
   180  }
   181  
   182  func (pk *VrfablePublicKey) Bytes() []byte {
   183  	pub := pk.PublicKey
   184  	if pub == nil || pub.X == nil || pub.Y == nil {
   185  		return nil
   186  	}
   187  
   188  	return elliptic.Marshal(curve, pub.X, pub.Y)
   189  }
   190  func (pk *VrfablePublicKey) Hex() string {
   191  	return hex.EncodeToString(pk.Bytes())
   192  }
   193  
   194  // ProofToHash asserts that proof is correct for m and outputs index.
   195  func (pk *VrfablePublicKey) ProofToHash(m, proof []byte) (index [32]byte, err error) {
   196  	nilIndex := [32]byte{}
   197  	// verifier checks that s == H2(m, [t]G + [s]([k]G), [t]H1(m) + [s]VRF_k(m))
   198  	if got, want := len(proof), 64+65; got != want {
   199  		return nilIndex, ErrInvalidVRF
   200  	}
   201  
   202  	// Parse proof into s, t, and vrf.
   203  	s := proof[0:32]
   204  	t := proof[32:64]
   205  	vrf := proof[64 : 64+65]
   206  
   207  	// uHx, uHy := elliptic.Unmarshal(curve, vrf)
   208  	uHx, uHy := curve.Unmarshal(vrf) //////???
   209  	if uHx == nil {
   210  		return nilIndex, ErrInvalidVRF
   211  	}
   212  
   213  	// [t]G + [s]([k]G) = [t+ks]G
   214  	tGx, tGy := curve.ScalarBaseMult(t)
   215  	ksGx, ksGy := curve.ScalarMult(pk.X, pk.Y, s)
   216  	tksGx, tksGy := curve.Add(tGx, tGy, ksGx, ksGy)
   217  
   218  	// H = H1(m)
   219  	// [t]H + [s]VRF = [t+ks]H
   220  	Hx, Hy := H1(m)
   221  	tHx, tHy := curve.ScalarMult(Hx, Hy, t)
   222  	sHx, sHy := curve.ScalarMult(uHx, uHy, s)
   223  	tksHx, tksHy := curve.Add(tHx, tHy, sHx, sHy)
   224  
   225  	//   H2(G, H, [k]G, VRF, [t]G + [s]([k]G), [t]H + [s]VRF)
   226  	// = H2(G, H, [k]G, VRF, [t+ks]G, [t+ks]H)
   227  	// = H2(G, H, [k]G, VRF, [r]G, [r]H)
   228  	var b bytes.Buffer
   229  	b.Write(curve.Marshal(params.Gx, params.Gy))
   230  	b.Write(curve.Marshal(Hx, Hy))
   231  	b.Write(curve.Marshal(pk.X, pk.Y))
   232  	b.Write(vrf)
   233  	b.Write(curve.Marshal(tksGx, tksGy))
   234  	b.Write(curve.Marshal(tksHx, tksHy))
   235  	h2 := H2(b.Bytes())
   236  
   237  	// Left pad h2 with zeros if needed. This will ensure that h2 is padded
   238  	// the same way s is.
   239  	var buf bytes.Buffer
   240  	buf.Write(make([]byte, 32-len(h2.Bytes())))
   241  	buf.Write(h2.Bytes())
   242  
   243  	if !hmac.Equal(s, buf.Bytes()) {
   244  		return nilIndex, ErrInvalidVRF
   245  	}
   246  	return sha256.Sum256(vrf), nil
   247  }
   248  
   249  func H1(m []byte) (x, y *big.Int) {
   250  	h := sha512.New()
   251  	var i uint32
   252  	byteLen := (params.BitSize + 7) >> 3
   253  	for x == nil && i < 100 {
   254  		// TODO: Use a NIST specified DRBG.
   255  		h.Reset()
   256  		binary.Write(h, binary.BigEndian, i)
   257  		h.Write(m)
   258  		r := []byte{2} // Set point encoding to "compressed", y=0.
   259  		r = h.Sum(r)
   260  		x, y = Unmarshal(curve, r[:byteLen+1])
   261  		i++
   262  	}
   263  
   264  	return
   265  }
   266  
   267  // H2 hashes to an integer [1,N-1]
   268  func H2(m []byte) *big.Int {
   269  	// NIST SP 800-90A § A.5.1: Simple discard method.
   270  	byteLen := (params.BitSize + 7) >> 3
   271  	h := sha512.New()
   272  	for i := uint32(0); ; i++ {
   273  		// TODO: Use a NIST specified DRBG.
   274  		h.Reset()
   275  		binary.Write(h, binary.BigEndian, i)
   276  		h.Write(m)
   277  		b := h.Sum(nil)
   278  		k := new(big.Int).SetBytes(b[:byteLen])
   279  		if k.Cmp(new(big.Int).Sub(params.N, one)) == -1 {
   280  			return k.Add(k, one)
   281  		}
   282  	}
   283  }
   284  
   285  // Unmarshal a compressed point in the form specified in section 4.3.6 of ANSI X9.62.
   286  func Unmarshal(curve elliptic.Curve, data []byte) (x, y *big.Int) {
   287  	byteLen := (curve.Params().BitSize + 7) >> 3
   288  	if (data[0] &^ 1) != 2 {
   289  		return // unrecognized point encoding
   290  	}
   291  	if len(data) != 1+byteLen {
   292  		return
   293  	}
   294  
   295  	// Based on Routine 2.2.4 in NIST Mathematical routines paper
   296  	params := curve.Params()
   297  	tx := new(big.Int).SetBytes(data[1 : 1+byteLen])
   298  	y2 := y2(params, tx)
   299  	sqrt := defaultSqrt
   300  	ty := sqrt(y2, params.P)
   301  	if ty == nil {
   302  		return // "y^2" is not a square: invalid point
   303  	}
   304  	var y2c big.Int
   305  	y2c.Mul(ty, ty).Mod(&y2c, params.P)
   306  	if y2c.Cmp(y2) != 0 {
   307  		return // sqrt(y2)^2 != y2: invalid point
   308  	}
   309  	if ty.Bit(0) != uint(data[0]&1) {
   310  		ty.Sub(params.P, ty)
   311  	}
   312  
   313  	x, y = tx, ty // valid point: return it
   314  	return
   315  }
   316  
   317  // Use the curve equation to calculate y² given x.
   318  // only applies to curves of the form y² = x³ - 3x + b.
   319  func y2(curve *elliptic.CurveParams, x *big.Int) *big.Int {
   320  
   321  	// y² = x³ - 3x + b
   322  	//x3 := new(big.Int).Mul(x, x)
   323  	//x3.Mul(x3, x)
   324  	//
   325  	//threeX := new(big.Int).Lsh(x, 1)
   326  	//threeX.Add(threeX, x)
   327  	//
   328  	//x3.Sub(x3, threeX)
   329  	//x3.Add(x3, curve.B)
   330  	//x3.Mod(x3, curve.P)
   331  
   332  	// change to bitelliptic : y² = x³ + b
   333  	x3 := new(big.Int).Mul(x, x)
   334  	x3.Mul(x3, x)
   335  
   336  	x3.Add(x3, curve.B)
   337  	x3.Mod(x3, curve.P)
   338  	return x3
   339  }
   340  
   341  func defaultSqrt(x, p *big.Int) *big.Int {
   342  	var r big.Int
   343  	if nil == r.ModSqrt(x, p) {
   344  		return nil // x is not a square
   345  	}
   346  	return &r
   347  }