mbed TLS library

Dependents:   HTTPClient-SSL WS_SERVER

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ecp.h Source File

ecp.h

Go to the documentation of this file.
00001 /**
00002  * \file ecp.h
00003  *
00004  * \brief Elliptic curves over GF(p)
00005  *
00006  *  Copyright (C) 2006-2013, ARM Limited, All Rights Reserved
00007  *
00008  *  This file is part of mbed TLS (https://tls.mbed.org)
00009  *
00010  *  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version.
00014  *
00015  *  This program is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *  GNU General Public License for more details.
00019  *
00020  *  You should have received a copy of the GNU General Public License along
00021  *  with this program; if not, write to the Free Software Foundation, Inc.,
00022  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00023  */
00024 #ifndef POLARSSL_ECP_H
00025 #define POLARSSL_ECP_H
00026 
00027 #include "bignum.h"
00028 
00029 /*
00030  * ECP error codes
00031  */
00032 #define POLARSSL_ERR_ECP_BAD_INPUT_DATA                    -0x4F80  /**< Bad input parameters to function. */
00033 #define POLARSSL_ERR_ECP_BUFFER_TOO_SMALL                  -0x4F00  /**< The buffer is too small to write to. */
00034 #define POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE               -0x4E80  /**< Requested curve not available. */
00035 #define POLARSSL_ERR_ECP_VERIFY_FAILED                     -0x4E00  /**< The signature is not valid. */
00036 #define POLARSSL_ERR_ECP_MALLOC_FAILED                     -0x4D80  /**< Memory allocation failed. */
00037 #define POLARSSL_ERR_ECP_RANDOM_FAILED                     -0x4D00  /**< Generation of random value, such as (ephemeral) key, failed. */
00038 #define POLARSSL_ERR_ECP_INVALID_KEY                       -0x4C80  /**< Invalid private or public key. */
00039 #define POLARSSL_ERR_ECP_SIG_LEN_MISMATCH                  -0x4C00  /**< Signature is valid but shorter than the user-supplied length. */
00040 
00041 #ifdef __cplusplus
00042 extern "C" {
00043 #endif
00044 
00045 /**
00046  * Domain parameters (curve, subgroup and generator) identifiers.
00047  *
00048  * Only curves over prime fields are supported.
00049  *
00050  * \warning This library does not support validation of arbitrary domain
00051  * parameters. Therefore, only well-known domain parameters from trusted
00052  * sources should be used. See ecp_use_known_dp().
00053  */
00054 typedef enum
00055 {
00056     POLARSSL_ECP_DP_NONE = 0,
00057     POLARSSL_ECP_DP_SECP192R1 ,      /*!< 192-bits NIST curve  */
00058     POLARSSL_ECP_DP_SECP224R1 ,      /*!< 224-bits NIST curve  */
00059     POLARSSL_ECP_DP_SECP256R1 ,      /*!< 256-bits NIST curve  */
00060     POLARSSL_ECP_DP_SECP384R1 ,      /*!< 384-bits NIST curve  */
00061     POLARSSL_ECP_DP_SECP521R1 ,      /*!< 521-bits NIST curve  */
00062     POLARSSL_ECP_DP_BP256R1 ,        /*!< 256-bits Brainpool curve */
00063     POLARSSL_ECP_DP_BP384R1 ,        /*!< 384-bits Brainpool curve */
00064     POLARSSL_ECP_DP_BP512R1 ,        /*!< 512-bits Brainpool curve */
00065     POLARSSL_ECP_DP_M221 ,           /*!< (not implemented yet)    */
00066     POLARSSL_ECP_DP_M255 ,           /*!< Curve25519               */
00067     POLARSSL_ECP_DP_M383 ,           /*!< (not implemented yet)    */
00068     POLARSSL_ECP_DP_M511 ,           /*!< (not implemented yet)    */
00069     POLARSSL_ECP_DP_SECP192K1 ,      /*!< 192-bits "Koblitz" curve */
00070     POLARSSL_ECP_DP_SECP224K1 ,      /*!< 224-bits "Koblitz" curve */
00071     POLARSSL_ECP_DP_SECP256K1 ,      /*!< 256-bits "Koblitz" curve */
00072 } ecp_group_id;
00073 
00074 /**
00075  * Number of supported curves (plus one for NONE).
00076  *
00077  * (Montgomery curves excluded for now.)
00078  */
00079 #define POLARSSL_ECP_DP_MAX     12
00080 
00081 /**
00082  * Curve information for use by other modules
00083  */
00084 typedef struct
00085 {
00086     ecp_group_id grp_id ;    /*!< Internal identifier        */
00087     uint16_t tls_id ;        /*!< TLS NamedCurve identifier  */
00088     uint16_t size ;          /*!< Curve size in bits         */
00089     const char *name ;       /*!< Human-friendly name        */
00090 } ecp_curve_info;
00091 
00092 /**
00093  * \brief           ECP point structure (jacobian coordinates)
00094  *
00095  * \note            All functions expect and return points satisfying
00096  *                  the following condition: Z == 0 or Z == 1. (Other
00097  *                  values of Z are used by internal functions only.)
00098  *                  The point is zero, or "at infinity", if Z == 0.
00099  *                  Otherwise, X and Y are its standard (affine) coordinates.
00100  */
00101 typedef struct
00102 {
00103     mpi X ;          /*!<  the point's X coordinate  */
00104     mpi Y ;          /*!<  the point's Y coordinate  */
00105     mpi Z ;          /*!<  the point's Z coordinate  */
00106 }
00107 ecp_point;
00108 
00109 /**
00110  * \brief           ECP group structure
00111  *
00112  * We consider two types of curves equations:
00113  * 1. Short Weierstrass y^2 = x^3 + A x + B     mod P   (SEC1 + RFC 4492)
00114  * 2. Montgomery,       y^2 = x^3 + A x^2 + x   mod P   (M255 + draft)
00115  * In both cases, a generator G for a prime-order subgroup is fixed. In the
00116  * short weierstrass, this subgroup is actually the whole curve, and its
00117  * cardinal is denoted by N.
00118  *
00119  * In the case of Short Weierstrass curves, our code requires that N is an odd
00120  * prime. (Use odd in ecp_mul() and prime in ecdsa_sign() for blinding.)
00121  *
00122  * In the case of Montgomery curves, we don't store A but (A + 2) / 4 which is
00123  * the quantity actually used in the formulas. Also, nbits is not the size of N
00124  * but the required size for private keys.
00125  *
00126  * If modp is NULL, reduction modulo P is done using a generic algorithm.
00127  * Otherwise, it must point to a function that takes an mpi in the range
00128  * 0..2^(2*pbits)-1 and transforms it in-place in an integer of little more
00129  * than pbits, so that the integer may be efficiently brought in the 0..P-1
00130  * range by a few additions or substractions. It must return 0 on success and
00131  * non-zero on failure.
00132  */
00133 typedef struct
00134 {
00135     ecp_group_id id ;    /*!<  internal group identifier                     */
00136     mpi P ;              /*!<  prime modulus of the base field               */
00137     mpi A ;              /*!<  1. A in the equation, or 2. (A + 2) / 4       */
00138     mpi B ;              /*!<  1. B in the equation, or 2. unused            */
00139     ecp_point G ;        /*!<  generator of the (sub)group used              */
00140     mpi N ;              /*!<  1. the order of G, or 2. unused               */
00141     size_t pbits ;       /*!<  number of bits in P                           */
00142     size_t nbits ;       /*!<  number of bits in 1. P, or 2. private keys    */
00143     unsigned int h ;     /*!<  internal: 1 if the constants are static       */
00144     int (*modp)(mpi *); /*!<  function for fast reduction mod P             */
00145     int (*t_pre)(ecp_point *, void *);  /*!< unused                         */
00146     int (*t_post)(ecp_point *, void *); /*!< unused                         */
00147     void *t_data ;                       /*!< unused                         */
00148     ecp_point *T ;       /*!<  pre-computed points for ecp_mul_comb()        */
00149     size_t T_size ;      /*!<  number for pre-computed points                */
00150 }
00151 ecp_group;
00152 
00153 /**
00154  * \brief           ECP key pair structure
00155  *
00156  * A generic key pair that could be used for ECDSA, fixed ECDH, etc.
00157  *
00158  * \note Members purposefully in the same order as struc ecdsa_context.
00159  */
00160 typedef struct
00161 {
00162     ecp_group grp ;      /*!<  Elliptic curve and base point     */
00163     mpi d ;              /*!<  our secret value                  */
00164     ecp_point Q ;        /*!<  our public value                  */
00165 }
00166 ecp_keypair;
00167 
00168 /**
00169  * \name SECTION: Module settings
00170  *
00171  * The configuration options you can set for this module are in this section.
00172  * Either change them in config.h or define them on the compiler command line.
00173  * \{
00174  */
00175 
00176 #if !defined(POLARSSL_ECP_MAX_BITS)
00177 /**
00178  * Maximum size of the groups (that is, of N and P)
00179  */
00180 #define POLARSSL_ECP_MAX_BITS     521   /**< Maximum bit size of groups */
00181 #endif
00182 
00183 #define POLARSSL_ECP_MAX_BYTES    ( ( POLARSSL_ECP_MAX_BITS + 7 ) / 8 )
00184 #define POLARSSL_ECP_MAX_PT_LEN   ( 2 * POLARSSL_ECP_MAX_BYTES + 1 )
00185 
00186 #if !defined(POLARSSL_ECP_WINDOW_SIZE)
00187 /*
00188  * Maximum "window" size used for point multiplication.
00189  * Default: 6.
00190  * Minimum value: 2. Maximum value: 7.
00191  *
00192  * Result is an array of at most ( 1 << ( POLARSSL_ECP_WINDOW_SIZE - 1 ) )
00193  * points used for point multiplication. This value is directly tied to EC
00194  * peak memory usage, so decreasing it by one should roughly cut memory usage
00195  * by two (if large curves are in use).
00196  *
00197  * Reduction in size may reduce speed, but larger curves are impacted first.
00198  * Sample performances (in ECDHE handshakes/s, with FIXED_POINT_OPTIM = 1):
00199  *      w-size:     6       5       4       3       2
00200  *      521       145     141     135     120      97
00201  *      384       214     209     198     177     146
00202  *      256       320     320     303     262     226
00203 
00204  *      224       475     475     453     398     342
00205  *      192       640     640     633     587     476
00206  */
00207 #define POLARSSL_ECP_WINDOW_SIZE    6   /**< Maximum window size used */
00208 #endif /* POLARSSL_ECP_WINDOW_SIZE */
00209 
00210 #if !defined(POLARSSL_ECP_FIXED_POINT_OPTIM)
00211 /*
00212  * Trade memory for speed on fixed-point multiplication.
00213  *
00214  * This speeds up repeated multiplication of the generator (that is, the
00215  * multiplication in ECDSA signatures, and half of the multiplications in
00216  * ECDSA verification and ECDHE) by a factor roughly 3 to 4.
00217  *
00218  * The cost is increasing EC peak memory usage by a factor roughly 2.
00219  *
00220  * Change this value to 0 to reduce peak memory usage.
00221  */
00222 #define POLARSSL_ECP_FIXED_POINT_OPTIM  1   /**< Enable fixed-point speed-up */
00223 #endif /* POLARSSL_ECP_FIXED_POINT_OPTIM */
00224 
00225 /* \} name SECTION: Module settings */
00226 
00227 /*
00228  * Point formats, from RFC 4492's enum ECPointFormat
00229  */
00230 #define POLARSSL_ECP_PF_UNCOMPRESSED    0   /**< Uncompressed point format */
00231 #define POLARSSL_ECP_PF_COMPRESSED      1   /**< Compressed point format */
00232 
00233 /*
00234  * Some other constants from RFC 4492
00235  */
00236 #define POLARSSL_ECP_TLS_NAMED_CURVE    3   /**< ECCurveType's named_curve */
00237 
00238 /**
00239  * \brief           Get the list of supported curves in order of preferrence
00240  *                  (full information)
00241  *
00242  * \return          A statically allocated array, the last entry is 0.
00243  */
00244 const ecp_curve_info *ecp_curve_list( void );
00245 
00246 /**
00247  * \brief           Get the list of supported curves in order of preferrence
00248  *                  (grp_id only)
00249  *
00250  * \return          A statically allocated array,
00251  *                  terminated with POLARSSL_ECP_DP_NONE.
00252  */
00253 const ecp_group_id *ecp_grp_id_list( void );
00254 
00255 /**
00256  * \brief           Get curve information from an internal group identifier
00257  *
00258  * \param grp_id    A POLARSSL_ECP_DP_XXX value
00259  *
00260  * \return          The associated curve information or NULL
00261  */
00262 const ecp_curve_info *ecp_curve_info_from_grp_id( ecp_group_id grp_id );
00263 
00264 /**
00265  * \brief           Get curve information from a TLS NamedCurve value
00266  *
00267  * \param tls_id    A POLARSSL_ECP_DP_XXX value
00268  *
00269  * \return          The associated curve information or NULL
00270  */
00271 const ecp_curve_info *ecp_curve_info_from_tls_id( uint16_t tls_id );
00272 
00273 /**
00274  * \brief           Get curve information from a human-readable name
00275  *
00276  * \param name      The name
00277  *
00278  * \return          The associated curve information or NULL
00279  */
00280 const ecp_curve_info *ecp_curve_info_from_name( const char *name );
00281 
00282 /**
00283  * \brief           Initialize a point (as zero)
00284  */
00285 void ecp_point_init( ecp_point *pt );
00286 
00287 /**
00288  * \brief           Initialize a group (to something meaningless)
00289  */
00290 void ecp_group_init( ecp_group *grp );
00291 
00292 /**
00293  * \brief           Initialize a key pair (as an invalid one)
00294  */
00295 void ecp_keypair_init( ecp_keypair *key );
00296 
00297 /**
00298  * \brief           Free the components of a point
00299  */
00300 void ecp_point_free( ecp_point *pt );
00301 
00302 /**
00303  * \brief           Free the components of an ECP group
00304  */
00305 void ecp_group_free( ecp_group *grp );
00306 
00307 /**
00308  * \brief           Free the components of a key pair
00309  */
00310 void ecp_keypair_free( ecp_keypair *key );
00311 
00312 /**
00313  * \brief           Copy the contents of point Q into P
00314  *
00315  * \param P         Destination point
00316  * \param Q         Source point
00317  *
00318  * \return          0 if successful,
00319  *                  POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
00320  */
00321 int ecp_copy( ecp_point *P, const ecp_point *Q );
00322 
00323 /**
00324  * \brief           Copy the contents of a group object
00325  *
00326  * \param dst       Destination group
00327  * \param src       Source group
00328  *
00329  * \return          0 if successful,
00330  *                  POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
00331  */
00332 int ecp_group_copy( ecp_group *dst, const ecp_group *src );
00333 
00334 /**
00335  * \brief           Set a point to zero
00336  *
00337  * \param pt        Destination point
00338  *
00339  * \return          0 if successful,
00340  *                  POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
00341  */
00342 int ecp_set_zero( ecp_point *pt );
00343 
00344 /**
00345  * \brief           Tell if a point is zero
00346  *
00347  * \param pt        Point to test
00348  *
00349  * \return          1 if point is zero, 0 otherwise
00350  */
00351 int ecp_is_zero( ecp_point *pt );
00352 
00353 /**
00354  * \brief           Import a non-zero point from two ASCII strings
00355  *
00356  * \param P         Destination point
00357  * \param radix     Input numeric base
00358  * \param x         First affine coordinate as a null-terminated string
00359  * \param y         Second affine coordinate as a null-terminated string
00360  *
00361  * \return          0 if successful, or a POLARSSL_ERR_MPI_XXX error code
00362  */
00363 int ecp_point_read_string( ecp_point *P, int radix,
00364                            const char *x, const char *y );
00365 
00366 /**
00367  * \brief           Export a point into unsigned binary data
00368  *
00369  * \param grp       Group to which the point should belong
00370  * \param P         Point to export
00371  * \param format    Point format, should be a POLARSSL_ECP_PF_XXX macro
00372  * \param olen      Length of the actual output
00373  * \param buf       Output buffer
00374  * \param buflen    Length of the output buffer
00375  *
00376  * \return          0 if successful,
00377  *                  or POLARSSL_ERR_ECP_BAD_INPUT_DATA
00378  *                  or POLARSSL_ERR_ECP_BUFFER_TOO_SMALL
00379  */
00380 int ecp_point_write_binary( const ecp_group *grp, const ecp_point *P,
00381                             int format, size_t *olen,
00382                             unsigned char *buf, size_t buflen );
00383 
00384 /**
00385  * \brief           Import a point from unsigned binary data
00386  *
00387  * \param grp       Group to which the point should belong
00388  * \param P         Point to import
00389  * \param buf       Input buffer
00390  * \param ilen      Actual length of input
00391  *
00392  * \return          0 if successful,
00393  *                  POLARSSL_ERR_ECP_BAD_INPUT_DATA if input is invalid,
00394  *                  POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
00395  *                  POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE if the point format
00396  *                  is not implemented.
00397  *
00398  * \note            This function does NOT check that the point actually
00399  *                  belongs to the given group, see ecp_check_pubkey() for
00400  *                  that.
00401  */
00402 int ecp_point_read_binary( const ecp_group *grp, ecp_point *P,
00403                            const unsigned char *buf, size_t ilen );
00404 
00405 /**
00406  * \brief           Import a point from a TLS ECPoint record
00407  *
00408  * \param grp       ECP group used
00409  * \param pt        Destination point
00410  * \param buf       $(Start of input buffer)
00411  * \param len       Buffer length
00412  *
00413  * \note            buf is updated to point right after the ECPoint on exit
00414  *
00415  * \return          0 if successful,
00416  *                  POLARSSL_ERR_MPI_XXX if initialization failed
00417  *                  POLARSSL_ERR_ECP_BAD_INPUT_DATA if input is invalid
00418  */
00419 int ecp_tls_read_point( const ecp_group *grp, ecp_point *pt,
00420                         const unsigned char **buf, size_t len );
00421 
00422 /**
00423  * \brief           Export a point as a TLS ECPoint record
00424  *
00425  * \param grp       ECP group used
00426  * \param pt        Point to export
00427  * \param format    Export format
00428  * \param olen      length of data written
00429  * \param buf       Buffer to write to
00430  * \param blen      Buffer length
00431  *
00432  * \return          0 if successful,
00433  *                  or POLARSSL_ERR_ECP_BAD_INPUT_DATA
00434  *                  or POLARSSL_ERR_ECP_BUFFER_TOO_SMALL
00435  */
00436 int ecp_tls_write_point( const ecp_group *grp, const ecp_point *pt,
00437                          int format, size_t *olen,
00438                          unsigned char *buf, size_t blen );
00439 
00440 /**
00441  * \brief           Import an ECP group from null-terminated ASCII strings
00442  *
00443  * \param grp       Destination group
00444  * \param radix     Input numeric base
00445  * \param p         Prime modulus of the base field
00446  * \param b         Constant term in the equation
00447  * \param gx        The generator's X coordinate
00448  * \param gy        The generator's Y coordinate
00449  * \param n         The generator's order
00450  *
00451  * \return          0 if successful, or a POLARSSL_ERR_MPI_XXX error code
00452  *
00453  * \note            Sets all fields except modp.
00454  */
00455 int ecp_group_read_string( ecp_group *grp, int radix,
00456                            const char *p, const char *b,
00457                            const char *gx, const char *gy, const char *n);
00458 
00459 /**
00460  * \brief           Set a group using well-known domain parameters
00461  *
00462  * \param grp       Destination group
00463  * \param index     Index in the list of well-known domain parameters
00464  *
00465  * \return          0 if successful,
00466  *                  POLARSSL_ERR_MPI_XXX if initialization failed
00467  *                  POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE for unkownn groups
00468  *
00469  * \note            Index should be a value of RFC 4492's enum NamdeCurve,
00470  *                  possibly in the form of a POLARSSL_ECP_DP_XXX macro.
00471  */
00472 int ecp_use_known_dp( ecp_group *grp, ecp_group_id index );
00473 
00474 /**
00475  * \brief           Set a group from a TLS ECParameters record
00476  *
00477  * \param grp       Destination group
00478  * \param buf       &(Start of input buffer)
00479  * \param len       Buffer length
00480  *
00481  * \note            buf is updated to point right after ECParameters on exit
00482  *
00483  * \return          0 if successful,
00484  *                  POLARSSL_ERR_MPI_XXX if initialization failed
00485  *                  POLARSSL_ERR_ECP_BAD_INPUT_DATA if input is invalid
00486  */
00487 int ecp_tls_read_group( ecp_group *grp, const unsigned char **buf, size_t len );
00488 
00489 /**
00490  * \brief           Write the TLS ECParameters record for a group
00491  *
00492  * \param grp       ECP group used
00493  * \param olen      Number of bytes actually written
00494  * \param buf       Buffer to write to
00495  * \param blen      Buffer length
00496  *
00497  * \return          0 if successful,
00498  *                  or POLARSSL_ERR_ECP_BUFFER_TOO_SMALL
00499  */
00500 int ecp_tls_write_group( const ecp_group *grp, size_t *olen,
00501                          unsigned char *buf, size_t blen );
00502 
00503 /**
00504  * \brief           Addition: R = P + Q
00505  *
00506  * \param grp       ECP group
00507  * \param R         Destination point
00508  * \param P         Left-hand point
00509  * \param Q         Right-hand point
00510  *
00511  * \return          0 if successful,
00512  *                  POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
00513  *
00514  * \note            This function does not support Montgomery curves, such as
00515  *                  Curve25519.
00516  */
00517 int ecp_add( const ecp_group *grp, ecp_point *R,
00518              const ecp_point *P, const ecp_point *Q );
00519 
00520 /**
00521  * \brief           Subtraction: R = P - Q
00522  *
00523  * \param grp       ECP group
00524  * \param R         Destination point
00525  * \param P         Left-hand point
00526  * \param Q         Right-hand point
00527  *
00528  * \return          0 if successful,
00529  *                  POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
00530  *
00531  * \note            This function does not support Montgomery curves, such as
00532  *                  Curve25519.
00533  */
00534 int ecp_sub( const ecp_group *grp, ecp_point *R,
00535              const ecp_point *P, const ecp_point *Q );
00536 
00537 /**
00538  * \brief           Multiplication by an integer: R = m * P
00539  *                  (Not thread-safe to use same group in multiple threads)
00540  *
00541  * \param grp       ECP group
00542  * \param R         Destination point
00543  * \param m         Integer by which to multiply
00544  * \param P         Point to multiply
00545  * \param f_rng     RNG function (see notes)
00546  * \param p_rng     RNG parameter
00547  *
00548  * \return          0 if successful,
00549  *                  POLARSSL_ERR_ECP_INVALID_KEY if m is not a valid privkey
00550  *                  or P is not a valid pubkey,
00551  *                  POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
00552  *
00553  * \note            In order to prevent timing attacks, this function
00554  *                  executes the exact same sequence of (base field)
00555  *                  operations for any valid m. It avoids any if-branch or
00556  *                  array index depending on the value of m.
00557  *
00558  * \note            If f_rng is not NULL, it is used to randomize intermediate
00559  *                  results in order to prevent potential timing attacks
00560  *                  targeting these results. It is recommended to always
00561  *                  provide a non-NULL f_rng (the overhead is negligible).
00562  */
00563 int ecp_mul( ecp_group *grp, ecp_point *R,
00564              const mpi *m, const ecp_point *P,
00565              int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
00566 
00567 /**
00568  * \brief           Check that a point is a valid public key on this curve
00569  *
00570  * \param grp       Curve/group the point should belong to
00571  * \param pt        Point to check
00572  *
00573  * \return          0 if point is a valid public key,
00574  *                  POLARSSL_ERR_ECP_INVALID_KEY otherwise.
00575  *
00576  * \note            This function only checks the point is non-zero, has valid
00577  *                  coordinates and lies on the curve, but not that it is
00578  *                  indeed a multiple of G. This is additional check is more
00579  *                  expensive, isn't required by standards, and shouldn't be
00580  *                  necessary if the group used has a small cofactor. In
00581  *                  particular, it is useless for the NIST groups which all
00582  *                  have a cofactor of 1.
00583  *
00584  * \note            Uses bare components rather than an ecp_keypair structure
00585  *                  in order to ease use with other structures such as
00586  *                  ecdh_context of ecdsa_context.
00587  */
00588 int ecp_check_pubkey( const ecp_group *grp, const ecp_point *pt );
00589 
00590 /**
00591  * \brief           Check that an mpi is a valid private key for this curve
00592  *
00593  * \param grp       Group used
00594  * \param d         Integer to check
00595  *
00596  * \return          0 if point is a valid private key,
00597  *                  POLARSSL_ERR_ECP_INVALID_KEY otherwise.
00598  *
00599  * \note            Uses bare components rather than an ecp_keypair structure
00600  *                  in order to ease use with other structures such as
00601  *                  ecdh_context of ecdsa_context.
00602  */
00603 int ecp_check_privkey( const ecp_group *grp, const mpi *d );
00604 
00605 /**
00606  * \brief           Generate a keypair
00607  *
00608  * \param grp       ECP group
00609  * \param d         Destination MPI (secret part)
00610  * \param Q         Destination point (public part)
00611  * \param f_rng     RNG function
00612  * \param p_rng     RNG parameter
00613  *
00614  * \return          0 if successful,
00615  *                  or a POLARSSL_ERR_ECP_XXX or POLARSSL_MPI_XXX error code
00616  *
00617  * \note            Uses bare components rather than an ecp_keypair structure
00618  *                  in order to ease use with other structures such as
00619  *                  ecdh_context of ecdsa_context.
00620  */
00621 int ecp_gen_keypair( ecp_group *grp, mpi *d, ecp_point *Q,
00622                      int (*f_rng)(void *, unsigned char *, size_t),
00623                      void *p_rng );
00624 
00625 /**
00626  * \brief           Generate a keypair
00627  *
00628  * \param grp_id    ECP group identifier
00629  * \param key       Destination keypair
00630  * \param f_rng     RNG function
00631  * \param p_rng     RNG parameter
00632  *
00633  * \return          0 if successful,
00634  *                  or a POLARSSL_ERR_ECP_XXX or POLARSSL_MPI_XXX error code
00635  */
00636 int ecp_gen_key( ecp_group_id grp_id, ecp_keypair *key,
00637                 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
00638 
00639 /**
00640  * \brief           Check a public-private key pair
00641  *
00642  * \param pub       Keypair structure holding a public key
00643  * \param prv       Keypair structure holding a private (plus public) key
00644  *
00645  * \return          0 if successful (keys are valid and match), or
00646  *                  POLARSSL_ERR_ECP_BAD_INPUT_DATA, or
00647  *                  a POLARSSL_ERR_ECP_XXX or POLARSSL_ERR_MPI_XXX code.
00648  */
00649 int ecp_check_pub_priv( const ecp_keypair *pub, const ecp_keypair *prv );
00650 
00651 #if defined(POLARSSL_SELF_TEST)
00652 /**
00653  * \brief          Checkup routine
00654  *
00655  * \return         0 if successful, or 1 if a test failed
00656  */
00657 int ecp_self_test( int verbose );
00658 #endif
00659 
00660 #ifdef __cplusplus
00661 }
00662 #endif
00663 
00664 #endif /* ecp.h */
00665