1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3
4 #include "tomcrypt_private.h"
5
6 #ifdef LTC_MECC
7
ltc_ecc_import_point(const unsigned char * in,unsigned long inlen,void * prime,void * a,void * b,void * x,void * y)8 int ltc_ecc_import_point(const unsigned char *in, unsigned long inlen, void *prime, void *a, void *b, void *x, void *y)
9 {
10 int err;
11 unsigned long size;
12 void *t1, *t2;
13
14 /* init key + temporary numbers */
15 if (mp_init_multi(&t1, &t2, LTC_NULL) != CRYPT_OK) {
16 return CRYPT_MEM;
17 }
18
19 size = mp_unsigned_bin_size(prime);
20
21 if (in[0] == 0x04 && (inlen&1) && ((inlen-1)>>1) == size) {
22 /* read uncompressed point */
23 /* load x */
24 if ((err = mp_read_unsigned_bin(x, (unsigned char *)in+1, size)) != CRYPT_OK) { goto cleanup; }
25 /* load y */
26 if ((err = mp_read_unsigned_bin(y, (unsigned char *)in+1+size, size)) != CRYPT_OK) { goto cleanup; }
27 }
28 else if ((in[0] == 0x02 || in[0] == 0x03) && (inlen-1) == size && ltc_mp.sqrtmod_prime != NULL) {
29 /* read compressed point - BEWARE: requires sqrtmod_prime */
30 /* load x */
31 if ((err = mp_read_unsigned_bin(x, (unsigned char *)in+1, size)) != CRYPT_OK) { goto cleanup; }
32 /* compute x^3 */
33 if ((err = mp_sqr(x, t1)) != CRYPT_OK) { goto cleanup; }
34 if ((err = mp_mulmod(t1, x, prime, t1)) != CRYPT_OK) { goto cleanup; }
35 /* compute x^3 + a*x */
36 if ((err = mp_mulmod(a, x, prime, t2)) != CRYPT_OK) { goto cleanup; }
37 if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto cleanup; }
38 /* compute x^3 + a*x + b */
39 if ((err = mp_add(t1, b, t1)) != CRYPT_OK) { goto cleanup; }
40 /* compute sqrt(x^3 + a*x + b) */
41 if ((err = mp_sqrtmod_prime(t1, prime, t2)) != CRYPT_OK) { goto cleanup; }
42 /* adjust y */
43 if ((mp_isodd(t2) && in[0] == 0x03) || (!mp_isodd(t2) && in[0] == 0x02)) {
44 if ((err = mp_mod(t2, prime, y)) != CRYPT_OK) { goto cleanup; }
45 }
46 else {
47 if ((err = mp_submod(prime, t2, prime, y)) != CRYPT_OK) { goto cleanup; }
48 }
49 }
50 else {
51 err = CRYPT_INVALID_PACKET;
52 goto cleanup;
53 }
54
55 err = CRYPT_OK;
56 cleanup:
57 mp_clear_multi(t1, t2, LTC_NULL);
58 return err;
59 }
60
61 #endif
62