Mercurial > dropbear
comparison libtomcrypt/src/math/fp/ltc_ecc_fp_mulmod.c @ 1435:f849a5ca2efc
update to libtomcrypt 1.17 (with Dropbear changes)
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sat, 24 Jun 2017 17:50:50 +0800 |
parents | 0cbe8f6dbf9e |
children | 6dba84798cd5 |
comparison
equal
deleted
inserted
replaced
1434:27b9ddb06b09 | 1435:f849a5ca2efc |
---|---|
4 * algorithms in a highly modular and flexible manner. | 4 * algorithms in a highly modular and flexible manner. |
5 * | 5 * |
6 * The library is free for all purposes without any express | 6 * The library is free for all purposes without any express |
7 * guarantee it works. | 7 * guarantee it works. |
8 * | 8 * |
9 * Tom St Denis, [email protected], http://libtomcrypt.com | 9 * Tom St Denis, [email protected], http://libtom.org |
10 */ | 10 */ |
11 #include "tomcrypt.h" | 11 #include "tomcrypt.h" |
12 | 12 |
13 /** | 13 /** |
14 @file ltc_ecc_fp_mulmod.c | 14 @file ltc_ecc_fp_mulmod.c |
15 ECC Crypto, Tom St Denis | 15 ECC Crypto, Tom St Denis |
16 */ | 16 */ |
17 | 17 |
18 #if defined(MECC) && defined(MECC_FP) | 18 #if defined(LTC_MECC) && defined(LTC_MECC_FP) |
19 #include <limits.h> | 19 #include <limits.h> |
20 | 20 |
21 /* number of entries in the cache */ | 21 /* number of entries in the cache */ |
22 #ifndef FP_ENTRIES | 22 #ifndef FP_ENTRIES |
23 #define FP_ENTRIES 16 | 23 #define FP_ENTRIES 16 |
36 static struct { | 36 static struct { |
37 ecc_point *g, /* cached COPY of base point */ | 37 ecc_point *g, /* cached COPY of base point */ |
38 *LUT[1U<<FP_LUT]; /* fixed point lookup */ | 38 *LUT[1U<<FP_LUT]; /* fixed point lookup */ |
39 void *mu; /* copy of the montgomery constant */ | 39 void *mu; /* copy of the montgomery constant */ |
40 int lru_count; /* amount of times this entry has been used */ | 40 int lru_count; /* amount of times this entry has been used */ |
41 int lock; /* flag to indicate cache eviction permitted (0) or not (1) */ | |
41 } fp_cache[FP_ENTRIES]; | 42 } fp_cache[FP_ENTRIES]; |
42 | 43 |
43 LTC_MUTEX_GLOBAL(ltc_ecc_fp_lock) | 44 LTC_MUTEX_GLOBAL(ltc_ecc_fp_lock) |
44 | 45 |
45 /* simple table to help direct the generation of the LUT */ | 46 /* simple table to help direct the generation of the LUT */ |
570 #endif | 571 #endif |
571 #endif | 572 #endif |
572 #endif | 573 #endif |
573 }; | 574 }; |
574 | 575 |
575 /* find a hole and free as required */ | 576 /* find a hole and free as required, return -1 if no hole found */ |
576 static int find_hole(void) | 577 static int find_hole(void) |
577 { | 578 { |
578 unsigned x; | 579 unsigned x; |
579 int y, z; | 580 int y, z; |
580 for (z = 0, y = INT_MAX, x = 0; x < FP_ENTRIES; x++) { | 581 for (z = -1, y = INT_MAX, x = 0; x < FP_ENTRIES; x++) { |
581 if (fp_cache[x].lru_count < y) { | 582 if (fp_cache[x].lru_count < y && fp_cache[x].lock == 0) { |
582 z = x; | 583 z = x; |
583 y = fp_cache[x].lru_count; | 584 y = fp_cache[x].lru_count; |
584 } | 585 } |
585 } | 586 } |
586 | 587 |
590 --(fp_cache[x].lru_count); | 591 --(fp_cache[x].lru_count); |
591 } | 592 } |
592 } | 593 } |
593 | 594 |
594 /* free entry z */ | 595 /* free entry z */ |
595 if (fp_cache[z].g) { | 596 if (z >= 0 && fp_cache[z].g) { |
596 if (fp_cache[z].mu != NULL) { | 597 if (fp_cache[z].mu != NULL) { |
597 mp_clear(fp_cache[z].mu); | 598 mp_clear(fp_cache[z].mu); |
598 fp_cache[z].mu = NULL; | 599 fp_cache[z].mu = NULL; |
599 } | 600 } |
600 ltc_ecc_del_point(fp_cache[z].g); | 601 ltc_ecc_del_point(fp_cache[z].g); |
1098 zeromem(kb, sizeof(kb)); | 1099 zeromem(kb, sizeof(kb)); |
1099 return ltc_ecc_map(R, modulus, mp); | 1100 return ltc_ecc_map(R, modulus, mp); |
1100 } | 1101 } |
1101 | 1102 |
1102 /** ECC Fixed Point mulmod global | 1103 /** ECC Fixed Point mulmod global |
1103 @param k The multiplicand | 1104 Computes kA*A + kB*B = C using Shamir's Trick |
1104 @param G Base point to multiply | 1105 @param A First point to multiply |
1105 @param R [out] Destination of product | 1106 @param kA What to multiple A by |
1106 @param modulus The modulus for the curve | 1107 @param B Second point to multiply |
1107 @param map [boolean] If non-zero maps the point back to affine co-ordinates, otherwise it's left in jacobian-montgomery form | 1108 @param kB What to multiple B by |
1108 @return CRYPT_OK if successful | 1109 @param C [out] Destination point (can overlap with A or B) |
1109 */ | 1110 @param modulus Modulus for curve |
1111 @return CRYPT_OK on success | |
1112 */ | |
1110 int ltc_ecc_fp_mul2add(ecc_point *A, void *kA, | 1113 int ltc_ecc_fp_mul2add(ecc_point *A, void *kA, |
1111 ecc_point *B, void *kB, | 1114 ecc_point *B, void *kB, |
1112 ecc_point *C, void *modulus) | 1115 ecc_point *C, void *modulus) |
1113 { | 1116 { |
1114 int idx1, idx2, err; | 1117 int idx1, idx2, err; |
1121 idx1 = find_base(A); | 1124 idx1 = find_base(A); |
1122 | 1125 |
1123 /* no entry? */ | 1126 /* no entry? */ |
1124 if (idx1 == -1) { | 1127 if (idx1 == -1) { |
1125 /* find hole and add it */ | 1128 /* find hole and add it */ |
1126 idx1 = find_hole(); | 1129 if ((idx1 = find_hole()) >= 0) { |
1127 | 1130 if ((err = add_entry(idx1, A)) != CRYPT_OK) { |
1128 if ((err = add_entry(idx1, A)) != CRYPT_OK) { | 1131 goto LBL_ERR; |
1129 goto LBL_ERR; | 1132 } |
1130 } | 1133 } |
1131 } | 1134 } |
1132 | 1135 if (idx1 != -1) { |
1133 /* increment LRU */ | 1136 /* increment LRU */ |
1134 ++(fp_cache[idx1].lru_count); | 1137 ++(fp_cache[idx1].lru_count); |
1135 | 1138 } |
1139 | |
1136 /* find point */ | 1140 /* find point */ |
1137 idx2 = find_base(B); | 1141 idx2 = find_base(B); |
1138 | 1142 |
1139 /* no entry? */ | 1143 /* no entry? */ |
1140 if (idx2 == -1) { | 1144 if (idx2 == -1) { |
1141 /* find hole and add it */ | 1145 /* find hole and add it */ |
1142 idx2 = find_hole(); | 1146 if ((idx2 = find_hole()) >= 0) { |
1143 | 1147 if ((err = add_entry(idx2, B)) != CRYPT_OK) { |
1144 if ((err = add_entry(idx2, B)) != CRYPT_OK) { | 1148 goto LBL_ERR; |
1145 goto LBL_ERR; | 1149 } |
1146 } | 1150 } |
1147 } | 1151 } |
1148 | 1152 if (idx2 != -1) { |
1149 /* increment LRU */ | 1153 /* increment LRU */ |
1150 ++(fp_cache[idx2].lru_count); | 1154 ++(fp_cache[idx2].lru_count); |
1155 } | |
1151 | 1156 |
1152 /* if it's 2 build the LUT, if it's higher just use the LUT */ | 1157 /* if it's 2 build the LUT, if it's higher just use the LUT */ |
1153 if (fp_cache[idx1].lru_count == 2) { | 1158 if (idx1 >= 0 && fp_cache[idx1].lru_count == 2) { |
1154 /* compute mp */ | 1159 /* compute mp */ |
1155 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; } | 1160 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; } |
1156 | 1161 |
1157 /* compute mu */ | 1162 /* compute mu */ |
1158 if ((err = mp_init(&mu)) != CRYPT_OK) { | 1163 if ((err = mp_init(&mu)) != CRYPT_OK) { |
1167 goto LBL_ERR;; | 1172 goto LBL_ERR;; |
1168 } | 1173 } |
1169 } | 1174 } |
1170 | 1175 |
1171 /* if it's 2 build the LUT, if it's higher just use the LUT */ | 1176 /* if it's 2 build the LUT, if it's higher just use the LUT */ |
1172 if (fp_cache[idx2].lru_count == 2) { | 1177 if (idx2 >= 0 && fp_cache[idx2].lru_count == 2) { |
1173 if (mp == NULL) { | 1178 if (mp == NULL) { |
1174 /* compute mp */ | 1179 /* compute mp */ |
1175 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; } | 1180 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; } |
1176 | 1181 |
1177 /* compute mu */ | 1182 /* compute mu */ |
1188 goto LBL_ERR;; | 1193 goto LBL_ERR;; |
1189 } | 1194 } |
1190 } | 1195 } |
1191 | 1196 |
1192 | 1197 |
1193 if (fp_cache[idx1].lru_count >= 2 && fp_cache[idx2].lru_count >= 2) { | 1198 if (idx1 >=0 && idx2 >= 0 && fp_cache[idx1].lru_count >= 2 && fp_cache[idx2].lru_count >= 2) { |
1194 if (mp == NULL) { | 1199 if (mp == NULL) { |
1195 /* compute mp */ | 1200 /* compute mp */ |
1196 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; } | 1201 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; } |
1197 } | 1202 } |
1198 err = accel_fp_mul2add(idx1, idx2, kA, kB, C, modulus, mp); | 1203 err = accel_fp_mul2add(idx1, idx2, kA, kB, C, modulus, mp); |
1233 /* no entry? */ | 1238 /* no entry? */ |
1234 if (idx == -1) { | 1239 if (idx == -1) { |
1235 /* find hole and add it */ | 1240 /* find hole and add it */ |
1236 idx = find_hole(); | 1241 idx = find_hole(); |
1237 | 1242 |
1238 if ((err = add_entry(idx, G)) != CRYPT_OK) { | 1243 if (idx >= 0) { |
1239 goto LBL_ERR; | 1244 if ((err = add_entry(idx, G)) != CRYPT_OK) { |
1240 } | 1245 goto LBL_ERR; |
1241 } | 1246 } |
1242 | 1247 } |
1243 /* increment LRU */ | 1248 } |
1244 ++(fp_cache[idx].lru_count); | 1249 if (idx != -1) { |
1250 /* increment LRU */ | |
1251 ++(fp_cache[idx].lru_count); | |
1252 } | |
1253 | |
1245 | 1254 |
1246 /* if it's 2 build the LUT, if it's higher just use the LUT */ | 1255 /* if it's 2 build the LUT, if it's higher just use the LUT */ |
1247 if (fp_cache[idx].lru_count == 2) { | 1256 if (idx >= 0 && fp_cache[idx].lru_count == 2) { |
1248 /* compute mp */ | 1257 /* compute mp */ |
1249 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; } | 1258 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; } |
1250 | 1259 |
1251 /* compute mu */ | 1260 /* compute mu */ |
1252 if ((err = mp_init(&mu)) != CRYPT_OK) { | 1261 if ((err = mp_init(&mu)) != CRYPT_OK) { |
1260 if ((err = build_lut(idx, modulus, mp, mu)) != CRYPT_OK) { | 1269 if ((err = build_lut(idx, modulus, mp, mu)) != CRYPT_OK) { |
1261 goto LBL_ERR;; | 1270 goto LBL_ERR;; |
1262 } | 1271 } |
1263 } | 1272 } |
1264 | 1273 |
1265 if (fp_cache[idx].lru_count >= 2) { | 1274 if (idx >= 0 && fp_cache[idx].lru_count >= 2) { |
1266 if (mp == NULL) { | 1275 if (mp == NULL) { |
1267 /* compute mp */ | 1276 /* compute mp */ |
1268 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; } | 1277 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; } |
1269 } | 1278 } |
1270 err = accel_fp_mul(idx, k, R, modulus, mp, map); | 1279 err = accel_fp_mul(idx, k, R, modulus, mp, map); |
1280 mp_clear(mu); | 1289 mp_clear(mu); |
1281 } | 1290 } |
1282 return err; | 1291 return err; |
1283 } | 1292 } |
1284 | 1293 |
1285 /** Free the Fixed Point tables */ | 1294 /* helper function for freeing the cache ... must be called with the cache mutex locked */ |
1286 void ltc_ecc_fp_free(void) | 1295 static void ltc_ecc_fp_free_cache(void) |
1287 { | 1296 { |
1288 unsigned x, y; | 1297 unsigned x, y; |
1289 LTC_MUTEX_LOCK(<c_ecc_fp_lock); | |
1290 for (x = 0; x < FP_ENTRIES; x++) { | 1298 for (x = 0; x < FP_ENTRIES; x++) { |
1291 if (fp_cache[x].g != NULL) { | 1299 if (fp_cache[x].g != NULL) { |
1292 for (y = 0; y < (1U<<FP_LUT); y++) { | 1300 for (y = 0; y < (1U<<FP_LUT); y++) { |
1293 ltc_ecc_del_point(fp_cache[x].LUT[y]); | 1301 ltc_ecc_del_point(fp_cache[x].LUT[y]); |
1294 fp_cache[x].LUT[y] = NULL; | 1302 fp_cache[x].LUT[y] = NULL; |
1298 if (fp_cache[x].mu != NULL) { | 1306 if (fp_cache[x].mu != NULL) { |
1299 mp_clear(fp_cache[x].mu); | 1307 mp_clear(fp_cache[x].mu); |
1300 fp_cache[x].mu = NULL; | 1308 fp_cache[x].mu = NULL; |
1301 } | 1309 } |
1302 fp_cache[x].lru_count = 0; | 1310 fp_cache[x].lru_count = 0; |
1311 fp_cache[x].lock = 0; | |
1303 } | 1312 } |
1304 } | 1313 } |
1314 } | |
1315 | |
1316 /** Free the Fixed Point cache */ | |
1317 void ltc_ecc_fp_free(void) | |
1318 { | |
1319 LTC_MUTEX_LOCK(<c_ecc_fp_lock); | |
1320 ltc_ecc_fp_free_cache(); | |
1305 LTC_MUTEX_UNLOCK(<c_ecc_fp_lock); | 1321 LTC_MUTEX_UNLOCK(<c_ecc_fp_lock); |
1306 } | 1322 } |
1323 | |
1324 /** Add a point to the cache and initialize the LUT | |
1325 @param g The point to add | |
1326 @param modulus Modulus for curve | |
1327 @param lock Flag to indicate if this entry should be locked into the cache or not | |
1328 @return CRYPT_OK on success | |
1329 */ | |
1330 int | |
1331 ltc_ecc_fp_add_point(ecc_point *g, void *modulus, int lock) | |
1332 { | |
1333 int idx; | |
1334 int err; | |
1335 void *mp = NULL; | |
1336 void *mu = NULL; | |
1337 | |
1338 LTC_MUTEX_LOCK(<c_ecc_fp_lock); | |
1339 if ((idx = find_base(g)) >= 0) { | |
1340 /* it is already in the cache ... just check that the LUT is initialized */ | |
1341 if(fp_cache[idx].lru_count >= 2) { | |
1342 LTC_MUTEX_UNLOCK(<c_ecc_fp_lock); | |
1343 return CRYPT_OK; | |
1344 } | |
1345 } | |
1346 | |
1347 if(idx == -1 && (idx = find_hole()) == -1) { | |
1348 err = CRYPT_BUFFER_OVERFLOW; | |
1349 goto LBL_ERR; | |
1350 } | |
1351 if ((err = add_entry(idx, g)) != CRYPT_OK) { | |
1352 goto LBL_ERR; | |
1353 } | |
1354 /* compute mp */ | |
1355 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { | |
1356 goto LBL_ERR; | |
1357 } | |
1358 | |
1359 /* compute mu */ | |
1360 if ((err = mp_init(&mu)) != CRYPT_OK) { | |
1361 goto LBL_ERR; | |
1362 } | |
1363 if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) { | |
1364 goto LBL_ERR; | |
1365 } | |
1366 | |
1367 /* build the LUT */ | |
1368 if ((err = build_lut(idx, modulus, mp, mu)) != CRYPT_OK) { | |
1369 goto LBL_ERR; | |
1370 } | |
1371 fp_cache[idx].lru_count = 2; | |
1372 fp_cache[idx].lock = lock; | |
1373 LBL_ERR: | |
1374 LTC_MUTEX_UNLOCK(<c_ecc_fp_lock); | |
1375 if (mp != NULL) { | |
1376 mp_montgomery_free(mp); | |
1377 } | |
1378 if (mu != NULL) { | |
1379 mp_clear(mu); | |
1380 } | |
1381 return err; | |
1382 } | |
1383 | |
1384 /** Prevent/permit the FP cache from being updated | |
1385 @param flag If flag is 0, remove cache lock (unlock), otherwise lock it | |
1386 */ | |
1387 void ltc_ecc_fp_tablelock(int lock) | |
1388 { | |
1389 int i; | |
1390 | |
1391 LTC_MUTEX_LOCK(<c_ecc_fp_lock); | |
1392 for (i = 0; i < FP_ENTRIES; i++) { | |
1393 fp_cache[i].lock = lock; | |
1394 } | |
1395 LTC_MUTEX_UNLOCK(<c_ecc_fp_lock); | |
1396 } | |
1397 | |
1398 /** Export the current cache as a binary packet | |
1399 @param out [out] pointer to malloc'ed space containing the packet | |
1400 @param outlen [out] size of exported packet | |
1401 @return CRYPT_OK if successful | |
1402 */ | |
1403 int ltc_ecc_fp_save_state(unsigned char **out, unsigned long *outlen) | |
1404 { | |
1405 ltc_asn1_list *cache_entry; | |
1406 unsigned int i, j, k; | |
1407 unsigned long fp_entries, fp_lut, num_entries; | |
1408 int err; | |
1409 | |
1410 LTC_ARGCHK(out != NULL); | |
1411 LTC_ARGCHK(outlen != NULL); | |
1412 | |
1413 fp_entries = FP_ENTRIES; | |
1414 fp_lut = FP_LUT; | |
1415 num_entries = 0; | |
1416 | |
1417 LTC_MUTEX_LOCK(<c_ecc_fp_lock); | |
1418 /* | |
1419 * build the list; | |
1420 Cache DEFINITIONS ::= | |
1421 BEGIN | |
1422 CacheDump ::= SEQUENCE { | |
1423 numEntries SHORTINTEGER, | |
1424 maxEntries SHORTINTEGER, | |
1425 numLUT SHORTINTEGER, | |
1426 cache SEQUENCE OF INTEGER | |
1427 } | |
1428 END | |
1429 * | |
1430 */ | |
1431 /* | |
1432 * The cache itself is a point (3 INTEGERS), | |
1433 * the LUT as pairs of INTEGERS (2 * 1<<FP_LUT), | |
1434 * and the mu INTEGER | |
1435 */ | |
1436 cache_entry = XCALLOC(FP_ENTRIES*(2*(1U<<FP_LUT)+4)+3, sizeof(ltc_asn1_list)); | |
1437 if (cache_entry == NULL) | |
1438 return CRYPT_MEM; | |
1439 j = 1; /* handle the zero'th element later */ | |
1440 | |
1441 LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_SHORT_INTEGER, &fp_entries, 1); | |
1442 LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_SHORT_INTEGER, &fp_lut, 1); | |
1443 | |
1444 for (i = 0; i < FP_ENTRIES; i++) { | |
1445 /* | |
1446 * do not save empty entries, or entries that have not yet had the lut built | |
1447 */ | |
1448 if (fp_cache[i].g == NULL || fp_cache[i].lru_count < 2) { | |
1449 continue; | |
1450 } | |
1451 num_entries++; | |
1452 LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].g->x, 1); | |
1453 LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].g->y, 1); | |
1454 LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].g->z, 1); | |
1455 for (k = 0; k < (1U<<FP_LUT); k++) { | |
1456 LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].LUT[k]->x, 1); | |
1457 LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].LUT[k]->y, 1); | |
1458 } | |
1459 LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].mu, 1); | |
1460 } | |
1461 LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_EOL, 0, 0); | |
1462 | |
1463 LTC_SET_ASN1(cache_entry, 0, LTC_ASN1_SHORT_INTEGER, &num_entries, 1); | |
1464 | |
1465 if ((err = der_length_sequence(cache_entry, j, outlen)) != CRYPT_OK) { | |
1466 goto save_err; | |
1467 } | |
1468 if ((*out = XMALLOC(*outlen)) == NULL) { | |
1469 err = CRYPT_MEM; | |
1470 goto save_err; | |
1471 } | |
1472 err = der_encode_sequence(cache_entry, j, *out, outlen); | |
1473 save_err: | |
1474 XFREE(cache_entry); | |
1475 LTC_MUTEX_UNLOCK(<c_ecc_fp_lock); | |
1476 return err; | |
1477 } | |
1478 | |
1479 /** Import a binary packet into the current cache | |
1480 @param in [in] pointer to packet | |
1481 @param inlen [in] size of packet (bytes) | |
1482 @return CRYPT_OK if successful | |
1483 */ | |
1484 int ltc_ecc_fp_restore_state(unsigned char *in, unsigned long inlen) | |
1485 { | |
1486 int err; | |
1487 ltc_asn1_list *asn1_list; | |
1488 unsigned long num_entries, fp_entries, fp_lut; | |
1489 unsigned long i, j; | |
1490 unsigned int x; | |
1491 | |
1492 LTC_ARGCHK(in != NULL); | |
1493 if (inlen == 0) { | |
1494 return CRYPT_INVALID_ARG; | |
1495 } | |
1496 | |
1497 /* zero indecies */ | |
1498 i = 0; | |
1499 j = 0; | |
1500 asn1_list = NULL; | |
1501 | |
1502 LTC_MUTEX_LOCK(<c_ecc_fp_lock); | |
1503 /* | |
1504 * start with an empty cache | |
1505 */ | |
1506 ltc_ecc_fp_free_cache(); | |
1507 | |
1508 /* | |
1509 * decode the input packet: It consists of a sequence with a few | |
1510 * integers (including the FP_ENTRIES and FP_LUT sizes), followed by a | |
1511 * SEQUENCE which is the cache itself. | |
1512 * | |
1513 * use standard decoding for the first part, then flexible for the second | |
1514 */ | |
1515 if((err = der_decode_sequence_multi(in, inlen, | |
1516 LTC_ASN1_SHORT_INTEGER, 1, &num_entries, | |
1517 LTC_ASN1_SHORT_INTEGER, 1, &fp_entries, | |
1518 LTC_ASN1_SHORT_INTEGER, 1, &fp_lut, | |
1519 LTC_ASN1_EOL, 0, 0)) != CRYPT_OK) { | |
1520 goto ERR_OUT; | |
1521 } | |
1522 if (fp_entries != FP_ENTRIES || fp_lut != FP_LUT || num_entries > fp_entries) { | |
1523 err = CRYPT_INVALID_PACKET; | |
1524 goto ERR_OUT; | |
1525 } | |
1526 if ((asn1_list = XCALLOC(3+num_entries*(4+2*(1<<FP_LUT))+1, sizeof(ltc_asn1_list))) == NULL) { | |
1527 err = CRYPT_MEM; | |
1528 goto ERR_OUT; | |
1529 } | |
1530 j = 0; | |
1531 LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_SHORT_INTEGER, &num_entries, 1); | |
1532 LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_SHORT_INTEGER, &fp_entries, 1); | |
1533 LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_SHORT_INTEGER, &fp_lut, 1); | |
1534 for (i = 0; i < num_entries; i++) { | |
1535 if((fp_cache[i].g = ltc_ecc_new_point()) == NULL) { | |
1536 err = CRYPT_MEM; | |
1537 goto ERR_OUT; | |
1538 } | |
1539 LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, fp_cache[i].g->x, 1); | |
1540 LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, fp_cache[i].g->y, 1); | |
1541 LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, fp_cache[i].g->z, 1); | |
1542 for (x = 0; x < (1U<<FP_LUT); x++) { | |
1543 /* since we don't store z in the cache, don't use ltc_ecc_new_point() | |
1544 * (which allocates space for z, only to have to free it later) */ | |
1545 ecc_point *p = XCALLOC(1, sizeof(*p)); | |
1546 | |
1547 if (p == NULL) { | |
1548 err = CRYPT_MEM; | |
1549 goto ERR_OUT; | |
1550 } | |
1551 fp_cache[i].LUT[x] = p; | |
1552 if ((err = mp_init_multi(&p->x, &p->y, NULL)) != CRYPT_OK) { | |
1553 goto ERR_OUT; | |
1554 } | |
1555 p->z = NULL; | |
1556 LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, p->x, 1); | |
1557 LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, p->y, 1); | |
1558 } | |
1559 if((err = mp_init(&fp_cache[i].mu)) != CRYPT_OK) { | |
1560 goto ERR_OUT; | |
1561 } | |
1562 LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, fp_cache[i].mu, 1); | |
1563 fp_cache[i].lru_count = 3; | |
1564 fp_cache[i].lock = 1; | |
1565 } | |
1566 | |
1567 if ((err = der_decode_sequence(in, inlen, asn1_list, j)) != CRYPT_OK) { | |
1568 goto ERR_OUT; | |
1569 } | |
1570 XFREE(asn1_list); | |
1571 LTC_MUTEX_UNLOCK(<c_ecc_fp_lock); | |
1572 return CRYPT_OK; | |
1573 ERR_OUT: | |
1574 if(asn1_list) | |
1575 XFREE(asn1_list); | |
1576 ltc_ecc_fp_free_cache(); | |
1577 LTC_MUTEX_UNLOCK(<c_ecc_fp_lock); | |
1578 return err; | |
1579 } | |
1307 | 1580 |
1308 #endif | 1581 #endif |
1309 | 1582 |
1310 | 1583 |
1311 /* $Source: /cvs/libtom/libtomcrypt/src/math/fp/ltc_ecc_fp_mulmod.c,v $ */ | 1584 /* $Source$ */ |
1312 /* $Revision: 1.27 $ */ | 1585 /* $Revision$ */ |
1313 /* $Date: 2006/12/03 00:39:56 $ */ | 1586 /* $Date$ */ |
1314 | 1587 |