ECC full import/export (not final version yet)
Karel Miko
10 years ago
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 |