ecp.h 20.8 KB
Newer Older
1 2 3 4 5
/**
 * \file ecp.h
 *
 * \brief Elliptic curves over GF(p)
 *
Paul Bakker's avatar
Paul Bakker committed
6
 *  Copyright (C) 2006-2013, Brainspark B.V.
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
 *
 *  This file is part of PolarSSL (http://www.polarssl.org)
 *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
 *
 *  All rights reserved.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
#ifndef POLARSSL_ECP_H
#define POLARSSL_ECP_H

30
#include "bignum.h"
31 32

/*
33
 * ECP error codes
34
 */
Paul Bakker's avatar
Paul Bakker committed
35
#define POLARSSL_ERR_ECP_BAD_INPUT_DATA                    -0x4F80  /**< Bad input parameters to function. */
Paul Bakker's avatar
Paul Bakker committed
36
#define POLARSSL_ERR_ECP_BUFFER_TOO_SMALL                  -0x4F00  /**< The buffer is too small to write to. */
37
#define POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE               -0x4E80  /**< Requested curve not available. */
38
#define POLARSSL_ERR_ECP_VERIFY_FAILED                     -0x4E00  /**< The signature is not valid. */
39 40 41
#define POLARSSL_ERR_ECP_MALLOC_FAILED                     -0x4D80  /**< Memory allocation failed. */
#define POLARSSL_ERR_ECP_RANDOM_FAILED                     -0x4D00  /**< Generation of random value, such as (ephemeral) key, failed. */
#define POLARSSL_ERR_ECP_INVALID_KEY                       -0x4C80  /**< Invalid private or public key. */
42

