/*
 *  Elliptic curves over GF(p)
 *
 *  Copyright (C) 2006-2013, Brainspark B.V.
 *
 *  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.
 */

/*
 * References:
 *
 * SEC1 http://www.secg.org/index.php?action=secg,docs_secg
 * GECC = Guide to Elliptic Curve Cryptography - Hankerson, Menezes, Vanstone
 * FIPS 186-3 http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf
 * RFC 4492 for the related TLS structures and constants
 */

#include "polarssl/config.h"

#if defined(POLARSSL_ECP_C)

#include "polarssl/ecp.h"

#if defined(POLARSSL_MEMORY_C)
#include "polarssl/memory.h"
#else
#define polarssl_malloc     malloc
#define polarssl_free       free
#endif

#include <limits.h>
#include <stdlib.h>

#if defined(POLARSSL_SELF_TEST)
/*
 * Counts of point addition and doubling operations.
 * Used to test resistance of point multiplication to SPA/timing attacks.
 */
unsigned long add_count, dbl_count;
#endif

/*
 * Initialize (the components of) a point
 */
void ecp_point_init( ecp_point *pt )
{
    if( pt == NULL )
        return;

    mpi_init( &pt->X );
    mpi_init( &pt->Y );
    mpi_init( &pt->Z );
}

/*
 * Initialize (the components of) a group
 */
void ecp_group_init( ecp_group *grp )
{
    if( grp == NULL )
        return;

    grp->id = 0;

    mpi_init( &grp->P );
    mpi_init( &grp->B );
    ecp_point_init( &grp->G );
    mpi_init( &grp->N );

    grp->pbits = 0;
    grp->nbits = 0;

    grp->modp = NULL;
}

/*
 * Initialize (the components of) a key pair
 */
void ecp_keypair_init( ecp_keypair *key )
{
    if ( key == NULL )
        return;

    ecp_group_init( &key->grp );
    mpi_init( &key->d );
    ecp_point_init( &key->Q );
}

/*
 * Unallocate (the components of) a point
 */
void ecp_point_free( ecp_point *pt )
{
    if( pt == NULL )
        return;

    mpi_free( &( pt->X ) );
    mpi_free( &( pt->Y ) );
    mpi_free( &( pt->Z ) );
}

/*
 * Unallocate (the components of) a group
 */
void ecp_group_free( ecp_group *grp )
{
    if( grp == NULL )
        return;

    mpi_free( &grp->P );
    mpi_free( &grp->B );
    ecp_point_free( &grp->G );
    mpi_free( &grp->N );
}

/*
 * Unallocate (the components of) a key pair
 */
void ecp_keypair_free( ecp_keypair *key )
{
    if ( key == NULL )
        return;

    ecp_group_free( &key->grp );
    mpi_free( &key->d );
    ecp_point_free( &key->Q );
}

/*
 * Set point to zero
 */
int ecp_set_zero( ecp_point *pt )
{
    int ret;

    MPI_CHK( mpi_lset( &pt->X , 1 ) );
    MPI_CHK( mpi_lset( &pt->Y , 1 ) );
    MPI_CHK( mpi_lset( &pt->Z , 0 ) );

cleanup:
    return( ret );
}

/*
 * Tell if a point is zero
 */
int ecp_is_zero( ecp_point *pt )
{
    return( mpi_cmp_int( &pt->Z, 0 ) == 0 );
}

/*
 * Copy the contents of Q into P
 */
int ecp_copy( ecp_point *P, const ecp_point *Q )
{
    int ret;

    MPI_CHK( mpi_copy( &P->X, &Q->X ) );
    MPI_CHK( mpi_copy( &P->Y, &Q->Y ) );
    MPI_CHK( mpi_copy( &P->Z, &Q->Z ) );

cleanup:
    return( ret );
}

/*
 * Import a non-zero point from ASCII strings
 */
int ecp_point_read_string( ecp_point *P, int radix,
                           const char *x, const char *y )
{
    int ret;

    MPI_CHK( mpi_read_string( &P->X, radix, x ) );
    MPI_CHK( mpi_read_string( &P->Y, radix, y ) );
    MPI_CHK( mpi_lset( &P->Z, 1 ) );

cleanup:
    return( ret );
}

/*
 * Import an ECP group from ASCII strings
 */
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)
{
    int ret;

    MPI_CHK( mpi_read_string( &grp->P, radix, p ) );
    MPI_CHK( mpi_read_string( &grp->B, radix, b ) );
    MPI_CHK( ecp_point_read_string( &grp->G, radix, gx, gy ) );
    MPI_CHK( mpi_read_string( &grp->N, radix, n ) );

    grp->pbits = mpi_msb( &grp->P );
    grp->nbits = mpi_msb( &grp->N );

cleanup:
    return( ret );
}

/*
 * Export a point into unsigned binary data (SEC1 2.3.3)
 */
int ecp_point_write_binary( const ecp_group *grp, const ecp_point *P,
                            int format, size_t *olen,
                            unsigned char *buf, size_t buflen )
{
    int ret = 0;
    size_t plen;

    if( format != POLARSSL_ECP_PF_UNCOMPRESSED &&
        format != POLARSSL_ECP_PF_COMPRESSED )
        return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );

    /*
     * Common case: P == 0
     */
    if( mpi_cmp_int( &P->Z, 0 ) == 0 )
    {
        if( buflen < 1 )
            return( POLARSSL_ERR_ECP_BUFFER_TOO_SMALL );

        buf[0] = 0x00;
        *olen = 1;

        return( 0 );
    }

    plen = mpi_size( &grp->P );

    if( format == POLARSSL_ECP_PF_UNCOMPRESSED )
    {
        *olen = 2 * plen + 1;

        if( buflen < *olen )
            return( POLARSSL_ERR_ECP_BUFFER_TOO_SMALL );

        buf[0] = 0x04;
        MPI_CHK( mpi_write_binary( &P->X, buf + 1, plen ) );
        MPI_CHK( mpi_write_binary( &P->Y, buf + 1 + plen, plen ) );
    }
    else if( format == POLARSSL_ECP_PF_COMPRESSED )
    {
        *olen = plen + 1;

        if( buflen < *olen )
            return( POLARSSL_ERR_ECP_BUFFER_TOO_SMALL );

        buf[0] = 0x02 + mpi_get_bit( &P->Y, 0 );
        MPI_CHK( mpi_write_binary( &P->X, buf + 1, plen ) );
    }

