aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/btcsuite/btcd/btcec/signature.go
blob: 4392ab41a2f85c2ea3da455bd02cb9b6d213c1e2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
// Copyright (c) 2013-2017 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package btcec

import (
    "bytes"
    "crypto/ecdsa"
    "crypto/elliptic"
    "crypto/hmac"
    "crypto/sha256"
    "errors"
    "fmt"
    "hash"
    "math/big"
)

// Errors returned by canonicalPadding.
var (
    errNegativeValue          = errors.New("value may be interpreted as negative")
    errExcessivelyPaddedValue = errors.New("value is excessively padded")
)

// Signature is a type representing an ecdsa signature.
type Signature struct {
    R *big.Int
    S *big.Int
}

var (
    // Used in RFC6979 implementation when testing the nonce for correctness
    one = big.NewInt(1)

    // oneInitializer is used to fill a byte slice with byte 0x01.  It is provided
    // here to avoid the need to create it multiple times.
    oneInitializer = []byte{0x01}
)

// Serialize returns the ECDSA signature in the more strict DER format.  Note
// that the serialized bytes returned do not include the appended hash type
// used in Bitcoin signature scripts.
//
// encoding/asn1 is broken so we hand roll this output:
//
// 0x30 <length> 0x02 <length r> r 0x02 <length s> s
func (sig *Signature) Serialize() []byte {
    // low 'S' malleability breaker
    sigS := sig.S
    if sigS.Cmp(S256().halfOrder) == 1 {
        sigS = new(big.Int).Sub(S256().N, sigS)
    }
    // Ensure the encoded bytes for the r and s values are canonical and
    // thus suitable for DER encoding.
    rb := canonicalizeInt(sig.R)
    sb := canonicalizeInt(sigS)

    // total length of returned signature is 1 byte for each magic and
    // length (6 total), plus lengths of r and s
    length := 6 + len(rb) + len(sb)
    b := make([]byte, length)

    b[0] = 0x30
    b[1] = byte(length - 2)
    b[2] = 0x02
    b[3] = byte(len(rb))
    offset := copy(b[4:], rb) + 4
    b[offset] = 0x02
    b[offset+1] = byte(len(sb))
    copy(b[offset+2:], sb)
    return b
}

// Verify calls ecdsa.Verify to verify the signature of hash using the public
// key.  It returns true if the signature is valid, false otherwise.
func (sig *Signature) Verify(hash []byte, pubKey *PublicKey) bool {
    return ecdsa.Verify(pubKey.ToECDSA(), hash, sig.R, sig.S)
}

// IsEqual compares this Signature instance to the one passed, returning true
// if both Signatures are equivalent. A signature is equivalent to another, if
// they both have the same scalar value for R and S.
func (sig *Signature) IsEqual(otherSig *Signature) bool {
    return sig.R.Cmp(otherSig.R) == 0 &&
        sig.S.Cmp(otherSig.S) == 0
}

