1 // SPDX-License-Identifier: BSD-2-Clause
2 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
3  *
4  * LibTomCrypt is a library that provides various cryptographic
5  * algorithms in a highly modular and flexible manner.
6  *
7  * The library is free for all purposes without any express
8  * guarantee it works.
9  */
10 
11 #include "tomcrypt_private.h"
12 
13 #ifdef LTC_MECC
14 
ltc_ecc_import_point(const unsigned char * in,unsigned long inlen,void * prime,void * a,void * b,void * x,void * y)15 int ltc_ecc_import_point(const unsigned char *in, unsigned long inlen, void *prime, void *a, void *b, void *x, void *y)
16 {
17    int err;
18    unsigned long size;
19    void *t1, *t2;
20 
21    /* init key + temporary numbers */
22    if (mp_init_multi(&t1, &t2, NULL) != CRYPT_OK) {
23       return CRYPT_MEM;
24    }
25 
26    size = mp_unsigned_bin_size(prime);
27 
28    if (in[0] == 0x04 && (inlen&1) && ((inlen-1)>>1) == size) {
29       /* read uncompressed point */
30       /* load x */
31       if ((err = mp_read_unsigned_bin(x, (unsigned char *)in+1, size)) != CRYPT_OK)      { goto cleanup; }
32       /* load y */
33       if ((err = mp_read_unsigned_bin(y, (unsigned char *)in+1+size, size)) != CRYPT_OK) { goto cleanup; }
34    }
35    else if ((in[0] == 0x02 || in[0] == 0x03) && (inlen-1) == size && ltc_mp.sqrtmod_prime != NULL) {
36       /* read compressed point - BEWARE: requires sqrtmod_prime */
37       /* load x */
38       if ((err = mp_read_unsigned_bin(x, (unsigned char *)in+1, size)) != CRYPT_OK)      { goto cleanup; }
39       /* compute x^3 */
40       if ((err = mp_sqr(x, t1)) != CRYPT_OK)                                             { goto cleanup; }
41       if ((err = mp_mulmod(t1, x, prime, t1)) != CRYPT_OK)                               { goto cleanup; }
42       /* compute x^3 + a*x */
43       if ((err = mp_mulmod(a, x, prime, t2)) != CRYPT_OK)                                { goto cleanup; }
44       if ((err = mp_add(t1, t2, t1)) != CRYPT_OK)                                        { goto cleanup; }
45       /* compute x^3 + a*x + b */
46       if ((err = mp_add(t1, b, t1)) != CRYPT_OK)                                         { goto cleanup; }
47       /* compute sqrt(x^3 + a*x + b) */
48       if ((err = mp_sqrtmod_prime(t1, prime, t2)) != CRYPT_OK)                           { goto cleanup; }
49       /* adjust y */
50       if ((mp_isodd(t2) && in[0] == 0x03) || (!mp_isodd(t2) && in[0] == 0x02)) {
51          if ((err = mp_mod(t2, prime, y)) != CRYPT_OK)                                   { goto cleanup; }
52       }
53       else {
54          if ((err = mp_submod(prime, t2, prime, y)) != CRYPT_OK)                         { goto cleanup; }
55       }
56    }
57    else {
58       err = CRYPT_INVALID_PACKET;
59       goto cleanup;
60    }
61 
62    err = CRYPT_OK;
63 cleanup:
64    mp_clear_multi(t1, t2, NULL);
65    return err;
66 }
67 
68 #endif
69 
70 /* ref:         $Format:%D$ */
71 /* git commit:  $Format:%H$ */
72 /* commit time: $Format:%ai$ */
73