forked from decred/dcrd
-
Notifications
You must be signed in to change notification settings - Fork 0
/
signature.go
109 lines (90 loc) · 2.95 KB
/
signature.go
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
// Copyright (c) 2013-2014 The btcsuite developers
// Copyright (c) 2015 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package edwards
import (
"fmt"
"math/big"
)
// Signature is a type representing an ecdsa signature.
type Signature struct {
R *big.Int
S *big.Int
}
// SignatureSize is the size of an encoded ECDSA signature.
const SignatureSize = 64
// NewSignature instantiates a new signature given some R,S values.
func NewSignature(r, s *big.Int) *Signature {
return &Signature{r, s}
}
// Serialize returns the ECDSA signature in the more strict format.
//
// The signatures are encoded as
// sig[0:32] R, a point encoded as little endian
// sig[32:64] S, scalar multiplication/addition results = (ab+c) mod l
// encoded also as little endian
func (sig Signature) Serialize() []byte {
rBytes := BigIntToEncodedBytes(sig.R)
sBytes := BigIntToEncodedBytes(sig.S)
all := append(rBytes[:], sBytes[:]...)
return all
}
// parseSig is the default method of parsing a serialized Ed25519 signature.
func parseSig(curve *TwistedEdwardsCurve, sigStr []byte, der bool) (*Signature,
error) {
if der {
return nil, fmt.Errorf("DER signatures not allowed in ed25519")
}
if len(sigStr) != SignatureSize {
return nil, fmt.Errorf("bad signature size; have %v, want %v",
len(sigStr), SignatureSize)
}
rBytes := copyBytes(sigStr[0:32])
r := EncodedBytesToBigInt(rBytes)
// r is a point on the curve as well. Evaluate it and make sure it's
// a valid point.
_, _, err := curve.EncodedBytesToBigIntPoint(rBytes)
if err != nil {
return nil, err
}
sBytes := copyBytes(sigStr[32:64])
s := EncodedBytesToBigInt(sBytes)
// s may not be zero or >= curve.N.
if s.Cmp(curve.N) >= 0 || s.Cmp(zero) == 0 {
return nil, fmt.Errorf("s scalar is empty or larger than the order of " +
"the curve")
}
return &Signature{r, s}, nil
}
// ParseSignature parses a signature in BER format for the curve type `curve'
// into a Signature type, perfoming some basic sanity checks.
func ParseSignature(curve *TwistedEdwardsCurve, sigStr []byte) (*Signature,
error) {
return parseSig(curve, sigStr, false)
}
// ParseDERSignature offers a legacy function for plugging into Decred, which
// is based off btcec.
func ParseDERSignature(curve *TwistedEdwardsCurve, sigStr []byte) (*Signature,
error) {
return parseSig(curve, sigStr, false)
}
// RecoverCompact uses a signature and a hash to recover is private
// key, is not yet implemented.
// TODO: Implement.
func RecoverCompact(signature, hash []byte) (*PublicKey, bool, error) {
// TODO One day reimplement this? cj
return nil, false, nil
}
// GetR satisfies the chainec Signature interface.
func (sig Signature) GetR() *big.Int {
return sig.R
}
// GetS satisfies the chainec Signature interface.
func (sig Signature) GetS() *big.Int {
return sig.S
}
// GetType satisfies the chainec Signature interface.
func (sig Signature) GetType() int {
return ecTypeEdwards
}