Codebase list libcryptx-perl / 5560e08
ECC ecc_import_point Karel Miko 10 years ago
1 changed file(s) with 69 addition(s) and 51 deletion(s). Raw diff Collapse all Expand all
1515
1616 #ifdef LTC_MECC
1717
18 int ecc_import_point(const unsigned char *in, unsigned long inlen, void *prime, void *a, void *b, void *x, void *y)
19 {
20 int err, size;
21 void *t1, *t2;
22
23 /* init key + temporary numbers */
24 if (mp_init_multi(&t1, &t2, NULL) != CRYPT_OK) {
25 return CRYPT_MEM;
26 }
27
28 size = mp_unsigned_bin_size(prime);
29
30 if (in[0] == 0x04 && (inlen&1) && ((inlen-1)>>1) == size) {
31 /* read uncompressed point */
32 /* load x */
33 if ((err = mp_read_unsigned_bin(x, (unsigned char *)in+1, size)) != CRYPT_OK) {
34 goto cleanup;
35 }
36 /* load y */
37 if ((err = mp_read_unsigned_bin(y, (unsigned char *)in+1+size, size)) != CRYPT_OK) {
38 goto cleanup;
39 }
40 }
41 else if ((in[0] == 0x02 || in[0] == 0x03) && (inlen-1) == size) {
42 /* read compressed point */
43 /* load x */
44 if ((err = mp_read_unsigned_bin(x, (unsigned char *)in+1, size)) != CRYPT_OK) {
45 goto cleanup;
46 }
47 /* compute x^3 */
48 if ((err = mp_sqr(x, t1)) != CRYPT_OK) { goto cleanup; }
49 if ((err = mp_mulmod(t1, x, prime, t1)) != CRYPT_OK) { goto cleanup; }
50 /* compute x^3 + a*x */
51 if ((err = mp_mulmod(a, x, prime, t2)) != CRYPT_OK) { goto cleanup; }
52 if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto cleanup; }
53 /* compute x^3 + a*x + b */
54 if ((err = mp_add(t1, b, t1)) != CRYPT_OK) { goto cleanup; }
55 /* compute sqrt(x^3 + a*x + b) */
56 if ((err = mp_sqrtmod_prime(t1, prime, t2)) != CRYPT_OK) { goto cleanup; }
57 /* adjust y */
58 if ((mp_isodd(t2) && in[0] == 0x03) || (!mp_isodd(t2) && in[0] == 0x02)) {
59 if ((err = mp_mod(t2, prime, y)) != CRYPT_OK) { goto cleanup; }
60 }
61 else {
62 if ((err = mp_submod(prime, t2, prime, y)) != CRYPT_OK) { goto cleanup; }
63 }
64 }
65 else {
66 err = CRYPT_INVALID_PACKET;
67 goto cleanup;
68 }
69
70 err = CRYPT_OK;
71 cleanup:
72 mp_clear_multi(t1, t2, NULL);
73 return err;
74 }
75
1876 /** Import raw public or private key (public keys = ANSI X9.63 compressed or uncompressed; private keys = raw bytes)
1977 @param in The input data to read
2078 @param inlen The length of the input data
2684 int ecc_import_raw(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp)
2785 {
2886 int err, size = 0, type = -1;
29 void *t1, *t2, *prime, *a, *b;
87 void *prime, *a, *b;
3088 ecc_point *base;
3189
3290 LTC_ARGCHK(in != NULL);
3492 LTC_ARGCHK(dp != NULL);
3593
3694 /* init key + temporary numbers */
37 if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, &t1, &t2, &prime, &a, &b, NULL) != CRYPT_OK) {
95 if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, &prime, &a, &b, NULL) != CRYPT_OK) {
3896 return CRYPT_MEM;
3997 }
4098
4199 if (inlen == dp->size) {
42 /* ######## read PRIVATE key */
100 /* read PRIVATE key */
43101 type = PK_PRIVATE;
44102 size = inlen;
45103 /* load private k */
68126 /* cleanup */
69127 ltc_ecc_del_point(base);
70128 }
71 else if (in[0] == 0x04 && (inlen&1) && ((inlen-1)>>1) == dp->size) {
72 /* ######## read PUBLIC key - uncompressed point */
129 else {
130 /* read PUBLIC key */
73131 type = PK_PUBLIC;
74 size = (inlen-1)>>1;
75 /* load public.x */
76 if ((err = mp_read_unsigned_bin(key->pubkey.x, (unsigned char *)in+1, size)) != CRYPT_OK) {
77 goto cleanup;
78 }
79 /* load public.y */
80 if ((err = mp_read_unsigned_bin(key->pubkey.y, (unsigned char *)in+1+size, size)) != CRYPT_OK) {
81 goto cleanup;
82 }
83 /* set public.z */
84 if ((err = mp_set(key->pubkey.z, 1)) != CRYPT_OK) { goto cleanup; }
85 }
86 else if ((in[0] == 0x02 || in[0] == 0x03) && (inlen-1) == dp->size) {
87 /* ######## read PUBLIC key - compressed point */
88 type = PK_PUBLIC;
89 size = inlen-1;
90 /* load public.x */
91 if ((err = mp_read_unsigned_bin(key->pubkey.x, (unsigned char *)in+1, size)) != CRYPT_OK) {
92 goto cleanup;
93 }
94 /* load prime + base point */
132 /* load prime + A + B */
95133 if ((err = mp_read_radix(prime, dp->prime, 16)) != CRYPT_OK) { goto cleanup; }
96134 if ((err = mp_read_radix(b, dp->B, 16)) != CRYPT_OK) { goto cleanup; }
97135 if ((err = mp_read_radix(a, dp->A, 16)) != CRYPT_OK) { goto cleanup; }
98 /* compute x^3 */
99 if ((err = mp_sqr(key->pubkey.x, t1)) != CRYPT_OK) { goto cleanup; }
100 if ((err = mp_mulmod(t1, key->pubkey.x, prime, t1)) != CRYPT_OK) { goto cleanup; }
101 /* compute x^3 + a*x */
102 if ((err = mp_mulmod(a, key->pubkey.x, prime, t2)) != CRYPT_OK) { goto cleanup; }
103 if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto cleanup; }
104 /* compute x^3 + a*x + b */
105 if ((err = mp_add(t1, b, t1)) != CRYPT_OK) { goto cleanup; }
106 /* compute sqrt(x^3 + a*x + b) */
107 if ((err = mp_sqrtmod_prime(t1, prime, t2)) != CRYPT_OK) { goto cleanup; }
108 /* adjust y */
109 if ((mp_isodd(t2) && in[0] == 0x03) || (!mp_isodd(t2) && in[0] == 0x02)) {
110 if ((err = mp_mod(t2, prime, key->pubkey.y)) != CRYPT_OK) { goto cleanup; }
111 }
112 else {
113 if ((err = mp_submod(prime, t2, prime, key->pubkey.y)) != CRYPT_OK) { goto cleanup; }
114 }
115 /* set public.z */
136 err = ecc_import_point(in, inlen, prime, a, b, key->pubkey.x, key->pubkey.y);
137 if (err != CRYPT_OK) { goto cleanup; }
116138 if ((err = mp_set(key->pubkey.z, 1)) != CRYPT_OK) { goto cleanup; }
117139 }
118 else {
119 err = CRYPT_INVALID_PACKET;
120 goto cleanup;
121 }
122
140
123141 if ((err = ltc_ecc_is_point(dp, key->pubkey.x, key->pubkey.y)) != CRYPT_OK) {
124142 err = CRYPT_INVALID_PACKET;
125143 goto cleanup;
130148 key->dp = dp;
131149
132150 /* we're done */
133 mp_clear_multi(t1, t2, prime, a, b, NULL);
151 mp_clear_multi(prime, a, b, NULL);
134152 return CRYPT_OK;
135153 cleanup:
136 mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, t1, t2, prime, a, b, NULL);
154 mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, prime, a, b, NULL);
137155 return err;
138156 }
139157