cleanup:
    return( ret );
}

/*
 * Import a point from unsigned binary data (SEC1 2.3.4)
 */
int ecp_point_read_binary( const ecp_group *grp, ecp_point *pt,
                           const unsigned char *buf, size_t ilen ) {
    int ret;
    size_t plen;

    if( ilen == 1 && buf[0] == 0x00 )
        return( ecp_set_zero( pt ) );

    plen = mpi_size( &grp->P );

    if( ilen != 2 * plen + 1 || buf[0] != 0x04 )
        return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );

    MPI_CHK( mpi_read_binary( &pt->X, buf + 1, plen ) );
    MPI_CHK( mpi_read_binary( &pt->Y, buf + 1 + plen, plen ) );
    MPI_CHK( mpi_lset( &pt->Z, 1 ) );

cleanup:
    return( ret );
}

/*
 * Import a point from a TLS ECPoint record (RFC 4492)
 *      struct {
 *          opaque point <1..2^8-1>;
 *      } ECPoint;
 */
int ecp_tls_read_point( const ecp_group *grp, ecp_point *pt,
                        const unsigned char **buf, size_t buf_len )
{
    unsigned char data_len;
    const unsigned char *buf_start;

    /*
     * We must have at least two bytes (1 for length, at least of for data)
     */
    if( buf_len < 2 )
        return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );

    data_len = *(*buf)++;
    if( data_len < 1 || data_len > buf_len - 1 )
        return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );

    /*
     * Save buffer start for read_binary and update buf
     */
    buf_start = *buf;
    *buf += data_len;

    return ecp_point_read_binary( grp, pt, buf_start, data_len );
}

/*
 * Export a point as a TLS ECPoint record (RFC 4492)
 *      struct {
 *          opaque point <1..2^8-1>;
 *      } ECPoint;
 */
int ecp_tls_write_point( const ecp_group *grp, const ecp_point *pt,
                         int format, size_t *olen,
                         unsigned char *buf, size_t blen )
{
    int ret;

    /*
     * buffer length must be at least one, for our length byte
     */
    if( blen < 1 )
        return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );

    if( ( ret = ecp_point_write_binary( grp, pt, format,
                    olen, buf + 1, blen - 1) ) != 0 )
        return( ret );

    /*
     * write length to the first byte and update total length
     */
    buf[0] = *olen;
    ++*olen;

    return 0;
}

/*
 * Wrapper around fast quasi-modp functions, with fall-back to mpi_mod_mpi.
 * See the documentation of struct ecp_group.
 */
static int ecp_modp( mpi *N, const ecp_group *grp )
{
    int ret;

    if( grp->modp == NULL )
        return( mpi_mod_mpi( N, N, &grp->P ) );

    if( mpi_cmp_int( N, 0 ) < 0 || mpi_msb( N ) > 2 * grp->pbits )
        return( POLARSSL_ERR_ECP_GENERIC );

    MPI_CHK( grp->modp( N ) );

    while( mpi_cmp_int( N, 0 ) < 0 )
        MPI_CHK( mpi_add_mpi( N, N, &grp->P ) );

    while( mpi_cmp_mpi( N, &grp->P ) >= 0 )
        MPI_CHK( mpi_sub_mpi( N, N, &grp->P ) );

cleanup:
    return( ret );
}

#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED)
/*
 * 192 bits in terms of t_uint
 */
#define P192_SIZE_INT   ( 192 / CHAR_BIT / sizeof( t_uint ) )

/*
 * Table to get S1, S2, S3 of FIPS 186-3 D.2.1:
 * -1 means let this chunk be 0
 * a positive value i means A_i.
 */
#define P192_CHUNKS         3
#define P192_CHUNK_CHAR     ( 64 / CHAR_BIT )
#define P192_CHUNK_INT      ( P192_CHUNK_CHAR / sizeof( t_uint ) )

const signed char p192_tbl[][P192_CHUNKS] = {
    { -1,   3,  3   }, /* S1 */
    { 4,    4,  -1  }, /* S2 */
    { 5,    5,  5   }, /* S3 */
};

/*
 * Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1)
 */
static int ecp_mod_p192( mpi *N )
{
    int ret;
    unsigned char i, j, offset;
    signed char chunk;
    mpi tmp, acc;
    t_uint tmp_p[P192_SIZE_INT], acc_p[P192_SIZE_INT + 1];

    tmp.s = 1;
    tmp.n = sizeof( tmp_p ) / sizeof( tmp_p[0] );
    tmp.p = tmp_p;

    acc.s = 1;
    acc.n = sizeof( acc_p ) / sizeof( acc_p[0] );
    acc.p = acc_p;

    MPI_CHK( mpi_grow( N, P192_SIZE_INT * 2 ) );

    /*
     * acc = T
     */
    memset( acc_p, 0, sizeof( acc_p ) );
    memcpy( acc_p, N->p, P192_CHUNK_CHAR * P192_CHUNKS );

    for( i = 0; i < sizeof( p192_tbl ) / sizeof( p192_tbl[0] ); i++)
    {
        /*
         * tmp = S_i
         */
        memset( tmp_p, 0, sizeof( tmp_p ) );
        for( j = 0, offset = P192_CHUNKS - 1; j < P192_CHUNKS; j++, offset-- )
        {
            chunk = p192_tbl[i][j];
            if( chunk >= 0 )
                memcpy( tmp_p + offset * P192_CHUNK_INT,
                        N->p + chunk * P192_CHUNK_INT,
                        P192_CHUNK_CHAR );
        }

        /*
         * acc += tmp
         */
        MPI_CHK( mpi_add_abs( &acc, &acc, &tmp ) );
    }

    MPI_CHK( mpi_copy( N, &acc ) );

cleanup:
    return( ret );
}
#endif /* POLARSSL_ECP_DP_SECP192R1_ENABLED */