func parseSig(sigStr []byte, curve elliptic.Curve, der bool) (*Signature, error) {
    // Originally this code used encoding/asn1 in order to parse the
    // signature, but a number of problems were found with this approach.
    // Despite the fact that signatures are stored as DER, the difference
    // between go's idea of a bignum (and that they have sign) doesn't agree
    // with the openssl one (where they do not). The above is true as of
    // Go 1.1. In the end it was simpler to rewrite the code to explicitly
    // understand the format which is this:
    // 0x30 <length of whole message> <0x02> <length of R> <R> 0x2
    // <length of S> <S>.

    signature := &Signature{}

    // minimal message is when both numbers are 1 bytes. adding up to:
    // 0x30 + len + 0x02 + 0x01 + <byte> + 0x2 + 0x01 + <byte>
    if len(sigStr) < 8 {
        return nil, errors.New("malformed signature: too short")
    }
    // 0x30
    index := 0
    if sigStr[index] != 0x30 {
        return nil, errors.New("malformed signature: no header magic")
    }
    index++
    // length of remaining message
    siglen := sigStr[index]
    index++
    if int(siglen+2) > len(sigStr) {
        return nil, errors.New("malformed signature: bad length")
    }
    // trim the slice we're working on so we only look at what matters.
    sigStr = sigStr[:siglen+2]

    // 0x02
    if sigStr[index] != 0x02 {
        return nil,
            errors.New("malformed signature: no 1st int marker")
    }
    index++

    // Length of signature R.
    rLen := int(sigStr[index])
    // must be positive, must be able to fit in another 0x2, <len> <s>
    // hence the -3. We assume that the length must be at least one byte.
    index++
    if rLen <= 0 || rLen > len(sigStr)-index-3 {
        return nil, errors.New("malformed signature: bogus R length")
    }

    // Then R itself.
    rBytes := sigStr[index : index+rLen]
    if der {
        switch err := canonicalPadding(rBytes); err {
        case errNegativeValue:
            return nil, errors.New("signature R is negative")
        case errExcessivelyPaddedValue:
            return nil, errors.New("signature R is excessively padded")
        }
    }
    signature.R = new(big.Int).SetBytes(rBytes)
    index += rLen
    // 0x02. length already checked in previous if.
    if sigStr[index] != 0x02 {
        return nil, errors.New("malformed signature: no 2nd int marker")
    }
    index++

    // Length of signature S.
    sLen := int(sigStr[index])
    index++
    // S should be the rest of the string.
    if sLen <= 0 || sLen > len(sigStr)-index {
        return nil, errors.New("malformed signature: bogus S length")
    }

    // Then S itself.
    sBytes := sigStr[index : index+sLen]
    if der {
        switch err := canonicalPadding(sBytes); err {
        case errNegativeValue:
            return nil, errors.New("signature S is negative")
        case errExcessivelyPaddedValue:
            return nil, errors.New("signature S is excessively padded")
        }
    }
    signature.S = new(big.Int).SetBytes(sBytes)
    index += sLen

    // sanity check length parsing
    if index != len(sigStr) {
        return nil, fmt.Errorf("malformed signature: bad final length %v != %v",
            index, len(sigStr))
    }

    // Verify also checks this, but we can be more sure that we parsed
    // correctly if we verify here too.
    // FWIW the ecdsa spec states that R and S must be | 1, N - 1 |
    // but crypto/ecdsa only checks for Sign != 0. Mirror that.
    if signature.R.Sign() != 1 {
        return nil, errors.New("signature R isn't 1 or more")
    }
    if signature.S.Sign() != 1 {
        return nil, errors.New("signature S isn't 1 or more")
    }
    if signature.R.Cmp(curve.Params().N) >= 0 {
        return nil, errors.New("signature R is >= curve.N")
    }
    if signature.S.Cmp(curve.Params().N) >= 0 {
        return nil, errors.New("signature S is >= curve.N")
    }

    return signature, nil
}

// ParseSignature parses a signature in BER format for the curve type `curve'
// into a Signature type, perfoming some basic sanity checks.  If parsing
// according to the more strict DER format is needed, use ParseDERSignature.
func ParseSignature(sigStr []byte, curve elliptic.Curve) (*Signature, error) {
    return parseSig(sigStr, curve, false)
}

// ParseDERSignature parses a signature in DER format for the curve type
// `curve` into a Signature type.  If parsing according to the less strict
// BER format is needed, use ParseSignature.
func ParseDERSignature(sigStr []byte, curve elliptic.Curve) (*Signature, error) {
    return parseSig(sigStr, curve, true)
}

// canonicalizeInt returns the bytes for the passed big integer adjusted as
// necessary to ensure that a big-endian encoded integer can't possibly be
// misinterpreted as a negative number.  This can happen when the most
// significant bit is set, so it is padded by a leading zero byte in this case.
// Also, the returned bytes will have at least a single byte when the passed
// value is 0.  This is required for DER encoding.
func canonicalizeInt(val *big.Int) []byte {
    b := val.Bytes()
    if len(b) == 0 {
        b = []byte{0x00}
    }
    if b[0]&0x80 != 0 {
        paddedBytes := make([]byte, len(b)+1)
        copy(paddedBytes[1:], b)
        b = paddedBytes
    }
    return b
}

// canonicalPadding checks whether a big-endian encoded integer could
// possibly be misinterpreted as a negative number (even though OpenSSL
// treats all numbers as unsigned), or if there is any unnecessary
// leading zero padding.
func canonicalPadding(b []byte) error {
    switch {
    case b[0]&0x80 == 0x80:
        return errNegativeValue
    case len(b) > 1 && b[0] == 0x00 && b[1]&0x80 != 0x80:
        return errExcessivelyPaddedValue
    default:
        return nil
    }
}

// hashToInt converts a hash value to an integer. There is some disagreement
// about how this is done. [NSA] suggests that this is done in the obvious
// manner, but [SECG] truncates the hash to the bit-length of the curve order
// first. We follow [SECG] because that's what OpenSSL does. Additionally,
// OpenSSL right shifts excess bits from the number if the hash is too large
// and we mirror that too.
// This is borrowed from crypto/ecdsa.
func hashToInt(hash []byte, c elliptic.Curve) *big.Int {
    orderBits := c.Params().N.BitLen()
    orderBytes := (orderBits + 7) / 8
    if len(hash) > orderBytes {
        hash = hash[:orderBytes]
    }

    ret := new(big.Int).SetBytes(hash)
    excess := len(hash)*8 - orderBits
    if excess > 0 {
        ret.Rsh(ret, uint(excess))
    }
    return ret
}

