Codebase list libcryptx-perl / 66f2675
ECC full import/export (not final version yet) Karel Miko 10 years ago
6 changed file(s) with 546 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 */
9
10 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
11 *
12 */
13
14 #include "tomcrypt.h"
15
16 #ifdef LTC_MECC
17
18 int ecc_dp_clear(ltc_ecc_set_type *dp)
19 {
20 if (dp == NULL) return CRYPT_INVALID_ARG;
21
22 if (dp->name != NULL) { XFREE(dp->name ); dp->name = NULL; }
23 if (dp->prime != NULL) { XFREE(dp->prime); dp->prime = NULL; }
24 if (dp->A != NULL) { XFREE(dp->A ); dp->A = NULL; }
25 if (dp->B != NULL) { XFREE(dp->B ); dp->B = NULL; }
26 if (dp->order != NULL) { XFREE(dp->order); dp->order = NULL; }
27 if (dp->Gx != NULL) { XFREE(dp->Gx ); dp->Gx = NULL; }
28 if (dp->Gy != NULL) { XFREE(dp->Gy ); dp->Gy = NULL; }
29 dp->cofactor = 0;
30
31 return CRYPT_OK;
32 }
33
34 #endif
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 */
9
10 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
11 *
12 */
13
14 #include "tomcrypt.h"
15
16 #ifdef LTC_MECC
17
18 int ecc_dp_init(ltc_ecc_set_type *dp)
19 {
20 if (dp == NULL) return CRYPT_INVALID_ARG;
21
22 dp->name = NULL;
23 dp->prime = NULL;
24 dp->A = NULL;
25 dp->B = NULL;
26 dp->order = NULL;
27 dp->Gx = NULL;
28 dp->Gy = NULL;
29 dp->cofactor = 0;
30
31 return CRYPT_OK;
32 }
33
34 #endif
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 */
9
10 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
11 *
12 */
13
14 #include "tomcrypt.h"
15
16 #ifdef LTC_MECC
17
18 int ecc_dp_set(ltc_ecc_set_type *dp, char *ch_prime, char *ch_A, char *ch_B, char *ch_order, char *ch_Gx, char *ch_Gy, int cofactor, char *ch_name)
19 {
20 unsigned long l_name, l_prime, l_A, l_B, l_order, l_Gx, l_Gy;
21
22 if (!dp || !ch_prime || !ch_A || !ch_B || !ch_order || !ch_Gx || !ch_Gy || cofactor<=0) return CRYPT_INVALID_ARG;
23
24 l_name = strlen(ch_name);
25 l_prime = strlen(ch_prime);
26 l_A = strlen(ch_A);
27 l_B = strlen(ch_B);
28 l_order = strlen(ch_order);
29 l_Gx = strlen(ch_Gx);
30 l_Gy = strlen(ch_Gy);
31
32 dp->cofactor = cofactor;
33
34 { /* calculate size */
35 void *p_num;
36 mp_init(&p_num);
37 mp_read_radix(p_num, ch_prime, 16);
38 dp->size = mp_unsigned_bin_size(p_num);
39 mp_clear(p_num);
40 }
41
42 if (dp->name != NULL) { XFREE(dp->name ); dp->name = NULL; }
43 if (dp->prime != NULL) { XFREE(dp->prime); dp->prime = NULL; }
44 if (dp->A != NULL) { XFREE(dp->A ); dp->A = NULL; }
45 if (dp->B != NULL) { XFREE(dp->B ); dp->B = NULL; }
46 if (dp->order != NULL) { XFREE(dp->order); dp->order = NULL; }
47 if (dp->Gx != NULL) { XFREE(dp->Gx ); dp->Gx = NULL; }
48 if (dp->Gy != NULL) { XFREE(dp->Gy ); dp->Gy = NULL; }
49
50 dp->name = XMALLOC(1+l_name); strncpy(dp->name, ch_name, 1+l_name);
51 dp->prime = XMALLOC(1+l_prime); strncpy(dp->prime, ch_prime, 1+l_prime);
52 dp->A = XMALLOC(1+l_A); strncpy(dp->A, ch_A, 1+l_A);
53 dp->B = XMALLOC(1+l_B); strncpy(dp->B, ch_B, 1+l_B);
54 dp->order = XMALLOC(1+l_order); strncpy(dp->order, ch_order, 1+l_order);
55 dp->Gx = XMALLOC(1+l_Gx); strncpy(dp->Gx, ch_Gx, 1+l_Gx);
56 dp->Gy = XMALLOC(1+l_Gy); strncpy(dp->Gy, ch_Gy, 1+l_Gy);
57
58 return CRYPT_OK;
59 }
60
61 #endif
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 */
9
10 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
11 *
12 */
13
14 #include "tomcrypt.h"
15
16 #ifdef LTC_MECC
17
18 /**
19 Export an ECC key as a binary packet
20 @param out [out] Destination for the key
21 @param outlen [in/out] Max size and resulting size of the exported key
22 @param type The type of key you want to export (PK_PRIVATE or PK_PUBLIC)
23 @param key The key to export
24 @return CRYPT_OK if successful
25 */
26
27 int ecc_export_full(unsigned char *out, unsigned long *outlen, int type, ecc_key *key)
28 {
29 int err;
30 void *prime, *order, *a, *b, *gx, *gy;
31 unsigned char bin_a[256], bin_b[256], bin_k[256], bin_g[512], bin_xy[512];
32 unsigned long len_a, len_b, len_k, len_g, len_xy;
33 unsigned long cofactor, one = 1;
34 oid_st oid;
35 ltc_asn1_list seq_fieldid[2], seq_curve[2], seq_ecparams[6], seq_priv[4];
36
37 LTC_ARGCHK(out != NULL);
38 LTC_ARGCHK(outlen != NULL);
39 LTC_ARGCHK(key != NULL);
40
41 if (key->type != PK_PRIVATE && type == PK_PRIVATE) return CRYPT_PK_TYPE_MISMATCH;
42 if (ltc_ecc_is_valid_idx(key->idx) == 0) return CRYPT_INVALID_ARG;
43
44 if ((err = mp_init_multi(&prime, &order, &a, &b, &gx, &gy, NULL)) != CRYPT_OK) return err;
45
46 if ((err = mp_read_radix(prime, key->dp->prime, 16)) != CRYPT_OK) goto error;
47 if ((err = mp_read_radix(order, key->dp->order, 16)) != CRYPT_OK) goto error;
48 if ((err = mp_read_radix(b, key->dp->B, 16)) != CRYPT_OK) goto error;
49 if ((err = mp_read_radix(a, key->dp->A, 16)) != CRYPT_OK) goto error;
50 if ((err = mp_read_radix(gx, key->dp->Gx, 16)) != CRYPT_OK) goto error;
51 if ((err = mp_read_radix(gy, key->dp->Gy, 16)) != CRYPT_OK) goto error;
52
53 /* curve param a */
54 len_a = mp_unsigned_bin_size(a);
55 if (len_a > sizeof(bin_a)) { err = CRYPT_BUFFER_OVERFLOW; goto error; }
56 if ((err = mp_to_unsigned_bin(a, bin_a)) != CRYPT_OK) goto error;
57 if (len_a == 0) { len_a = 1; bin_a[0] = 0; } /* XXX-TODO hack to handle case a == 0 */
58
59 /* curve param b */
60 len_b = mp_unsigned_bin_size(b);
61 if (len_b > sizeof(bin_b)) { err = CRYPT_BUFFER_OVERFLOW; goto error; }
62 if ((err = mp_to_unsigned_bin(b, bin_b)) != CRYPT_OK) goto error;
63 if (len_b == 0) { len_b = 1; bin_b[0] = 0; } /* XXX-TODO hack to handle case b == 0 */
64
65 /* base point - we export uncompressed form */
66 len_g = sizeof(bin_g);
67 if ((err = ecc_export_point(bin_g, &len_g, gx, gy, key->dp->size, 0)) != CRYPT_OK) goto error;
68
69 /* public key */
70 len_xy = sizeof(bin_xy);
71 if ((err = ecc_export_point(bin_xy, &len_xy, key->pubkey.x, key->pubkey.y, key->dp->size, 0)) != CRYPT_OK) goto error;
72
73 /* co-factor */
74 cofactor = key->dp->cofactor;
75
76 /* we support only prime-field EC */
77 if ((err = pk_get_oid(EC_PRIME_FIELD, &oid)) != CRYPT_OK) goto error;
78
79 /* FieldID SEQUENCE */
80 LTC_SET_ASN1(seq_fieldid, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid.OID, oid.OIDlen);
81 LTC_SET_ASN1(seq_fieldid, 1, LTC_ASN1_INTEGER, prime, 1UL);
82
83 /* Curve SEQUENCE */
84 LTC_SET_ASN1(seq_curve, 0, LTC_ASN1_OCTET_STRING, bin_a, len_a);
85 LTC_SET_ASN1(seq_curve, 1, LTC_ASN1_OCTET_STRING, bin_b, len_b);
86
87 /* ECParameters SEQUENCE */
88 LTC_SET_ASN1(seq_ecparams, 0, LTC_ASN1_SHORT_INTEGER, &one, 1UL);
89 LTC_SET_ASN1(seq_ecparams, 1, LTC_ASN1_SEQUENCE, seq_fieldid, 2UL);
90 LTC_SET_ASN1(seq_ecparams, 2, LTC_ASN1_SEQUENCE, seq_curve, 2UL);
91 LTC_SET_ASN1(seq_ecparams, 3, LTC_ASN1_OCTET_STRING, bin_g, len_g);
92 LTC_SET_ASN1(seq_ecparams, 4, LTC_ASN1_INTEGER, order, 1UL);
93 LTC_SET_ASN1(seq_ecparams, 5, LTC_ASN1_SHORT_INTEGER, &cofactor, 1UL);
94
95 if (type == PK_PRIVATE) {
96 /* private key format: http://tools.ietf.org/html/rfc5915
97
98 ECPrivateKey ::= SEQUENCE { # SEQUENCE
99 version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), # INTEGER :01
100 privateKey OCTET STRING, # OCTET STRING
101 [0] ECParameters ::= SEQUENCE { # SEQUENCE
102 version INTEGER { ecpVer1(1) } (ecpVer1), # INTEGER :01
103 FieldID ::= SEQUENCE { # SEQUENCE
104 fieldType FIELD-ID.&id({IOSet}), # OBJECT :prime-field
105 parameters FIELD-ID.&Type({IOSet}{@fieldType}) # INTEGER
106 }
107 Curve ::= SEQUENCE { # SEQUENCE
108 a FieldElement ::= OCTET STRING # OCTET STRING
109 b FieldElement ::= OCTET STRING # OCTET STRING
110 seed BIT STRING OPTIONAL
111 }
112 base ECPoint ::= OCTET STRING # OCTET STRING
113 order INTEGER, # INTEGER
114 cofactor INTEGER OPTIONAL # INTEGER
115 }
116 [1] publicKey # BIT STRING
117 }
118 */
119
120 /* private key */
121 len_k = mp_unsigned_bin_size(key->k);
122 if (len_k > sizeof(bin_k)) { err = CRYPT_BUFFER_OVERFLOW; goto error; }
123 if ((err = mp_to_unsigned_bin(key->k, bin_k)) != CRYPT_OK) goto error;
124
125 LTC_SET_ASN1(seq_priv, 0, LTC_ASN1_SHORT_INTEGER, &one, 1UL);
126 LTC_SET_ASN1(seq_priv, 1, LTC_ASN1_OCTET_STRING, bin_k, len_k);
127 LTC_SET_ASN1(seq_priv, 2, LTC_ASN1_SEQUENCE, seq_ecparams, 6UL);
128 LTC_SET_ASN1(seq_priv, 3, LTC_ASN1_RAW_BIT_STRING, bin_xy, 8*len_xy);
129
130 err = der_encode_sequence(seq_priv, 4, out, outlen);
131 }
132 else {
133 /* public key format: http://tools.ietf.org/html/rfc5480
134
135 SubjectPublicKeyInfo ::= SEQUENCE { # SEQUENCE
136 AlgorithmIdentifier ::= SEQUENCE { # SEQUENCE
137 algorithm OBJECT IDENTIFIER # OBJECT :id-ecPublicKey
138 ECParameters ::= SEQUENCE { # SEQUENCE
139 version INTEGER { ecpVer1(1) } (ecpVer1), # INTEGER :01
140 FieldID ::= SEQUENCE { # SEQUENCE
141 fieldType FIELD-ID.&id({IOSet}), # OBJECT :prime-field
142 parameters FIELD-ID.&Type({IOSet}{@fieldType}) # INTEGER
143 }
144 Curve ::= SEQUENCE { # SEQUENCE
145 a FieldElement ::= OCTET STRING # OCTET STRING
146 b FieldElement ::= OCTET STRING # OCTET STRING
147 seed BIT STRING OPTIONAL
148 }
149 base ECPoint ::= OCTET STRING # OCTET STRING
150 order INTEGER, # INTEGER
151 cofactor INTEGER OPTIONAL # INTEGER
152 }
153 }
154 subjectPublicKey BIT STRING # BIT STRING
155 }
156 */
157
158 err = der_encode_subject_public_key_info( out, outlen,
159 PKA_EC, bin_xy, len_xy,
160 LTC_ASN1_SEQUENCE, seq_ecparams, 6 );
161 }
162
163 error:
164 mp_clear_multi(prime, order, a, b, gx, gy, NULL);
165 return err;
166 }
167
168 #endif
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
12 *
13 */
14
15 #include "tomcrypt.h"
16
17 #ifdef LTC_MECC
18
19 static int _populate_dp(void *a, void *b, void *prime, void *order, void *gx, void *gy, int cofactor, ltc_ecc_set_type *dp)
20 {
21 unsigned char buf[ECC_BUF_SIZE];
22 unsigned long len;
23
24 /* a */
25 mp_tohex(a, (char *)buf);
26 len = strlen((char *)buf);
27 if ((dp->A = XMALLOC(1+len)) == NULL) goto cleanup1;
28 strncpy(dp->A, (char*)buf, 1+len);
29 /* b */
30 mp_tohex(b, (char *)buf);
31 len = strlen((char *)buf);
32 if ((dp->B = XMALLOC(1+len)) == NULL) goto cleanup2;
33 strncpy(dp->B, (char*)buf, 1+len);
34 /* order */
35 mp_tohex(order, (char *)buf);
36 len = strlen((char *)buf);
37 if ((dp->order = XMALLOC(1+len)) == NULL) goto cleanup3;
38 strncpy(dp->order, (char*)buf, 1+len);
39 /* prime */
40 mp_tohex(prime, (char *)buf);
41 len = strlen((char *)buf);
42 if ((dp->prime = XMALLOC(1+len)) == NULL) goto cleanup4;
43 strncpy(dp->prime, (char*)buf, 1+len);
44 /* gx */
45 mp_tohex(gx, (char *)buf);
46 len = strlen((char *)buf);
47 if ((dp->Gx = XMALLOC(1+len)) == NULL) goto cleanup5;
48 strncpy(dp->Gx, (char*)buf, 1+len);
49 /* gy */
50 mp_tohex(gy, (char *)buf);
51 len = strlen((char *)buf);
52 if ((dp->Gy = XMALLOC(1+len)) == NULL) goto cleanup6;
53 strncpy(dp->Gy, (char*)buf, 1+len);
54 /* cofactor & size */
55 dp->cofactor = cofactor;
56 dp->size = mp_unsigned_bin_size(prime);
57 /* name */
58 if ((dp->name = XMALLOC(7)) == NULL) goto cleanup7;
59 strcpy(dp->name, "custom"); /* XXX-TODO check this */
60 /* done - success */
61 return CRYPT_OK;
62
63 XFREE(dp->name);
64 cleanup7:
65 XFREE(dp->Gy);
66 cleanup6:
67 XFREE(dp->Gx);
68 cleanup5:
69 XFREE(dp->prime);
70 cleanup4:
71 XFREE(dp->order);
72 cleanup3:
73 XFREE(dp->B);
74 cleanup2:
75 XFREE(dp->A);
76 cleanup1:
77 return CRYPT_MEM;
78 }
79
80 int ecc_import_full(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp)
81 {
82 void *prime, *order, *a, *b, *gx, *gy;
83 ltc_asn1_list seq_fieldid[3], seq_curve[3], seq_ecparams[7], seq_priv[5];
84 unsigned char bin_a[ECC_MAXSIZE], bin_b[ECC_MAXSIZE], bin_k[ECC_MAXSIZE], bin_g[2*ECC_MAXSIZE+1], bin_xy[2*ECC_MAXSIZE+2];
85 unsigned long len_a, len_b, len_k, len_g, len_xy;
86 unsigned long cofactor = 0, ecver = 0, pkver = 0, tmpoid[16];
87 /*oid_st oid;*/
88 int err;
89
90 if ((err = mp_init_multi(&prime, &order, &a, &b, &gx, &gy, NULL)) != CRYPT_OK) return err;
91
92 /* ECParameters SEQUENCE */
93 LTC_SET_ASN1(seq_ecparams, 0, LTC_ASN1_SHORT_INTEGER, &ecver, 1UL);
94 LTC_SET_ASN1(seq_ecparams, 1, LTC_ASN1_SEQUENCE, seq_fieldid, 2UL);
95 LTC_SET_ASN1(seq_ecparams, 2, LTC_ASN1_SEQUENCE, seq_curve, 2UL);
96 LTC_SET_ASN1(seq_ecparams, 3, LTC_ASN1_OCTET_STRING, bin_g, (unsigned long)2*ECC_MAXSIZE+1);
97 LTC_SET_ASN1(seq_ecparams, 4, LTC_ASN1_INTEGER, order, 1UL);
98 LTC_SET_ASN1(seq_ecparams, 5, LTC_ASN1_SHORT_INTEGER, &cofactor, 1UL);
99 /* FieldID SEQUENCE */
100 LTC_SET_ASN1(seq_fieldid, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, 16UL);
101 LTC_SET_ASN1(seq_fieldid, 1, LTC_ASN1_INTEGER, prime, 1UL);
102 /* Curve SEQUENCE */
103 LTC_SET_ASN1(seq_curve, 0, LTC_ASN1_OCTET_STRING, bin_a, (unsigned long)ECC_MAXSIZE);
104 LTC_SET_ASN1(seq_curve, 1, LTC_ASN1_OCTET_STRING, bin_b, (unsigned long)ECC_MAXSIZE);
105
106 len_xy = sizeof(bin_xy);
107 /* try to load public key */
108 err = der_decode_subject_public_key_info(in, inlen, PKA_EC, bin_xy, &len_xy, LTC_ASN1_SEQUENCE, seq_ecparams, 6);
109 if (err == CRYPT_OK) {
110 len_a = seq_curve[0].size;
111 len_b = seq_curve[1].size;
112 len_g = seq_ecparams[3].size;
113 /* create bignums */
114 if ((err = mp_read_unsigned_bin(a, bin_a, len_a)) != CRYPT_OK) { goto error; }
115 if ((err = mp_read_unsigned_bin(b, bin_b, len_b)) != CRYPT_OK) { goto error; }
116 if ((err = ecc_import_point(bin_g, len_g, prime, a, b, gx, gy)) != CRYPT_OK) { goto error; }
117 /* load curve parameters */
118 if ((err = _populate_dp(a, b, prime, order, gx, gy, cofactor, dp)) != CRYPT_OK) { goto error; }
119 /* load public key */
120 if ((err = ecc_import_raw(bin_xy, len_xy, key, dp)) != CRYPT_OK) { goto error; }
121 }
122 else {
123 /* ECPrivateKey SEQUENCE */
124 LTC_SET_ASN1(seq_priv, 0, LTC_ASN1_SHORT_INTEGER, &pkver, 1UL);
125 LTC_SET_ASN1(seq_priv, 1, LTC_ASN1_OCTET_STRING, bin_k, (unsigned long)ECC_MAXSIZE);
126 LTC_SET_ASN1(seq_priv, 2, LTC_ASN1_SEQUENCE, seq_ecparams, 6UL);
127 LTC_SET_ASN1(seq_priv, 3, LTC_ASN1_RAW_BIT_STRING, bin_xy, (unsigned long)8*(2*ECC_MAXSIZE+2));
128 /* ECParameters SEQUENCE */
129 LTC_SET_ASN1(seq_ecparams, 0, LTC_ASN1_SHORT_INTEGER, &ecver, 1UL);
130 LTC_SET_ASN1(seq_ecparams, 1, LTC_ASN1_SEQUENCE, seq_fieldid, 2UL);
131 LTC_SET_ASN1(seq_ecparams, 2, LTC_ASN1_SEQUENCE, seq_curve, 2UL);
132 LTC_SET_ASN1(seq_ecparams, 3, LTC_ASN1_OCTET_STRING, bin_g, (unsigned long)2*ECC_MAXSIZE+1);
133 LTC_SET_ASN1(seq_ecparams, 4, LTC_ASN1_INTEGER, order, 1UL);
134 LTC_SET_ASN1(seq_ecparams, 5, LTC_ASN1_SHORT_INTEGER, &cofactor, 1UL);
135 /* FieldID SEQUENCE */
136 LTC_SET_ASN1(seq_fieldid, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, 16UL);
137 LTC_SET_ASN1(seq_fieldid, 1, LTC_ASN1_INTEGER, prime, 1UL);
138 /* Curve SEQUENCE */
139 LTC_SET_ASN1(seq_curve, 0, LTC_ASN1_OCTET_STRING, bin_a, (unsigned long)ECC_MAXSIZE);
140 LTC_SET_ASN1(seq_curve, 1, LTC_ASN1_OCTET_STRING, bin_b, (unsigned long)ECC_MAXSIZE);
141
142 /* try to load private key */
143 if ((err = der_decode_sequence(in, inlen, seq_priv, 3)) != CRYPT_OK) { goto error; }
144 len_k = seq_priv[1].size;
145 len_xy = seq_priv[3].size;
146 len_a = seq_curve[0].size;
147 len_b = seq_curve[1].size;
148 len_g = seq_ecparams[3].size;
149 /* create bignums */
150 if ((err = mp_read_unsigned_bin(a, bin_a, len_a)) != CRYPT_OK) { goto error; }
151 if ((err = mp_read_unsigned_bin(b, bin_b, len_b)) != CRYPT_OK) { goto error; }
152 if ((err = ecc_import_point(bin_g, len_g, prime, a, b, gx, gy)) != CRYPT_OK) { goto error; }
153 /* load curve parameters */
154 if ((err = _populate_dp(a, b, prime, order, gx, gy, cofactor, dp)) != CRYPT_OK) { goto error; }
155 /* load private+public key */
156 if ((err = ecc_import_raw(bin_k, len_k, key, dp)) != CRYPT_OK) { goto error; }
157 }
158
159 err = CRYPT_OK;
160 error:
161 mp_clear_multi(prime, order, a, b, gx, gy, NULL);
162 return err;
163 }
164
165 #endif
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 */
9
10 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
11 *
12 */
13
14 #include "tomcrypt.h"
15
16 /* origin of this code - OLPC */
17
18 #ifdef LTC_MECC
19
20 /**
21 Verify a key according to ANSI spec
22 @param key The key to validate
23 @return CRYPT_OK if successful
24 */
25
26 int ecc_verify_key(ecc_key *key)
27 {
28 int err;
29 void *prime = NULL;
30 void *order = NULL;
31 void *a = NULL;
32 ecc_point *test_output = NULL;
33 test_output = malloc(sizeof(ecc_point));
34
35 /* XXX test_output->infinity = 0; */
36 if (mp_init_multi(&(test_output->x), &(test_output->y), &(test_output->z), &order, &prime, NULL) != CRYPT_OK) {
37 return CRYPT_MEM;
38 }
39
40 /* Test 1: Are the x amd y points of the public key in the field? */
41 if((err = ltc_mp.read_radix(prime, key->dp->prime, 16)) != CRYPT_OK) { goto error;}
42
43 if(ltc_mp.compare_d(key->pubkey.z, 1) == LTC_MP_EQ) {
44 if(
45 (ltc_mp.compare(key->pubkey.x, prime) != LTC_MP_LT)
46 || (ltc_mp.compare(key->pubkey.y, prime) != LTC_MP_LT)
47 || (ltc_mp.compare_d(key->pubkey.x, 0) != LTC_MP_GT)
48 || (ltc_mp.compare_d(key->pubkey.y, 0) != LTC_MP_GT) )
49 {
50 err = CRYPT_INVALID_PACKET;
51 goto error;
52 }
53 }
54
55 /* Test 2: is the public key on the curve? */
56 if((err = ltc_ecc_is_point(key->dp, key->pubkey.x, key->pubkey.y)) != CRYPT_OK) { goto error;}
57
58 /* Test 3: does nG = O? (n = order, 0 = point at infinity, G = public key) */
59 if((err = ltc_mp.read_radix(order, key->dp->order, 16)) != CRYPT_OK) { goto error;}
60 if((err = ltc_mp.read_radix(a, key->dp->A, 16)) != CRYPT_OK) { goto error;}
61 if((err = ltc_ecc_mulmod(order, &(key->pubkey), test_output, a, prime, 1)) != CRYPT_OK) {
62 goto error;
63 }
64
65 /* XXX
66 if(!test_output->infinity){
67 err = CRYPT_INVALID_PACKET;
68 goto error;
69 }
70 */
71
72 err = CRYPT_OK;
73 error:
74 mp_clear_multi(prime, order, test_output->z, test_output->y, test_output->x, NULL);
75 return err;
76 }
77
78 #endif