29#if defined(BOLOS_RELEASE) && defined(HAVE_ECC_WITH_NO_RANDOMIZE)
30#error HAVE_ECC_WITH_NO_RANDOMIZE not allowed for release
42cx_err_t cx_ecfp_init_private_key_no_throw(cx_curve_t curve,
43 const uint8_t *raw_key,
45 cx_ecfp_private_key_t *key)
50 CX_CHECK(cx_ecdomain_parameters_length(curve, &domain_length));
52 if (!(((raw_key == NULL) && (key_len == 0)) || ((raw_key) && (key_len == domain_length)))) {
53 error = CX_INVALID_PARAMETER;
59 memmove(key->d, raw_key, key_len);
71cx_err_t cx_ecfp_init_public_key_no_throw(cx_curve_t curve,
72 const uint8_t *rawkey,
74 cx_ecfp_public_key_t *key)
76 size_t expected_key_len;
77 size_t expected_compressed_key_len;
81 error = cx_ecdomain_parameters_length(curve, &size);
88 memset(key, 0,
sizeof(cx_ecfp_public_key_t));
93 expected_compressed_key_len = 0;
96#ifdef HAVE_ECC_WEIERSTRASS
97 if (CX_CURVE_RANGE(curve, WEIERSTRASS)) {
98 expected_key_len = 1 + (size) *2;
102#ifdef HAVE_ECC_TWISTED_EDWARDS
103 if (CX_CURVE_RANGE(curve, TWISTED_EDWARDS)) {
104 expected_key_len = 1 + (size) *2;
105 expected_compressed_key_len = 1 + (size);
109#ifdef HAVE_ECC_MONTGOMERY
110 if (CX_CURVE_RANGE(curve, MONTGOMERY)) {
111 expected_compressed_key_len = 1 + (size);
116 if ((key_len == expected_key_len) && (rawkey[0] == 0x04)) {
119 if ((key_len == expected_compressed_key_len) && (rawkey[0] == 0x02)) {
123 return INVALID_PARAMETER;
132 key->W_len = key_len;
133 memmove(key->W, rawkey, key_len);
141cx_err_t cx_ecfp_generate_pair_no_throw(cx_curve_t curve,
142 cx_ecfp_public_key_t *public_key,
143 cx_ecfp_private_key_t *private_key,
146 return cx_ecfp_generate_pair2_no_throw(curve, public_key, private_key, keep_private, CX_SHA512);
149cx_err_t cx_ecfp_generate_pair2_no_throw(cx_curve_t curve,
150 cx_ecfp_public_key_t *public_key,
151 cx_ecfp_private_key_t *private_key,
161#ifndef HAVE_ECC_TWISTED_EDWARDS
165 CX_CHECK(cx_ecdomain_parameters_length(curve, &size));
169 CX_CHECK(cx_bn_lock(size, 0));
170 CX_CHECK(cx_bn_alloc(&n, size));
171 CX_CHECK(cx_ecdomain_parameter_bn(curve, CX_CURVE_PARAM_Order, n));
172 CX_CHECK(cx_bn_alloc(&r, size));
177 if ((private_key->curve != curve) || (private_key->d_len != size)) {
178 error = CX_INVALID_PARAMETER;
181 CX_CHECK(cx_bn_init(r, private_key->d, private_key->d_len));
184 CX_CHECK(cx_bn_alloc(&a, 2 * size));
185 CX_CHECK(cx_bn_rand(a));
186 CX_CHECK(cx_bn_reduce(r, a, n));
187 CX_CHECK(cx_bn_destroy(&a));
188 CX_CHECK(cx_bn_export(r, private_key->d, size));
189 private_key->curve = curve;
190 private_key->d_len = size;
192#ifdef HAVE_ECC_MONTGOMERY
193 if (CX_CURVE_RANGE(curve, MONTGOMERY)) {
194 if (curve == CX_CURVE_Curve25519) {
195 private_key->d[size - 1] &= 0xF8;
196 private_key->d[0] = (private_key->d[0] & 0x7F) | 0x40;
199 private_key->d[size - 1] &= 0xFC;
200 private_key->d[0] |= 0x80;
207#ifdef HAVE_ECC_WEIERSTRASS
208 if (CX_CURVE_RANGE(curve, WEIERSTRASS)) {
209 CX_CHECK(cx_ecpoint_alloc(&W, private_key->curve));
210 CX_CHECK(cx_ecdomain_generator_bn(curve, &W));
213 if ((CX_CURVE_BLS12_381_G1 == private_key->curve)
214 || (CX_CURVE_BLS12_377_G1 == private_key->curve)) {
215 CX_CHECK(cx_ecpoint_rnd_scalarmul(&W, private_key->d, private_key->d_len));
218 CX_CHECK(cx_ecpoint_rnd_fixed_scalarmul(&W, private_key->d, private_key->d_len));
220 public_key->curve = curve;
221 public_key->W_len = 1 + 2 * size;
222 public_key->W[0] = 0x04;
223 CX_CHECK(cx_ecpoint_export(&W, &public_key->W[1], size, &public_key->W[1 + size], size));
228#ifdef HAVE_ECC_TWISTED_EDWARDS
229 if (CX_CURVE_RANGE(curve, TWISTED_EDWARDS)) {
232 if ((curve == CX_CURVE_EdBLS12) || (curve == CX_CURVE_JUBJUB)) {
233 CX_CHECK(cx_ecpoint_alloc(&W, private_key->curve));
234 CX_CHECK(cx_ecdomain_generator_bn(curve, &W));
235 CX_CHECK(cx_ecpoint_rnd_scalarmul(&W, private_key->d, private_key->d_len));
236 public_key->curve = curve;
237 public_key->W_len = 1 + 2 * size;
238 public_key->W[0] = 0x04;
240 cx_ecpoint_export(&W, &public_key->W[1], size, &public_key->W[1 + size], size));
243 CX_CHECK(cx_eddsa_get_public_key_internal(
244 private_key, hashID, public_key, NULL, 0, NULL, 0, scal));
250#ifdef HAVE_ECC_MONTGOMERY
251 if (CX_CURVE_RANGE(curve, MONTGOMERY)) {
252 CX_CHECK(cx_ecpoint_alloc(&W, private_key->curve));
253 CX_CHECK(cx_ecdomain_generator_bn(curve, &W));
254 CX_CHECK(cx_ecpoint_rnd_scalarmul(&W, private_key->d, private_key->d_len));
255 public_key->curve = curve;
256 public_key->W_len = 1 + 2 * size;
257 public_key->W[0] = 0x04;
258 CX_CHECK(cx_ecpoint_export(&W, &public_key->W[1], size, &public_key->W[1 + size], size));
263 error = CX_EC_INVALID_POINT;
270cx_err_t cx_ecfp_add_point_no_throw(cx_curve_t curve,
272 const unsigned char *P,
273 const unsigned char *Q)
276 cx_ecpoint_t ecR, ecP, ecQ;
279 CX_CHECK(cx_ecdomain_parameters_length(curve, &size));
280 CX_CHECK(cx_bn_lock(size, 0));
282 CX_CHECK(cx_ecpoint_alloc(&ecP, curve));
283 CX_CHECK(cx_ecpoint_alloc(&ecQ, curve));
284 CX_CHECK(cx_ecpoint_alloc(&ecR, curve));
285 CX_CHECK(cx_ecpoint_init(&ecP, P + 1, size, P + 1 + size, size));
286 CX_CHECK(cx_ecpoint_init(&ecQ, Q + 1, size, Q + 1 + size, size));
287 CX_CHECK(cx_ecpoint_add(&ecR, &ecP, &ecQ));
289 CX_CHECK(cx_ecpoint_export(&ecR, &R[1], size, &R[1 + size], size));
299cx_err_t cx_ecfp_scalar_mult_no_throw(cx_curve_t curve, uint8_t *P,
const uint8_t *k,
size_t k_len)
305 CX_CHECK(cx_ecdomain_parameters_length(curve, &size));
306 CX_CHECK(cx_bn_lock(size, 0));
308 CX_CHECK(cx_ecpoint_alloc(&ecP, curve));
309 CX_CHECK(cx_ecpoint_init(&ecP, P + 1, size, P + 1 + size, size));
310 CX_CHECK(cx_ecpoint_rnd_scalarmul(&ecP, k, k_len));
312 CX_CHECK(cx_ecpoint_export(&ecP, &P[1], size, &P[1 + size], size));
319#ifdef HAVE_ECC_TWISTED_EDWARDS
321cx_err_t cx_edwards_compress_point_no_throw(cx_curve_t curve, uint8_t *P,
size_t P_len)
329 CX_CHECK(cx_ecdomain_parameters_length(curve, &size));
330 CX_CHECK(cx_bn_lock(size, 0));
331 CX_CHECK(cx_ecpoint_alloc(&P_ec, curve));
332 CX_CHECK(cx_ecpoint_init(&P_ec, P + 1, size, P + 1 + size, size));
333 CX_CHECK(cx_ecpoint_compress(&P_ec, P + 1, size, &sign));
334 cx_encode_coord(P + 1, size, sign);
335 memmove(P + 1 + size, P + 1, size);
343cx_err_t cx_edwards_decompress_point_no_throw(cx_curve_t curve, uint8_t *P,
size_t P_len)
351 CX_CHECK(cx_ecdomain_parameters_length(curve, &size));
352 CX_CHECK(cx_bn_lock(size, 0));
353 sign = cx_decode_coord(P + 1, size);
354 CX_CHECK(cx_ecpoint_alloc(&P_ec, curve));
355 memmove(P + 1 + size, P + 1, size);
356 CX_CHECK(cx_ecpoint_decompress(&P_ec, P + 1, size, sign));
357 CX_CHECK(cx_ecpoint_export(&P_ec, P + 1, size, P + 1 + size, size));
367static size_t asn1_get_encoded_length_size(
size_t len)
384static size_t asn1_get_encoded_integer_size(uint8_t
const *val,
size_t len)
388 while (len && (*val == 0)) {
396 else if (*val & 0x80u) {
400 l0 = asn1_get_encoded_length_size(len);
407static int asn1_insert_tag(uint8_t **p,
const uint8_t *end,
unsigned int tag)
409 if ((end - *p) < 1) {
417static int asn1_insert_len(uint8_t **p,
const uint8_t *end,
size_t len)
420 if ((end - *p) < 1) {
423 (*p)[0] = len & 0xFF;
429 if ((end - *p) < 2) {
433 (*p)[1] = len & 0xFF;
439 if ((end - *p) < 3) {
443 (*p)[1] = (len >> 8) & 0xFF;
444 (*p)[2] = len & 0xFF;
452static int asn1_insert_integer(uint8_t **p,
const uint8_t *end,
const uint8_t *val,
size_t len)
454 while (len && (*val == 0)) {
458 if (!asn1_insert_tag(p, end, 0x02)) {
464 if ((end - *p) < 2) {
474 if (!asn1_insert_len(p, end, (*val & 0x80) ? len + 1 : len)) {
479 if ((end - *p) < 1) {
485 if ((end - *p) < (
int) len) {
488 memmove(*p, val, len);
496size_t cx_ecfp_encode_sig_der(uint8_t *sig,
504 const uint8_t *sig_end = sig + sig_len;
508 l0 = asn1_get_encoded_integer_size(r, r_len);
514 l0 = asn1_get_encoded_integer_size(s, s_len);
520 if (!asn1_insert_tag(&sig, sig_end, 0x30) || !asn1_insert_len(&sig, sig_end, len)
521 || !asn1_insert_integer(&sig, sig_end, r, r_len)
522 || !asn1_insert_integer(&sig, sig_end, s, s_len)) {
525 return sig_len - (sig_end - sig);
528static int asn1_read_len(
const uint8_t **p,
const uint8_t *end,
size_t *len)
544 if ((b1 & 0x80u) == 0) {
554 lenleft = b1 & 0x7Fu;
555 if (lenleft > end - *p) {
562 if ((
size_t) lenleft >
sizeof(size_t)) {
568 while (lenleft > 0) {
569 if ((*len >> ((
sizeof(
size_t) - 1) * 8)) != 0) {
572 *len = (*len << 8u) | **p;
573 if (*len + lenleft > (
size_t) (end - *p)) {
587static int asn1_read_tag(
const uint8_t **p,
const uint8_t *end,
size_t *len,
int tag)
589 if ((end - *p) < 1) {
598 return asn1_read_len(p, end, len);
601static int asn1_parse_integer(
const uint8_t **p,
609 if (!asn1_read_tag(p, end, &len, 0x02)) {
613 if (len == 0 || len > (
size_t) (end - *p)) {
617 if (((*p)[0] & 0x80u) == 0x80u) {
622 if ((*p)[0] == 0 && len >= 2 && ((*p)[1] & 0x80u) == 0) {
627 while (len > 0 && **p == 0 && *p != end) {
646int cx_ecfp_decode_sig_der(
const uint8_t *input,
656 const uint8_t *input_end = input + input_len;
663 const uint8_t *p = (
const uint8_t *) input;
665 if (!asn1_read_tag(&p, input_end, &len, 0x30)) {
669 if (p + len != input_end) {
673 if (!asn1_parse_integer(&p, input_end, r, r_len)
674 || !asn1_parse_integer(&p, input_end, s, s_len)) {
678 if (p != input_end) {
682 if (*r_len > max_size || *s_len > max_size) {
Key pair generation based on elliptic curves.
EDDSA (Edwards Curve Digital Signature Algorithm)
Include cryptography files.