43 44 45 46
#ifdef __cplusplus
extern "C" {
#endif

47 48 49 50 51 52 53 54 55 56 57 58
/**
 * Domain parameters (curve, subgroup and generator) identifiers.
 *
 * Only curves over prime fields are supported.
 *
 * \warning This library does not support validation of arbitrary domain
 * parameters. Therefore, only well-known domain parameters from trusted
 * sources should be used. See ecp_use_known_dp().
 */
typedef enum
{
    POLARSSL_ECP_DP_NONE = 0,
59 60 61 62 63
    POLARSSL_ECP_DP_SECP192R1,      /*!< 192-bits NIST curve  */
    POLARSSL_ECP_DP_SECP224R1,      /*!< 224-bits NIST curve  */
    POLARSSL_ECP_DP_SECP256R1,      /*!< 256-bits NIST curve  */
    POLARSSL_ECP_DP_SECP384R1,      /*!< 384-bits NIST curve  */
    POLARSSL_ECP_DP_SECP521R1,      /*!< 521-bits NIST curve  */
64 65 66
    POLARSSL_ECP_DP_BP256R1,        /*!< 256-bits Brainpool curve */
    POLARSSL_ECP_DP_BP384R1,        /*!< 384-bits Brainpool curve */
    POLARSSL_ECP_DP_BP512R1,        /*!< 512-bits Brainpool curve */
67 68 69 70
    POLARSSL_ECP_DP_M221,           /*!< (not implemented yet)    */
    POLARSSL_ECP_DP_M255,           /*!< Curve25519               */
    POLARSSL_ECP_DP_M383,           /*!< (not implemented yet)    */
    POLARSSL_ECP_DP_M511,           /*!< (not implemented yet)    */
71 72
} ecp_group_id;

73
/**
74 75 76
 * Number of supported curves (plus one for NONE).
 *
 * (Montgomery curves excluded for now.)
77
 */
78
#define POLARSSL_ECP_DP_MAX     9
79

80
/**
81
 * Curve information for use by other modules
82 83 84
 */
typedef struct
{
85 86 87 88
    ecp_group_id grp_id;    /*!< Internal identifier        */
    uint16_t tls_id;        /*!< TLS NamedCurve identifier  */
    uint16_t size;          /*!< Curve size in bits         */
    const char *name;       /*!< Human-friendly name        */
89 90
} ecp_curve_info;

91
/**
92
 * \brief           ECP point structure (jacobian coordinates)
93
 *
94 95 96 97 98
 * \note            All functions expect and return points satisfying
 *                  the following condition: Z == 0 or Z == 1. (Other
 *                  values of Z are used by internal functions only.)
 *                  The point is zero, or "at infinity", if Z == 0.
 *                  Otherwise, X and Y are its standard (affine) coordinates.
99 100 101
 */
typedef struct
{
102 103
    mpi X;          /*!<  the point's X coordinate  */
    mpi Y;          /*!<  the point's Y coordinate  */
104
    mpi Z;          /*!<  the point's Z coordinate  */
105 106 107 108 109 110
}
ecp_point;

/**
 * \brief           ECP group structure
 *
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
111 112 113 114 115 116
 * We consider two types of curves equations:
 * 1. Short Weierstrass y^2 = x^3 + A x + B     mod P   (SEC1 + RFC 4492)
 * 2. Montgomery,       y^2 = x^3 + A x^2 + x   mod P   (M255 + draft)
 * In both cases, a generator G for a prime-order subgroup is fixed. In the
 * short weierstrass, this subgroup is actually the whole curve, and its
 * cardinal is denoted by N.
117
 *
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
118 119 120
 * In the case of Montgomery curves, we don't store A but (A + 2) / 4 which is
 * the quantity actualy used in the formulas. Also, nbits is not the size of N
 * but the required size for private keys.
121
 *
122 123 124 125 126 127
 * If modp is NULL, reduction modulo P is done using a generic algorithm.
 * Otherwise, it must point to a function that takes an mpi in the range
 * 0..2^(2*pbits)-1 and transforms it in-place in an integer of little more
 * than pbits, so that the integer may be efficiently brought in the 0..P-1
 * range by a few additions or substractions. It must return 0 on success and
 * non-zero on failure.
128 129 130
 */
typedef struct
{
131 132
    ecp_group_id id;    /*!<  internal group identifier                     */
    mpi P;              /*!<  prime modulus of the base field               */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
133 134 135 136
    mpi A;              /*!<  1. A in the equation, or 2. (A + 2) / 4       */
    mpi B;              /*!<  1. B in the equation, or 2. unused            */
    ecp_point G;        /*!<  generator of the (sub)group used              */
    mpi N;              /*!<  1. the order of G, or 2. unused               */
137
    size_t pbits;       /*!<  number of bits in P                           */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
138
    size_t nbits;       /*!<  number of bits in 1. P, or 2. private keys    */
139
    unsigned int h;     /*!<  internal: 1 if the constants are static       */
140
    int (*modp)(mpi *); /*!<  function for fast reduction mod P             */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
141 142 143 144
    int (*t_pre)(ecp_point *, void *);  /*!< unused                         */
    int (*t_post)(ecp_point *, void *); /*!< unused                         */
    void *t_data;                       /*!< unused                         */
    ecp_point *T;       /*!<  pre-computed points for ecp_mul_comb()        */
145
    size_t T_size;      /*!<  number for pre-computed points                */
146 147 148
}
ecp_group;

149 150 151 152
/**
 * \brief           ECP key pair structure
 *
 * A generic key pair that could be used for ECDSA, fixed ECDH, etc.
153 154
 *
 * \note Members purposefully in the same order as struc ecdsa_context.
155 156 157 158 159 160 161 162 163
 */
typedef struct
{
    ecp_group grp;      /*!<  Elliptic curve and base point     */
    mpi d;              /*!<  our secret value                  */
    ecp_point Q;        /*!<  our public value                  */
}
ecp_keypair;

164
#if !defined(POLARSSL_CONFIG_OPTIONS)
165
/**
166
 * Maximum size of the groups (that is, of N and P)
167
 */
168 169 170
#define POLARSSL_ECP_MAX_BITS     521   /**< Maximum bit size of groups */
#endif

171
#define POLARSSL_ECP_MAX_BYTES    ( ( POLARSSL_ECP_MAX_BITS + 7 ) / 8 )
172
#define POLARSSL_ECP_MAX_PT_LEN   ( 2 * POLARSSL_ECP_MAX_BYTES + 1 )
173

174
#if !defined(POLARSSL_CONFIG_OPTIONS)
175
/*
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
176 177 178
 * Maximum "window" size used for point multiplication.
 * Default: 6.
 * Minimum value: 2. Maximum value: 7.
179
 *
180
 * Result is an array of at most ( 1 << ( POLARSSL_ECP_WINDOW_SIZE - 1 ) )
181
 * points used for point multiplication.
182 183 184
 *
 * Reduction in size may reduce speed for big curves.
 */
185 186
#define POLARSSL_ECP_WINDOW_SIZE    6   /**< Maximum window size used */
#endif
187

188
/*
189
 * Point formats, from RFC 4492's enum ECPointFormat
190 191 192 193
 */
#define POLARSSL_ECP_PF_UNCOMPRESSED    0   /**< Uncompressed point format */
#define POLARSSL_ECP_PF_COMPRESSED      1   /**< Compressed point format */

194
/*
195
 * Some other constants from RFC 4492
196
 */
197
#define POLARSSL_ECP_TLS_NAMED_CURVE    3   /**< ECCurveType's named_curve */
198

199 200 201 202 203 204 205
/**
 * \brief           Return the list of supported curves with associated info
 *
 * \return          A statically allocated array, the last entry is 0.
 */
const ecp_curve_info *ecp_curve_list( void );

206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
/**
 * \brief           Get curve information from an internal group identifier
 *
 * \param grp_id    A POLARSSL_ECP_DP_XXX value
 *
 * \return          The associated curve information or NULL
 */
const ecp_curve_info *ecp_curve_info_from_grp_id( ecp_group_id grp_id );

/**
 * \brief           Get curve information from a TLS NamedCurve value
 *
 * \param grp_id    A POLARSSL_ECP_DP_XXX value
 *
 * \return          The associated curve information or NULL
 */
const ecp_curve_info *ecp_curve_info_from_tls_id( uint16_t tls_id );

224 225 226 227 228 229 230 231 232
/**
 * \brief           Get curve information from a human-readable name
 *
 * \param name      The name
 *
 * \return          The associated curve information or NULL
 */
const ecp_curve_info *ecp_curve_info_from_name( const char *name );

233
/**
234
 * \brief           Initialize a point (as zero)
235 236 237
 */
void ecp_point_init( ecp_point *pt );

238 239 240 241 242
/**
 * \brief           Initialize a group (to something meaningless)
 */
void ecp_group_init( ecp_group *grp );

243 244 245 246 247
/**
 * \brief           Initialize a key pair (as an invalid one)
 */
void ecp_keypair_init( ecp_keypair *key );

248 249 250 251 252 253 254 255 256 257
/**
 * \brief           Free the components of a point
 */
void ecp_point_free( ecp_point *pt );

/**
 * \brief           Free the components of an ECP group
 */
void ecp_group_free( ecp_group *grp );

258 259 260 261 262
/**
 * \brief           Free the components of a key pair
 */
void ecp_keypair_free( ecp_keypair *key );

263
/**
264
 * \brief           Copy the contents of point Q into P
265
 *
266 267
 * \param P         Destination point
 * \param Q         Source point
268
 *
269 270
 * \return          0 if successful,
 *                  POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
271
 */
272
int ecp_copy( ecp_point *P, const ecp_point *Q );
273

274
/**
275
 * \brief           Copy the contents of a group object
276
 *
277 278
 * \param dst       Destination group
 * \param src       Source group
279
 *
280 281
 * \return          0 if successful,
 *                  POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
282
 */
283
int ecp_group_copy( ecp_group *dst, const ecp_group *src );
284

285
/**
286
 * \brief           Set a point to zero
287
 *
288
 * \param pt        Destination point
289
 *
290 291
 * \return          0 if successful,
 *                  POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
292
 */
293
int ecp_set_zero( ecp_point *pt );
294

295
/**
296
 * \brief           Tell if a point is zero
297
 *
298
 * \param pt        Point to test
299
 *
300
 * \return          1 if point is zero, 0 otherwise
301
 */
302
int ecp_is_zero( ecp_point *pt );
303

304 305 306 307 308 309 310 311 312 313 314 315 316
/**
 * \brief           Import a non-zero point from two ASCII strings
 *
 * \param P         Destination point
 * \param radix     Input numeric base
 * \param x         First affine coordinate as a null-terminated string
 * \param y         Second affine coordinate as a null-terminated string
 *
 * \return          0 if successful, or a POLARSSL_ERR_MPI_XXX error code
 */
int ecp_point_read_string( ecp_point *P, int radix,
                           const char *x, const char *y );

317
/**
318
 * \brief           Export a point into unsigned binary data
319
 *
320
 * \param grp       Group to which the point should belong
321
 * \param P         Point to export
322
 * \param format    Point format, should be a POLARSSL_ECP_PF_XXX macro
323
 * \param olen      Length of the actual output
324 325 326
 * \param buf       Output buffer
 * \param buflen    Length of the output buffer
 *
327 328 329
 * \return          0 if successful,
 *                  or POLARSSL_ERR_ECP_BAD_INPUT_DATA
 *                  or POLARSSL_ERR_ECP_BUFFER_TOO_SMALL
330
 */
331
int ecp_point_write_binary( const ecp_group *grp, const ecp_point *P,
332
                            int format, size_t *olen,
333
                            unsigned char *buf, size_t buflen );
334

335 336 337 338 339 340 341 342 343
/**
 * \brief           Import a point from unsigned binary data
 *
 * \param grp       Group to which the point should belong
 * \param P         Point to import
 * \param buf       Input buffer
 * \param ilen      Actual length of input
 *
 * \return          0 if successful,
344
 *                  POLARSSL_ERR_ECP_BAD_INPUT_DATA if input is invalid
345 346 347 348 349 350
 *                  POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
 *
 * \note            This function does NOT check that the point actually
 *                  belongs to the given group, see ecp_check_pubkey() for
 *                  that.
 */
351 352
int ecp_point_read_binary( const ecp_group *grp, ecp_point *P,
                           const unsigned char *buf, size_t ilen );
353

354
/**
355
 * \brief           Import a point from a TLS ECPoint record
356
 *
357 358 359
 * \param grp       ECP group used
 * \param pt        Destination point
 * \param buf       $(Start of input buffer)
360 361 362 363 364
 * \param len       Buffer length
 *
 * \return          O if successful,
 *                  POLARSSL_ERR_MPI_XXX if initialization failed
 *                  POLARSSL_ERR_ECP_BAD_INPUT_DATA if input is invalid
365
 */
366 367
int ecp_tls_read_point( const ecp_group *grp, ecp_point *pt,
                        const unsigned char **buf, size_t len );
368

369
/**
370
 * \brief           Export a point as a TLS ECPoint record
371 372
 *
 * \param grp       ECP group used
373 374 375
 * \param pt        Point to export
 * \param format    Export format
 * \param olen      length of data written
376 377 378 379
 * \param buf       Buffer to write to
 * \param blen      Buffer length
 *
 * \return          0 if successful,
380
 *                  or POLARSSL_ERR_ECP_BAD_INPUT_DATA
381 382
 *                  or POLARSSL_ERR_ECP_BUFFER_TOO_SMALL
 */
383 384
int ecp_tls_write_point( const ecp_group *grp, const ecp_point *pt,
                         int format, size_t *olen,
385 386
                         unsigned char *buf, size_t blen );

387
/**
388
 * \brief           Import an ECP group from null-terminated ASCII strings
389
 *
390 391 392 393 394 395 396
 * \param grp       Destination group
 * \param radix     Input numeric base
 * \param p         Prime modulus of the base field
 * \param b         Constant term in the equation
 * \param gx        The generator's X coordinate
 * \param gy        The generator's Y coordinate
 * \param n         The generator's order
397
 *
398 399 400
 * \return          0 if successful, or a POLARSSL_ERR_MPI_XXX error code
 *
 * \note            Sets all fields except modp.
401
 */
402 403 404
int ecp_group_read_string( ecp_group *grp, int radix,
                           const char *p, const char *b,
                           const char *gx, const char *gy, const char *n);
405 406

/**
407
 * \brief           Set a group using well-known domain parameters
408
 *
409 410
 * \param grp       Destination group
 * \param index     Index in the list of well-known domain parameters
411
 *
412 413 414 415 416 417
 * \return          O if successful,
 *                  POLARSSL_ERR_MPI_XXX if initialization failed
 *                  POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE for unkownn groups
 *
 * \note            Index should be a value of RFC 4492's enum NamdeCurve,
 *                  possibly in the form of a POLARSSL_ECP_DP_XXX macro.
418
 */
419
int ecp_use_known_dp( ecp_group *grp, ecp_group_id index );
420

421
/**
422
 * \brief           Set a group from a TLS ECParameters record
423
 *
424 425
 * \param grp       Destination group
 * \param buf       &(Start of input buffer)
426 427 428 429 430 431
 * \param len       Buffer length
 *
 * \return          O if successful,
 *                  POLARSSL_ERR_MPI_XXX if initialization failed
 *                  POLARSSL_ERR_ECP_BAD_INPUT_DATA if input is invalid
 */
432
int ecp_tls_read_group( ecp_group *grp, const unsigned char **buf, size_t len );
433 434

/**
435
 * \brief           Write the TLS ECParameters record for a group
436 437
 *
 * \param grp       ECP group used
438
 * \param olen      Number of bytes actually written
439
 * \param buf       Buffer to write to
440
 * \param blen      Buffer length
441 442 443 444
 *
 * \return          0 if successful,
 *                  or POLARSSL_ERR_ECP_BUFFER_TOO_SMALL
 */
445
int ecp_tls_write_group( const ecp_group *grp, size_t *olen,
446
                         unsigned char *buf, size_t blen );
447

448 449 450 451 452 453 454 455
/**
 * \brief           Addition: R = P + Q
 *
 * \param grp       ECP group
 * \param R         Destination point
 * \param P         Left-hand point
 * \param Q         Right-hand point
 *
456
 * \return          0 if successful,
457
 *                  POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
458 459 460
 *
 * \note            This function does not support Montgomery curves, such as
 *                  Curve25519.
461 462 463 464
 */
int ecp_add( const ecp_group *grp, ecp_point *R,
             const ecp_point *P, const ecp_point *Q );

465 466 467 468 469 470 471 472 473 474
/**
 * \brief           Subtraction: R = P - Q
 *
 * \param grp       ECP group
 * \param R         Destination point
 * \param P         Left-hand point
 * \param Q         Right-hand point
 *
 * \return          0 if successful,
 *                  POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
475 476 477
 *
 * \note            This function does not support Montgomery curves, such as
 *                  Curve25519.
478 479 480 481
 */
int ecp_sub( const ecp_group *grp, ecp_point *R,
             const ecp_point *P, const ecp_point *Q );

482 483
/**
 * \brief           Multiplication by an integer: R = m * P
Paul Bakker's avatar
Paul Bakker committed
484
 *                  (Not thread-safe to use same group in multiple threads)
485 486 487 488 489
 *
 * \param grp       ECP group
 * \param R         Destination point
 * \param m         Integer by which to multiply
 * \param P         Point to multiply
490 491
 * \param f_rng     RNG function (see notes)
 * \param p_rng     RNG parameter
492
 *
493
 * \return          0 if successful,
494 495
 *                  POLARSSL_ERR_ECP_INVALID_KEY if m is not a valid privkey
 *                  or P is not a valid pubkey,
496
 *                  POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
497
 *
498 499 500 501
 * \note            In order to prevent timing attacks, this function
 *                  executes the exact same sequence of (base field)
 *                  operations for any valid m. It avoids any if-branch or
 *                  array index depending on the value of m.
502
 *
503
 * \note            If f_rng is not NULL, it is used to randomize intermediate
504 505 506
 *                  results in order to prevent potential timing attacks
 *                  targetting these results. It is recommended to always
 *                  provide a non-NULL f_rng (the overhead is negligible).
507
 */
508 509 510
int ecp_mul( ecp_group *grp, ecp_point *R,
             const mpi *m, const ecp_point *P,
             int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
511

512 513 514 515 516 517 518
/**
 * \brief           Check that a point is a valid public key on this curve
 *
 * \param grp       Curve/group the point should belong to
 * \param pt        Point to check
 *
 * \return          0 if point is a valid public key,
519
 *                  POLARSSL_ERR_ECP_INVALID_KEY otherwise.
520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541
 *
 * \note            This function only checks the point is non-zero, has valid
 *                  coordinates and lies on the curve, but not that it is
 *                  indeed a multiple of G. This is additional check is more
 *                  expensive, isn't required by standards, and shouldn't be
 *                  necessary if the group used has a small cofactor. In
 *                  particular, it is useless for the NIST groups which all
 *                  have a cofactor of 1.
 *
 * \note            Uses bare components rather than an ecp_keypair structure
 *                  in order to ease use with other structures such as
 *                  ecdh_context of ecdsa_context.
 */
int ecp_check_pubkey( const ecp_group *grp, const ecp_point *pt );

/**
 * \brief           Check that an mpi is a valid private key for this curve
 *
 * \param grp       Group used
 * \param d         Integer to check
 *
 * \return          0 if point is a valid private key,
542
 *                  POLARSSL_ERR_ECP_INVALID_KEY otherwise.
543 544 545 546 547
 *
 * \note            Uses bare components rather than an ecp_keypair structure
 *                  in order to ease use with other structures such as
 *                  ecdh_context of ecdsa_context.
 */
548
int ecp_check_privkey( const ecp_group *grp, const mpi *d );
549

550 551 552 553 554 555 556 557 558 559 560
/**
 * \brief           Generate a keypair
 *
 * \param grp       ECP group
 * \param d         Destination MPI (secret part)
 * \param Q         Destination point (public part)
 * \param f_rng     RNG function
 * \param p_rng     RNG parameter
 *
 * \return          0 if successful,
 *                  or a POLARSSL_ERR_ECP_XXX or POLARSSL_MPI_XXX error code
561 562 563 564
 *
 * \note            Uses bare components rather than an ecp_keypair structure
 *                  in order to ease use with other structures such as
 *                  ecdh_context of ecdsa_context.
565
 */
566
int ecp_gen_keypair( ecp_group *grp, mpi *d, ecp_point *Q,
567 568 569
                     int (*f_rng)(void *, unsigned char *, size_t),
                     void *p_rng );

570 571 572 573 574 575 576 577 578 579 580 581 582 583
/**
 * \brief           Generate a keypair
 *
 * \param grp_id    ECP group identifier
 * \param key       Destination keypair
 * \param f_rng     RNG function
 * \param p_rng     RNG parameter
 *
 * \return          0 if successful,
 *                  or a POLARSSL_ERR_ECP_XXX or POLARSSL_MPI_XXX error code
 */
int ecp_gen_key( ecp_group_id grp_id, ecp_keypair *key,
                int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );

584 585 586 587 588 589 590 591 592 593 594 595
/**
 * \brief          Checkup routine
 *
 * \return         0 if successful, or 1 if the test failed
 */
int ecp_self_test( int verbose );

#ifdef __cplusplus
}
#endif

#endif