// recoverKeyFromSignature recoves a public key from the signature "sig" on the
// given message hash "msg". Based on the algorithm found in section 5.1.5 of
// SEC 1 Ver 2.0, page 47-48 (53 and 54 in the pdf). This performs the details
// in the inner loop in Step 1. The counter provided is actually the j parameter
// of the loop * 2 - on the first iteration of j we do the R case, else the -R
// case in step 1.6. This counter is used in the bitcoin compressed signature
// format and thus we match bitcoind's behaviour here.
func recoverKeyFromSignature(curve *KoblitzCurve, sig *Signature, msg []byte,
    iter int, doChecks bool) (*PublicKey, error) {
    // 1.1 x = (n * i) + r
    Rx := new(big.Int).Mul(curve.Params().N,
        new(big.Int).SetInt64(int64(iter/2)))
    Rx.Add(Rx, sig.R)
    if Rx.Cmp(curve.Params().P) != -1 {
        return nil, errors.New("calculated Rx is larger than curve P")
    }

    // convert 02<Rx> to point R. (step 1.2 and 1.3). If we are on an odd
    // iteration then 1.6 will be done with -R, so we calculate the other
    // term when uncompressing the point.
    Ry, err := decompressPoint(curve, Rx, iter%2 == 1)
    if err != nil {
        return nil, err
    }

    // 1.4 Check n*R is point at infinity
    if doChecks {
        nRx, nRy := curve.ScalarMult(Rx, Ry, curve.Params().N.Bytes())
        if nRx.Sign() != 0 || nRy.Sign() != 0 {
            return nil, errors.New("n*R does not equal the point at infinity")
        }
    }

    // 1.5 calculate e from message using the same algorithm as ecdsa
    // signature calculation.
    e := hashToInt(msg, curve)

    // Step 1.6.1:
    // We calculate the two terms sR and eG separately multiplied by the
    // inverse of r (from the signature). We then add them to calculate
    // Q = r^-1(sR-eG)
    invr := new(big.Int).ModInverse(sig.R, curve.Params().N)

    // first term.
    invrS := new(big.Int).Mul(invr, sig.S)
    invrS.Mod(invrS, curve.Params().N)
    sRx, sRy := curve.ScalarMult(Rx, Ry, invrS.Bytes())

    // second term.
    e.Neg(e)
    e.Mod(e, curve.Params().N)
    e.Mul(e, invr)
    e.Mod(e, curve.Params().N)
    minuseGx, minuseGy := curve.ScalarBaseMult(e.Bytes())

    // TODO: this would be faster if we did a mult and add in one
    // step to prevent the jacobian conversion back and forth.
    Qx, Qy := curve.Add(sRx, sRy, minuseGx, minuseGy)

    return &PublicKey{
        Curve: curve,
        X:     Qx,
        Y:     Qy,
    }, nil
}

// SignCompact produces a compact signature of the data in hash with the given
// private key on the given koblitz curve. The isCompressed  parameter should
// be used to detail if the given signature should reference a compressed
// public key or not. If successful the bytes of the compact signature will be
// returned in the format:
// <(byte of 27+public key solution)+4 if compressed >< padded bytes for signature R><padded bytes for signature S>
// where the R and S parameters are padde up to the bitlengh of the curve.
func SignCompact(curve *KoblitzCurve, key *PrivateKey,
    hash []byte, isCompressedKey bool) ([]byte, error) {
    sig, err := key.Sign(hash)
    if err != nil {
        return nil, err
    }

    // bitcoind checks the bit length of R and S here. The ecdsa signature
    // algorithm returns R and S mod N therefore they will be the bitsize of
    // the curve, and thus correctly sized.
    for i := 0; i < (curve.H+1)*2; i++ {
        pk, err := recoverKeyFromSignature(curve, sig, hash, i, true)
        if err == nil && pk.X.Cmp(key.X) == 0 && pk.Y.Cmp(key.Y) == 0 {
            result := make([]byte, 1, 2*curve.byteSize+1)
            result[0] = 27 + byte(i)
            if isCompressedKey {
                result[0] += 4
            }
            // Not sure this needs rounding but safer to do so.
            curvelen := (curve.BitSize + 7) / 8

            // Pad R and S to curvelen if needed.
            bytelen := (sig.R.BitLen() + 7) / 8
            if bytelen < curvelen {
                result = append(result,
                    make([]byte, curvelen-bytelen)...)
            }
            result = append(result, sig.R.Bytes()...)

            bytelen = (sig.S.BitLen() + 7) / 8
            if bytelen < curvelen {
                result = append(result,
                    make([]byte, curvelen-bytelen)...)
            }
            result = append(result, sig.S.Bytes()...)

            return result, nil
        }
    }

    return nil, errors.New("no valid solution for pubkey found")
}

