github.com/chain5j/chain5j-pkg@v1.0.7/crypto/signature/rft6979.go (about)

     1  // Package signature
     2  //
     3  // @author: xwc1125
     4  package signature
     5  
     6  import (
     7  	"bytes"
     8  	"crypto/ecdsa"
     9  	"crypto/elliptic"
    10  	"crypto/hmac"
    11  	"errors"
    12  	"hash"
    13  	"math/big"
    14  )
    15  
    16  var (
    17  	// Used in RFC6979 implementation when testing the nonce for correctness
    18  	one = big.NewInt(1)
    19  
    20  	// oneInitializer is used to fill a byte slice with byte 0x01.  It is provided
    21  	// here to avoid the need to create it multiple times.
    22  	oneInitializer = []byte{0x01}
    23  )
    24  
    25  // NewSignature instantiates a new signature given some R,S values.
    26  func NewSignature(curve elliptic.Curve, r, s *big.Int) *SignatureECDSA {
    27  	order := new(big.Int).Set(curve.Params().N)
    28  	return &SignatureECDSA{
    29  		curve:     curve,
    30  		order:     order,
    31  		halfOrder: new(big.Int).Rsh(order, 1),
    32  		R:         r,
    33  		S:         s,
    34  	}
    35  }
    36  
    37  // SignatureECDSA is a type representing an ecdsa signature.
    38  type SignatureECDSA struct {
    39  	curve elliptic.Curve
    40  	// Curve order and halfOrder, used to tame ECDSA malleability (see BIP-0062)
    41  	order     *big.Int
    42  	halfOrder *big.Int
    43  	R         *big.Int
    44  	S         *big.Int
    45  }
    46  
    47  func (sig *SignatureECDSA) Verify(hash []byte, pubKey *ecdsa.PublicKey) bool {
    48  	return ecdsa.Verify(pubKey, hash, sig.GetR(), sig.GetS())
    49  }
    50  
    51  // GetR satisfies the chainec PublicKey interface.
    52  func (sig *SignatureECDSA) GetR() *big.Int {
    53  	return sig.R
    54  }
    55  
    56  // GetS satisfies the chainec PublicKey interface.
    57  func (sig *SignatureECDSA) GetS() *big.Int {
    58  	return sig.S
    59  }
    60  
    61  func getOrder(curve elliptic.Curve) *big.Int {
    62  	return new(big.Int).Set(curve.Params().N)
    63  }
    64  
    65  func getHalforder(curve elliptic.Curve) *big.Int {
    66  	return new(big.Int).Rsh(getOrder(curve), 1)
    67  }
    68  
    69  // SignRFC6979 produces a compact signature of the data in hash with the given
    70  // private key on the given koblitz curve. The isCompressed  parameter should
    71  // be used to detail if the given signature should reference a compressed
    72  // public key or not. If successful the bytes of the compact signature will be
    73  // returned in the format:
    74  // <(byte of 27+public key solution)+4 if compressed >< padded bytes for signature R><padded bytes for signature S>
    75  // where the R and S parameters are padde up to the bitlengh of the curve.
    76  func SignRFC6979(key *ecdsa.PrivateKey, hash []byte) ([]byte, error) {
    77  	curve := key.Curve
    78  	sig, err := signRFC6979(key, hash)
    79  	if err != nil {
    80  		return nil, err
    81  	}
    82  	result := make([]byte, 0, 2*curve.Params().BitSize)
    83  	curvelen := (curve.Params().BitSize + 7) / 8
    84  
    85  	// Pad R and S to curvelen if needed.
    86  	bytelen := (sig.R.BitLen() + 7) / 8
    87  	if bytelen < curvelen {
    88  		result = append(result,
    89  			make([]byte, curvelen-bytelen)...)
    90  	}
    91  	result = append(result, sig.R.Bytes()...)
    92  	bytelen = (sig.S.BitLen() + 7) / 8
    93  	if bytelen < curvelen {
    94  		result = append(result,
    95  			make([]byte, curvelen-bytelen)...)
    96  	}
    97  	result = append(result, sig.S.Bytes()...)
    98  	return result, nil
    99  }
   100  
   101  // signRFC6979 generates a deterministic ECDSA signature according to RFC 6979
   102  // and BIP 62.
   103  func signRFC6979(privkey *ecdsa.PrivateKey, hash []byte) (*SignatureECDSA, error) {
   104  	curve := privkey.Curve
   105  	N := new(big.Int).Set(curve.Params().N)
   106  	// 获取唯一的nonce
   107  	k := NonceRFC6979(curve, privkey.D, hash, nil, nil)
   108  
   109  	inv := new(big.Int).ModInverse(k, N)
   110  	r, _ := curve.ScalarBaseMult(k.Bytes())
   111  	r.Mod(r, N)
   112  
   113  	if r.Sign() == 0 {
   114  		return nil, errors.New("calculated R is zero")
   115  	}
   116  
   117  	e := hashToInt(curve, hash)
   118  	s := new(big.Int).Mul(privkey.D, r)
   119  	s.Add(s, e)
   120  	s.Mul(s, inv)
   121  	s.Mod(s, N)
   122  
   123  	if s.Cmp(getHalforder(curve)) == 1 {
   124  		s.Sub(N, s)
   125  	}
   126  	if s.Sign() == 0 {
   127  		return nil, errors.New("calculated S is zero")
   128  	}
   129  	return &SignatureECDSA{
   130  		curve: curve,
   131  		R:     r,
   132  		S:     s,
   133  	}, nil
   134  }
   135  
   136  // NonceRFC6979 generates an ECDSA nonce (`k`) deterministically according to
   137  // RFC 6979. It takes a 32-byte hash as an input and returns 32-byte nonce to
   138  // be used in ECDSA algorithm.
   139  func NonceRFC6979(curve elliptic.Curve, privkey *big.Int, hash []byte, extra []byte, version []byte) *big.Int {
   140  	q := curve.Params().N
   141  	x := privkey
   142  	alg := HashFunc(curve.Params().Name)
   143  
   144  	qlen := q.BitLen()
   145  	holen := alg().Size()
   146  	rolen := (qlen + 7) >> 3
   147  	bx := append(int2octets(x, rolen), bits2octets(curve, hash, rolen)...)
   148  	if len(extra) == 32 {
   149  		bx = append(bx, extra...)
   150  	}
   151  	if len(version) == 16 && len(extra) == 32 {
   152  		bx = append(bx, extra...)
   153  	}
   154  	if len(version) == 16 && len(extra) != 32 {
   155  		bx = append(bx, bytes.Repeat([]byte{0x00}, 32)...)
   156  		bx = append(bx, version...)
   157  	}
   158  
   159  	// Step B
   160  	v := bytes.Repeat(oneInitializer, holen)
   161  
   162  	// Step C (Go zeroes the all allocated memory)
   163  	k := make([]byte, holen)
   164  
   165  	// Step D
   166  	k = mac(alg, k, append(append(v, 0x00), bx...))
   167  
   168  	// Step E
   169  	v = mac(alg, k, v)
   170  
   171  	// Step F
   172  	k = mac(alg, k, append(append(v, 0x01), bx...))
   173  
   174  	// Step G
   175  	v = mac(alg, k, v)
   176  
   177  	// Step H
   178  	for {
   179  		// Step H1
   180  		var t []byte
   181  
   182  		// Step H2
   183  		for len(t)*8 < qlen {
   184  			v = mac(alg, k, v)
   185  			t = append(t, v...)
   186  		}
   187  
   188  		// Step H3
   189  		secret := hashToInt(curve, t)
   190  		if secret.Cmp(one) >= 0 && secret.Cmp(q) < 0 {
   191  			return secret
   192  		}
   193  		k = mac(alg, k, append(v, 0x00))
   194  		v = mac(alg, k, v)
   195  	}
   196  }
   197  
   198  // mac returns an HMAC of the given key and message.
   199  func mac(alg func() hash.Hash, k, m []byte) []byte {
   200  	h := hmac.New(alg, k)
   201  	h.Write(m)
   202  	return h.Sum(nil)
   203  }
   204  
   205  // https://tools.ietf.org/html/rfc6979#section-2.3.3
   206  func int2octets(v *big.Int, rolen int) []byte {
   207  	out := v.Bytes()
   208  
   209  	// left pad with zeros if it's too short
   210  	if len(out) < rolen {
   211  		out2 := make([]byte, rolen)
   212  		copy(out2[rolen-len(out):], out)
   213  		return out2
   214  	}
   215  
   216  	// drop most significant bytes if it's too long
   217  	if len(out) > rolen {
   218  		out2 := make([]byte, rolen)
   219  		copy(out2, out[len(out)-rolen:])
   220  		return out2
   221  	}
   222  
   223  	return out
   224  }
   225  
   226  // https://tools.ietf.org/html/rfc6979#section-2.3.4
   227  func bits2octets(curve elliptic.Curve, in []byte, rolen int) []byte {
   228  	z1 := hashToInt(curve, in)
   229  	z2 := new(big.Int).Sub(z1, curve.Params().N)
   230  	if z2.Sign() < 0 {
   231  		return int2octets(z1, rolen)
   232  	}
   233  	return int2octets(z2, rolen)
   234  }
   235  
   236  // hashToInt converts a hash value to an integer. There is some disagreement
   237  // about how this is done. [NSA] suggests that this is done in the obvious
   238  // manner, but [SECG] truncates the hash to the bit-length of the curve order
   239  // first. We follow [SECG] because that's what OpenSSL does. Additionally,
   240  // OpenSSL right shifts excess bits from the number if the hash is too large
   241  // and we mirror that too.
   242  // This is borrowed from crypto/ecdsa.
   243  func hashToInt(curve elliptic.Curve, hash []byte) *big.Int {
   244  	orderBits := curve.Params().N.BitLen()
   245  	orderBytes := (orderBits + 7) / 8
   246  	if len(hash) > orderBytes {
   247  		hash = hash[:orderBytes]
   248  	}
   249  
   250  	ret := new(big.Int).SetBytes(hash)
   251  	excess := len(hash)*8 - orderBits
   252  	if excess > 0 {
   253  		ret.Rsh(ret, uint(excess))
   254  	}
   255  	return ret
   256  }
   257  
   258  // VerifyRFC6979 验证签名
   259  func VerifyRFC6979(pubkey *ecdsa.PublicKey, msg, signature []byte) bool {
   260  	bitlen := (pubkey.Curve.Params().BitSize + 7) / 8
   261  	if len(signature) != bitlen*2 {
   262  		return false
   263  	}
   264  
   265  	// 校验码在最后一位
   266  	sig := &SignatureECDSA{
   267  		curve: pubkey.Curve,
   268  		R:     new(big.Int).SetBytes(signature[:bitlen]),
   269  		S:     new(big.Int).SetBytes(signature[bitlen : bitlen*2]),
   270  	}
   271  	verify := sig.Verify(msg, pubkey)
   272  	return verify
   273  }