/
error.go
150 lines (122 loc) · 4.49 KB
/
error.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
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
// Copyright (c) 2014 Conformal Systems LLC.
// Copyright (c) 2015-2020 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package schnorr
import (
"fmt"
)
// ErrorCode identifies a kind of signature-related error. It has full support
// for errors.Is and errors.As, so the caller can directly check against an
// error code when determining the reason for an error.
type ErrorCode int
// These constants are used to identify a specific RuleError.
const (
// ErrInvalidHashLen indicates that the input hash to sign or verify is not
// the required length.
ErrInvalidHashLen ErrorCode = iota
// ErrPrivateKeyIsZero indicates an attempt was made to sign a message with
// a private key that is equal to zero.
ErrPrivateKeyIsZero
// ErrSchnorrHashValue indicates that the hash of (R || m) was too large and
// so a new nonce should be used.
ErrSchnorrHashValue
// ErrPubKeyNotOnCurve indicates that a point was not on the given elliptic
// curve.
ErrPubKeyNotOnCurve
// ErrSigRYIsOdd indicates that the calculated Y value of R was odd.
ErrSigRYIsOdd
// ErrSigRNotOnCurve indicates that the calculated or given point R for some
// signature was not on the curve.
ErrSigRNotOnCurve
// ErrUnequalRValues indicates that the calculated point R for some
// signature was not the same as the given R value for the signature.
ErrUnequalRValues
// ErrSigTooShort is returned when a signature that should be a Schnorr
// signature is too short.
ErrSigTooShort
// ErrSigTooLong is returned when a signature that should be a Schnorr
// signature is too long.
ErrSigTooLong
// ErrSigRTooBig is returned when a signature has r with a value that is
// greater than or equal to the prime of the field underlying the group.
ErrSigRTooBig
// ErrSigSTooBig is returned when a signature has s with a value that is
// greater than or equal to the group order.
ErrSigSTooBig
// numErrorCodes is the maximum error code number used in tests. This entry
// MUST be the last entry in the enum.
numErrorCodes
)
// Map of ErrorCode values back to their constant names for pretty printing.
var errorCodeStrings = map[ErrorCode]string{
ErrInvalidHashLen: "ErrInvalidHashLen",
ErrPrivateKeyIsZero: "ErrPrivateKeyIsZero",
ErrSchnorrHashValue: "ErrSchnorrHashValue",
ErrPubKeyNotOnCurve: "ErrPubKeyNotOnCurve",
ErrSigRYIsOdd: "ErrSigRYIsOdd",
ErrSigRNotOnCurve: "ErrSigRNotOnCurve",
ErrUnequalRValues: "ErrUnequalRValues",
ErrSigTooShort: "ErrSigTooShort",
ErrSigTooLong: "ErrSigTooLong",
ErrSigRTooBig: "ErrSigRTooBig",
ErrSigSTooBig: "ErrSigSTooBig",
}
// String returns the ErrorCode as a human-readable name.
func (e ErrorCode) String() string {
if s := errorCodeStrings[e]; s != "" {
return s
}
return fmt.Sprintf("Unknown ErrorCode (%d)", int(e))
}
// Error implements the error interface.
func (e ErrorCode) Error() string {
return e.String()
}
// Is implements the interface to work with the standard library's errors.Is.
//
// It returns true in the following cases:
// - The target is an Error and the error codes match
// - The target is an ErrorCode and the error codes match
func (e ErrorCode) Is(target error) bool {
switch target := target.(type) {
case Error:
return e == target.ErrorCode
case ErrorCode:
return e == target
}
return false
}
// Error identifies a signature-related error. It has full support for
// errors.Is and errors.As, so the caller can ascertain the specific reason for
// the error by checking the underlying error code.
type Error struct {
ErrorCode ErrorCode // Describes the kind of error
Description string // Human readable description of the issue
}
// Error satisfies the error interface and prints human-readable errors.
func (e Error) Error() string {
return e.Description
}
// Is implements the interface to work with the standard library's errors.Is.
//
// It returns true in the following cases:
// - The target is an Error and the error codes match
// - The target is an ErrorCode and the error codes match
func (e Error) Is(target error) bool {
switch target := target.(type) {
case Error:
return e.ErrorCode == target.ErrorCode
case ErrorCode:
return target == e.ErrorCode
}
return false
}
// Unwrap returns the underlying wrapped error code.
func (e Error) Unwrap() error {
return e.ErrorCode
}
// signatureError creates an Error given a set of arguments.
func signatureError(c ErrorCode, desc string) Error {
return Error{ErrorCode: c, Description: desc}
}