38 cx_err_t cx_ecfp_init_private_key_no_throw(cx_curve_t curve,
41 cx_ecfp_private_key_t *key)
46 CX_CHECK(cx_ecdomain_parameters_length(curve, &domain_length));
48 if (!(((raw_key == NULL) && (key_len == 0)) || ((raw_key) && (key_len == domain_length)))) {
49 error = CX_INVALID_PARAMETER;
55 memmove(key->d, raw_key, key_len);
67 cx_err_t cx_ecfp_init_public_key_no_throw(cx_curve_t curve,
70 cx_ecfp_public_key_t *key)
72 size_t expected_key_len;
73 size_t expected_compressed_key_len;
77 error = cx_ecdomain_parameters_length(curve, &size);
84 memset(key, 0,
sizeof(cx_ecfp_public_key_t));
89 expected_compressed_key_len = 0;
92 #ifdef HAVE_ECC_WEIERSTRASS
93 if (CX_CURVE_RANGE(curve, WEIERSTRASS)) {
94 expected_key_len = 1 + (size) *2;
98 #ifdef HAVE_ECC_TWISTED_EDWARDS
99 if (CX_CURVE_RANGE(curve, TWISTED_EDWARDS)) {
100 expected_key_len = 1 + (size) *2;
101 expected_compressed_key_len = 1 + (size);
105 #ifdef HAVE_ECC_MONTGOMERY
106 if (CX_CURVE_RANGE(curve, MONTGOMERY)) {
107 expected_compressed_key_len = 1 + (size);
112 if ((key_len == expected_key_len) && (rawkey[0] == 0x04)) {
115 if ((key_len == expected_compressed_key_len) && (rawkey[0] == 0x02)) {
119 return INVALID_PARAMETER;
128 key->W_len = key_len;
129 memmove(key->W, rawkey, key_len);
137 cx_err_t cx_ecfp_generate_pair_no_throw(cx_curve_t curve,
138 cx_ecfp_public_key_t *public_key,
139 cx_ecfp_private_key_t *private_key,
142 return cx_ecfp_generate_pair2_no_throw(curve, public_key, private_key, keep_private, CX_SHA512);
145 cx_err_t cx_ecfp_generate_pair2_no_throw(cx_curve_t curve,
146 cx_ecfp_public_key_t *public_key,
147 cx_ecfp_private_key_t *private_key,
157 #ifndef HAVE_ECC_TWISTED_EDWARDS
161 CX_CHECK(cx_ecdomain_parameters_length(curve, &size));
165 CX_CHECK(cx_bn_lock(size, 0));
166 CX_CHECK(cx_bn_alloc(&n, size));
167 CX_CHECK(cx_ecdomain_parameter_bn(curve, CX_CURVE_PARAM_Order, n));
168 CX_CHECK(cx_bn_alloc(&r, size));
173 if ((private_key->curve != curve) || (private_key->d_len != size)) {
174 error = CX_INVALID_PARAMETER;
177 CX_CHECK(cx_bn_init(r, private_key->d, private_key->d_len));
180 CX_CHECK(cx_bn_alloc(&a, 2 * size));
181 CX_CHECK(cx_bn_rand(a));
182 CX_CHECK(cx_bn_reduce(r, a, n));
183 CX_CHECK(cx_bn_destroy(&a));
184 CX_CHECK(cx_bn_export(r, private_key->d, size));
185 private_key->curve = curve;
186 private_key->d_len = size;
188 #ifdef HAVE_ECC_MONTGOMERY
189 if (CX_CURVE_RANGE(curve, MONTGOMERY)) {
190 if (curve == CX_CURVE_Curve25519) {
191 private_key->d[size - 1] &= 0xF8;
192 private_key->d[0] = (private_key->d[0] & 0x7F) | 0x40;
195 private_key->d[size - 1] &= 0xFC;
196 private_key->d[0] |= 0x80;
203 #ifdef HAVE_ECC_WEIERSTRASS
204 if (CX_CURVE_RANGE(curve, WEIERSTRASS)) {
205 CX_CHECK(cx_ecpoint_alloc(&W, private_key->curve));
206 CX_CHECK(cx_ecdomain_generator_bn(curve, &W));
209 if (CX_CURVE_BLS12_381_G1 == private_key->curve) {
210 CX_CHECK(cx_ecpoint_rnd_scalarmul(&W, private_key->d, private_key->d_len));
213 CX_CHECK(cx_ecpoint_rnd_fixed_scalarmul(&W, private_key->d, private_key->d_len));
215 public_key->curve = curve;
216 public_key->W_len = 1 + 2 * size;
217 public_key->W[0] = 0x04;
218 CX_CHECK(cx_ecpoint_export(&W, &public_key->W[1], size, &public_key->W[1 + size], size));
223 #ifdef HAVE_ECC_TWISTED_EDWARDS
224 if (CX_CURVE_RANGE(curve, TWISTED_EDWARDS)) {
226 CX_CHECK(cx_eddsa_get_public_key_internal(
227 private_key, hashID, public_key, NULL, 0, NULL, 0, scal));
232 #ifdef HAVE_ECC_MONTGOMERY
233 if (CX_CURVE_RANGE(curve, MONTGOMERY)) {
234 CX_CHECK(cx_ecpoint_alloc(&W, private_key->curve));
235 CX_CHECK(cx_ecdomain_generator_bn(curve, &W));
236 CX_CHECK(cx_ecpoint_rnd_scalarmul(&W, private_key->d, private_key->d_len));
237 public_key->curve = curve;
238 public_key->W_len = 1 + 2 * size;
239 public_key->W[0] = 0x04;
240 CX_CHECK(cx_ecpoint_export(&W, &public_key->W[1], size, &public_key->W[1 + size], size));
245 error = CX_EC_INVALID_POINT;
252 cx_err_t cx_ecfp_add_point_no_throw(cx_curve_t curve,
254 const unsigned char *P,
255 const unsigned char *Q)
258 cx_ecpoint_t ecR, ecP, ecQ;
261 CX_CHECK(cx_ecdomain_parameters_length(curve, &size));
262 CX_CHECK(cx_bn_lock(size, 0));
264 CX_CHECK(cx_ecpoint_alloc(&ecP, curve));
265 CX_CHECK(cx_ecpoint_alloc(&ecQ, curve));
266 CX_CHECK(cx_ecpoint_alloc(&ecR, curve));
267 CX_CHECK(cx_ecpoint_init(&ecP, P + 1, size, P + 1 + size, size));
268 CX_CHECK(cx_ecpoint_init(&ecQ, Q + 1, size, Q + 1 + size, size));
269 CX_CHECK(cx_ecpoint_add(&ecR, &ecP, &ecQ));
271 CX_CHECK(cx_ecpoint_export(&ecR, &R[1], size, &R[1 + size], size));
281 cx_err_t cx_ecfp_scalar_mult_no_throw(cx_curve_t curve,
uint8_t *P,
const uint8_t *k,
size_t k_len)
287 CX_CHECK(cx_ecdomain_parameters_length(curve, &size));
288 CX_CHECK(cx_bn_lock(size, 0));
290 CX_CHECK(cx_ecpoint_alloc(&ecP, curve));
291 CX_CHECK(cx_ecpoint_init(&ecP, P + 1, size, P + 1 + size, size));
292 CX_CHECK(cx_ecpoint_rnd_scalarmul(&ecP, k, k_len));
294 CX_CHECK(cx_ecpoint_export(&ecP, &P[1], size, &P[1 + size], size));
301 #ifdef HAVE_ECC_TWISTED_EDWARDS
303 cx_err_t cx_edwards_compress_point_no_throw(cx_curve_t curve,
uint8_t *P,
size_t P_len)
311 CX_CHECK(cx_ecdomain_parameters_length(curve, &size));
312 CX_CHECK(cx_bn_lock(size, 0));
313 CX_CHECK(cx_ecpoint_alloc(&P_ec, curve));
314 CX_CHECK(cx_ecpoint_init(&P_ec, P + 1, size, P + 1 + size, size));
315 CX_CHECK(cx_ecpoint_compress(&P_ec, P + 1, size, &sign));
316 cx_encode_coord(P + 1, size, sign);
317 memmove(P + 1 + size, P + 1, size);
325 cx_err_t cx_edwards_decompress_point_no_throw(cx_curve_t curve,
uint8_t *P,
size_t P_len)
333 CX_CHECK(cx_ecdomain_parameters_length(curve, &size));
334 CX_CHECK(cx_bn_lock(size, 0));
335 sign = cx_decode_coord(P + 1, size);
336 CX_CHECK(cx_ecpoint_alloc(&P_ec, curve));
337 memmove(P + 1 + size, P + 1, size);
338 CX_CHECK(cx_ecpoint_decompress(&P_ec, P + 1, size, sign));
339 CX_CHECK(cx_ecpoint_export(&P_ec, P + 1, size, P + 1 + size, size));
349 static size_t asn1_get_encoded_length_size(
size_t len)
366 static size_t asn1_get_encoded_integer_size(
uint8_t const *val,
size_t len)
370 while (len && (*val == 0)) {
378 else if (*val & 0x80u) {
382 l0 = asn1_get_encoded_length_size(len);
389 static int asn1_insert_tag(
uint8_t **p,
const uint8_t *end,
unsigned int tag)
391 if ((end - *p) < 1) {
399 static int asn1_insert_len(
uint8_t **p,
const uint8_t *end,
size_t len)
402 if ((end - *p) < 1) {
405 (*p)[0] = len & 0xFF;
411 if ((end - *p) < 2) {
415 (*p)[1] = len & 0xFF;
421 if ((end - *p) < 3) {
425 (*p)[1] = (len >> 8) & 0xFF;
426 (*p)[2] = len & 0xFF;
436 while (len && (*val == 0)) {
440 if (!asn1_insert_tag(p, end, 0x02)) {
446 if ((end - *p) < 2) {
456 if (!asn1_insert_len(p, end, (*val & 0x80) ? len + 1 : len)) {
461 if ((end - *p) < 1) {
467 if ((end - *p) < (
int) len) {
470 memmove(*p, val, len);
478 size_t cx_ecfp_encode_sig_der(
uint8_t *sig,
486 const uint8_t *sig_end = sig + sig_len;
490 l0 = asn1_get_encoded_integer_size(r, r_len);
496 l0 = asn1_get_encoded_integer_size(s, s_len);
502 if (!asn1_insert_tag(&sig, sig_end, 0x30) || !asn1_insert_len(&sig, sig_end, len)
503 || !asn1_insert_integer(&sig, sig_end, r, r_len)
504 || !asn1_insert_integer(&sig, sig_end, s, s_len)) {
507 return sig_len - (sig_end - sig);
510 static int asn1_read_len(
const uint8_t **p,
const uint8_t *end,
size_t *len)
526 if ((b1 & 0x80u) == 0) {
536 lenleft = b1 & 0x7Fu;
537 if (lenleft > end - *p) {
544 if ((
size_t) lenleft >
sizeof(size_t)) {
550 while (lenleft > 0) {
551 if ((*len >> ((
sizeof(
size_t) - 1) * 8)) != 0) {
554 *len = (*len << 8u) | **p;
555 if (*len + lenleft > (
size_t) (end - *p)) {
569 static int asn1_read_tag(
const uint8_t **p,
const uint8_t *end,
size_t *len,
int tag)
571 if ((end - *p) < 1) {
580 return asn1_read_len(p, end, len);
583 static int asn1_parse_integer(
const uint8_t **p,
591 if (!asn1_read_tag(p, end, &len, 0x02)) {
595 if (len == 0 || len > (
size_t) (end - *p)) {
599 if (((*p)[0] & 0x80u) == 0x80u) {
604 if ((*p)[0] == 0 && len >= 2 && ((*p)[1] & 0x80u) == 0) {
609 while (len > 0 && **p == 0 && *p != end) {
628 int cx_ecfp_decode_sig_der(
const uint8_t *input,
638 const uint8_t *input_end = input + input_len;
647 if (!asn1_read_tag(&p, input_end, &len, 0x30)) {
651 if (p + len != input_end) {
655 if (!asn1_parse_integer(&p, input_end, r, r_len)
656 || !asn1_parse_integer(&p, input_end, s, s_len)) {
660 if (p != input_end) {
664 if (*r_len > max_size || *s_len > max_size) {
Include cryptography files.