#if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED)
/*
 * Size of p521 in terms of t_uint
 */
#define P521_SIZE_INT   ( 521 / CHAR_BIT / sizeof( t_uint ) + 1 )

/*
 * Bits to keep in the most significant t_uint
 */
#if defined(POLARSS_HAVE_INT8)
#define P521_MASK       0x01
#else
#define P521_MASK       0x01FF
#endif

/*
 * Fast quasi-reduction modulo p521 (FIPS 186-3 D.2.5)
 */
static int ecp_mod_p521( mpi *N )
{
    int ret;
    t_uint Mp[P521_SIZE_INT];
    mpi M;

    if( N->n < P521_SIZE_INT )
        return( 0 );

    memset( Mp, 0, P521_SIZE_INT * sizeof( t_uint ) );
    memcpy( Mp, N->p, P521_SIZE_INT * sizeof( t_uint ) );
    Mp[P521_SIZE_INT - 1] &= P521_MASK;

    M.s = 1;
    M.n = P521_SIZE_INT;
    M.p = Mp;

    MPI_CHK( mpi_shift_r( N, 521 ) );

    MPI_CHK( mpi_add_abs( N, N, &M ) );

cleanup:
    return( ret );
}
#endif /* POLARSSL_ECP_DP_SECP521R1_ENABLED */

/*
 * Domain parameters for secp192r1
 */
#define SECP192R1_P \
    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"
#define SECP192R1_B \
    "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1"
#define SECP192R1_GX \
    "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012"
#define SECP192R1_GY \
    "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811"
#define SECP192R1_N \
    "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831"

/*
 * Domain parameters for secp224r1
 */
#define SECP224R1_P \
    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001"
#define SECP224R1_B \
    "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4"
#define SECP224R1_GX \
    "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21"
#define SECP224R1_GY \
    "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34"
#define SECP224R1_N \
    "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D"

/*
 * Domain parameters for secp256r1
 */
#define SECP256R1_P \
    "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF"
#define SECP256R1_B \
    "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B"
#define SECP256R1_GX \
    "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296"
#define SECP256R1_GY \
    "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5"
#define SECP256R1_N \
    "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551"

/*
 * Domain parameters for secp384r1
 */
#define SECP384R1_P \
    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
    "FFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF"
#define SECP384R1_B \
    "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE814112" \
    "0314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF"
#define SECP384R1_GX \
    "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B98" \
    "59F741E082542A385502F25DBF55296C3A545E3872760AB7"
#define SECP384R1_GY \
    "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147C" \
    "E9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F"
#define SECP384R1_N \
    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
    "C7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973"

/*
 * Domain parameters for secp521r1
 */
#define SECP521R1_P \
    "000001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
#define SECP521R1_B \
    "00000051953EB9618E1C9A1F929A21A0B68540EEA2DA725B" \
    "99B315F3B8B489918EF109E156193951EC7E937B1652C0BD" \
    "3BB1BF073573DF883D2C34F1EF451FD46B503F00"
#define SECP521R1_GX \
    "000000C6858E06B70404E9CD9E3ECB662395B4429C648139" \
    "053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127" \
    "A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66"
#define SECP521R1_GY \
    "0000011839296A789A3BC0045C8A5FB42C7D1BD998F54449" \
    "579B446817AFBD17273E662C97EE72995EF42640C550B901" \
    "3FAD0761353C7086A272C24088BE94769FD16650"
#define SECP521R1_N \
    "000001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
    "FFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148" \
    "F709A5D03BB5C9B8899C47AEBB6FB71E91386409"

/*
 * Set a group using well-known domain parameters
 */
int ecp_use_known_dp( ecp_group *grp, ecp_group_id id )
{
    grp->id = id;

    switch( id )
    {
#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED)
        case POLARSSL_ECP_DP_SECP192R1:
            grp->modp = ecp_mod_p192;
            return( ecp_group_read_string( grp, 16,
                        SECP192R1_P, SECP192R1_B,
                        SECP192R1_GX, SECP192R1_GY, SECP192R1_N ) );
#endif /* POLARSSL_ECP_DP_SECP192R1_ENABLED */

#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED)
        case POLARSSL_ECP_DP_SECP224R1:
            return( ecp_group_read_string( grp, 16,
                        SECP224R1_P, SECP224R1_B,
                        SECP224R1_GX, SECP224R1_GY, SECP224R1_N ) );
#endif /* POLARSSL_ECP_DP_SECP224R1_ENABLED */

#if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED)
        case POLARSSL_ECP_DP_SECP256R1:
            return( ecp_group_read_string( grp, 16,
                        SECP256R1_P, SECP256R1_B,
                        SECP256R1_GX, SECP256R1_GY, SECP256R1_N ) );
#endif /* POLARSSL_ECP_DP_SECP256R1_ENABLED */

#if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED)
        case POLARSSL_ECP_DP_SECP384R1:
            return( ecp_group_read_string( grp, 16,
                        SECP384R1_P, SECP384R1_B,
                        SECP384R1_GX, SECP384R1_GY, SECP384R1_N ) );
#endif /* POLARSSL_ECP_DP_SECP384R1_ENABLED */

#if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED)
        case POLARSSL_ECP_DP_SECP521R1:
            grp->modp = ecp_mod_p521;
            return( ecp_group_read_string( grp, 16,
                        SECP521R1_P, SECP521R1_B,
                        SECP521R1_GX, SECP521R1_GY, SECP521R1_N ) );
#endif /* POLARSSL_ECP_DP_SECP521R1_ENABLED */
    }

    return( POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE );
}

/*
 * Set a group from an ECParameters record (RFC 4492)
 */
int ecp_tls_read_group( ecp_group *grp, const unsigned char **buf, size_t len )
{
    ecp_group_id id;

    /*
     * We expect at least three bytes (see below)
     */
    if( len < 3 )
        return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );

    /*
     * First byte is curve_type; only named_curve is handled
     */
    if( *(*buf)++ != POLARSSL_ECP_TLS_NAMED_CURVE )
        return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );

    /*
     * Next two bytes are the namedcurve value
     */
    id = *(*buf)++;
    id <<= 8;
    id |= *(*buf)++;
    return ecp_use_known_dp( grp, id );
}

