31 static cx_err_t truernd(
uint8_t *rnd, cx_curve_t cv)
34 uint8_t domain_order[CX_ECDSA_MAX_ORDER_LEN];
38 CX_CHECK(cx_ecdomain_parameters_length(cv, &domain_length));
39 CX_CHECK(cx_ecdomain_parameter(cv, CX_CURVE_PARAM_Order, domain_order,
sizeof(domain_order)));
41 CX_CHECK(cx_bn_lock(domain_length, 0));
42 CX_CHECK(cx_bn_alloc(&r, domain_length));
43 CX_CHECK(cx_bn_alloc(&t, 2 * domain_length));
44 CX_CHECK(cx_bn_alloc_init(&n, domain_length, domain_order, domain_length));
45 CX_CHECK(cx_bn_rand(t));
46 CX_CHECK(cx_bn_reduce(r, t, n));
47 CX_CHECK(cx_bn_export(r, rnd, domain_length));
53 static cx_err_t rfcrnd(
uint8_t *rnd,
56 const cx_ecfp_private_key_t *key,
61 uint8_t domain_order[CX_ECDSA_MAX_ORDER_LEN];
65 CX_CHECK(cx_ecdomain_parameters_length(cv, &domain_length));
66 CX_CHECK(cx_ecdomain_parameter(cv, CX_CURVE_PARAM_Order, domain_order,
sizeof(domain_order)));
68 CX_CHECK(cx_rng_rfc6979_init(&
G_cx.rfc6979,
77 for (uint32_t i = 0; i < skip; i++) {
78 CX_CHECK(cx_rng_rfc6979_next(&
G_cx.rfc6979, rnd, domain_length));
90 static cx_err_t initialize_hash(
const uint8_t *hash,
92 size_t domain_bit_length,
101 CX_CHECK(cx_bn_init(v, hash,
MIN(hash_length, domain_length)));
103 if (domain_bit_length < hash_length * 8) {
105 if (domain_bit_length % 8) {
106 CX_CHECK(cx_bn_shr(v, 8 - (domain_bit_length % 8)));
117 cx_err_t cx_ecdsa_sign_no_throw(
const cx_ecfp_private_key_t *key,
126 #ifndef HAVE_RNG_RFC6979
130 #define CX_MAX_TRIES 100
133 uint32_t
volatile out_sig_len = 0;
134 size_t domain_length;
135 size_t domain_bit_length;
141 uint8_t _rnd[CX_ECDSA_MAX_ORDER_LEN];
143 cx_bn_t _n, _t, _t1, _t2, _v;
145 uint8_t _rs[CX_ECDSA_MAX_ORDER_LEN * 2];
147 #define tries u._tries
158 CX_CHECK(cx_ecdomain_parameters_length(key->curve, &domain_length));
159 CX_CHECK(cx_ecdomain_size(key->curve, &domain_bit_length));
161 if (!CX_CURVE_RANGE(key->curve, WEIERSTRASS) || *sig_len < 6 + 2 * (domain_length + 1)
162 || key->d_len != domain_length) {
163 error = CX_INVALID_PARAMETER;
171 out_sig_len = *sig_len;
176 if (tries == CX_MAX_TRIES) {
178 error = CX_INTERNAL_ERROR;
184 error = CX_INVALID_PARAMETER;
190 error = CX_INTERNAL_ERROR;
193 memmove(rnd, sig, domain_length);
197 CX_CHECK(truernd(rnd, key->curve));
200 #ifdef HAVE_RNG_RFC6979
209 rfcrnd(rnd, tries, key->curve, key, hashID, hash,
MIN(hash_len, domain_length)));
216 CX_CHECK(cx_bn_lock(domain_length, 0));
219 CX_CHECK(cx_ecpoint_alloc(&Q, key->curve));
220 CX_CHECK(cx_ecdomain_generator_bn(key->curve, &Q));
222 #ifdef HAVE_FIXED_SCALAR_LENGTH
225 CX_CHECK(cx_ecpoint_rnd_fixed_scalarmul(&Q, rnd, domain_length));
227 CX_CHECK(cx_ecpoint_rnd_scalarmul(&Q, rnd, domain_length));
231 CX_CHECK(cx_bn_is_odd(Q.y, &odd));
234 CX_CHECK(cx_bn_alloc(&n, domain_length));
235 CX_CHECK(cx_ecdomain_parameter_bn(key->curve, CX_CURVE_PARAM_Order, n));
238 CX_CHECK(cx_bn_alloc(&r, domain_length));
239 CX_CHECK(cx_ecpoint_export_bn(&Q, &r, NULL));
240 CX_CHECK(cx_ecpoint_destroy(&Q));
241 CX_CHECK(cx_bn_cmp(r, n, &diff));
243 CX_CHECK_IGNORE_CARRY(cx_bn_sub(r, r, n));
245 *info |= CX_ECCINFO_xGTn;
250 CX_CHECK(cx_bn_cmp_u32(r, 0, &diff));
256 CX_CHECK(cx_bn_alloc(&s, domain_length));
257 CX_CHECK(cx_bn_alloc(&t, domain_length));
258 CX_CHECK(cx_bn_alloc(&v, domain_length));
259 CX_CHECK(cx_bn_alloc(&t1, domain_length));
260 CX_CHECK(cx_bn_alloc(&t2, domain_length));
270 CX_CHECK(cx_bn_rng(t, n));
271 CX_CHECK(cx_bn_init(t1, key->d, key->d_len));
272 CX_CHECK(cx_bn_mod_sub(v, t1, t, n));
273 CX_CHECK(cx_bn_mod_mul(t2, v, r, n));
274 CX_CHECK(cx_bn_mod_mul(t1, t, r, n));
276 CX_CHECK(initialize_hash(hash, v, domain_bit_length, hash_len, domain_length));
278 CX_CHECK(cx_bn_mod_add(v, v, t1, n));
279 CX_CHECK(cx_bn_mod_add(v, v, t2, n));
280 CX_CHECK(cx_bn_init(t1, rnd, domain_length));
281 CX_CHECK(cx_bn_mod_invert_nprime(t2, t1, n));
282 CX_CHECK(cx_bn_mod_mul(s, v, t2, n));
284 CX_CHECK(cx_bn_cmp_u32(s, 0, &diff));
292 CX_CHECK_IGNORE_CARRY(cx_bn_sub(t1, n, s));
293 CX_CHECK(cx_bn_shr(n, 1));
294 CX_CHECK(cx_bn_cmp(s, n, &diff));
296 CX_CHECK(cx_bn_copy(s, t1));
303 CX_CHECK(cx_bn_export(r, rs, domain_length));
304 CX_CHECK(cx_bn_export(s, rs + domain_length, domain_length));
309 out_sig_len = cx_ecfp_encode_sig_der(
310 sig, out_sig_len, rs, domain_length, rs + domain_length, domain_length);
312 *info |= odd ? CX_ECCINFO_PARITY_ODD : 0;
316 *sig_len = out_sig_len;
335 bool cx_ecdsa_verify_no_throw(
const cx_ecfp_public_key_t *key,
342 size_t domain_length, domain_bit_length;
343 cx_bn_t c, n, r, s, u1, u2, h;
344 cx_ecpoint_t R, Q, G;
351 CX_CHECK(cx_ecdomain_parameters_length(key->curve, &domain_length));
352 CX_CHECK(cx_ecdomain_size(key->curve, &domain_bit_length));
354 if (!CX_CURVE_RANGE(key->curve, WEIERSTRASS) || key->W_len != 1 + 2 * domain_length) {
355 error = CX_INVALID_PARAMETER;
361 if (hash_len > (8 + 2 * domain_length)) {
362 error = CX_INVALID_PARAMETER;
367 size_t sig_rlen, sig_slen;
370 if (!cx_ecfp_decode_sig_der(
371 sig, sig_len, domain_length, &sig_r, &sig_rlen, &sig_s, &sig_slen)) {
372 error = CX_INVALID_PARAMETER;
377 CX_CHECK(cx_bn_lock(domain_length, 0));
378 CX_CHECK(cx_bn_alloc(&n, domain_length));
379 CX_CHECK(cx_ecdomain_parameter_bn(key->curve, CX_CURVE_PARAM_Order, n));
380 CX_CHECK(cx_bn_alloc_init(&r, domain_length, sig_r, sig_rlen));
381 CX_CHECK(cx_bn_alloc_init(&s, domain_length, sig_s, sig_slen));
382 CX_CHECK(cx_bn_alloc(&h, domain_length));
383 CX_CHECK(initialize_hash(hash, h, domain_bit_length, hash_len, domain_length));
384 CX_CHECK(cx_bn_alloc(&u1, domain_length));
385 CX_CHECK(cx_bn_alloc(&u2, domain_length));
386 CX_CHECK(cx_bn_alloc(&c, domain_length));
389 CX_CHECK(cx_bn_set_u32(u2, 0));
390 CX_CHECK(cx_bn_cmp(r, u2, &diff));
394 CX_CHECK(cx_bn_cmp(r, n, &diff));
398 CX_CHECK(cx_bn_cmp(s, u2, &diff));
402 CX_CHECK(cx_bn_cmp(s, n, &diff));
409 CX_CHECK(cx_bn_mod_invert_nprime(c, s, n));
411 CX_CHECK(cx_bn_mod_mul(u1, h, c, n));
413 CX_CHECK(cx_bn_mod_mul(u2, r, c, n));
415 CX_CHECK(cx_bn_destroy(&h));
416 CX_CHECK(cx_bn_destroy(&c));
417 CX_CHECK(cx_bn_destroy(&s));
418 CX_CHECK(cx_ecpoint_alloc(&G, key->curve));
419 CX_CHECK(cx_ecdomain_generator_bn(key->curve, &G));
420 CX_CHECK(cx_ecpoint_alloc(&Q, key->curve));
422 cx_ecpoint_init(&Q, &key->W[1], domain_length, &key->W[1 + domain_length], domain_length));
424 CX_CHECK(cx_ecpoint_alloc(&R, key->curve));
427 CX_CHECK(cx_ecpoint_double_scalarmul_bn(&R, &G, &Q, u1, u2));
430 CX_CHECK(cx_ecpoint_is_at_infinity(&R, &is_infinite));
435 CX_CHECK(cx_ecpoint_export_bn(&R, &u1, NULL));
436 CX_CHECK(cx_bn_reduce(u2, u1, n));
438 CX_CHECK(cx_bn_cmp(u2, r, &diff));
447 return (error == CX_OK) && verified;