comparison src/pk/ecc/ecc_sys.c @ 209:39d5d58461d6 libtomcrypt-orig LTC_1.05

Import of libtomcrypt 1.05
author Matt Johnston <matt@ucc.asn.au>
date Wed, 06 Jul 2005 03:53:40 +0000
parents 1c15b283127b
children
comparison
equal deleted inserted replaced
191:1c15b283127b 209:39d5d58461d6
31 prng_state *prng, int wprng, int hash, 31 prng_state *prng, int wprng, int hash,
32 ecc_key *key) 32 ecc_key *key)
33 { 33 {
34 unsigned char *pub_expt, *ecc_shared, *skey; 34 unsigned char *pub_expt, *ecc_shared, *skey;
35 ecc_key pubkey; 35 ecc_key pubkey;
36 unsigned long x, y, z, hashsize, pubkeysize; 36 unsigned long x, y, pubkeysize;
37 int err; 37 int err;
38 38
39 LTC_ARGCHK(in != NULL); 39 LTC_ARGCHK(in != NULL);
40 LTC_ARGCHK(out != NULL); 40 LTC_ARGCHK(out != NULL);
41 LTC_ARGCHK(outlen != NULL); 41 LTC_ARGCHK(outlen != NULL);
80 if ((err = ecc_export(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) { 80 if ((err = ecc_export(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) {
81 ecc_free(&pubkey); 81 ecc_free(&pubkey);
82 goto LBL_ERR; 82 goto LBL_ERR;
83 } 83 }
84 84
85 /* now check if the out buffer is big enough */
86 if (*outlen < (9 + PACKET_SIZE + pubkeysize + hash_descriptor[hash].hashsize)) {
87 ecc_free(&pubkey);
88 err = CRYPT_BUFFER_OVERFLOW;
89 goto LBL_ERR;
90 }
91
92 /* make random key */ 85 /* make random key */
93 hashsize = hash_descriptor[hash].hashsize; 86 x = ECC_BUF_SIZE;
94 x = ECC_BUF_SIZE;
95 if ((err = ecc_shared_secret(&pubkey, key, ecc_shared, &x)) != CRYPT_OK) { 87 if ((err = ecc_shared_secret(&pubkey, key, ecc_shared, &x)) != CRYPT_OK) {
96 ecc_free(&pubkey); 88 ecc_free(&pubkey);
97 goto LBL_ERR; 89 goto LBL_ERR;
98 } 90 }
99 ecc_free(&pubkey); 91 ecc_free(&pubkey);
100 z = MAXBLOCKSIZE; 92 y = MAXBLOCKSIZE;
101 if ((err = hash_memory(hash, ecc_shared, x, skey, &z)) != CRYPT_OK) { 93 if ((err = hash_memory(hash, ecc_shared, x, skey, &y)) != CRYPT_OK) {
102 goto LBL_ERR; 94 goto LBL_ERR;
103 } 95 }
104 96
105 /* store header */ 97 /* Encrypt key */
106 packet_store_header(out, PACKET_SECT_ECC, PACKET_SUB_ENC_KEY); 98 for (x = 0; x < inlen; x++) {
107 99 skey[x] ^= in[x];
108 /* output header */ 100 }
109 y = PACKET_SIZE; 101
110 102 err = der_encode_sequence_multi(out, outlen,
111 /* size of hash name and the name itself */ 103 LTC_ASN1_OBJECT_IDENTIFIER, hash_descriptor[hash].OIDlen, hash_descriptor[hash].OID,
112 out[y++] = hash_descriptor[hash].ID; 104 LTC_ASN1_OCTET_STRING, pubkeysize, pub_expt,
113 105 LTC_ASN1_OCTET_STRING, inlen, skey,
114 /* length of ECC pubkey and the key itself */ 106 LTC_ASN1_EOL, 0UL, NULL);
115 STORE32L(pubkeysize, out+y); 107
116 y += 4;
117
118 for (x = 0; x < pubkeysize; x++, y++) {
119 out[y] = pub_expt[x];
120 }
121
122 STORE32L(inlen, out+y);
123 y += 4;
124
125 /* Encrypt/Store the encrypted key */
126 for (x = 0; x < inlen; x++, y++) {
127 out[y] = skey[x] ^ in[x];
128 }
129 *outlen = y;
130
131 err = CRYPT_OK;
132 LBL_ERR: 108 LBL_ERR:
133 #ifdef LTC_CLEAN_STACK 109 #ifdef LTC_CLEAN_STACK
134 /* clean up */ 110 /* clean up */
135 zeromem(pub_expt, ECC_BUF_SIZE); 111 zeromem(pub_expt, ECC_BUF_SIZE);
136 zeromem(ecc_shared, ECC_BUF_SIZE); 112 zeromem(ecc_shared, ECC_BUF_SIZE);
155 */ 131 */
156 int ecc_decrypt_key(const unsigned char *in, unsigned long inlen, 132 int ecc_decrypt_key(const unsigned char *in, unsigned long inlen,
157 unsigned char *out, unsigned long *outlen, 133 unsigned char *out, unsigned long *outlen,
158 ecc_key *key) 134 ecc_key *key)
159 { 135 {
160 unsigned char *shared_secret, *skey; 136 unsigned char *ecc_shared, *skey, *pub_expt;
161 unsigned long x, y, z, hashsize, keysize; 137 unsigned long x, y, hashOID[32];
162 int hash, err; 138 int hash, err;
163 ecc_key pubkey; 139 ecc_key pubkey;
140 ltc_asn1_list decode[3];
164 141
165 LTC_ARGCHK(in != NULL); 142 LTC_ARGCHK(in != NULL);
166 LTC_ARGCHK(out != NULL); 143 LTC_ARGCHK(out != NULL);
167 LTC_ARGCHK(outlen != NULL); 144 LTC_ARGCHK(outlen != NULL);
168 LTC_ARGCHK(key != NULL); 145 LTC_ARGCHK(key != NULL);
170 /* right key type? */ 147 /* right key type? */
171 if (key->type != PK_PRIVATE) { 148 if (key->type != PK_PRIVATE) {
172 return CRYPT_PK_NOT_PRIVATE; 149 return CRYPT_PK_NOT_PRIVATE;
173 } 150 }
174 151
175 /* correct length ? */ 152 /* decode to find out hash */
176 if (inlen < PACKET_SIZE+1+4+4) { 153 LTC_SET_ASN1(decode, 0, LTC_ASN1_OBJECT_IDENTIFIER, hashOID, sizeof(hashOID)/sizeof(hashOID[0]));
154
155 if ((err = der_decode_sequence(in, inlen, decode, 1)) != CRYPT_OK) {
156 return err;
157 }
158 for (hash = 0; hash_descriptor[hash].name != NULL &&
159 (hash_descriptor[hash].OIDlen != decode[0].size ||
160 memcmp(hash_descriptor[hash].OID, hashOID, sizeof(unsigned long)*decode[0].size)); hash++);
161
162 if (hash_descriptor[hash].name == NULL) {
177 return CRYPT_INVALID_PACKET; 163 return CRYPT_INVALID_PACKET;
178 } else { 164 }
179 inlen -= PACKET_SIZE+1+4+4; 165
180 } 166 /* we now have the hash! */
181
182 /* is header correct? */
183 if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_ECC, PACKET_SUB_ENC_KEY)) != CRYPT_OK) {
184 return err;
185 }
186
187 /* now lets get the hash name */
188 y = PACKET_SIZE;
189 hash = find_hash_id(in[y++]);
190 if (hash == -1) {
191 return CRYPT_INVALID_HASH;
192 }
193
194 /* common values */
195 hashsize = hash_descriptor[hash].hashsize;
196
197 /* get public key */
198 LOAD32L(x, in+y);
199 if (inlen < x) {
200 return CRYPT_INVALID_PACKET;
201 } else {
202 inlen -= x;
203 }
204 y += 4;
205 if ((err = ecc_import(in+y, x, &pubkey)) != CRYPT_OK) {
206 return err;
207 }
208 y += x;
209 167
210 /* allocate memory */ 168 /* allocate memory */
211 shared_secret = XMALLOC(ECC_BUF_SIZE); 169 pub_expt = XMALLOC(ECC_BUF_SIZE);
212 skey = XMALLOC(MAXBLOCKSIZE); 170 ecc_shared = XMALLOC(ECC_BUF_SIZE);
213 if (shared_secret == NULL || skey == NULL) { 171 skey = XMALLOC(MAXBLOCKSIZE);
214 if (shared_secret != NULL) { 172 if (pub_expt == NULL || ecc_shared == NULL || skey == NULL) {
215 XFREE(shared_secret); 173 if (pub_expt != NULL) {
174 XFREE(pub_expt);
175 }
176 if (ecc_shared != NULL) {
177 XFREE(ecc_shared);
216 } 178 }
217 if (skey != NULL) { 179 if (skey != NULL) {
218 XFREE(skey); 180 XFREE(skey);
219 } 181 }
220 ecc_free(&pubkey);
221 return CRYPT_MEM; 182 return CRYPT_MEM;
183 }
184 LTC_SET_ASN1(decode, 1, LTC_ASN1_OCTET_STRING, pub_expt, ECC_BUF_SIZE);
185 LTC_SET_ASN1(decode, 2, LTC_ASN1_OCTET_STRING, skey, MAXBLOCKSIZE);
186
187 /* read the structure in now */
188 if ((err = der_decode_sequence(in, inlen, decode, 3)) != CRYPT_OK) {
189 goto LBL_ERR;
190 }
191
192 /* import ECC key from packet */
193 if ((err = ecc_import(decode[1].data, decode[1].size, &pubkey)) != CRYPT_OK) {
194 goto LBL_ERR;
222 } 195 }
223 196
224 /* make shared key */ 197 /* make shared key */
225 x = ECC_BUF_SIZE; 198 x = ECC_BUF_SIZE;
226 if ((err = ecc_shared_secret(key, &pubkey, shared_secret, &x)) != CRYPT_OK) { 199 if ((err = ecc_shared_secret(key, &pubkey, ecc_shared, &x)) != CRYPT_OK) {
227 ecc_free(&pubkey); 200 ecc_free(&pubkey);
228 goto LBL_ERR; 201 goto LBL_ERR;
229 } 202 }
230 ecc_free(&pubkey); 203 ecc_free(&pubkey);
231 204
232 z = MAXBLOCKSIZE; 205 y = MAXBLOCKSIZE;
233 if ((err = hash_memory(hash, shared_secret, x, skey, &z)) != CRYPT_OK) { 206 if ((err = hash_memory(hash, ecc_shared, x, ecc_shared, &y)) != CRYPT_OK) {
234 goto LBL_ERR; 207 goto LBL_ERR;
235 } 208 }
236 209
237 LOAD32L(keysize, in+y); 210 /* ensure the hash of the shared secret is at least as big as the encrypt itself */
238 if (inlen < keysize) { 211 if (decode[2].size > y) {
239 err = CRYPT_INVALID_PACKET; 212 err = CRYPT_INVALID_PACKET;
240 goto LBL_ERR; 213 goto LBL_ERR;
241 } else { 214 }
242 inlen -= keysize; 215
243 } 216 /* avoid buffer overflow */
244 y += 4; 217 if (*outlen < decode[2].size) {
245 218 err = CRYPT_BUFFER_OVERFLOW;
246 if (*outlen < keysize) { 219 goto LBL_ERR;
247 err = CRYPT_BUFFER_OVERFLOW;
248 goto LBL_ERR;
249 } 220 }
250 221
251 /* Decrypt the key */ 222 /* Decrypt the key */
252 for (x = 0; x < keysize; x++, y++) { 223 for (x = 0; x < decode[2].size; x++) {
253 out[x] = skey[x] ^ in[y]; 224 out[x] = skey[x] ^ ecc_shared[x];
254 } 225 }
255 226 *outlen = x;
256 *outlen = keysize;
257 227
258 err = CRYPT_OK; 228 err = CRYPT_OK;
259 LBL_ERR: 229 LBL_ERR:
260 #ifdef LTC_CLEAN_STACK 230 #ifdef LTC_CLEAN_STACK
261 zeromem(shared_secret, ECC_BUF_SIZE); 231 zeromem(pub_expt, ECC_BUF_SIZE);
262 zeromem(skey, MAXBLOCKSIZE); 232 zeromem(ecc_shared, ECC_BUF_SIZE);
233 zeromem(skey, MAXBLOCKSIZE);
263 #endif 234 #endif
264 235
236 XFREE(pub_expt);
237 XFREE(ecc_shared);
265 XFREE(skey); 238 XFREE(skey);
266 XFREE(shared_secret);
267 239
268 return err; 240 return err;
269 } 241 }
270 242
271 /** 243 /**
282 int ecc_sign_hash(const unsigned char *in, unsigned long inlen, 254 int ecc_sign_hash(const unsigned char *in, unsigned long inlen,
283 unsigned char *out, unsigned long *outlen, 255 unsigned char *out, unsigned long *outlen,
284 prng_state *prng, int wprng, ecc_key *key) 256 prng_state *prng, int wprng, ecc_key *key)
285 { 257 {
286 ecc_key pubkey; 258 ecc_key pubkey;
287 mp_int b, p; 259 mp_int r, s, e, p;
288 unsigned char *epubkey, *er;
289 unsigned long x, y, pubkeysize, rsize;
290 int err; 260 int err;
291 261
292 LTC_ARGCHK(in != NULL); 262 LTC_ARGCHK(in != NULL);
293 LTC_ARGCHK(out != NULL); 263 LTC_ARGCHK(out != NULL);
294 LTC_ARGCHK(outlen != NULL); 264 LTC_ARGCHK(outlen != NULL);
306 276
307 if ((err = prng_is_valid(wprng)) != CRYPT_OK) { 277 if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
308 return err; 278 return err;
309 } 279 }
310 280
311 /* make up a key and export the public copy */ 281 /* get the hash and load it as a bignum into 'e' */
312 if ((err = ecc_make_key(prng, wprng, ecc_get_size(key), &pubkey)) != CRYPT_OK) {
313 return err;
314 }
315
316 /* allocate ram */
317 epubkey = XMALLOC(ECC_BUF_SIZE);
318 er = XMALLOC(ECC_BUF_SIZE);
319 if (epubkey == NULL || er == NULL) {
320 if (epubkey != NULL) {
321 XFREE(epubkey);
322 }
323 if (er != NULL) {
324 XFREE(er);
325 }
326 ecc_free(&pubkey);
327 return CRYPT_MEM;
328 }
329
330 pubkeysize = ECC_BUF_SIZE;
331 if ((err = ecc_export(epubkey, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) {
332 ecc_free(&pubkey);
333 goto LBL_ERR;
334 }
335
336 /* get the hash and load it as a bignum into 'b' */
337 /* init the bignums */ 282 /* init the bignums */
338 if ((err = mp_init_multi(&b, &p, NULL)) != MP_OKAY) { 283 if ((err = mp_init_multi(&r, &s, &p, &e, NULL)) != MP_OKAY) {
339 ecc_free(&pubkey); 284 ecc_free(&pubkey);
340 err = mpi_to_ltc_error(err); 285 err = mpi_to_ltc_error(err);
341 goto LBL_ERR; 286 goto LBL_ERR;
342 } 287 }
343 if ((err = mp_read_radix(&p, (char *)sets[key->idx].order, 64)) != MP_OKAY) { goto error; } 288 if ((err = mp_read_radix(&p, (char *)sets[key->idx].order, 64)) != MP_OKAY) { goto error; }
344 if ((err = mp_read_unsigned_bin(&b, (unsigned char *)in, (int)inlen)) != MP_OKAY) { goto error; } 289 if ((err = mp_read_unsigned_bin(&e, (unsigned char *)in, (int)inlen)) != MP_OKAY) { goto error; }
345 290
346 /* find b = (m - x)/k */ 291 /* make up a key and export the public copy */
347 if ((err = mp_invmod(&pubkey.k, &p, &pubkey.k)) != MP_OKAY) { goto error; } /* k = 1/k */ 292 for (;;) {
348 if ((err = mp_submod(&b, &key->k, &p, &b)) != MP_OKAY) { goto error; } /* b = m - x */ 293 if ((err = ecc_make_key(prng, wprng, ecc_get_size(key), &pubkey)) != CRYPT_OK) {
349 if ((err = mp_mulmod(&b, &pubkey.k, &p, &b)) != MP_OKAY) { goto error; } /* b = (m - x)/k */ 294 return err;
350 295 }
351 /* export it */ 296
352 rsize = (unsigned long)mp_unsigned_bin_size(&b); 297 /* find r = x1 mod n */
353 if (rsize > ECC_BUF_SIZE) { 298 if ((err = mp_mod(&pubkey.pubkey.x, &p, &r)) != MP_OKAY) { goto error; }
354 err = CRYPT_BUFFER_OVERFLOW; 299
355 goto error; 300 if (mp_iszero(&r)) {
356 } 301 ecc_free(&pubkey);
357 if ((err = mp_to_unsigned_bin(&b, er)) != MP_OKAY) { goto error; } 302 } else {
358 303 /* find s = (e + xr)/k */
359 /* now lets check the outlen before we write */ 304 if ((err = mp_invmod(&pubkey.k, &p, &pubkey.k)) != MP_OKAY) { goto error; } /* k = 1/k */
360 if (*outlen < (12 + rsize + pubkeysize)) { 305 if ((err = mp_mulmod(&key->k, &r, &p, &s)) != MP_OKAY) { goto error; } /* s = xr */
361 err = CRYPT_BUFFER_OVERFLOW; 306 if ((err = mp_addmod(&e, &s, &p, &s)) != MP_OKAY) { goto error; } /* s = e + xr */
362 goto LBL_ERR; 307 if ((err = mp_mulmod(&s, &pubkey.k, &p, &s)) != MP_OKAY) { goto error; } /* s = (e + xr)/k */
363 } 308
364 309 if (mp_iszero(&s)) {
365 /* lets output */ 310 ecc_free(&pubkey);
366 y = PACKET_SIZE; 311 } else {
367 312 break;
368 /* size of public key */ 313 }
369 STORE32L(pubkeysize, out+y); 314 }
370 y += 4; 315 }
371 316
372 /* copy the public key */ 317 /* store as SEQUENCE { r, s -- integer } */
373 for (x = 0; x < pubkeysize; x++, y++) { 318 err = der_encode_sequence_multi(out, outlen,
374 out[y] = epubkey[x]; 319 LTC_ASN1_INTEGER, 1UL, &r,
375 } 320 LTC_ASN1_INTEGER, 1UL, &s,
376 321 LTC_ASN1_EOL, 0UL, NULL);
377 /* size of 'r' */
378 STORE32L(rsize, out+y);
379 y += 4;
380
381 /* copy r */
382 for (x = 0; x < rsize; x++, y++) {
383 out[y] = er[x];
384 }
385
386 /* store header */
387 packet_store_header(out, PACKET_SECT_ECC, PACKET_SUB_SIGNED);
388 *outlen = y;
389
390 /* all ok */
391 err = CRYPT_OK;
392 goto LBL_ERR; 322 goto LBL_ERR;
393 error: 323 error:
394 err = mpi_to_ltc_error(err); 324 err = mpi_to_ltc_error(err);
395 LBL_ERR: 325 LBL_ERR:
396 mp_clear_multi(&b, &p, NULL); 326 mp_clear_multi(&r, &s, &p, &e, NULL);
397 ecc_free(&pubkey); 327 ecc_free(&pubkey);
398 #ifdef LTC_CLEAN_STACK
399 zeromem(er, ECC_BUF_SIZE);
400 zeromem(epubkey, ECC_BUF_SIZE);
401 #endif
402
403 XFREE(epubkey);
404 XFREE(er);
405 328
406 return err; 329 return err;
407 } 330 }
408 331
409 /* verify that mG = (bA + Y) 332 /* verify
410 * 333 *
411 * The signatures work by making up a fresh key "a" with a public key "A". Now we want to sign so the 334 * w = s^-1 mod n
412 * public key Y = xG can verify it. 335 * u1 = xw
413 * 336 * u2 = rw
414 * b = (m - x)/k, A is the public key embedded and Y is the users public key [who signed it] 337 * X = u1*G + u2*Q
415 * A = kG therefore bA == ((m-x)/k)kG == (m-x)G 338 * v = X_x1 mod n
416 * 339 * accept if v == r
417 * Adding Y = xG to the bA gives us (m-x)G + xG == mG
418 *
419 * The user given only xG, kG and b cannot determine k or x which means they can't find the private key.
420 *
421 */ 340 */
422 341
423 /** 342 /**
424 Verify an ECC signature 343 Verify an ECC signature
425 @param sig The signature to verify 344 @param sig The signature to verify
432 */ 351 */
433 int ecc_verify_hash(const unsigned char *sig, unsigned long siglen, 352 int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
434 const unsigned char *hash, unsigned long hashlen, 353 const unsigned char *hash, unsigned long hashlen,
435 int *stat, ecc_key *key) 354 int *stat, ecc_key *key)
436 { 355 {
437 ecc_point *mG; 356 ecc_point *mG, *mQ;
438 ecc_key pubkey; 357 mp_int r, s, v, w, u1, u2, e, p, m;
439 mp_int b, p, m, mu; 358 mp_digit mp;
440 unsigned long x, y;
441 int err; 359 int err;
442 360
443 LTC_ARGCHK(sig != NULL); 361 LTC_ARGCHK(sig != NULL);
444 LTC_ARGCHK(hash != NULL); 362 LTC_ARGCHK(hash != NULL);
445 LTC_ARGCHK(stat != NULL); 363 LTC_ARGCHK(stat != NULL);
446 LTC_ARGCHK(key != NULL); 364 LTC_ARGCHK(key != NULL);
447 365
448 /* default to invalid signature */ 366 /* default to invalid signature */
449 *stat = 0; 367 *stat = 0;
450 368
451 if (siglen < PACKET_SIZE+4+4) { 369 /* is the IDX valid ? */
452 return CRYPT_INVALID_PACKET; 370 if (is_valid_idx(key->idx) != 1) {
453 } else { 371 return CRYPT_PK_INVALID_TYPE;
454 siglen -= PACKET_SIZE+4+4; 372 }
455 } 373
456 374 /* allocate ints */
457 /* is the message format correct? */ 375 if ((err = mp_init_multi(&r, &s, &v, &w, &u1, &u2, &p, &e, &m, NULL)) != MP_OKAY) {
458 if ((err = packet_valid_header((unsigned char *)sig, PACKET_SECT_ECC, PACKET_SUB_SIGNED)) != CRYPT_OK) { 376 return CRYPT_MEM;
459 return err; 377 }
460 } 378
461 379 /* allocate points */
462 /* get hash name */
463 y = PACKET_SIZE;
464
465 /* get size of public key */
466 LOAD32L(x, sig+y);
467 if (siglen < x) {
468 return CRYPT_INVALID_PACKET;
469 } else {
470 siglen -= x;
471 }
472 y += 4;
473
474 /* load the public key */
475 if ((err = ecc_import((unsigned char*)sig+y, x, &pubkey)) != CRYPT_OK) {
476 return err;
477 }
478 y += x;
479
480 /* load size of 'b' */
481 LOAD32L(x, sig+y);
482 if (siglen < x) {
483 return CRYPT_INVALID_PACKET;
484 } else {
485 siglen -= x;
486 }
487 y += 4;
488
489 /* init values */
490 if ((err = mp_init_multi(&b, &m, &p, &mu, NULL)) != MP_OKAY) {
491 ecc_free(&pubkey);
492 return mpi_to_ltc_error(err);
493 }
494
495 mG = new_point(); 380 mG = new_point();
496 if (mG == NULL) { 381 mQ = new_point();
497 mp_clear_multi(&b, &m, &p, &mu, NULL); 382 if (mQ == NULL || mG == NULL) {
498 ecc_free(&pubkey); 383 err = CRYPT_MEM;
499 return CRYPT_MEM; 384 goto done;
500 } 385 }
501 386
502 /* load b */ 387 /* parse header */
503 if ((err = mp_read_unsigned_bin(&b, (unsigned char *)sig+y, (int)x)) != MP_OKAY) { goto error; } 388 if ((err = der_decode_sequence_multi(sig, siglen,
504 y += x; 389 LTC_ASN1_INTEGER, 1UL, &r,
505 390 LTC_ASN1_INTEGER, 1UL, &s,
506 /* get m in binary a bignum */ 391 LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
507 if ((err = mp_read_unsigned_bin(&m, (unsigned char *)hash, (int)hashlen)) != MP_OKAY) { goto error; } 392 goto done;
508 393 }
509 /* load prime */ 394
510 if ((err = mp_read_radix(&p, (char *)sets[key->idx].prime, 64)) != MP_OKAY) { goto error; } 395 /* get the order */
511 396 if ((err = mp_read_radix(&p, (char *)sets[key->idx].order, 64)) != MP_OKAY) { goto error; }
512 /* calculate barrett stuff */ 397
513 mp_set(&mu, 1); 398 /* get the modulus */
514 mp_lshd(&mu, 2 * USED(&p)); 399 if ((err = mp_read_radix(&m, (char *)sets[key->idx].prime, 64)) != MP_OKAY) { goto error; }
515 if ((err = mp_div(&mu, &p, &mu, NULL)) != MP_OKAY) { goto error; } 400
516 401 /* check for zero */
517 /* get bA */ 402 if (mp_iszero(&r) || mp_iszero(&s) || mp_cmp(&r, &p) != MP_LT || mp_cmp(&s, &p) != MP_LT) {
518 if ((err = ecc_mulmod(&b, &pubkey.pubkey, &pubkey.pubkey, &p)) != CRYPT_OK) { goto done; } 403 err = CRYPT_INVALID_PACKET;
519 404 goto done;
520 /* get bA + Y */ 405 }
521 if ((err = add_point(&pubkey.pubkey, &key->pubkey, &pubkey.pubkey, &p, &mu)) != CRYPT_OK) { goto done; } 406
522 407 /* read hash */
523 /* we have to transform it */ 408 if ((err = mp_read_unsigned_bin(&e, (unsigned char *)hash, (int)hashlen)) != MP_OKAY) { goto error; }
524 if ((err = ecc_map(&pubkey.pubkey, &p, &mu)) != CRYPT_OK) { goto done; } 409
525 410 /* w = s^-1 mod n */
526 /* get mG */ 411 if ((err = mp_invmod(&s, &p, &w)) != MP_OKAY) { goto error; }
412
413 /* u1 = ew */
414 if ((err = mp_mulmod(&e, &w, &p, &u1)) != MP_OKAY) { goto error; }
415
416 /* u2 = rw */
417 if ((err = mp_mulmod(&r, &w, &p, &u2)) != MP_OKAY) { goto error; }
418
419 /* find mG = u1*G */
527 if ((err = mp_read_radix(&mG->x, (char *)sets[key->idx].Gx, 64)) != MP_OKAY) { goto error; } 420 if ((err = mp_read_radix(&mG->x, (char *)sets[key->idx].Gx, 64)) != MP_OKAY) { goto error; }
528 if ((err = mp_read_radix(&mG->y, (char *)sets[key->idx].Gy, 64)) != MP_OKAY) { goto error; } 421 if ((err = mp_read_radix(&mG->y, (char *)sets[key->idx].Gy, 64)) != MP_OKAY) { goto error; }
529 mp_set(&mG->z, 1); 422 mp_set(&mG->z, 1);
530 if ((err = ecc_mulmod(&m, mG, mG, &p)) != CRYPT_OK) { goto done; } 423 if ((err = ecc_mulmod(&u1, mG, mG, &m, 0)) != CRYPT_OK) { goto done; }
531 424
532 /* compare mG to bA + Y */ 425 /* find mQ = u2*Q */
533 if (mp_cmp(&mG->x, &pubkey.pubkey.x) == MP_EQ && mp_cmp(&mG->y, &pubkey.pubkey.y) == MP_EQ) { 426 if ((err = mp_copy(&key->pubkey.x, &mQ->x)) != MP_OKAY) { goto error; }
427 if ((err = mp_copy(&key->pubkey.y, &mQ->y)) != MP_OKAY) { goto error; }
428 if ((err = mp_copy(&key->pubkey.z, &mQ->z)) != MP_OKAY) { goto error; }
429 if ((err = ecc_mulmod(&u2, mQ, mQ, &m, 0)) != CRYPT_OK) { goto done; }
430
431 /* find the montgomery mp */
432 if ((err = mp_montgomery_setup(&m, &mp)) != MP_OKAY) { goto error; }
433 /* add them */
434 if ((err = add_point(mQ, mG, mG, &m, mp)) != CRYPT_OK) { goto done; }
435
436 /* reduce */
437 if ((err = ecc_map(mG, &m, mp)) != CRYPT_OK) { goto done; }
438
439 /* v = X_x1 mod n */
440 if ((err = mp_mod(&mG->x, &p, &v)) != CRYPT_OK) { goto done; }
441
442 /* does v == r */
443 if (mp_cmp(&v, &r) == MP_EQ) {
534 *stat = 1; 444 *stat = 1;
535 } 445 }
536 446
537 /* clear up and return */ 447 /* clear up and return */
538 err = CRYPT_OK; 448 err = CRYPT_OK;
539 goto done; 449 goto done;
540 error: 450 error:
541 err = mpi_to_ltc_error(err); 451 err = mpi_to_ltc_error(err);
542 done: 452 done:
543 del_point(mG); 453 del_point(mG);
544 ecc_free(&pubkey); 454 del_point(mQ);
545 mp_clear_multi(&p, &m, &b, &mu, NULL); 455 mp_clear_multi(&r, &s, &v, &w, &u1, &u2, &p, &e, &m, NULL);
546 return err; 456 return err;
547 } 457 }
548 458
459
460 /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_sys.c,v $ */
461 /* $Revision: 1.18 $ */
462 /* $Date: 2005/06/14 20:47:55 $ */