/*
 * Write the ECParameters record corresponding to a group (RFC 4492)
 */
int ecp_tls_write_group( const ecp_group *grp, size_t *olen,
                         unsigned char *buf, size_t blen )
{
    /*
     * We are going to write 3 bytes (see below)
     */
    *olen = 3;
    if( blen < *olen )
        return( POLARSSL_ERR_ECP_BUFFER_TOO_SMALL );

    /*
     * First byte is curve_type, always named_curve
     */
    *buf++ = POLARSSL_ECP_TLS_NAMED_CURVE;

    /*
     * Next two bytes are the namedcurve value
     */
    buf[0] = grp->id >> 8;
    buf[1] = grp->id & 0xFF;

    return 0;
}

/*
 * Fast mod-p functions expect their argument to be in the 0..p^2 range.
 *
 * In order to guarantee that, we need to ensure that operands of
 * mpi_mul_mpi are in the 0..p range. So, after each operation we will
 * bring the result back to this range.
 *
 * The following macros are shortcuts for doing that.
 */

/*
 * Reduce a mpi mod p in-place, general case, to use after mpi_mul_mpi
 */
#define MOD_MUL( N )    MPI_CHK( ecp_modp( &N, grp ) )

/*
 * Reduce a mpi mod p in-place, to use after mpi_sub_mpi
 */
#define MOD_SUB( N )                                \
    while( mpi_cmp_int( &N, 0 ) < 0 )               \
        MPI_CHK( mpi_add_mpi( &N, &N, &grp->P ) )

/*
 * Reduce a mpi mod p in-place, to use after mpi_add_mpi and mpi_mul_int
 */
#define MOD_ADD( N )                                \
    while( mpi_cmp_mpi( &N, &grp->P ) >= 0 )        \
        MPI_CHK( mpi_sub_mpi( &N, &N, &grp->P ) )

/*
 * Normalize jacobian coordinates so that Z == 0 || Z == 1  (GECC 3.2.1)
 */
static int ecp_normalize( const ecp_group *grp, ecp_point *pt )
{
    int ret;
    mpi Zi, ZZi;

    if( mpi_cmp_int( &pt->Z, 0 ) == 0 )
        return( 0 );

    mpi_init( &Zi ); mpi_init( &ZZi );

    /*
     * X = X / Z^2  mod p
     */
    MPI_CHK( mpi_inv_mod( &Zi,      &pt->Z,     &grp->P ) );
    MPI_CHK( mpi_mul_mpi( &ZZi,     &Zi,        &Zi     ) ); MOD_MUL( ZZi );
    MPI_CHK( mpi_mul_mpi( &pt->X,   &pt->X,     &ZZi    ) ); MOD_MUL( pt->X );

    /*
     * Y = Y / Z^3  mod p
     */
    MPI_CHK( mpi_mul_mpi( &pt->Y,   &pt->Y,     &ZZi    ) ); MOD_MUL( pt->Y );
    MPI_CHK( mpi_mul_mpi( &pt->Y,   &pt->Y,     &Zi     ) ); MOD_MUL( pt->Y );

    /*
     * Z = 1
     */
    MPI_CHK( mpi_lset( &pt->Z, 1 ) );

cleanup:

    mpi_free( &Zi ); mpi_free( &ZZi );

    return( ret );
}

/*
 * Normalize jacobian coordinates of an array of points,
 * using Montgomery's trick to perform only one inversion mod P.
 * (See for example Cohen's "A Course in Computational Algebraic Number
 * Theory", Algorithm 10.3.4.)
 *
 * Warning: fails if one of the points is zero!
 * This should never happen, see choice of w in ecp_mul().
 */
static int ecp_normalize_many( const ecp_group *grp,
                               ecp_point T[], size_t t_len )
{
    int ret;
    size_t i;
    mpi *c, u, Zi, ZZi;

    if( t_len < 2 )
        return( ecp_normalize( grp, T ) );

    if( ( c = (mpi *) polarssl_malloc( t_len * sizeof( mpi ) ) ) == NULL )
        return( POLARSSL_ERR_ECP_GENERIC );

    mpi_init( &u ); mpi_init( &Zi ); mpi_init( &ZZi );
    for( i = 0; i < t_len; i++ )
        mpi_init( &c[i] );

    /*
     * c[i] = Z_0 * ... * Z_i
     */
    MPI_CHK( mpi_copy( &c[0], &T[0].Z ) );
    for( i = 1; i < t_len; i++ )
    {
        MPI_CHK( mpi_mul_mpi( &c[i], &c[i-1], &T[i].Z ) );
        MOD_MUL( c[i] );
    }

    /*
     * u = 1 / (Z_0 * ... * Z_n) mod P
     */
    MPI_CHK( mpi_inv_mod( &u, &c[t_len-1], &grp->P ) );

    for( i = t_len - 1; ; i-- )
    {
        /*
         * Zi = 1 / Z_i mod p
         * u = 1 / (Z_0 * ... * Z_i) mod P
         */
        if( i == 0 ) {
            MPI_CHK( mpi_copy( &Zi, &u ) );
        }
        else
        {
            MPI_CHK( mpi_mul_mpi( &Zi, &u, &c[i-1] ) ); MOD_MUL( Zi );
            MPI_CHK( mpi_mul_mpi( &u,  &u, &T[i].Z ) ); MOD_MUL( u );
        }

        /*
         * proceed as in normalize()
         */
        MPI_CHK( mpi_mul_mpi( &ZZi,    &Zi,     &Zi     ) ); MOD_MUL( ZZi );
        MPI_CHK( mpi_mul_mpi( &T[i].X, &T[i].X, &ZZi    ) ); MOD_MUL( T[i].X );
        MPI_CHK( mpi_mul_mpi( &T[i].Y, &T[i].Y, &ZZi    ) ); MOD_MUL( T[i].Y );
        MPI_CHK( mpi_mul_mpi( &T[i].Y, &T[i].Y, &Zi     ) ); MOD_MUL( T[i].Y );
        MPI_CHK( mpi_lset( &T[i].Z, 1 ) );

        if( i == 0 )
            break;
    }

cleanup:

    mpi_free( &u ); mpi_free( &Zi ); mpi_free( &ZZi );
    for( i = 0; i < t_len; i++ )
        mpi_free( &c[i] );
    polarssl_free( c );

    return( ret );
}


