-
Notifications
You must be signed in to change notification settings - Fork 372
/
secp256k1.hpp
226 lines (169 loc) · 8.03 KB
/
secp256k1.hpp
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
/**
* Copyright (c) 2011-2022 libbitcoin developers (see AUTHORS)
*
* This file is part of libbitcoin.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef LIBBITCOIN_SYSTEM_CRYPTO_SECP256K1_HPP
#define LIBBITCOIN_SYSTEM_CRYPTO_SECP256K1_HPP
#include <bitcoin/system/data/data.hpp>
#include <bitcoin/system/define.hpp>
#include <bitcoin/system/hash/hash.hpp>
#include <bitcoin/system/radix/radix.hpp>
namespace libbitcoin {
namespace system {
/// The sign byte value for an even (y-valued) key.
static constexpr uint8_t ec_even_sign = 2;
/// Private key:
static constexpr size_t ec_secret_size = 32;
typedef data_array<ec_secret_size> ec_secret;
typedef std::vector<ec_secret> secret_list;
/// Compressed public key:
static constexpr size_t ec_compressed_size = 33;
typedef data_array<ec_compressed_size> ec_compressed;
typedef std::vector<ec_compressed> compressed_list;
/// Uncompressed public key:
static constexpr size_t ec_uncompressed_size = 65;
typedef data_array<ec_uncompressed_size> ec_uncompressed;
typedef std::vector<ec_uncompressed> uncompressed_list;
// Parsed ECDSA signature:
static constexpr size_t ec_signature_size = 64;
typedef data_array<ec_signature_size> ec_signature;
// DER encoded signature:
static constexpr size_t max_der_signature_size = 72;
typedef data_chunk der_signature;
/// DER encoded signature with sighash byte for contract endorsement:
static constexpr size_t min_endorsement_size = 9;
static constexpr size_t max_endorsement_size = 73;
typedef data_chunk endorsement;
typedef std::vector<endorsement> endorsements;
// secg.org/sec2-v2.pdf
constexpr ec_compressed ec_compressed_generator = base16_array("02"
"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798");
// secg.org/sec2-v2.pdf
constexpr ec_uncompressed ec_uncompressed_generator = base16_array("04"
"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"
"483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8");
constexpr ec_compressed null_ec_compressed = base16_array("00"
"0000000000000000000000000000000000000000000000000000000000000000");
constexpr ec_uncompressed null_ec_uncompressed = base16_array("00"
"0000000000000000000000000000000000000000000000000000000000000000"
"0000000000000000000000000000000000000000000000000000000000000000");
/// Recoverable ecdsa signature for message signing.
struct BC_API recoverable_signature
{
ec_signature signature;
uint8_t recovery_id;
};
// Add EC values
// ----------------------------------------------------------------------------
/// Compute the sum a += G * b.
BC_API bool ec_add(ec_compressed& point, const ec_secret& scalar) NOEXCEPT;
/// Compute the sum a += G * b.
BC_API bool ec_add(ec_uncompressed& point, const ec_secret& scalar) NOEXCEPT;
/// Compute the sum a = (a + b) % n.
BC_API bool ec_add(ec_secret& left, const ec_secret& right) NOEXCEPT;
/// Compute the sum a += b.
BC_API bool ec_add(ec_compressed& left, const ec_compressed& right) NOEXCEPT;
/// Compute the sum a += b.
BC_API bool ec_add(ec_compressed& left, const ec_uncompressed& right) NOEXCEPT;
/// Compute the sum of compressed point values.
BC_API bool ec_sum(ec_compressed& out, const compressed_list& values) NOEXCEPT;
// Multiply EC values
// ----------------------------------------------------------------------------
/// Compute the product point *= secret.
BC_API bool ec_multiply(ec_compressed& point,
const ec_secret& scalar) NOEXCEPT;
/// Compute the product point *= secret.
BC_API bool ec_multiply(ec_uncompressed& point,
const ec_secret& scalar) NOEXCEPT;
/// Compute the product a = (a * b) % n.
BC_API bool ec_multiply(ec_secret& left, const ec_secret& right) NOEXCEPT;
// Negate EC values
// ----------------------------------------------------------------------------
/// Negate scalar.
BC_API bool ec_negate(ec_secret& scalar) NOEXCEPT;
/// Invert point (flip on Y axis).
BC_API bool ec_negate(ec_compressed& point) NOEXCEPT;
/// Invert point (flip on Y axis).
BC_API bool ec_negate(ec_uncompressed& point) NOEXCEPT;
// Convert keys
// ----------------------------------------------------------------------------
/// Convert uncompressed point to compressed.
BC_API bool compress(ec_compressed& out,
const ec_uncompressed& point) NOEXCEPT;
/// Convert compressed point to decompressed.
BC_API bool decompress(ec_uncompressed& out,
const ec_compressed& point) NOEXCEPT;
/// Convert secret to a compressed point.
BC_API bool secret_to_public(ec_compressed& out,
const ec_secret& secret) NOEXCEPT;
/// Convert secret to an uncompressed point.
BC_API bool secret_to_public(ec_uncompressed& out,
const ec_secret& secret) NOEXCEPT;
// Verify keys
// ----------------------------------------------------------------------------
/// Verify secret.
BC_API bool verify(const ec_secret& secret) NOEXCEPT;
/// Verify point.
BC_API bool verify(const data_slice& point) NOEXCEPT;
// Detect public keys
// ----------------------------------------------------------------------------
/// Determine if the compressed public key is even (y-valued).
BC_API bool is_even_key(const ec_compressed& point) NOEXCEPT;
/// Fast detection of compressed public key structure.
BC_API bool is_compressed_key(const data_slice& point) NOEXCEPT;
/// Fast detection of uncompressed public key structure.
BC_API bool is_uncompressed_key(const data_slice& point) NOEXCEPT;
/// Fast detection of compressed or uncompressed public key structure.
BC_API bool is_public_key(const data_slice& point) NOEXCEPT;
/// Fast detection of endorsement structure (DER with signature hash type).
BC_API bool is_endorsement(const endorsement& endorsement) NOEXCEPT;
// DER parse/encode
// ----------------------------------------------------------------------------
/// Parse an endorsement into signature hash type and DER signature.
BC_API bool parse_endorsement(uint8_t& sighash_flags, data_slice& der_signature,
const endorsement& endorsement) NOEXCEPT;
/// Parse a DER encoded signature with optional strict DER enforcement.
/// Treat an empty DER signature as invalid, in accordance with BIP66.
BC_API bool parse_signature(ec_signature& out, const data_slice& der_signature,
bool strict) NOEXCEPT;
/// Encode an EC signature as DER (strict).
BC_API bool encode_signature(der_signature& out,
const ec_signature& signature) NOEXCEPT;
// EC sign/verify
// ----------------------------------------------------------------------------
/// Create a deterministic ECDSA signature using a private key.
BC_API bool sign(ec_signature& out, const ec_secret& secret,
const hash_digest& hash) NOEXCEPT;
/// Verify an EC signature using a potential point.
BC_API bool verify_signature(const data_slice& point, const hash_digest& hash,
const ec_signature& signature) NOEXCEPT;
// Recoverable sign/recover
// ----------------------------------------------------------------------------
/// Create a recoverable signature for use in message signing.
BC_API bool sign_recoverable(recoverable_signature& out,
const ec_secret& secret, const hash_digest& hash) NOEXCEPT;
/// Recover the compressed point from a recoverable message signature.
BC_API bool recover_public(ec_compressed& out,
const recoverable_signature& recoverable,
const hash_digest& hash) NOEXCEPT;
/// Recover the uncompressed point from a recoverable message signature.
BC_API bool recover_public(ec_uncompressed& out,
const recoverable_signature& recoverable,
const hash_digest& hash) NOEXCEPT;
} // namespace system
} // namespace libbitcoin
#endif