// RecoverCompact verifies the compact signature "signature" of "hash" for the
// Koblitz curve in "curve". If the signature matches then the recovered public
// key will be returned as well as a boolen if the original key was compressed
// or not, else an error will be returned.
func RecoverCompact(curve *KoblitzCurve, signature,
    hash []byte) (*PublicKey, bool, error) {
    bitlen := (curve.BitSize + 7) / 8
    if len(signature) != 1+bitlen*2 {
        return nil, false, errors.New("invalid compact signature size")
    }

    iteration := int((signature[0] - 27) & ^byte(4))

    // format is <header byte><bitlen R><bitlen S>
    sig := &Signature{
        R: new(big.Int).SetBytes(signature[1 : bitlen+1]),
        S: new(big.Int).SetBytes(signature[bitlen+1:]),
    }
    // The iteration used here was encoded
    key, err := recoverKeyFromSignature(curve, sig, hash, iteration, false)
    if err != nil {
        return nil, false, err
    }

    return key, ((signature[0] - 27) & 4) == 4, nil
}

// signRFC6979 generates a deterministic ECDSA signature according to RFC 6979 and BIP 62.
func signRFC6979(privateKey *PrivateKey, hash []byte) (*Signature, error) {

    privkey := privateKey.ToECDSA()
    N := S256().N
    halfOrder := S256().halfOrder
    k := nonceRFC6979(privkey.D, hash)
    inv := new(big.Int).ModInverse(k, N)
    r, _ := privkey.Curve.ScalarBaseMult(k.Bytes())
    if r.Cmp(N) == 1 {
        r.Sub(r, N)
    }

    if r.Sign() == 0 {
        return nil, errors.New("calculated R is zero")
    }

    e := hashToInt(hash, privkey.Curve)
    s := new(big.Int).Mul(privkey.D, r)
    s.Add(s, e)
    s.Mul(s, inv)
    s.Mod(s, N)

    if s.Cmp(halfOrder) == 1 {
        s.Sub(N, s)
    }
    if s.Sign() == 0 {
        return nil, errors.New("calculated S is zero")
    }
    return &Signature{R: r, S: s}, nil
}

// nonceRFC6979 generates an ECDSA nonce (`k`) deterministically according to RFC 6979.
// It takes a 32-byte hash as an input and returns 32-byte nonce to be used in ECDSA algorithm.
func nonceRFC6979(privkey *big.Int, hash []byte) *big.Int {

    curve := S256()
    q := curve.Params().N
    x := privkey
    alg := sha256.New

    qlen := q.BitLen()
    holen := alg().Size()
    rolen := (qlen + 7) >> 3
    bx := append(int2octets(x, rolen), bits2octets(hash, curve, rolen)...)

    // Step B
    v := bytes.Repeat(oneInitializer, holen)

    // Step C (Go zeroes the all allocated memory)
    k := make([]byte, holen)

    // Step D
    k = mac(alg, k, append(append(v, 0x00), bx...))

    // Step E
    v = mac(alg, k, v)

    // Step F
    k = mac(alg, k, append(append(v, 0x01), bx...))

    // Step G
    v = mac(alg, k, v)

    // Step H
    for {
        // Step H1
        var t []byte

        // Step H2
        for len(t)*8 < qlen {
            v = mac(alg, k, v)
            t = append(t, v...)
        }

        // Step H3
        secret := hashToInt(t, curve)
        if secret.Cmp(one) >= 0 && secret.Cmp(q) < 0 {
            return secret
        }
        k = mac(alg, k, append(v, 0x00))
        v = mac(alg, k, v)
    }
}

// mac returns an HMAC of the given key and message.
func mac(alg func() hash.Hash, k, m []byte) []byte {
    h := hmac.New(alg, k)
    h.Write(m)
    return h.Sum(nil)
}

// https://tools.ietf.org/html/rfc6979#section-2.3.3
func int2octets(v *big.Int, rolen int) []byte {
    out := v.Bytes()

    // left pad with zeros if it's too short
    if len(out) < rolen {
        out2 := make([]byte, rolen)
        copy(out2[rolen-len(out):], out)
        return out2
    }

    // drop most significant bytes if it's too long
    if len(out) > rolen {
        out2 := make([]byte, rolen)
        copy(out2, out[len(out)-rolen:])
        return out2
    }

    return out
}

// https://tools.ietf.org/html/rfc6979#section-2.3.4
func bits2octets(in []byte, curve elliptic.Curve, rolen int) []byte {
    z1 := hashToInt(in, curve)
    z2 := new(big.Int).Sub(z1, curve.Params().N)
    if z2.Sign() < 0 {
        return int2octets(z1, rolen)
    }
    return int2octets(z2, rolen)
}