/*
 * Point doubling R = 2 P, Jacobian coordinates (GECC 3.21)
 */
static int ecp_double_jac( const ecp_group *grp, ecp_point *R,
                           const ecp_point *P )
{
    int ret;
    mpi T1, T2, T3, X, Y, Z;

#if defined(POLARSSL_SELF_TEST)
    dbl_count++;
#endif

    if( mpi_cmp_int( &P->Z, 0 ) == 0 )
        return( ecp_set_zero( R ) );

    mpi_init( &T1 ); mpi_init( &T2 ); mpi_init( &T3 );
    mpi_init( &X ); mpi_init( &Y ); mpi_init( &Z );

    MPI_CHK( mpi_mul_mpi( &T1,  &P->Z,  &P->Z ) );  MOD_MUL( T1 );
    MPI_CHK( mpi_sub_mpi( &T2,  &P->X,  &T1   ) );  MOD_SUB( T2 );
    MPI_CHK( mpi_add_mpi( &T1,  &P->X,  &T1   ) );  MOD_ADD( T1 );
    MPI_CHK( mpi_mul_mpi( &T2,  &T2,    &T1   ) );  MOD_MUL( T2 );
    MPI_CHK( mpi_mul_int( &T2,  &T2,    3     ) );  MOD_ADD( T2 );
    MPI_CHK( mpi_mul_int( &Y,   &P->Y,  2     ) );  MOD_ADD( Y  );
    MPI_CHK( mpi_mul_mpi( &Z,   &Y,     &P->Z ) );  MOD_MUL( Z  );
    MPI_CHK( mpi_mul_mpi( &Y,   &Y,     &Y    ) );  MOD_MUL( Y  );
    MPI_CHK( mpi_mul_mpi( &T3,  &Y,     &P->X ) );  MOD_MUL( T3 );
    MPI_CHK( mpi_mul_mpi( &Y,   &Y,     &Y    ) );  MOD_MUL( Y  );

    /*
     * For Y = Y / 2 mod p, we must make sure that Y is even before
     * using right-shift. No need to reduce mod p afterwards.
     */
    if( mpi_get_bit( &Y, 0 ) == 1 )
        MPI_CHK( mpi_add_mpi( &Y, &Y, &grp->P ) );
    MPI_CHK( mpi_shift_r( &Y,   1             ) );

    MPI_CHK( mpi_mul_mpi( &X,   &T2,    &T2   ) );  MOD_MUL( X  );
    MPI_CHK( mpi_mul_int( &T1,  &T3,    2     ) );  MOD_ADD( T1 );
    MPI_CHK( mpi_sub_mpi( &X,   &X,     &T1   ) );  MOD_SUB( X  );
    MPI_CHK( mpi_sub_mpi( &T1,  &T3,    &X    ) );  MOD_SUB( T1 );
    MPI_CHK( mpi_mul_mpi( &T1,  &T1,    &T2   ) );  MOD_MUL( T1 );
    MPI_CHK( mpi_sub_mpi( &Y,   &T1,    &Y    ) );  MOD_SUB( Y  );

    MPI_CHK( mpi_copy( &R->X, &X ) );
    MPI_CHK( mpi_copy( &R->Y, &Y ) );
    MPI_CHK( mpi_copy( &R->Z, &Z ) );

cleanup:

    mpi_free( &T1 ); mpi_free( &T2 ); mpi_free( &T3 );
    mpi_free( &X ); mpi_free( &Y ); mpi_free( &Z );

    return( ret );
}

/*
 * Addition or subtraction: R = P + Q or R = P + Q,
 * mixed affine-Jacobian coordinates (GECC 3.22)
 *
 * The coordinates of Q must be normalized (= affine),
 * but those of P don't need to. R is not normalized.
 *
 * If sign >= 0, perform addition, otherwise perform subtraction,
 * taking advantage of the fact that, for Q != 0, we have
 * -Q = (Q.X, -Q.Y, Q.Z)
 */
