00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #include "polarssl/config.h"
00047
00048 #if defined(POLARSSL_ECP_C)
00049
00050 #include "polarssl/ecp.h"
00051
00052 #if defined(POLARSSL_MEMORY_C)
00053 #include "polarssl/memory.h"
00054 #else
00055 #define polarssl_malloc malloc
00056 #define polarssl_free free
00057 #endif
00058
00059 #include <limits.h>
00060 #include <stdlib.h>
00061
00062 #if defined(_MSC_VER) && !defined(inline)
00063 #define inline _inline
00064 #else
00065 #if defined(__ARMCC_VERSION) && !defined(inline)
00066 #define inline __inline
00067 #endif
00068 #endif
00069
00070 #if defined(POLARSSL_SELF_TEST)
00071
00072
00073
00074
00075 unsigned long add_count, dbl_count;
00076 #endif
00077
00078
00079
00080
00081
00082
00083
00084
00085 const ecp_curve_info ecp_supported_curves[] =
00086 {
00087 #if defined(POLARSSL_ECP_DP_BP512R1_ENABLED)
00088 { POLARSSL_ECP_DP_BP512R1, 28, 512, "brainpool512r1" },
00089 #endif
00090 #if defined(POLARSSL_ECP_DP_BP384R1_ENABLED)
00091 { POLARSSL_ECP_DP_BP384R1, 27, 384, "brainpool384r1" },
00092 #endif
00093 #if defined(POLARSSL_ECP_DP_BP256R1_ENABLED)
00094 { POLARSSL_ECP_DP_BP256R1, 26, 256, "brainpool256r1" },
00095 #endif
00096 #if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED)
00097 { POLARSSL_ECP_DP_SECP521R1, 25, 521, "secp521r1" },
00098 #endif
00099 #if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED)
00100 { POLARSSL_ECP_DP_SECP384R1, 24, 384, "secp384r1" },
00101 #endif
00102 #if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED)
00103 { POLARSSL_ECP_DP_SECP256R1, 23, 256, "secp256r1" },
00104 #endif
00105 #if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED)
00106 { POLARSSL_ECP_DP_SECP224R1, 21, 224, "secp224r1" },
00107 #endif
00108 #if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED)
00109 { POLARSSL_ECP_DP_SECP192R1, 19, 192, "secp192r1" },
00110 #endif
00111 { POLARSSL_ECP_DP_NONE, 0, 0, NULL },
00112 };
00113
00114
00115
00116
00117 const ecp_curve_info *ecp_curve_list( void )
00118 {
00119 return ecp_supported_curves;
00120 }
00121
00122
00123
00124
00125 const ecp_curve_info *ecp_curve_info_from_grp_id( ecp_group_id grp_id )
00126 {
00127 const ecp_curve_info *curve_info;
00128
00129 for( curve_info = ecp_curve_list();
00130 curve_info->grp_id != POLARSSL_ECP_DP_NONE;
00131 curve_info++ )
00132 {
00133 if( curve_info->grp_id == grp_id )
00134 return( curve_info );
00135 }
00136
00137 return( NULL );
00138 }
00139
00140
00141
00142
00143 const ecp_curve_info *ecp_curve_info_from_tls_id( uint16_t tls_id )
00144 {
00145 const ecp_curve_info *curve_info;
00146
00147 for( curve_info = ecp_curve_list();
00148 curve_info->grp_id != POLARSSL_ECP_DP_NONE;
00149 curve_info++ )
00150 {
00151 if( curve_info->tls_id == tls_id )
00152 return( curve_info );
00153 }
00154
00155 return( NULL );
00156 }
00157
00158
00159
00160
00161 void ecp_point_init( ecp_point *pt )
00162 {
00163 if( pt == NULL )
00164 return;
00165
00166 mpi_init( &pt->X );
00167 mpi_init( &pt->Y );
00168 mpi_init( &pt->Z );
00169 }
00170
00171
00172
00173
00174 void ecp_group_init( ecp_group *grp )
00175 {
00176 if( grp == NULL )
00177 return;
00178
00179 memset( grp, 0, sizeof( ecp_group ) );
00180 }
00181
00182
00183
00184
00185 void ecp_keypair_init( ecp_keypair *key )
00186 {
00187 if ( key == NULL )
00188 return;
00189
00190 ecp_group_init( &key->grp );
00191 mpi_init( &key->d );
00192 ecp_point_init( &key->Q );
00193 }
00194
00195
00196
00197
00198 void ecp_point_free( ecp_point *pt )
00199 {
00200 if( pt == NULL )
00201 return;
00202
00203 mpi_free( &( pt->X ) );
00204 mpi_free( &( pt->Y ) );
00205 mpi_free( &( pt->Z ) );
00206 }
00207
00208
00209
00210
00211 void ecp_group_free( ecp_group *grp )
00212 {
00213 size_t i;
00214
00215 if( grp == NULL )
00216 return;
00217
00218 mpi_free( &grp->P );
00219 mpi_free( &grp->A );
00220 mpi_free( &grp->B );
00221 ecp_point_free( &grp->G );
00222 mpi_free( &grp->N );
00223
00224 if( grp->T != NULL )
00225 {
00226 for( i = 0; i < grp->T_size; i++ )
00227 ecp_point_free( &grp->T[i] );
00228 polarssl_free( grp->T );
00229 }
00230
00231 memset( grp, 0, sizeof( ecp_group ) );
00232 }
00233
00234
00235
00236
00237 void ecp_keypair_free( ecp_keypair *key )
00238 {
00239 if ( key == NULL )
00240 return;
00241
00242 ecp_group_free( &key->grp );
00243 mpi_free( &key->d );
00244 ecp_point_free( &key->Q );
00245 }
00246
00247
00248
00249
00250 int ecp_copy( ecp_point *P, const ecp_point *Q )
00251 {
00252 int ret;
00253
00254 MPI_CHK( mpi_copy( &P->X, &Q->X ) );
00255 MPI_CHK( mpi_copy( &P->Y, &Q->Y ) );
00256 MPI_CHK( mpi_copy( &P->Z, &Q->Z ) );
00257
00258 cleanup:
00259 return( ret );
00260 }
00261
00262
00263
00264
00265 int ecp_group_copy( ecp_group *dst, const ecp_group *src )
00266 {
00267 return ecp_use_known_dp( dst, src->id );
00268 }
00269
00270
00271
00272
00273 int ecp_set_zero( ecp_point *pt )
00274 {
00275 int ret;
00276
00277 MPI_CHK( mpi_lset( &pt->X , 1 ) );
00278 MPI_CHK( mpi_lset( &pt->Y , 1 ) );
00279 MPI_CHK( mpi_lset( &pt->Z , 0 ) );
00280
00281 cleanup:
00282 return( ret );
00283 }
00284
00285
00286
00287
00288 int ecp_is_zero( ecp_point *pt )
00289 {
00290 return( mpi_cmp_int( &pt->Z, 0 ) == 0 );
00291 }
00292
00293
00294
00295
00296 int ecp_point_read_string( ecp_point *P, int radix,
00297 const char *x, const char *y )
00298 {
00299 int ret;
00300
00301 MPI_CHK( mpi_read_string( &P->X, radix, x ) );
00302 MPI_CHK( mpi_read_string( &P->Y, radix, y ) );
00303 MPI_CHK( mpi_lset( &P->Z, 1 ) );
00304
00305 cleanup:
00306 return( ret );
00307 }
00308
00309
00310
00311
00312 int ecp_point_write_binary( const ecp_group *grp, const ecp_point *P,
00313 int format, size_t *olen,
00314 unsigned char *buf, size_t buflen )
00315 {
00316 int ret = 0;
00317 size_t plen;
00318
00319 if( format != POLARSSL_ECP_PF_UNCOMPRESSED &&
00320 format != POLARSSL_ECP_PF_COMPRESSED )
00321 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
00322
00323
00324
00325
00326 if( mpi_cmp_int( &P->Z, 0 ) == 0 )
00327 {
00328 if( buflen < 1 )
00329 return( POLARSSL_ERR_ECP_BUFFER_TOO_SMALL );
00330
00331 buf[0] = 0x00;
00332 *olen = 1;
00333
00334 return( 0 );
00335 }
00336
00337 plen = mpi_size( &grp->P );
00338
00339 if( format == POLARSSL_ECP_PF_UNCOMPRESSED )
00340 {
00341 *olen = 2 * plen + 1;
00342
00343 if( buflen < *olen )
00344 return( POLARSSL_ERR_ECP_BUFFER_TOO_SMALL );
00345
00346 buf[0] = 0x04;
00347 MPI_CHK( mpi_write_binary( &P->X, buf + 1, plen ) );
00348 MPI_CHK( mpi_write_binary( &P->Y, buf + 1 + plen, plen ) );
00349 }
00350 else if( format == POLARSSL_ECP_PF_COMPRESSED )
00351 {
00352 *olen = plen + 1;
00353
00354 if( buflen < *olen )
00355 return( POLARSSL_ERR_ECP_BUFFER_TOO_SMALL );
00356
00357 buf[0] = 0x02 + mpi_get_bit( &P->Y, 0 );
00358 MPI_CHK( mpi_write_binary( &P->X, buf + 1, plen ) );
00359 }
00360
00361 cleanup:
00362 return( ret );
00363 }
00364
00365
00366
00367
00368 int ecp_point_read_binary( const ecp_group *grp, ecp_point *pt,
00369 const unsigned char *buf, size_t ilen ) {
00370 int ret;
00371 size_t plen;
00372
00373 if( ilen == 1 && buf[0] == 0x00 )
00374 return( ecp_set_zero( pt ) );
00375
00376 plen = mpi_size( &grp->P );
00377
00378 if( ilen != 2 * plen + 1 || buf[0] != 0x04 )
00379 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
00380
00381 MPI_CHK( mpi_read_binary( &pt->X, buf + 1, plen ) );
00382 MPI_CHK( mpi_read_binary( &pt->Y, buf + 1 + plen, plen ) );
00383 MPI_CHK( mpi_lset( &pt->Z, 1 ) );
00384
00385 cleanup:
00386 return( ret );
00387 }
00388
00389
00390
00391
00392
00393
00394
00395 int ecp_tls_read_point( const ecp_group *grp, ecp_point *pt,
00396 const unsigned char **buf, size_t buf_len )
00397 {
00398 unsigned char data_len;
00399 const unsigned char *buf_start;
00400
00401
00402
00403
00404 if( buf_len < 2 )
00405 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
00406
00407 data_len = *(*buf)++;
00408 if( data_len < 1 || data_len > buf_len - 1 )
00409 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
00410
00411
00412
00413
00414 buf_start = *buf;
00415 *buf += data_len;
00416
00417 return ecp_point_read_binary( grp, pt, buf_start, data_len );
00418 }
00419
00420
00421
00422
00423
00424
00425
00426 int ecp_tls_write_point( const ecp_group *grp, const ecp_point *pt,
00427 int format, size_t *olen,
00428 unsigned char *buf, size_t blen )
00429 {
00430 int ret;
00431
00432
00433
00434
00435 if( blen < 1 )
00436 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
00437
00438 if( ( ret = ecp_point_write_binary( grp, pt, format,
00439 olen, buf + 1, blen - 1) ) != 0 )
00440 return( ret );
00441
00442
00443
00444
00445 buf[0] = (unsigned char) *olen;
00446 ++*olen;
00447
00448 return 0;
00449 }
00450
00451
00452
00453
00454 static int ecp_group_read_string_gen( ecp_group *grp, int radix,
00455 const char *p, const char *a, const char *b,
00456 const char *gx, const char *gy, const char *n)
00457 {
00458 int ret;
00459
00460 MPI_CHK( mpi_read_string( &grp->P, radix, p ) );
00461 MPI_CHK( mpi_read_string( &grp->A, radix, a ) );
00462 MPI_CHK( mpi_read_string( &grp->B, radix, b ) );
00463 MPI_CHK( ecp_point_read_string( &grp->G, radix, gx, gy ) );
00464 MPI_CHK( mpi_read_string( &grp->N, radix, n ) );
00465
00466 grp->pbits = mpi_msb( &grp->P );
00467 grp->nbits = mpi_msb( &grp->N );
00468
00469 cleanup:
00470 if( ret != 0 )
00471 ecp_group_free( grp );
00472
00473 return( ret );
00474 }
00475
00476
00477
00478
00479 int ecp_group_read_string( ecp_group *grp, int radix,
00480 const char *p, const char *b,
00481 const char *gx, const char *gy, const char *n)
00482 {
00483 int ret;
00484
00485 MPI_CHK( ecp_group_read_string_gen( grp, radix, p, "00", b, gx, gy, n ) );
00486 MPI_CHK( mpi_add_int( &grp->A, &grp->P, -3 ) );
00487
00488 cleanup:
00489 if( ret != 0 )
00490 ecp_group_free( grp );
00491
00492 return( ret );
00493 }
00494
00495
00496
00497
00498 #define SECP192R1_P \
00499 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"
00500 #define SECP192R1_B \
00501 "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1"
00502 #define SECP192R1_GX \
00503 "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012"
00504 #define SECP192R1_GY \
00505 "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811"
00506 #define SECP192R1_N \
00507 "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831"
00508
00509
00510
00511
00512 #define SECP224R1_P \
00513 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001"
00514 #define SECP224R1_B \
00515 "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4"
00516 #define SECP224R1_GX \
00517 "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21"
00518 #define SECP224R1_GY \
00519 "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34"
00520 #define SECP224R1_N \
00521 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D"
00522
00523
00524
00525
00526 #define SECP256R1_P \
00527 "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF"
00528 #define SECP256R1_B \
00529 "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B"
00530 #define SECP256R1_GX \
00531 "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296"
00532 #define SECP256R1_GY \
00533 "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5"
00534 #define SECP256R1_N \
00535 "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551"
00536
00537
00538
00539
00540 #define SECP384R1_P \
00541 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
00542 "FFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF"
00543 #define SECP384R1_B \
00544 "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE814112" \
00545 "0314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF"
00546 #define SECP384R1_GX \
00547 "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B98" \
00548 "59F741E082542A385502F25DBF55296C3A545E3872760AB7"
00549 #define SECP384R1_GY \
00550 "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147C" \
00551 "E9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F"
00552 #define SECP384R1_N \
00553 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
00554 "C7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973"
00555
00556
00557
00558
00559 #define SECP521R1_P \
00560 "000001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
00561 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
00562 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
00563 #define SECP521R1_B \
00564 "00000051953EB9618E1C9A1F929A21A0B68540EEA2DA725B" \
00565 "99B315F3B8B489918EF109E156193951EC7E937B1652C0BD" \
00566 "3BB1BF073573DF883D2C34F1EF451FD46B503F00"
00567 #define SECP521R1_GX \
00568 "000000C6858E06B70404E9CD9E3ECB662395B4429C648139" \
00569 "053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127" \
00570 "A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66"
00571 #define SECP521R1_GY \
00572 "0000011839296A789A3BC0045C8A5FB42C7D1BD998F54449" \
00573 "579B446817AFBD17273E662C97EE72995EF42640C550B901" \
00574 "3FAD0761353C7086A272C24088BE94769FD16650"
00575 #define SECP521R1_N \
00576 "000001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
00577 "FFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148" \
00578 "F709A5D03BB5C9B8899C47AEBB6FB71E91386409"
00579
00580
00581
00582
00583 #define BP256R1_P \
00584 "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377"
00585 #define BP256R1_A \
00586 "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9"
00587 #define BP256R1_B \
00588 "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6"
00589 #define BP256R1_GX \
00590 "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262"
00591 #define BP256R1_GY \
00592 "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997"
00593 #define BP256R1_N \
00594 "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7"
00595
00596
00597
00598
00599 #define BP384R1_P \
00600 "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB711" \
00601 "23ACD3A729901D1A71874700133107EC53"
00602 #define BP384R1_A \
00603 "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F9" \
00604 "0F8AA5814A503AD4EB04A8C7DD22CE2826"
00605 #define BP384R1_B \
00606 "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62" \
00607 "D57CB4390295DBC9943AB78696FA504C11"
00608 #define BP384R1_GX \
00609 "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10" \
00610 "E8E826E03436D646AAEF87B2E247D4AF1E"
00611 #define BP384R1_GY \
00612 "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129" \
00613 "280E4646217791811142820341263C5315"
00614 #define BP384R1_N \
00615 "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425" \
00616 "A7CF3AB6AF6B7FC3103B883202E9046565"
00617
00618
00619
00620
00621 #define BP512R1_P \
00622 "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308" \
00623 "717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3"
00624 #define BP512R1_A \
00625 "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863" \
00626 "BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA"
00627 #define BP512R1_B \
00628 "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117" \
00629 "A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723"
00630 #define BP512R1_GX \
00631 "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D009" \
00632 "8EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822"
00633 #define BP512R1_GY \
00634 "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F81" \
00635 "11B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892"
00636 #define BP512R1_N \
00637 "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308" \
00638 "70553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069"
00639
00640 #if defined(POLARSSL_ECP_NIST_OPTIM)
00641
00642 static int ecp_mod_p192( mpi * );
00643 static int ecp_mod_p224( mpi * );
00644 static int ecp_mod_p256( mpi * );
00645 static int ecp_mod_p384( mpi * );
00646 static int ecp_mod_p521( mpi * );
00647 #endif
00648
00649
00650
00651
00652 int ecp_use_known_dp( ecp_group *grp, ecp_group_id id )
00653 {
00654 grp->id = id;
00655
00656 switch( id )
00657 {
00658 #if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED)
00659 case POLARSSL_ECP_DP_SECP192R1:
00660 #if defined(POLARSSL_ECP_NIST_OPTIM)
00661 grp->modp = ecp_mod_p192;
00662 #endif
00663 return( ecp_group_read_string( grp, 16,
00664 SECP192R1_P, SECP192R1_B,
00665 SECP192R1_GX, SECP192R1_GY, SECP192R1_N ) );
00666 #endif
00667
00668 #if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED)
00669 case POLARSSL_ECP_DP_SECP224R1:
00670 #if defined(POLARSSL_ECP_NIST_OPTIM)
00671 grp->modp = ecp_mod_p224;
00672 #endif
00673 return( ecp_group_read_string( grp, 16,
00674 SECP224R1_P, SECP224R1_B,
00675 SECP224R1_GX, SECP224R1_GY, SECP224R1_N ) );
00676 #endif
00677
00678 #if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED)
00679 case POLARSSL_ECP_DP_SECP256R1:
00680 #if defined(POLARSSL_ECP_NIST_OPTIM)
00681 grp->modp = ecp_mod_p256;
00682 #endif
00683 return( ecp_group_read_string( grp, 16,
00684 SECP256R1_P, SECP256R1_B,
00685 SECP256R1_GX, SECP256R1_GY, SECP256R1_N ) );
00686 #endif
00687
00688 #if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED)
00689 case POLARSSL_ECP_DP_SECP384R1:
00690 #if defined(POLARSSL_ECP_NIST_OPTIM)
00691 grp->modp = ecp_mod_p384;
00692 #endif
00693 return( ecp_group_read_string( grp, 16,
00694 SECP384R1_P, SECP384R1_B,
00695 SECP384R1_GX, SECP384R1_GY, SECP384R1_N ) );
00696 #endif
00697
00698 #if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED)
00699 case POLARSSL_ECP_DP_SECP521R1:
00700 #if defined(POLARSSL_ECP_NIST_OPTIM)
00701 grp->modp = ecp_mod_p521;
00702 #endif
00703 return( ecp_group_read_string( grp, 16,
00704 SECP521R1_P, SECP521R1_B,
00705 SECP521R1_GX, SECP521R1_GY, SECP521R1_N ) );
00706 #endif
00707
00708 #if defined(POLARSSL_ECP_DP_BP256R1_ENABLED)
00709 case POLARSSL_ECP_DP_BP256R1:
00710 return( ecp_group_read_string_gen( grp, 16,
00711 BP256R1_P, BP256R1_A, BP256R1_B,
00712 BP256R1_GX, BP256R1_GY, BP256R1_N ) );
00713 #endif
00714
00715 #if defined(POLARSSL_ECP_DP_BP384R1_ENABLED)
00716 case POLARSSL_ECP_DP_BP384R1:
00717 return( ecp_group_read_string_gen( grp, 16,
00718 BP384R1_P, BP384R1_A, BP384R1_B,
00719 BP384R1_GX, BP384R1_GY, BP384R1_N ) );
00720 #endif
00721
00722 #if defined(POLARSSL_ECP_DP_BP512R1_ENABLED)
00723 case POLARSSL_ECP_DP_BP512R1:
00724 return( ecp_group_read_string_gen( grp, 16,
00725 BP512R1_P, BP512R1_A, BP512R1_B,
00726 BP512R1_GX, BP512R1_GY, BP512R1_N ) );
00727 #endif
00728
00729 default:
00730 ecp_group_free( grp );
00731 return( POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE );
00732 }
00733 }
00734
00735
00736
00737
00738 int ecp_tls_read_group( ecp_group *grp, const unsigned char **buf, size_t len )
00739 {
00740 uint16_t tls_id;
00741 const ecp_curve_info *curve_info;
00742
00743
00744
00745
00746 if( len < 3 )
00747 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
00748
00749
00750
00751
00752 if( *(*buf)++ != POLARSSL_ECP_TLS_NAMED_CURVE )
00753 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
00754
00755
00756
00757
00758 tls_id = *(*buf)++;
00759 tls_id <<= 8;
00760 tls_id |= *(*buf)++;
00761
00762 if( ( curve_info = ecp_curve_info_from_tls_id( tls_id ) ) == NULL )
00763 return( POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE );
00764
00765 return ecp_use_known_dp( grp, curve_info->grp_id );
00766 }
00767
00768
00769
00770
00771 int ecp_tls_write_group( const ecp_group *grp, size_t *olen,
00772 unsigned char *buf, size_t blen )
00773 {
00774 const ecp_curve_info *curve_info;
00775
00776 if( ( curve_info = ecp_curve_info_from_grp_id( grp->id ) ) == NULL )
00777 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
00778
00779
00780
00781
00782 *olen = 3;
00783 if( blen < *olen )
00784 return( POLARSSL_ERR_ECP_BUFFER_TOO_SMALL );
00785
00786
00787
00788
00789 *buf++ = POLARSSL_ECP_TLS_NAMED_CURVE;
00790
00791
00792
00793
00794 buf[0] = curve_info->tls_id >> 8;
00795 buf[1] = curve_info->tls_id & 0xFF;
00796
00797 return 0;
00798 }
00799
00800
00801
00802
00803
00804
00805
00806 static int ecp_modp( mpi *N, const ecp_group *grp )
00807 {
00808 int ret;
00809
00810 if( grp->modp == NULL )
00811 return( mpi_mod_mpi( N, N, &grp->P ) );
00812
00813
00814 if( ( N->s < 0 && mpi_cmp_int( N, 0 ) != 0 ) ||
00815 mpi_msb( N ) > 2 * grp->pbits )
00816 {
00817 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
00818 }
00819
00820 MPI_CHK( grp->modp( N ) );
00821
00822
00823 while( N->s < 0 && mpi_cmp_int( N, 0 ) != 0 )
00824 MPI_CHK( mpi_add_mpi( N, N, &grp->P ) );
00825
00826 while( mpi_cmp_mpi( N, &grp->P ) >= 0 )
00827
00828 MPI_CHK( mpi_sub_abs( N, N, &grp->P ) );
00829
00830 cleanup:
00831 return( ret );
00832 }
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847 #define MOD_MUL( N ) MPI_CHK( ecp_modp( &N, grp ) )
00848
00849
00850
00851
00852
00853 #define MOD_SUB( N ) \
00854 while( N.s < 0 && mpi_cmp_int( &N, 0 ) != 0 ) \
00855 MPI_CHK( mpi_add_mpi( &N, &N, &grp->P ) )
00856
00857
00858
00859
00860
00861
00862 #define MOD_ADD( N ) \
00863 while( mpi_cmp_mpi( &N, &grp->P ) >= 0 ) \
00864 MPI_CHK( mpi_sub_abs( &N, &N, &grp->P ) )
00865
00866
00867
00868
00869 static int ecp_normalize( const ecp_group *grp, ecp_point *pt )
00870 {
00871 int ret;
00872 mpi Zi, ZZi;
00873
00874 if( mpi_cmp_int( &pt->Z, 0 ) == 0 )
00875 return( 0 );
00876
00877 mpi_init( &Zi ); mpi_init( &ZZi );
00878
00879
00880
00881
00882 MPI_CHK( mpi_inv_mod( &Zi, &pt->Z, &grp->P ) );
00883 MPI_CHK( mpi_mul_mpi( &ZZi, &Zi, &Zi ) ); MOD_MUL( ZZi );
00884 MPI_CHK( mpi_mul_mpi( &pt->X, &pt->X, &ZZi ) ); MOD_MUL( pt->X );
00885
00886
00887
00888
00889 MPI_CHK( mpi_mul_mpi( &pt->Y, &pt->Y, &ZZi ) ); MOD_MUL( pt->Y );
00890 MPI_CHK( mpi_mul_mpi( &pt->Y, &pt->Y, &Zi ) ); MOD_MUL( pt->Y );
00891
00892
00893
00894
00895 MPI_CHK( mpi_lset( &pt->Z, 1 ) );
00896
00897 cleanup:
00898
00899 mpi_free( &Zi ); mpi_free( &ZZi );
00900
00901 return( ret );
00902 }
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913 static int ecp_normalize_many( const ecp_group *grp,
00914 ecp_point T[], size_t t_len )
00915 {
00916 int ret;
00917 size_t i;
00918 mpi *c, u, Zi, ZZi;
00919
00920 if( t_len < 2 )
00921 return( ecp_normalize( grp, T ) );
00922
00923 if( ( c = (mpi *) polarssl_malloc( t_len * sizeof( mpi ) ) ) == NULL )
00924 return( POLARSSL_ERR_ECP_MALLOC_FAILED );
00925
00926 mpi_init( &u ); mpi_init( &Zi ); mpi_init( &ZZi );
00927 for( i = 0; i < t_len; i++ )
00928 mpi_init( &c[i] );
00929
00930
00931
00932
00933 MPI_CHK( mpi_copy( &c[0], &T[0].Z ) );
00934 for( i = 1; i < t_len; i++ )
00935 {
00936 MPI_CHK( mpi_mul_mpi( &c[i], &c[i-1], &T[i].Z ) );
00937 MOD_MUL( c[i] );
00938 }
00939
00940
00941
00942
00943 MPI_CHK( mpi_inv_mod( &u, &c[t_len-1], &grp->P ) );
00944
00945 for( i = t_len - 1; ; i-- )
00946 {
00947
00948
00949
00950
00951 if( i == 0 ) {
00952 MPI_CHK( mpi_copy( &Zi, &u ) );
00953 }
00954 else
00955 {
00956 MPI_CHK( mpi_mul_mpi( &Zi, &u, &c[i-1] ) ); MOD_MUL( Zi );
00957 MPI_CHK( mpi_mul_mpi( &u, &u, &T[i].Z ) ); MOD_MUL( u );
00958 }
00959
00960
00961
00962
00963 MPI_CHK( mpi_mul_mpi( &ZZi, &Zi, &Zi ) ); MOD_MUL( ZZi );
00964 MPI_CHK( mpi_mul_mpi( &T[i].X, &T[i].X, &ZZi ) ); MOD_MUL( T[i].X );
00965 MPI_CHK( mpi_mul_mpi( &T[i].Y, &T[i].Y, &ZZi ) ); MOD_MUL( T[i].Y );
00966 MPI_CHK( mpi_mul_mpi( &T[i].Y, &T[i].Y, &Zi ) ); MOD_MUL( T[i].Y );
00967 MPI_CHK( mpi_lset( &T[i].Z, 1 ) );
00968
00969 if( i == 0 )
00970 break;
00971 }
00972
00973 cleanup:
00974
00975 mpi_free( &u ); mpi_free( &Zi ); mpi_free( &ZZi );
00976 for( i = 0; i < t_len; i++ )
00977 mpi_free( &c[i] );
00978 polarssl_free( c );
00979
00980 return( ret );
00981 }
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991 static int ecp_double_jac( const ecp_group *grp, ecp_point *R,
00992 const ecp_point *P )
00993 {
00994 int ret;
00995 mpi T1, T2, T3, X3, Y3, Z3;
00996
00997 #if defined(POLARSSL_SELF_TEST)
00998 dbl_count++;
00999 #endif
01000
01001 mpi_init( &T1 ); mpi_init( &T2 ); mpi_init( &T3 );
01002 mpi_init( &X3 ); mpi_init( &Y3 ); mpi_init( &Z3 );
01003
01004 MPI_CHK( mpi_mul_mpi( &T3, &P->X, &P->X ) ); MOD_MUL( T3 );
01005 MPI_CHK( mpi_mul_mpi( &T2, &P->Y, &P->Y ) ); MOD_MUL( T2 );
01006 MPI_CHK( mpi_mul_mpi( &Y3, &T2, &T2 ) ); MOD_MUL( Y3 );
01007 MPI_CHK( mpi_add_mpi( &X3, &P->X, &T2 ) ); MOD_ADD( X3 );
01008 MPI_CHK( mpi_mul_mpi( &X3, &X3, &X3 ) ); MOD_MUL( X3 );
01009 MPI_CHK( mpi_sub_mpi( &X3, &X3, &Y3 ) ); MOD_SUB( X3 );
01010 MPI_CHK( mpi_sub_mpi( &X3, &X3, &T3 ) ); MOD_SUB( X3 );
01011 MPI_CHK( mpi_mul_int( &T1, &X3, 2 ) ); MOD_ADD( T1 );
01012 MPI_CHK( mpi_mul_mpi( &Z3, &P->Z, &P->Z ) ); MOD_MUL( Z3 );
01013 MPI_CHK( mpi_mul_mpi( &X3, &Z3, &Z3 ) ); MOD_MUL( X3 );
01014 MPI_CHK( mpi_mul_int( &T3, &T3, 3 ) ); MOD_ADD( T3 );
01015 MPI_CHK( mpi_mul_mpi( &X3, &X3, &grp->A ) ); MOD_MUL( X3 );
01016 MPI_CHK( mpi_add_mpi( &T3, &T3, &X3 ) ); MOD_ADD( T3 );
01017 MPI_CHK( mpi_mul_mpi( &X3, &T3, &T3 ) ); MOD_MUL( X3 );
01018 MPI_CHK( mpi_sub_mpi( &X3, &X3, &T1 ) ); MOD_SUB( X3 );
01019 MPI_CHK( mpi_sub_mpi( &X3, &X3, &T1 ) ); MOD_SUB( X3 );
01020 MPI_CHK( mpi_sub_mpi( &T1, &T1, &X3 ) ); MOD_SUB( T1 );
01021 MPI_CHK( mpi_mul_mpi( &T1, &T3, &T1 ) ); MOD_MUL( T1 );
01022 MPI_CHK( mpi_mul_int( &T3, &Y3, 8 ) ); MOD_ADD( T3 );
01023 MPI_CHK( mpi_sub_mpi( &Y3, &T1, &T3 ) ); MOD_SUB( Y3 );
01024 MPI_CHK( mpi_add_mpi( &T1, &P->Y, &P->Z ) ); MOD_ADD( T1 );
01025 MPI_CHK( mpi_mul_mpi( &T1, &T1, &T1 ) ); MOD_MUL( T1 );
01026 MPI_CHK( mpi_sub_mpi( &T1, &T1, &T2 ) ); MOD_SUB( T1 );
01027 MPI_CHK( mpi_sub_mpi( &Z3, &T1, &Z3 ) ); MOD_SUB( Z3 );
01028
01029 MPI_CHK( mpi_copy( &R->X, &X3 ) );
01030 MPI_CHK( mpi_copy( &R->Y, &Y3 ) );
01031 MPI_CHK( mpi_copy( &R->Z, &Z3 ) );
01032
01033 cleanup:
01034 mpi_free( &T1 ); mpi_free( &T2 ); mpi_free( &T3 );
01035 mpi_free( &X3 ); mpi_free( &Y3 ); mpi_free( &Z3 );
01036
01037 return( ret );
01038 }
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051 static int ecp_add_mixed( const ecp_group *grp, ecp_point *R,
01052 const ecp_point *P, const ecp_point *Q,
01053 signed char sign )
01054 {
01055 int ret;
01056 mpi T1, T2, T3, T4, X, Y, Z;
01057
01058 #if defined(POLARSSL_SELF_TEST)
01059 add_count++;
01060 #endif
01061
01062
01063
01064
01065
01066 if( mpi_cmp_int( &Q->Z, 0 ) == 0 )
01067 return( ecp_copy( R, P ) );
01068
01069 if( mpi_cmp_int( &P->Z, 0 ) == 0 )
01070 {
01071 ret = ecp_copy( R, Q );
01072
01073
01074
01075
01076 if( ret == 0 && sign < 0)
01077 if( mpi_cmp_int( &R->Y, 0 ) != 0 )
01078 ret = mpi_sub_mpi( &R->Y, &grp->P, &R->Y );
01079
01080 return( ret );
01081 }
01082
01083
01084
01085
01086 if( mpi_cmp_int( &Q->Z, 1 ) != 0 )
01087 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
01088
01089 mpi_init( &T1 ); mpi_init( &T2 ); mpi_init( &T3 ); mpi_init( &T4 );
01090 mpi_init( &X ); mpi_init( &Y ); mpi_init( &Z );
01091
01092 MPI_CHK( mpi_mul_mpi( &T1, &P->Z, &P->Z ) ); MOD_MUL( T1 );
01093 MPI_CHK( mpi_mul_mpi( &T2, &T1, &P->Z ) ); MOD_MUL( T2 );
01094 MPI_CHK( mpi_mul_mpi( &T1, &T1, &Q->X ) ); MOD_MUL( T1 );
01095 MPI_CHK( mpi_mul_mpi( &T2, &T2, &Q->Y ) ); MOD_MUL( T2 );
01096
01097
01098
01099
01100
01101 if( sign < 0 )
01102 {
01103 MPI_CHK( mpi_sub_mpi( &T2, &grp->P, &T2 ) );
01104 MOD_SUB( T2 );
01105 }
01106
01107 MPI_CHK( mpi_sub_mpi( &T1, &T1, &P->X ) ); MOD_SUB( T1 );
01108 MPI_CHK( mpi_sub_mpi( &T2, &T2, &P->Y ) ); MOD_SUB( T2 );
01109
01110 if( mpi_cmp_int( &T1, 0 ) == 0 )
01111 {
01112 if( mpi_cmp_int( &T2, 0 ) == 0 )
01113 {
01114 ret = ecp_double_jac( grp, R, P );
01115 goto cleanup;
01116 }
01117 else
01118 {
01119 ret = ecp_set_zero( R );
01120 goto cleanup;
01121 }
01122 }
01123
01124 MPI_CHK( mpi_mul_mpi( &Z, &P->Z, &T1 ) ); MOD_MUL( Z );
01125 MPI_CHK( mpi_mul_mpi( &T3, &T1, &T1 ) ); MOD_MUL( T3 );
01126 MPI_CHK( mpi_mul_mpi( &T4, &T3, &T1 ) ); MOD_MUL( T4 );
01127 MPI_CHK( mpi_mul_mpi( &T3, &T3, &P->X ) ); MOD_MUL( T3 );
01128 MPI_CHK( mpi_mul_int( &T1, &T3, 2 ) ); MOD_ADD( T1 );
01129 MPI_CHK( mpi_mul_mpi( &X, &T2, &T2 ) ); MOD_MUL( X );
01130 MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) ); MOD_SUB( X );
01131 MPI_CHK( mpi_sub_mpi( &X, &X, &T4 ) ); MOD_SUB( X );
01132 MPI_CHK( mpi_sub_mpi( &T3, &T3, &X ) ); MOD_SUB( T3 );
01133 MPI_CHK( mpi_mul_mpi( &T3, &T3, &T2 ) ); MOD_MUL( T3 );
01134 MPI_CHK( mpi_mul_mpi( &T4, &T4, &P->Y ) ); MOD_MUL( T4 );
01135 MPI_CHK( mpi_sub_mpi( &Y, &T3, &T4 ) ); MOD_SUB( Y );
01136
01137 MPI_CHK( mpi_copy( &R->X, &X ) );
01138 MPI_CHK( mpi_copy( &R->Y, &Y ) );
01139 MPI_CHK( mpi_copy( &R->Z, &Z ) );
01140
01141 cleanup:
01142
01143 mpi_free( &T1 ); mpi_free( &T2 ); mpi_free( &T3 ); mpi_free( &T4 );
01144 mpi_free( &X ); mpi_free( &Y ); mpi_free( &Z );
01145
01146 return( ret );
01147 }
01148
01149
01150
01151
01152 int ecp_add( const ecp_group *grp, ecp_point *R,
01153 const ecp_point *P, const ecp_point *Q )
01154 {
01155 int ret;
01156
01157 MPI_CHK( ecp_add_mixed( grp, R, P, Q , 1 ) );
01158 MPI_CHK( ecp_normalize( grp, R ) );
01159
01160 cleanup:
01161 return( ret );
01162 }
01163
01164
01165
01166
01167 int ecp_sub( const ecp_group *grp, ecp_point *R,
01168 const ecp_point *P, const ecp_point *Q )
01169 {
01170 int ret;
01171
01172 MPI_CHK( ecp_add_mixed( grp, R, P, Q, -1 ) );
01173 MPI_CHK( ecp_normalize( grp, R ) );
01174
01175 cleanup:
01176 return( ret );
01177 }
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205 static int ecp_w_naf_fixed( signed char x[], size_t k,
01206 unsigned char w, const mpi *m )
01207 {
01208 int ret;
01209 unsigned int i, u, mask, carry;
01210 mpi M;
01211
01212 mpi_init( &M );
01213
01214 MPI_CHK( mpi_copy( &M, m ) );
01215 mask = ( 1 << w ) - 1;
01216 carry = 1 << ( w - 1 );
01217
01218 for( i = 0; i < k; i++ )
01219 {
01220 u = M.p[0] & mask;
01221
01222 if( ( u & 1 ) == 0 && i > 0 )
01223 x[i - 1] -= carry;
01224
01225 x[i] = u >> 1;
01226 mpi_shift_r( &M, w );
01227 }
01228
01229
01230
01231
01232 if( mpi_cmp_int( &M, 0 ) != 0 )
01233 ret = POLARSSL_ERR_ECP_BAD_INPUT_DATA;
01234
01235 cleanup:
01236
01237 mpi_free( &M );
01238
01239 return( ret );
01240 }
01241
01242
01243
01244
01245
01246 static int ecp_precompute( const ecp_group *grp,
01247 ecp_point T[], size_t t_len,
01248 const ecp_point *P )
01249 {
01250 int ret;
01251 size_t i;
01252 ecp_point PP;
01253
01254 ecp_point_init( &PP );
01255
01256 MPI_CHK( ecp_add( grp, &PP, P, P ) );
01257
01258 MPI_CHK( ecp_copy( &T[0], P ) );
01259
01260 for( i = 1; i < t_len; i++ )
01261 MPI_CHK( ecp_add_mixed( grp, &T[i], &T[i-1], &PP, +1 ) );
01262
01263
01264
01265
01266 MPI_CHK( ecp_normalize_many( grp, T + 1, t_len - 1 ) );
01267
01268 cleanup:
01269
01270 ecp_point_free( &PP );
01271
01272 return( ret );
01273 }
01274
01275
01276
01277
01278
01279
01280 static int ecp_randomize_coordinates( const ecp_group *grp, ecp_point *pt,
01281 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
01282 {
01283 int ret;
01284 mpi l, ll;
01285 size_t p_size = (grp->pbits + 7) / 8;
01286 int count = 0;
01287
01288 mpi_init( &l ); mpi_init( &ll );
01289
01290
01291 do
01292 {
01293 mpi_fill_random( &l, p_size, f_rng, p_rng );
01294
01295 while( mpi_cmp_mpi( &l, &grp->P ) >= 0 )
01296 mpi_shift_r( &l, 1 );
01297
01298 if( count++ > 10 )
01299 return( POLARSSL_ERR_ECP_RANDOM_FAILED );
01300 }
01301 while( mpi_cmp_int( &l, 1 ) <= 0 );
01302
01303
01304 MPI_CHK( mpi_mul_mpi( &pt->Z, &pt->Z, &l ) ); MOD_MUL( pt->Z );
01305
01306
01307 MPI_CHK( mpi_mul_mpi( &ll, &l, &l ) ); MOD_MUL( ll );
01308 MPI_CHK( mpi_mul_mpi( &pt->X, &pt->X, &ll ) ); MOD_MUL( pt->X );
01309
01310
01311 MPI_CHK( mpi_mul_mpi( &ll, &ll, &l ) ); MOD_MUL( ll );
01312 MPI_CHK( mpi_mul_mpi( &pt->Y, &pt->Y, &ll ) ); MOD_MUL( pt->Y );
01313
01314 cleanup:
01315 mpi_free( &l ); mpi_free( &ll );
01316
01317 return( ret );
01318 }
01319
01320
01321
01322
01323 #define MAX_PRE_LEN ( 1 << (POLARSSL_ECP_WINDOW_SIZE - 1) )
01324
01325
01326
01327
01328
01329
01330 #define MAX_NAF_LEN ( POLARSSL_ECP_MAX_BITS / 2 + 1 )
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345 int ecp_mul( ecp_group *grp, ecp_point *R,
01346 const mpi *m, const ecp_point *P,
01347 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
01348 {
01349 int ret;
01350 unsigned char w, m_is_odd, p_eq_g;
01351 size_t pre_len = 1, naf_len, i, j;
01352 signed char naf[ MAX_NAF_LEN ];
01353 ecp_point Q, *T = NULL, S[2];
01354 mpi M;
01355
01356 if( mpi_cmp_int( m, 0 ) < 0 || mpi_msb( m ) > grp->nbits )
01357 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
01358
01359 mpi_init( &M );
01360 ecp_point_init( &Q );
01361 ecp_point_init( &S[0] );
01362 ecp_point_init( &S[1] );
01363
01364
01365
01366
01367 p_eq_g = ( mpi_cmp_int( &P->Z, 1 ) == 0 &&
01368 mpi_cmp_mpi( &P->Y, &grp->G.Y ) == 0 &&
01369 mpi_cmp_mpi( &P->X, &grp->G.X ) == 0 );
01370
01371
01372
01373
01374
01375 if( p_eq_g )
01376 w = POLARSSL_ECP_WINDOW_SIZE;
01377 else
01378 w = grp->nbits >= 512 ? 6 :
01379 grp->nbits >= 224 ? 5 :
01380 4;
01381
01382
01383
01384
01385
01386
01387
01388 if( w > POLARSSL_ECP_WINDOW_SIZE )
01389 w = POLARSSL_ECP_WINDOW_SIZE;
01390 if( w < 2 || w >= grp->nbits )
01391 w = 2;
01392
01393 pre_len <<= ( w - 1 );
01394 naf_len = grp->nbits / w + 1;
01395
01396
01397
01398
01399
01400 if( ! p_eq_g || grp->T == NULL )
01401 {
01402 T = (ecp_point *) polarssl_malloc( pre_len * sizeof( ecp_point ) );
01403 if( T == NULL )
01404 {
01405 ret = POLARSSL_ERR_ECP_MALLOC_FAILED;
01406 goto cleanup;
01407 }
01408
01409 for( i = 0; i < pre_len; i++ )
01410 ecp_point_init( &T[i] );
01411
01412 MPI_CHK( ecp_precompute( grp, T, pre_len, P ) );
01413
01414 if( p_eq_g )
01415 {
01416 grp->T = T;
01417 grp->T_size = pre_len;
01418 }
01419 }
01420 else
01421 {
01422 T = grp->T;
01423
01424
01425 if( pre_len != grp->T_size )
01426 {
01427 ret = POLARSSL_ERR_ECP_BAD_INPUT_DATA;
01428 goto cleanup;
01429 }
01430 }
01431
01432
01433
01434
01435
01436 m_is_odd = ( mpi_get_bit( m, 0 ) == 1 );
01437
01438 MPI_CHK( mpi_copy( &M, m ) );
01439 MPI_CHK( mpi_add_int( &M, &M, 1 + m_is_odd ) );
01440
01441
01442
01443
01444 MPI_CHK( ecp_w_naf_fixed( naf, naf_len, w, &M ) );
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454 MPI_CHK( ecp_set_zero( &Q ) );
01455 i = naf_len - 1;
01456 while( 1 )
01457 {
01458
01459 if( f_rng != NULL )
01460 ecp_randomize_coordinates( grp, &Q, f_rng, p_rng );
01461
01462 if( naf[i] < 0 )
01463 {
01464 MPI_CHK( ecp_add_mixed( grp, &Q, &Q, &T[ - naf[i] - 1 ], -1 ) );
01465 }
01466 else
01467 {
01468 MPI_CHK( ecp_add_mixed( grp, &Q, &Q, &T[ naf[i] ], +1 ) );
01469 }
01470
01471 if( i == 0 )
01472 break;
01473 i--;
01474
01475 for( j = 0; j < w; j++ )
01476 {
01477 MPI_CHK( ecp_double_jac( grp, &Q, &Q ) );
01478 }
01479 }
01480
01481
01482
01483
01484 MPI_CHK( ecp_copy( &S[0], P ) );
01485 MPI_CHK( ecp_add( grp, &S[1], P, P ) );
01486 MPI_CHK( ecp_sub( grp, R, &Q, &S[m_is_odd] ) );
01487
01488
01489 cleanup:
01490
01491 if( T != NULL && ! p_eq_g )
01492 {
01493 for( i = 0; i < pre_len; i++ )
01494 ecp_point_free( &T[i] );
01495 polarssl_free( T );
01496 }
01497
01498 ecp_point_free( &S[1] );
01499 ecp_point_free( &S[0] );
01500 ecp_point_free( &Q );
01501 mpi_free( &M );
01502
01503 return( ret );
01504 }
01505
01506
01507
01508
01509 int ecp_check_pubkey( const ecp_group *grp, const ecp_point *pt )
01510 {
01511 int ret;
01512 mpi YY, RHS;
01513
01514 if( mpi_cmp_int( &pt->Z, 0 ) == 0 )
01515 return( POLARSSL_ERR_ECP_INVALID_KEY );
01516
01517
01518
01519
01520 if( mpi_cmp_int( &pt->Z, 1 ) != 0 )
01521 return( POLARSSL_ERR_ECP_INVALID_KEY );
01522
01523 if( mpi_cmp_int( &pt->X, 0 ) < 0 ||
01524 mpi_cmp_int( &pt->Y, 0 ) < 0 ||
01525 mpi_cmp_mpi( &pt->X, &grp->P ) >= 0 ||
01526 mpi_cmp_mpi( &pt->Y, &grp->P ) >= 0 )
01527 return( POLARSSL_ERR_ECP_INVALID_KEY );
01528
01529 mpi_init( &YY ); mpi_init( &RHS );
01530
01531
01532
01533
01534
01535 MPI_CHK( mpi_mul_mpi( &YY, &pt->Y, &pt->Y ) ); MOD_MUL( YY );
01536 MPI_CHK( mpi_mul_mpi( &RHS, &pt->X, &pt->X ) ); MOD_MUL( RHS );
01537 MPI_CHK( mpi_add_mpi( &RHS, &RHS, &grp->A ) ); MOD_ADD( RHS );
01538 MPI_CHK( mpi_mul_mpi( &RHS, &RHS, &pt->X ) ); MOD_MUL( RHS );
01539 MPI_CHK( mpi_add_mpi( &RHS, &RHS, &grp->B ) ); MOD_ADD( RHS );
01540
01541 if( mpi_cmp_mpi( &YY, &RHS ) != 0 )
01542 ret = POLARSSL_ERR_ECP_INVALID_KEY;
01543
01544 cleanup:
01545
01546 mpi_free( &YY ); mpi_free( &RHS );
01547
01548 return( ret );
01549 }
01550
01551
01552
01553
01554 int ecp_check_privkey( const ecp_group *grp, const mpi *d )
01555 {
01556
01557 if ( mpi_cmp_int( d, 1 ) < 0 || mpi_cmp_mpi( d, &grp->N ) >= 0 )
01558 return( POLARSSL_ERR_ECP_INVALID_KEY );
01559
01560 return( 0 );
01561 }
01562
01563
01564
01565
01566 int ecp_gen_keypair( ecp_group *grp, mpi *d, ecp_point *Q,
01567 int (*f_rng)(void *, unsigned char *, size_t),
01568 void *p_rng )
01569 {
01570 int count = 0;
01571 size_t n_size = (grp->nbits + 7) / 8;
01572
01573
01574
01575
01576 do
01577 {
01578 mpi_fill_random( d, n_size, f_rng, p_rng );
01579
01580 while( mpi_cmp_mpi( d, &grp->N ) >= 0 )
01581 mpi_shift_r( d, 1 );
01582
01583 if( count++ > 10 )
01584 return( POLARSSL_ERR_ECP_RANDOM_FAILED );
01585 }
01586 while( mpi_cmp_int( d, 1 ) < 0 );
01587
01588 return( ecp_mul( grp, Q, d, &grp->G, f_rng, p_rng ) );
01589 }
01590
01591 #if defined(POLARSSL_ECP_NIST_OPTIM)
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602 #if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED)
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616 static inline void add64( t_uint *dst, t_uint *src, t_uint *carry )
01617 {
01618 unsigned char i;
01619 t_uint c = 0;
01620 for( i = 0; i < 8 / sizeof( t_uint ); i++, dst++, src++ )
01621 {
01622 *dst += c; c = ( *dst < c );
01623 *dst += *src; c += ( *dst < *src );
01624 }
01625 *carry += c;
01626 }
01627
01628
01629 static inline void carry64( t_uint *dst, t_uint *carry )
01630 {
01631 unsigned char i;
01632 for( i = 0; i < 8 / sizeof( t_uint ); i++, dst++ )
01633 {
01634 *dst += *carry;
01635 *carry = ( *dst < *carry );
01636 }
01637 }
01638
01639 #define WIDTH 8 / sizeof( t_uint )
01640 #define A( i ) N->p + i * WIDTH
01641 #define ADD( i ) add64( p, A( i ), &c )
01642 #define NEXT p += WIDTH; carry64( p, &c )
01643 #define LAST p += WIDTH; *p = c; while( ++p < end ) *p = 0
01644
01645
01646
01647
01648 static int ecp_mod_p192( mpi *N )
01649 {
01650 int ret;
01651 t_uint c = 0;
01652 t_uint *p, *end;
01653
01654
01655 MPI_CHK( mpi_grow( N, 6 * WIDTH ) );
01656
01657 p = N->p;
01658 end = p + N->n;
01659
01660 ADD( 3 ); ADD( 5 ); NEXT;
01661 ADD( 3 ); ADD( 4 ); ADD( 5 ); NEXT;
01662 ADD( 4 ); ADD( 5 ); LAST;
01663
01664 cleanup:
01665 return( ret );
01666 }
01667
01668 #undef WIDTH
01669 #undef A
01670 #undef ADD
01671 #undef NEXT
01672 #undef LAST
01673 #endif
01674
01675 #if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) || \
01676 defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) || \
01677 defined(POLARSSL_ECP_DP_SECP384R1_ENABLED)
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694 #define LOAD32 cur = A( i );
01695
01696 #if defined(POLARSSL_HAVE_INT8)
01697
01698 #define MAX32 N->n / 4
01699 #define A( j ) (uint32_t)( N->p[4*j+0] ) | \
01700 ( N->p[4*j+1] << 8 ) | \
01701 ( N->p[4*j+2] << 16 ) | \
01702 ( N->p[4*j+3] << 24 )
01703 #define STORE32 N->p[4*i+0] = (uint8_t)( cur ); \
01704 N->p[4*i+1] = (uint8_t)( cur >> 8 ); \
01705 N->p[4*i+2] = (uint8_t)( cur >> 16 ); \
01706 N->p[4*i+3] = (uint8_t)( cur >> 24 );
01707
01708 #elif defined(POLARSSL_HAVE_INT16)
01709
01710 #define MAX32 N->n / 2
01711 #define A( j ) (uint32_t)( N->p[2*j] ) | ( N->p[2*j+1] << 16 )
01712 #define STORE32 N->p[2*i+0] = (uint16_t)( cur ); \
01713 N->p[2*i+1] = (uint16_t)( cur >> 16 );
01714
01715 #elif defined(POLARSSL_HAVE_INT32)
01716
01717 #define MAX32 N->n
01718 #define A( j ) N->p[j]
01719 #define STORE32 N->p[i] = cur;
01720
01721 #else
01722
01723 #define MAX32 N->n * 2
01724 #define A( j ) j % 2 ? (uint32_t)( N->p[j/2] >> 32 ) : (uint32_t)( N->p[j/2] )
01725 #define STORE32 \
01726 if( i % 2 ) { \
01727 N->p[i/2] &= 0x00000000FFFFFFFF; \
01728 N->p[i/2] |= ((uint64_t) cur) << 32; \
01729 } else { \
01730 N->p[i/2] &= 0xFFFFFFFF00000000; \
01731 N->p[i/2] |= (uint64_t) cur; \
01732 }
01733
01734 #endif
01735
01736
01737
01738
01739 static inline void add32( uint32_t *dst, uint32_t src, signed char *carry )
01740 {
01741 *dst += src;
01742 *carry += ( *dst < src );
01743 }
01744
01745 static inline void sub32( uint32_t *dst, uint32_t src, signed char *carry )
01746 {
01747 *carry -= ( *dst < src );
01748 *dst -= src;
01749 }
01750
01751 #define ADD( j ) add32( &cur, A( j ), &c );
01752 #define SUB( j ) sub32( &cur, A( j ), &c );
01753
01754
01755
01756
01757
01758 #define INIT( b ) \
01759 int ret; \
01760 signed char c = 0, cc; \
01761 uint32_t cur; \
01762 size_t i = 0, bits = b; \
01763 mpi C; \
01764 t_uint Cp[ b / 8 / sizeof( t_uint) + 1 ]; \
01765 \
01766 C.s = 1; \
01767 C.n = b / 8 / sizeof( t_uint) + 1; \
01768 C.p = Cp; \
01769 memset( Cp, 0, C.n * sizeof( t_uint ) ); \
01770 \
01771 MPI_CHK( mpi_grow( N, b * 2 / 8 / sizeof( t_uint ) ) ); \
01772 LOAD32;
01773
01774 #define NEXT \
01775 STORE32; i++; LOAD32; \
01776 cc = c; c = 0; \
01777 if( cc < 0 ) \
01778 sub32( &cur, -cc, &c ); \
01779 else \
01780 add32( &cur, cc, &c ); \
01781
01782 #define LAST \
01783 STORE32; i++; \
01784 cur = c > 0 ? c : 0; STORE32; \
01785 cur = 0; while( ++i < MAX32 ) { STORE32; } \
01786 if( c < 0 ) fix_negative( N, c, &C, bits );
01787
01788
01789
01790
01791
01792 static inline int fix_negative( mpi *N, signed char c, mpi *C, size_t bits )
01793 {
01794 int ret;
01795
01796
01797 #if !defined(POLARSSL_HAVE_INT64)
01798 ((void) bits);
01799 #else
01800 if( bits == 224 )
01801 C->p[ C->n - 1 ] = ((t_uint) -c) << 32;
01802 else
01803 #endif
01804 C->p[ C->n - 1 ] = (t_uint) -c;
01805
01806
01807 MPI_CHK( mpi_sub_abs( N, C, N ) );
01808 N->s = -1;
01809
01810 cleanup:
01811
01812 return( ret );
01813 }
01814
01815 #if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED)
01816
01817
01818
01819 static int ecp_mod_p224( mpi *N )
01820 {
01821 INIT( 224 );
01822
01823 SUB( 7 ); SUB( 11 ); NEXT;
01824 SUB( 8 ); SUB( 12 ); NEXT;
01825 SUB( 9 ); SUB( 13 ); NEXT;
01826 SUB( 10 ); ADD( 7 ); ADD( 11 ); NEXT;
01827 SUB( 11 ); ADD( 8 ); ADD( 12 ); NEXT;
01828 SUB( 12 ); ADD( 9 ); ADD( 13 ); NEXT;
01829 SUB( 13 ); ADD( 10 ); LAST;
01830
01831 cleanup:
01832 return( ret );
01833 }
01834 #endif
01835
01836 #if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED)
01837
01838
01839
01840 static int ecp_mod_p256( mpi *N )
01841 {
01842 INIT( 256 );
01843
01844 ADD( 8 ); ADD( 9 );
01845 SUB( 11 ); SUB( 12 ); SUB( 13 ); SUB( 14 ); NEXT;
01846
01847 ADD( 9 ); ADD( 10 );
01848 SUB( 12 ); SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT;
01849
01850 ADD( 10 ); ADD( 11 );
01851 SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT;
01852
01853 ADD( 11 ); ADD( 11 ); ADD( 12 ); ADD( 12 ); ADD( 13 );
01854 SUB( 15 ); SUB( 8 ); SUB( 9 ); NEXT;
01855
01856 ADD( 12 ); ADD( 12 ); ADD( 13 ); ADD( 13 ); ADD( 14 );
01857 SUB( 9 ); SUB( 10 ); NEXT;
01858
01859 ADD( 13 ); ADD( 13 ); ADD( 14 ); ADD( 14 ); ADD( 15 );
01860 SUB( 10 ); SUB( 11 ); NEXT;
01861
01862 ADD( 14 ); ADD( 14 ); ADD( 15 ); ADD( 15 ); ADD( 14 ); ADD( 13 );
01863 SUB( 8 ); SUB( 9 ); NEXT;
01864
01865 ADD( 15 ); ADD( 15 ); ADD( 15 ); ADD( 8 );
01866 SUB( 10 ); SUB( 11 ); SUB( 12 ); SUB( 13 ); LAST;
01867
01868 cleanup:
01869 return( ret );
01870 }
01871 #endif
01872
01873 #if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED)
01874
01875
01876
01877 static int ecp_mod_p384( mpi *N )
01878 {
01879 INIT( 384 );
01880
01881 ADD( 12 ); ADD( 21 ); ADD( 20 );
01882 SUB( 23 ); NEXT;
01883
01884 ADD( 13 ); ADD( 22 ); ADD( 23 );
01885 SUB( 12 ); SUB( 20 ); NEXT;
01886
01887 ADD( 14 ); ADD( 23 );
01888 SUB( 13 ); SUB( 21 ); NEXT;
01889
01890 ADD( 15 ); ADD( 12 ); ADD( 20 ); ADD( 21 );
01891 SUB( 14 ); SUB( 22 ); SUB( 23 ); NEXT;
01892
01893 ADD( 21 ); ADD( 21 ); ADD( 16 ); ADD( 13 ); ADD( 12 ); ADD( 20 ); ADD( 22 );
01894 SUB( 15 ); SUB( 23 ); SUB( 23 ); NEXT;
01895
01896 ADD( 22 ); ADD( 22 ); ADD( 17 ); ADD( 14 ); ADD( 13 ); ADD( 21 ); ADD( 23 );
01897 SUB( 16 ); NEXT;
01898
01899 ADD( 23 ); ADD( 23 ); ADD( 18 ); ADD( 15 ); ADD( 14 ); ADD( 22 );
01900 SUB( 17 ); NEXT;
01901
01902 ADD( 19 ); ADD( 16 ); ADD( 15 ); ADD( 23 );
01903 SUB( 18 ); NEXT;
01904
01905 ADD( 20 ); ADD( 17 ); ADD( 16 );
01906 SUB( 19 ); NEXT;
01907
01908 ADD( 21 ); ADD( 18 ); ADD( 17 );
01909 SUB( 20 ); NEXT;
01910
01911 ADD( 22 ); ADD( 19 ); ADD( 18 );
01912 SUB( 21 ); NEXT;
01913
01914 ADD( 23 ); ADD( 20 ); ADD( 19 );
01915 SUB( 22 ); LAST;
01916
01917 cleanup:
01918 return( ret );
01919 }
01920 #endif
01921
01922 #undef A
01923 #undef LOAD32
01924 #undef STORE32
01925 #undef MAX32
01926 #undef INIT
01927 #undef NEXT
01928 #undef LAST
01929
01930 #endif
01931
01932
01933
01934 #if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED)
01935
01936
01937
01938
01939
01940
01941 #define P521_WIDTH ( 521 / 8 / sizeof( t_uint ) + 1 )
01942
01943
01944 #if defined(POLARSSL_HAVE_INT8)
01945 #define P521_MASK 0x01
01946 #else
01947 #define P521_MASK 0x01FF
01948 #endif
01949
01950
01951
01952
01953
01954 static int ecp_mod_p521( mpi *N )
01955 {
01956 int ret;
01957 size_t i;
01958 mpi M;
01959 t_uint Mp[P521_WIDTH + 1];
01960
01961
01962
01963
01964 if( N->n < P521_WIDTH )
01965 return( 0 );
01966
01967
01968 M.s = 1;
01969 M.n = N->n - ( P521_WIDTH - 1 );
01970 if( M.n > P521_WIDTH + 1 )
01971 M.n = P521_WIDTH + 1;
01972 M.p = Mp;
01973 memcpy( Mp, N->p + P521_WIDTH - 1, M.n * sizeof( t_uint ) );
01974 MPI_CHK( mpi_shift_r( &M, 521 % ( 8 * sizeof( t_uint ) ) ) );
01975
01976
01977 N->p[P521_WIDTH - 1] &= P521_MASK;
01978 for( i = P521_WIDTH; i < N->n; i++ )
01979 N->p[i] = 0;
01980
01981
01982 MPI_CHK( mpi_add_abs( N, N, &M ) );
01983
01984 cleanup:
01985 return( ret );
01986 }
01987
01988 #undef P521_WIDTH
01989 #undef P521_MASK
01990 #endif
01991
01992 #endif
01993
01994 #if defined(POLARSSL_SELF_TEST)
01995
01996
01997
01998
01999 int ecp_self_test( int verbose )
02000 {
02001 int ret;
02002 size_t i;
02003 ecp_group grp;
02004 ecp_point R, P;
02005 mpi m;
02006 unsigned long add_c_prev, dbl_c_prev;
02007
02008 const char *exponents[] =
02009 {
02010 "000000000000000000000000000000000000000000000000",
02011 "000000000000000000000000000000000000000000000001",
02012 "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831",
02013 "5EA6F389A38B8BC81E767753B15AA5569E1782E30ABE7D25",
02014 "400000000000000000000000000000000000000000000000",
02015 "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
02016 "555555555555555555555555555555555555555555555555",
02017 };
02018
02019 ecp_group_init( &grp );
02020 ecp_point_init( &R );
02021 ecp_point_init( &P );
02022 mpi_init( &m );
02023
02024
02025 #if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED)
02026 MPI_CHK( ecp_use_known_dp( &grp, POLARSSL_ECP_DP_SECP192R1 ) );
02027 #else
02028 MPI_CHK( ecp_use_known_dp( &grp, ecp_curve_list()->grp_id ) );
02029 #endif
02030
02031 if( verbose != 0 )
02032 printf( " ECP test #1 (constant op_count, base point G): " );
02033
02034
02035 MPI_CHK( mpi_lset( &m, 2 ) );
02036 MPI_CHK( ecp_mul( &grp, &P, &m, &grp.G, NULL, NULL ) );
02037
02038 add_count = 0;
02039 dbl_count = 0;
02040 MPI_CHK( mpi_read_string( &m, 16, exponents[0] ) );
02041 MPI_CHK( ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL ) );
02042
02043 for( i = 1; i < sizeof( exponents ) / sizeof( exponents[0] ); i++ )
02044 {
02045 add_c_prev = add_count;
02046 dbl_c_prev = dbl_count;
02047 add_count = 0;
02048 dbl_count = 0;
02049
02050 MPI_CHK( mpi_read_string( &m, 16, exponents[i] ) );
02051 MPI_CHK( ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL ) );
02052
02053 if( add_count != add_c_prev || dbl_count != dbl_c_prev )
02054 {
02055 if( verbose != 0 )
02056 printf( "failed (%zu)\n", i );
02057
02058 ret = 1;
02059 goto cleanup;
02060 }
02061 }
02062
02063 if( verbose != 0 )
02064 printf( "passed\n" );
02065
02066 if( verbose != 0 )
02067 printf( " ECP test #2 (constant op_count, other point): " );
02068
02069
02070 add_count = 0;
02071 dbl_count = 0;
02072 MPI_CHK( mpi_read_string( &m, 16, exponents[0] ) );
02073 MPI_CHK( ecp_mul( &grp, &R, &m, &P, NULL, NULL ) );
02074
02075 for( i = 1; i < sizeof( exponents ) / sizeof( exponents[0] ); i++ )
02076 {
02077 add_c_prev = add_count;
02078 dbl_c_prev = dbl_count;
02079 add_count = 0;
02080 dbl_count = 0;
02081
02082 MPI_CHK( mpi_read_string( &m, 16, exponents[i] ) );
02083 MPI_CHK( ecp_mul( &grp, &R, &m, &P, NULL, NULL ) );
02084
02085 if( add_count != add_c_prev || dbl_count != dbl_c_prev )
02086 {
02087 if( verbose != 0 )
02088 printf( "failed (%zu)\n", i );
02089
02090 ret = 1;
02091 goto cleanup;
02092 }
02093 }
02094
02095 if( verbose != 0 )
02096 printf( "passed\n" );
02097
02098 cleanup:
02099
02100 if( ret < 0 && verbose != 0 )
02101 printf( "Unexpected error, return code = %08X\n", ret );
02102
02103 ecp_group_free( &grp );
02104 ecp_point_free( &R );
02105 ecp_point_free( &P );
02106 mpi_free( &m );
02107
02108 if( verbose != 0 )
02109 printf( "\n" );
02110
02111 return( ret );
02112 }
02113
02114 #endif
02115
02116 #endif