]>
Commit | Line | Data |
---|---|---|
71712b27 | 1 | /********************************************************************** |
fea19e7b | 2 | * Copyright (c) 2013-2015 Pieter Wuille * |
71712b27 GM |
3 | * Distributed under the MIT software license, see the accompanying * |
4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* | |
5 | **********************************************************************/ | |
6 | ||
0a433ea2 | 7 | |
7a4b7691 PW |
8 | #ifndef _SECP256K1_ECDSA_IMPL_H_ |
9 | #define _SECP256K1_ECDSA_IMPL_H_ | |
10 | ||
f24041d6 | 11 | #include "scalar.h" |
11ab5622 PW |
12 | #include "field.h" |
13 | #include "group.h" | |
14 | #include "ecmult.h" | |
949c1ebb | 15 | #include "ecmult_gen.h" |
11ab5622 | 16 | #include "ecdsa.h" |
607884fc | 17 | |
6efd6e77 GM |
18 | /** Group order for secp256k1 defined as 'n' in "Standards for Efficient Cryptography" (SEC2) 2.7.1 |
19 | * sage: for t in xrange(1023, -1, -1): | |
20 | * .. p = 2**256 - 2**32 - t | |
21 | * .. if p.is_prime(): | |
22 | * .. print '%x'%p | |
23 | * .. break | |
24 | * 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f' | |
25 | * sage: a = 0 | |
26 | * sage: b = 7 | |
27 | * sage: F = FiniteField (p) | |
28 | * sage: '%x' % (EllipticCurve ([F (a), F (b)]).order()) | |
29 | * 'fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141' | |
30 | */ | |
dd891e0e | 31 | static const secp256k1_fe secp256k1_ecdsa_const_order_as_fe = SECP256K1_FE_CONST( |
4732d260 PW |
32 | 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFEUL, |
33 | 0xBAAEDCE6UL, 0xAF48A03BUL, 0xBFD25E8CUL, 0xD0364141UL | |
34 | ); | |
f24041d6 | 35 | |
6efd6e77 GM |
36 | /** Difference between field and order, values 'p' and 'n' values defined in |
37 | * "Standards for Efficient Cryptography" (SEC2) 2.7.1. | |
38 | * sage: p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F | |
39 | * sage: a = 0 | |
40 | * sage: b = 7 | |
41 | * sage: F = FiniteField (p) | |
42 | * sage: '%x' % (p - EllipticCurve ([F (a), F (b)]).order()) | |
43 | * '14551231950b75fc4402da1722fc9baee' | |
44 | */ | |
dd891e0e | 45 | static const secp256k1_fe secp256k1_ecdsa_const_p_minus_order = SECP256K1_FE_CONST( |
4732d260 PW |
46 | 0, 0, 0, 1, 0x45512319UL, 0x50B75FC4UL, 0x402DA172UL, 0x2FC9BAEEUL |
47 | ); | |
f24041d6 | 48 | |
3bb9c447 PW |
49 | static int secp256k1_der_read_len(const unsigned char **sigp, const unsigned char *sigend) { |
50 | int lenleft, b1; | |
51 | size_t ret = 0; | |
52 | if (*sigp >= sigend) { | |
53 | return -1; | |
26320197 | 54 | } |
3bb9c447 PW |
55 | b1 = *((*sigp)++); |
56 | if (b1 == 0xFF) { | |
57 | /* X.690-0207 8.1.3.5.c the value 0xFF shall not be used. */ | |
58 | return -1; | |
26320197 | 59 | } |
3bb9c447 PW |
60 | if ((b1 & 0x80) == 0) { |
61 | /* X.690-0207 8.1.3.4 short form length octets */ | |
62 | return b1; | |
26320197 | 63 | } |
3bb9c447 PW |
64 | if (b1 == 0x80) { |
65 | /* Indefinite length is not allowed in DER. */ | |
66 | return -1; | |
67 | } | |
68 | /* X.690-207 8.1.3.5 long form length octets */ | |
69 | lenleft = b1 & 0x7F; | |
70 | if (lenleft > sigend - *sigp) { | |
71 | return -1; | |
72 | } | |
73 | if (**sigp == 0) { | |
74 | /* Not the shortest possible length encoding. */ | |
75 | return -1; | |
76 | } | |
77 | if ((size_t)lenleft > sizeof(size_t)) { | |
78 | /* The resulthing length would exceed the range of a size_t, so | |
79 | certainly longer than the passed array size. */ | |
80 | return -1; | |
26320197 | 81 | } |
3bb9c447 PW |
82 | while (lenleft > 0) { |
83 | if ((ret >> ((sizeof(size_t) - 1) * 8)) != 0) { | |
84 | } | |
85 | ret = (ret << 8) | **sigp; | |
86 | if (ret + lenleft > (size_t)(sigend - *sigp)) { | |
87 | /* Result exceeds the length of the passed array. */ | |
88 | return -1; | |
89 | } | |
90 | (*sigp)++; | |
91 | lenleft--; | |
92 | } | |
93 | if (ret < 128) { | |
94 | /* Not the shortest possible length encoding. */ | |
95 | return -1; | |
96 | } | |
97 | return ret; | |
98 | } | |
99 | ||
100 | static int secp256k1_der_parse_integer(secp256k1_scalar *r, const unsigned char **sig, const unsigned char *sigend) { | |
101 | int overflow = 0; | |
102 | unsigned char ra[32] = {0}; | |
103 | int rlen; | |
104 | ||
105 | if (*sig == sigend || **sig != 0x02) { | |
106 | /* Not a primitive integer (X.690-0207 8.3.1). */ | |
26320197 GM |
107 | return 0; |
108 | } | |
3bb9c447 PW |
109 | (*sig)++; |
110 | rlen = secp256k1_der_read_len(sig, sigend); | |
111 | if (rlen <= 0 || (*sig) + rlen > sigend) { | |
112 | /* Exceeds bounds or not at least length 1 (X.690-0207 8.3.1). */ | |
26320197 GM |
113 | return 0; |
114 | } | |
3bb9c447 PW |
115 | if (**sig == 0x00 && rlen > 1 && (((*sig)[1]) & 0x80) == 0x00) { |
116 | /* Excessive 0x00 padding. */ | |
26320197 GM |
117 | return 0; |
118 | } | |
3bb9c447 PW |
119 | if (**sig == 0xFF && rlen > 1 && (((*sig)[1]) & 0x80) == 0x80) { |
120 | /* Excessive 0xFF padding. */ | |
26320197 GM |
121 | return 0; |
122 | } | |
3bb9c447 PW |
123 | if ((**sig & 0x80) == 0x80) { |
124 | /* Negative. */ | |
125 | overflow = 1; | |
126 | } | |
127 | while (rlen > 0 && **sig == 0) { | |
128 | /* Skip leading zero bytes */ | |
129 | rlen--; | |
130 | (*sig)++; | |
131 | } | |
132 | if (rlen > 32) { | |
133 | overflow = 1; | |
f24041d6 | 134 | } |
3bb9c447 PW |
135 | if (!overflow) { |
136 | memcpy(ra + 32 - rlen, *sig, rlen); | |
137 | secp256k1_scalar_set_b32(r, ra, &overflow); | |
138 | } | |
139 | if (overflow) { | |
140 | secp256k1_scalar_set_int(r, 0); | |
141 | } | |
142 | (*sig) += rlen; | |
143 | return 1; | |
144 | } | |
145 | ||
146 | static int secp256k1_ecdsa_sig_parse(secp256k1_scalar *rr, secp256k1_scalar *rs, const unsigned char *sig, size_t size) { | |
147 | const unsigned char *sigend = sig + size; | |
148 | int rlen; | |
149 | if (sig == sigend || *(sig++) != 0x30) { | |
150 | /* The encoding doesn't start with a constructed sequence (X.690-0207 8.9.1). */ | |
26320197 GM |
151 | return 0; |
152 | } | |
3bb9c447 PW |
153 | rlen = secp256k1_der_read_len(&sig, sigend); |
154 | if (rlen < 0 || sig + rlen > sigend) { | |
155 | /* Tuple exceeds bounds */ | |
156 | return 0; | |
f24041d6 | 157 | } |
3bb9c447 PW |
158 | if (sig + rlen != sigend) { |
159 | /* Garbage after tuple. */ | |
26320197 GM |
160 | return 0; |
161 | } | |
3bb9c447 PW |
162 | |
163 | if (!secp256k1_der_parse_integer(rr, &sig, sigend)) { | |
26320197 GM |
164 | return 0; |
165 | } | |
3bb9c447 | 166 | if (!secp256k1_der_parse_integer(rs, &sig, sigend)) { |
26320197 GM |
167 | return 0; |
168 | } | |
3bb9c447 PW |
169 | |
170 | if (sig != sigend) { | |
171 | /* Trailing garbage inside tuple. */ | |
172 | return 0; | |
173 | } | |
174 | ||
d41e93a5 | 175 | return 1; |
607884fc PW |
176 | } |
177 | ||
dd891e0e | 178 | static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, size_t *size, const secp256k1_scalar* ar, const secp256k1_scalar* as) { |
f24041d6 | 179 | unsigned char r[33] = {0}, s[33] = {0}; |
f24041d6 | 180 | unsigned char *rp = r, *sp = s; |
788038d3 | 181 | size_t lenR = 33, lenS = 33; |
18c329c5 PW |
182 | secp256k1_scalar_get_b32(&r[1], ar); |
183 | secp256k1_scalar_get_b32(&s[1], as); | |
f24041d6 PW |
184 | while (lenR > 1 && rp[0] == 0 && rp[1] < 0x80) { lenR--; rp++; } |
185 | while (lenS > 1 && sp[0] == 0 && sp[1] < 0x80) { lenS--; sp++; } | |
26320197 | 186 | if (*size < 6+lenS+lenR) { |
74a2acdb | 187 | *size = 6 + lenS + lenR; |
d41e93a5 | 188 | return 0; |
26320197 | 189 | } |
0a07e62f PW |
190 | *size = 6 + lenS + lenR; |
191 | sig[0] = 0x30; | |
192 | sig[1] = 4 + lenS + lenR; | |
193 | sig[2] = 0x02; | |
194 | sig[3] = lenR; | |
f24041d6 | 195 | memcpy(sig+4, rp, lenR); |
0a07e62f PW |
196 | sig[4+lenR] = 0x02; |
197 | sig[5+lenR] = lenS; | |
f24041d6 | 198 | memcpy(sig+lenR+6, sp, lenS); |
d41e93a5 | 199 | return 1; |
0a07e62f PW |
200 | } |
201 | ||
dd891e0e | 202 | static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context *ctx, const secp256k1_scalar *sigr, const secp256k1_scalar *sigs, const secp256k1_ge *pubkey, const secp256k1_scalar *message) { |
792bcdb0 | 203 | unsigned char c[32]; |
dd891e0e PW |
204 | secp256k1_scalar sn, u1, u2; |
205 | secp256k1_fe xr; | |
206 | secp256k1_gej pubkeyj; | |
207 | secp256k1_gej pr; | |
792bcdb0 | 208 | |
18c329c5 | 209 | if (secp256k1_scalar_is_zero(sigr) || secp256k1_scalar_is_zero(sigs)) { |
d41e93a5 | 210 | return 0; |
26320197 | 211 | } |
607884fc | 212 | |
18c329c5 | 213 | secp256k1_scalar_inverse_var(&sn, sigs); |
f24041d6 | 214 | secp256k1_scalar_mul(&u1, &sn, message); |
18c329c5 | 215 | secp256k1_scalar_mul(&u2, &sn, sigr); |
792bcdb0 | 216 | secp256k1_gej_set_ge(&pubkeyj, pubkey); |
a9b6595e | 217 | secp256k1_ecmult(ctx, &pr, &pubkeyj, &u2, &u1); |
ce7eb6fb PW |
218 | if (secp256k1_gej_is_infinity(&pr)) { |
219 | return 0; | |
220 | } | |
18c329c5 | 221 | secp256k1_scalar_get_b32(c, sigr); |
ce7eb6fb | 222 | secp256k1_fe_set_b32(&xr, c); |
13278f64 | 223 | |
3627437d GM |
224 | /** We now have the recomputed R point in pr, and its claimed x coordinate (modulo n) |
225 | * in xr. Naively, we would extract the x coordinate from pr (requiring a inversion modulo p), | |
226 | * compute the remainder modulo n, and compare it to xr. However: | |
227 | * | |
228 | * xr == X(pr) mod n | |
229 | * <=> exists h. (xr + h * n < p && xr + h * n == X(pr)) | |
230 | * [Since 2 * n > p, h can only be 0 or 1] | |
231 | * <=> (xr == X(pr)) || (xr + n < p && xr + n == X(pr)) | |
232 | * [In Jacobian coordinates, X(pr) is pr.x / pr.z^2 mod p] | |
233 | * <=> (xr == pr.x / pr.z^2 mod p) || (xr + n < p && xr + n == pr.x / pr.z^2 mod p) | |
234 | * [Multiplying both sides of the equations by pr.z^2 mod p] | |
235 | * <=> (xr * pr.z^2 mod p == pr.x) || (xr + n < p && (xr + n) * pr.z^2 mod p == pr.x) | |
236 | * | |
237 | * Thus, we can avoid the inversion, but we have to check both cases separately. | |
238 | * secp256k1_gej_eq_x implements the (xr * pr.z^2 mod p == pr.x) test. | |
239 | */ | |
ce7eb6fb | 240 | if (secp256k1_gej_eq_x_var(&xr, &pr)) { |
6c476a8a | 241 | /* xr * pr.z^2 mod p == pr.x, so the signature is valid. */ |
ce7eb6fb PW |
242 | return 1; |
243 | } | |
4732d260 | 244 | if (secp256k1_fe_cmp_var(&xr, &secp256k1_ecdsa_const_p_minus_order) >= 0) { |
6c476a8a | 245 | /* xr + n >= p, so we can skip testing the second case. */ |
ce7eb6fb | 246 | return 0; |
4adf6b2a | 247 | } |
4732d260 | 248 | secp256k1_fe_add(&xr, &secp256k1_ecdsa_const_order_as_fe); |
ce7eb6fb | 249 | if (secp256k1_gej_eq_x_var(&xr, &pr)) { |
3627437d | 250 | /* (xr + n) * pr.z^2 mod p == pr.x, so the signature is valid. */ |
ce7eb6fb PW |
251 | return 1; |
252 | } | |
253 | return 0; | |
607884fc PW |
254 | } |
255 | ||
dd891e0e | 256 | static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context *ctx, secp256k1_scalar *sigr, secp256k1_scalar *sigs, const secp256k1_scalar *seckey, const secp256k1_scalar *message, const secp256k1_scalar *nonce, int *recid) { |
792bcdb0 | 257 | unsigned char b[32]; |
dd891e0e PW |
258 | secp256k1_gej rp; |
259 | secp256k1_ge r; | |
260 | secp256k1_scalar n; | |
792bcdb0 GM |
261 | int overflow = 0; |
262 | ||
a9b6595e | 263 | secp256k1_ecmult_gen(ctx, &rp, nonce); |
50eb498e | 264 | secp256k1_ge_set_gej(&r, &rp); |
50eb498e PW |
265 | secp256k1_fe_normalize(&r.x); |
266 | secp256k1_fe_normalize(&r.y); | |
267 | secp256k1_fe_get_b32(b, &r.x); | |
18c329c5 PW |
268 | secp256k1_scalar_set_b32(sigr, b, &overflow); |
269 | if (secp256k1_scalar_is_zero(sigr)) { | |
d26e26f2 | 270 | /* P.x = order is on the curve, so technically sig->r could end up zero, which would be an invalid signature. */ |
6c476a8a | 271 | /* This branch is cryptographically unreachable as hitting it requires finding the discrete log of P.x = N. */ |
d26e26f2 GM |
272 | secp256k1_gej_clear(&rp); |
273 | secp256k1_ge_clear(&r); | |
274 | return 0; | |
275 | } | |
26320197 | 276 | if (recid) { |
a9f5c8b8 | 277 | *recid = (overflow ? 2 : 0) | (secp256k1_fe_is_odd(&r.y) ? 1 : 0); |
26320197 | 278 | } |
18c329c5 | 279 | secp256k1_scalar_mul(&n, sigr, seckey); |
a9f5c8b8 | 280 | secp256k1_scalar_add(&n, &n, message); |
18c329c5 PW |
281 | secp256k1_scalar_inverse(sigs, nonce); |
282 | secp256k1_scalar_mul(sigs, sigs, &n); | |
a9f5c8b8 | 283 | secp256k1_scalar_clear(&n); |
2f6c8019 GM |
284 | secp256k1_gej_clear(&rp); |
285 | secp256k1_ge_clear(&r); | |
18c329c5 | 286 | if (secp256k1_scalar_is_zero(sigs)) { |
d41e93a5 | 287 | return 0; |
26320197 | 288 | } |
18c329c5 PW |
289 | if (secp256k1_scalar_is_high(sigs)) { |
290 | secp256k1_scalar_negate(sigs, sigs); | |
26320197 | 291 | if (recid) { |
50eb498e | 292 | *recid ^= 1; |
26320197 | 293 | } |
50eb498e | 294 | } |
eb0be8ee | 295 | return 1; |
0a07e62f PW |
296 | } |
297 | ||
7a4b7691 | 298 | #endif |