static int ecp_add_mixed( const ecp_group *grp, ecp_point *R,
                          const ecp_point *P, const ecp_point *Q,
                          signed char sign )
{
    int ret;
    mpi T1, T2, T3, T4, X, Y, Z;

#if defined(POLARSSL_SELF_TEST)
    add_count++;
#endif

    /*
     * Trivial cases: P == 0 or Q == 0
     * (Check Q first, so that we know Q != 0 when we compute -Q.)
     */
    if( mpi_cmp_int( &Q->Z, 0 ) == 0 )
        return( ecp_copy( R, P ) );

    if( mpi_cmp_int( &P->Z, 0 ) == 0 )
    {
        ret = ecp_copy( R, Q );

        /*
         * -R.Y mod P = P - R.Y unless R.Y == 0
         */
        if( ret == 0 && sign < 0)
            if( mpi_cmp_int( &R->Y, 0 ) != 0 )
                ret = mpi_sub_mpi( &R->Y, &grp->P, &R->Y );

        return( ret );
    }

    /*
     * Make sure Q coordinates are normalized
     */
    if( mpi_cmp_int( &Q->Z, 1 ) != 0 )
        return( POLARSSL_ERR_ECP_GENERIC );

    mpi_init( &T1 ); mpi_init( &T2 ); mpi_init( &T3 ); mpi_init( &T4 );
    mpi_init( &X ); mpi_init( &Y ); mpi_init( &Z );

    MPI_CHK( mpi_mul_mpi( &T1,  &P->Z,  &P->Z ) );  MOD_MUL( T1 );
    MPI_CHK( mpi_mul_mpi( &T2,  &T1,    &P->Z ) );  MOD_MUL( T2 );
    MPI_CHK( mpi_mul_mpi( &T1,  &T1,    &Q->X ) );  MOD_MUL( T1 );
    MPI_CHK( mpi_mul_mpi( &T2,  &T2,    &Q->Y ) );  MOD_MUL( T2 );

    /*
     * For subtraction, -Q.Y should have been used instead of Q.Y,
     * so we replace T2 by -T2, which is P - T2 mod P
     */
    if( sign < 0 )
    {
        MPI_CHK( mpi_sub_mpi( &T2, &grp->P, &T2 ) );
        MOD_SUB( T2 );
    }

    MPI_CHK( mpi_sub_mpi( &T1,  &T1,    &P->X ) );  MOD_SUB( T1 );
    MPI_CHK( mpi_sub_mpi( &T2,  &T2,    &P->Y ) );  MOD_SUB( T2 );

    if( mpi_cmp_int( &T1, 0 ) == 0 )
    {
        if( mpi_cmp_int( &T2, 0 ) == 0 )
        {
            ret = ecp_double_jac( grp, R, P );
            goto cleanup;
        }
        else
        {
            ret = ecp_set_zero( R );
            goto cleanup;
        }
    }

    MPI_CHK( mpi_mul_mpi( &Z,   &P->Z,  &T1   ) );  MOD_MUL( Z  );
    MPI_CHK( mpi_mul_mpi( &T3,  &T1,    &T1   ) );  MOD_MUL( T3 );
    MPI_CHK( mpi_mul_mpi( &T4,  &T3,    &T1   ) );  MOD_MUL( T4 );
    MPI_CHK( mpi_mul_mpi( &T3,  &T3,    &P->X ) );  MOD_MUL( T3 );
    MPI_CHK( mpi_mul_int( &T1,  &T3,    2     ) );  MOD_ADD( T1 );
    MPI_CHK( mpi_mul_mpi( &X,   &T2,    &T2   ) );  MOD_MUL( X  );
    MPI_CHK( mpi_sub_mpi( &X,   &X,     &T1   ) );  MOD_SUB( X  );
    MPI_CHK( mpi_sub_mpi( &X,   &X,     &T4   ) );  MOD_SUB( X  );
    MPI_CHK( mpi_sub_mpi( &T3,  &T3,    &X    ) );  MOD_SUB( T3 );
    MPI_CHK( mpi_mul_mpi( &T3,  &T3,    &T2   ) );  MOD_MUL( T3 );
    MPI_CHK( mpi_mul_mpi( &T4,  &T4,    &P->Y ) );  MOD_MUL( T4 );
    MPI_CHK( mpi_sub_mpi( &Y,   &T3,    &T4   ) );  MOD_SUB( Y  );

    MPI_CHK( mpi_copy( &R->X, &X ) );
    MPI_CHK( mpi_copy( &R->Y, &Y ) );
    MPI_CHK( mpi_copy( &R->Z, &Z ) );

cleanup:

    mpi_free( &T1 ); mpi_free( &T2 ); mpi_free( &T3 ); mpi_free( &T4 );
    mpi_free( &X ); mpi_free( &Y ); mpi_free( &Z );

    return( ret );
}

/*
 * Addition: R = P + Q, result's coordinates normalized
 */
int ecp_add( const ecp_group *grp, ecp_point *R,
             const ecp_point *P, const ecp_point *Q )
{
    int ret;

    MPI_CHK( ecp_add_mixed( grp, R, P, Q , 1 ) );
    MPI_CHK( ecp_normalize( grp, R ) );

cleanup:
    return( ret );
}

/*
 * Subtraction: R = P - Q, result's coordinates normalized
 */
int ecp_sub( const ecp_group *grp, ecp_point *R,
             const ecp_point *P, const ecp_point *Q )
{
    int ret;

    MPI_CHK( ecp_add_mixed( grp, R, P, Q, -1 ) );
    MPI_CHK( ecp_normalize( grp, R ) );

cleanup:
    return( ret );
}

/*
 * Compute a modified width-w non-adjacent form (NAF) of a number,
 * with a fixed pattern for resistance to SPA/timing attacks,
 * see <http://rd.springer.com/chapter/10.1007/3-540-36563-X_23>.
 * (The resulting multiplication algorithm can also been seen as a
 * modification of 2^w-ary multiplication, with signed coefficients,
 * all of them odd.)
 *
 * Input:
 * m must be an odd positive mpi less than w * k bits long
 * x must be an array of k elements
 * w must be less than a certain maximum (currently 8)
 *
 * The result is a sequence x[0], ..., x[k-1] with x[i] in the range
 * - 2^(width - 1) .. 2^(width - 1) - 1 such that
 * m = (2 * x[0] + 1) + 2^width * (2 * x[1] + 1) + ...
 *     + 2^((k-1) * width) * (2 * x[k-1] + 1)
 *
 * Compared to "Algorithm SPA-resistant Width-w NAF with Odd Scalar"
 * p. 335 of the cited reference, here we return only u, not d_w since
 * it is known that the other d_w[j] will be 0.  Moreover, the returned
 * string doesn't actually store u_i but x_i = u_i / 2 since it is known
 * that u_i is odd. Also, since we always select a positive value for d
 * mod 2^w, we don't need to check the sign of u[i-1] when the reference
 * does. Finally, there is an off-by-one error in the reference: the
 * last index should be k-1, not k.
 */
static int ecp_w_naf_fixed( signed char x[], size_t k,
                            unsigned char w, const mpi *m )
{
    int ret;
    unsigned int i, u, mask, carry;
    mpi M;

    mpi_init( &M );

    MPI_CHK( mpi_copy( &M, m ) );
    mask = ( 1 << w ) - 1;
    carry = 1 << ( w - 1 );

    for( i = 0; i < k; i++ )
    {
        u = M.p[0] & mask;

        if( ( u & 1 ) == 0 && i > 0 )
            x[i - 1] -= carry;

        x[i] = u >> 1;
        mpi_shift_r( &M, w );
    }

    /*
     * We should have consumed all the bits now
     */
    if( mpi_cmp_int( &M, 0 ) != 0 )
        ret = POLARSSL_ERR_ECP_GENERIC;

cleanup:

    mpi_free( &M );

    return( ret );
}

