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 }