github.com/piotrnar/gocoin@v0.0.0-20240512203912-faa0448c5e96/lib/secp256k1/sig.go (about)

     1  package secp256k1
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/hex"
     6  	"fmt"
     7  )
     8  
     9  type Signature struct {
    10  	R, S Number
    11  }
    12  
    13  func (s *Signature) Print(lab string) {
    14  	fmt.Println(lab+".R:", hex.EncodeToString(s.R.Bytes()))
    15  	fmt.Println(lab+".S:", hex.EncodeToString(s.S.Bytes()))
    16  }
    17  
    18  func (r *Signature) ParseBytes(sig []byte) int {
    19  	if len(sig) < 5 || sig[0] != 0x30 {
    20  		return -1
    21  	}
    22  
    23  	lenr := int(sig[3])
    24  	if lenr == 0 || 5+lenr >= len(sig) || sig[lenr+4] != 0x02 {
    25  		return -1
    26  	}
    27  
    28  	lens := int(sig[lenr+5])
    29  	if lens == 0 || int(sig[1]) != lenr+lens+4 || lenr+lens+6 > len(sig) || sig[2] != 0x02 {
    30  		return -1
    31  	}
    32  
    33  	r.R.SetBytes(sig[4 : 4+lenr])
    34  	r.S.SetBytes(sig[6+lenr : 6+lenr+lens])
    35  	return 6 + lenr + lens
    36  }
    37  
    38  func (r *Signature) Verify(pubkey *XY, message *Number) (ret bool) {
    39  	var r2 Number
    40  	ret = r.recompute(&r2, pubkey, message) && r.R.Cmp(&r2.Int) == 0
    41  	return
    42  }
    43  
    44  func (sig *Signature) recompute(r2 *Number, pubkey *XY, message *Number) (ret bool) {
    45  	var sn, u1, u2 Number
    46  
    47  	sn.mod_inv(&sig.S, &TheCurve.Order)
    48  	u1.mod_mul(&sn, message, &TheCurve.Order)
    49  	u2.mod_mul(&sn, &sig.R, &TheCurve.Order)
    50  
    51  	var pr, pubkeyj XYZ
    52  	pubkeyj.SetXY(pubkey)
    53  
    54  	pubkeyj.ECmult(&pr, &u2, &u1)
    55  	if !pr.IsInfinity() {
    56  		var xr Field
    57  		pr.get_x(&xr)
    58  		xr.Normalize()
    59  		var xrb [32]byte
    60  		xr.GetB32(xrb[:])
    61  		r2.SetBytes(xrb[:])
    62  		r2.Mod(&r2.Int, &TheCurve.Order.Int)
    63  		ret = true
    64  	}
    65  
    66  	return
    67  }
    68  
    69  func (sig *Signature) recover(pubkey *XY, m *Number, recid int) (ret bool) {
    70  	var rx, rn, u1, u2 Number
    71  	var fx Field
    72  	var X XY
    73  	var xj, qj XYZ
    74  
    75  	rx.Set(&sig.R.Int)
    76  	if (recid & 2) != 0 {
    77  		rx.Add(&rx.Int, &TheCurve.Order.Int)
    78  		if rx.Cmp(&TheCurve.p.Int) >= 0 {
    79  			return false
    80  		}
    81  	}
    82  
    83  	fx.SetB32(rx.get_bin(32))
    84  
    85  	X.SetXO(&fx, (recid&1) != 0)
    86  	if !X.IsValid() {
    87  		return false
    88  	}
    89  
    90  	xj.SetXY(&X)
    91  	rn.mod_inv(&sig.R, &TheCurve.Order)
    92  	u1.mod_mul(&rn, m, &TheCurve.Order)
    93  	u1.Sub(&TheCurve.Order.Int, &u1.Int)
    94  	u2.mod_mul(&rn, &sig.S, &TheCurve.Order)
    95  	xj.ECmult(&qj, &u2, &u1)
    96  	pubkey.SetXYZ(&qj)
    97  
    98  	return true
    99  }
   100  
   101  func (sig *Signature) Sign(seckey, message, nonce *Number, recid *int) int {
   102  	var r XY
   103  	var rp XYZ
   104  	var n Number
   105  	var b [32]byte
   106  
   107  	ECmultGen(&rp, nonce)
   108  	r.SetXYZ(&rp)
   109  	r.X.Normalize()
   110  	r.Y.Normalize()
   111  	r.X.GetB32(b[:])
   112  	sig.R.SetBytes(b[:])
   113  	if recid != nil {
   114  		*recid = 0
   115  		if sig.R.Cmp(&TheCurve.Order.Int) >= 0 {
   116  			*recid |= 2
   117  		}
   118  		if r.Y.IsOdd() {
   119  			*recid |= 1
   120  		}
   121  	}
   122  	sig.R.mod(&TheCurve.Order)
   123  	n.mod_mul(&sig.R, seckey, &TheCurve.Order)
   124  	n.Add(&n.Int, &message.Int)
   125  	n.mod(&TheCurve.Order)
   126  	sig.S.mod_inv(nonce, &TheCurve.Order)
   127  	sig.S.mod_mul(&sig.S, &n, &TheCurve.Order)
   128  	if sig.S.Sign() == 0 {
   129  		return 0
   130  	}
   131  	if sig.S.is_odd() {
   132  		sig.S.Sub(&TheCurve.Order.Int, &sig.S.Int)
   133  		if recid != nil {
   134  			*recid ^= 1
   135  		}
   136  	}
   137  
   138  	if FORCE_LOW_S && sig.S.Cmp(&TheCurve.HalfOrder.Int) == 1 {
   139  		sig.S.Sub(&TheCurve.Order.Int, &sig.S.Int)
   140  		if recid != nil {
   141  			*recid ^= 1
   142  		}
   143  	}
   144  
   145  	return 1
   146  }
   147  
   148  func (sig *Signature) Bytes() []byte {
   149  	r := sig.R.Bytes()
   150  	if r[0] >= 0x80 {
   151  		r = append([]byte{0}, r...)
   152  	}
   153  	s := sig.S.Bytes()
   154  	if s[0] >= 0x80 {
   155  		s = append([]byte{0}, s...)
   156  	}
   157  	res := new(bytes.Buffer)
   158  	res.WriteByte(0x30)
   159  	res.WriteByte(byte(4 + len(r) + len(s)))
   160  	res.WriteByte(0x02)
   161  	res.WriteByte(byte(len(r)))
   162  	res.Write(r)
   163  	res.WriteByte(0x02)
   164  	res.WriteByte(byte(len(s)))
   165  	res.Write(s)
   166  	return res.Bytes()
   167  }