/*
 * Precompute odd multiples of P up to (2 * t_len - 1) P.
 * The table is filled with T[i] = (2 * i + 1) P.
 */
static int ecp_precompute( const ecp_group *grp,
                           ecp_point T[], size_t t_len,
                           const ecp_point *P )
{
    int ret;
    size_t i;
    ecp_point PP;

    ecp_point_init( &PP );

    MPI_CHK( ecp_add( grp, &PP, P, P ) );

    MPI_CHK( ecp_copy( &T[0], P ) );

    for( i = 1; i < t_len; i++ )
        MPI_CHK( ecp_add_mixed( grp, &T[i], &T[i-1], &PP, +1 ) );

    /*
     * T[0] = P already has normalized coordinates
     */
    MPI_CHK( ecp_normalize_many( grp, T + 1, t_len - 1 ) );

cleanup:

    ecp_point_free( &PP );

    return( ret );
}

/*
 * Maximum length of the precomputed table
 */
#define MAX_PRE_LEN     ( 1 << (POLARSSL_ECP_WINDOW_SIZE - 1) )

/*
 * Maximum length of the NAF: ceil( grp->nbits + 1 ) / w
 * (that is: grp->nbits / w + 1)
 * Allow p_bits + 1 bits in case M = grp->N + 1 is one bit longer than N.
 */
#define MAX_NAF_LEN     ( POLARSSL_ECP_MAX_N_BITS / 2 + 1 )

/*
 * Integer multiplication: R = m * P
 *
 * Based on fixed-pattern width-w NAF, see comments of ecp_w_naf_fixed()
 * and <http://rd.springer.com/chapter/10.1007/3-540-36563-X_23>.
 *
 * This function executes a fixed number of operations for
 * random m in the range 0 .. 2^nbits - 1.
 */
int ecp_mul( const ecp_group *grp, ecp_point *R,
             const mpi *m, const ecp_point *P )
{
    int ret;
    unsigned char w, m_is_odd;
    size_t pre_len, naf_len, i, j;
    signed char naf[ MAX_NAF_LEN ];
    ecp_point Q, T[ MAX_PRE_LEN ];
    mpi M;

    if( mpi_cmp_int( m, 0 ) < 0 || mpi_msb( m ) > grp->nbits )
        return( POLARSSL_ERR_ECP_GENERIC );

    w = grp->nbits >= 521 ? 6 :
        grp->nbits >= 224 ? 5 :
        4;

    /*
     * Make sure w is within the limits.
     * The last test ensures that none of the precomputed points is zero,
     * which wouldn't be handled correctly by ecp_normalize_many().
     * It is only useful for small curves, as used in the test suite.
     */
    if( w > POLARSSL_ECP_WINDOW_SIZE )
        w = POLARSSL_ECP_WINDOW_SIZE;
    if( w < 2 || w >= grp->nbits )
        w = 2;

    pre_len = 1 << ( w - 1 );
    naf_len = grp->nbits / w + 1;

    mpi_init( &M );
    ecp_point_init( &Q );
    for( i = 0; i < pre_len; i++ )
        ecp_point_init( &T[i] );

    m_is_odd = ( mpi_get_bit( m, 0 ) == 1 );

    /*
     * Make sure M is odd:
     * later we'll get m * P by subtracting * P or 2 * P to M * P.
     */
    MPI_CHK( mpi_copy( &M, m ) );
    MPI_CHK( mpi_add_int( &M, &M, 1 + m_is_odd ) );

    /*
     * Compute the fixed-pattern NAF and precompute odd multiples
     */
    MPI_CHK( ecp_w_naf_fixed( naf, naf_len, w, &M ) );
    MPI_CHK( ecp_precompute( grp, T, pre_len, P ) );

    /*
     * Compute M * P, using a variant of left-to-right 2^w-ary multiplication:
     * at each step we add (2 * naf[i] + 1) P, then multiply by 2^w.
     *
     * If naf[i] >= 0, we have (2 * naf[i] + 1) P == T[ naf[i] ]
     * Otherwise, (2 * naf[i] + 1) P == - ( 2 * ( - naf[i] - 1 ) + 1) P
     *                               == T[ - naf[i] - 1 ]
     */
    MPI_CHK( ecp_set_zero( &Q ) );
    i = naf_len - 1;
    while( 1 )
    {
        if( naf[i] < 0 )
        {
            MPI_CHK( ecp_add_mixed( grp, &Q, &Q, &T[ - naf[i] - 1 ], -1 ) );
        }
        else
        {
            MPI_CHK( ecp_add_mixed( grp, &Q, &Q, &T[ naf[i] ], +1 ) );
        }

        if( i == 0 )
            break;
        i--;

        for( j = 0; j < w; j++ )
        {
            MPI_CHK( ecp_double_jac( grp, &Q, &Q ) );
        }
    }

    /*
     * Now get m * P from M * P.
     * Since we don't need T[] any more, we can recycle it:
     * we already have T[0] = P, now set T[1] = 2 * P.
     */
    MPI_CHK( ecp_add( grp, &T[1], P, P ) );
    MPI_CHK( ecp_sub( grp, R, &Q, &T[m_is_odd] ) );


cleanup:

    mpi_free( &M );
    ecp_point_free( &Q );
    for( i = 0; i < pre_len; i++ )
        ecp_point_free( &T[i] );

    return( ret );
}

/*
 * Check that a point is valid as a public key (SEC1 3.2.3.1)
 */
int ecp_check_pubkey( const ecp_group *grp, const ecp_point *pt )
{
    int ret;
    mpi YY, RHS;

    if( mpi_cmp_int( &pt->Z, 0 ) == 0 )
        return( POLARSSL_ERR_ECP_GENERIC );

    /*
     * pt coordinates must be normalized for our checks
     */
    if( mpi_cmp_int( &pt->Z, 1 ) != 0 )
        return( POLARSSL_ERR_ECP_GENERIC );

    if( mpi_cmp_int( &pt->X, 0 ) < 0 ||
        mpi_cmp_int( &pt->Y, 0 ) < 0 ||
        mpi_cmp_mpi( &pt->X, &grp->P ) >= 0 ||
        mpi_cmp_mpi( &pt->Y, &grp->P ) >= 0 )
        return( POLARSSL_ERR_ECP_GENERIC );

    mpi_init( &YY ); mpi_init( &RHS );

    /*
     * YY = Y^2
     * RHS = X (X^2 - 3) + B = X^3 - 3X + B
     */
    MPI_CHK( mpi_mul_mpi( &YY,  &pt->Y,  &pt->Y   ) );  MOD_MUL( YY  );
    MPI_CHK( mpi_mul_mpi( &RHS, &pt->X,  &pt->X   ) );  MOD_MUL( RHS );
    MPI_CHK( mpi_sub_int( &RHS, &RHS,    3        ) );  MOD_SUB( RHS );
    MPI_CHK( mpi_mul_mpi( &RHS, &RHS,    &pt->X   ) );  MOD_MUL( RHS );
    MPI_CHK( mpi_add_mpi( &RHS, &RHS,    &grp->B  ) );  MOD_ADD( RHS );

    if( mpi_cmp_mpi( &YY, &RHS ) != 0 )
        ret = POLARSSL_ERR_ECP_GENERIC;

cleanup:

    mpi_free( &YY ); mpi_free( &RHS );

    return( ret );
}

/*
 * Check that an mpi is valid as a private key (SEC1 3.2)
 */
int ecp_check_privkey( const ecp_group *grp, const mpi *d )
{
    /* We want 1 <= d <= N-1 */
    if ( mpi_cmp_int( d, 1 ) < 0 || mpi_cmp_mpi( d, &grp->N ) >= 0 )
        return( POLARSSL_ERR_ECP_GENERIC );

    return( 0 );
}

/*
 * Generate a keypair (SEC1 3.2.1)
 */
int ecp_gen_keypair( const ecp_group *grp, mpi *d, ecp_point *Q,
                     int (*f_rng)(void *, unsigned char *, size_t),
                     void *p_rng )
{
    int count = 0;
    size_t n_size = (grp->nbits + 7) / 8;

    /*
     * Generate d such that 1 <= n < N
     */
    do
    {
        mpi_fill_random( d, n_size, f_rng, p_rng );

        while( mpi_cmp_mpi( d, &grp->N ) >= 0 )
            mpi_shift_r( d, 1 );

        if( count++ > 10 )
            return( POLARSSL_ERR_ECP_GENERIC );
    }
    while( mpi_cmp_int( d, 1 ) < 0 );

    return( ecp_mul( grp, Q, d, &grp->G ) );
}

#if defined(POLARSSL_SELF_TEST)

/*
 * Checkup routine
 */
int ecp_self_test( int verbose )
{
    int ret;
    size_t i;
    ecp_group grp;
    ecp_point R;
    mpi m;
    unsigned long add_c_prev, dbl_c_prev;
    const char *exponents[] =
    {
        "000000000000000000000000000000000000000000000000", /* zero */
        "000000000000000000000000000000000000000000000001", /* one */
        "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", /* N */
        "5EA6F389A38B8BC81E767753B15AA5569E1782E30ABE7D25", /* random */
        "400000000000000000000000000000000000000000000000",
        "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
        "555555555555555555555555555555555555555555555555",
    };

    ecp_group_init( &grp );
    ecp_point_init( &R );
    mpi_init( &m );

#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED)
    MPI_CHK( ecp_use_known_dp( &grp, POLARSSL_ECP_DP_SECP192R1 ) );
#else
#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED)
    MPI_CHK( ecp_use_known_dp( &grp, POLARSSL_ECP_DP_SECP224R1 ) );
#else
#if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED)
    MPI_CHK( ecp_use_known_dp( &grp, POLARSSL_ECP_DP_SECP256R1 ) );
#else
#if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED)
    MPI_CHK( ecp_use_known_dp( &grp, POLARSSL_ECP_DP_SECP384R1 ) );
#else
#if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED)
    MPI_CHK( ecp_use_known_dp( &grp, POLARSSL_ECP_DP_SECP521R1 ) );
#else
#error No curves defines
#endif /* POLARSSL_ECP_DP_SECP512R1_ENABLED */
#endif /* POLARSSL_ECP_DP_SECP384R1_ENABLED */
#endif /* POLARSSL_ECP_DP_SECP256R1_ENABLED */
#endif /* POLARSSL_ECP_DP_SECP224R1_ENABLED */
#endif /* POLARSSL_ECP_DP_SECP192R1_ENABLED */

    if( verbose != 0 )
        printf( "  ECP test #1 (SPA resistance): " );

    add_count = 0;
    dbl_count = 0;
    MPI_CHK( mpi_read_string( &m, 16, exponents[0] ) );
    MPI_CHK( ecp_mul( &grp, &R, &m, &grp.G ) );

    for( i = 1; i < sizeof( exponents ) / sizeof( exponents[0] ); i++ )
    {
        add_c_prev = add_count;
        dbl_c_prev = dbl_count;
        add_count = 0;
        dbl_count = 0;

        MPI_CHK( mpi_read_string( &m, 16, exponents[i] ) );
        MPI_CHK( ecp_mul( &grp, &R, &m, &grp.G ) );

        if( add_count != add_c_prev || dbl_count != dbl_c_prev )
        {
            if( verbose != 0 )
                printf( "failed (%zu)\n", i );

            ret = 1;
            goto cleanup;
        }
    }

    if( verbose != 0 )
        printf( "passed\n" );

cleanup:

    if( ret < 0 && verbose != 0 )
        printf( "Unexpected error, return code = %08X\n", ret );

    ecp_group_free( &grp );
    ecp_point_free( &R );
    mpi_free( &m );

    if( verbose != 0 )
        printf( "\n" );

    return( ret );
}

#endif

#endif
