Sergey Pastor / 1

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ec_curves.c Source File

ec_curves.c

Go to the documentation of this file.
00001 /**
00002  * @file ec_curves.c
00003  * @brief Elliptic curves
00004  *
00005  * @section License
00006  *
00007  * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved.
00008  *
00009  * This file is part of CycloneCrypto Open.
00010  *
00011  * This program is free software; you can redistribute it and/or
00012  * modify it under the terms of the GNU General Public License
00013  * as published by the Free Software Foundation; either version 2
00014  * of the License, or (at your option) any later version.
00015  *
00016  * This program is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU General Public License
00022  * along with this program; if not, write to the Free Software Foundation,
00023  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00024  *
00025  * @author Oryx Embedded SARL (www.oryx-embedded.com)
00026  * @version 1.7.6
00027  **/
00028 
00029 //Switch to the appropriate trace level
00030 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
00031 
00032 //Dependencies
00033 #include <stdlib.h>
00034 #include <string.h>
00035 #include "crypto.h"
00036 #include "ec_curves.h"
00037 #include "oid.h"
00038 #include "debug.h"
00039 
00040 //Check crypto library configuration
00041 #if (EC_SUPPORT == ENABLED)
00042 
00043 //Macro definition
00044 #define CLEAR_WORD32(a, i, n) memset((a)->data + i, 0, n * MPI_INT_SIZE);
00045 #define COPY_WORD32(a, i, b, j, n) memcpy((a)->data + i, (b)->data + j, n * MPI_INT_SIZE);
00046 
00047 //secp112r1 OID (1.3.132.0.6)
00048 const uint8_t SECP112R1_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x06};
00049 //secp112r2 OID (1.3.132.0.7)
00050 const uint8_t SECP112R2_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x07};
00051 //secp128r1 OID (1.3.132.0.28)
00052 const uint8_t SECP128R1_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x1C};
00053 //secp128r2 OID (1.3.132.0.29)
00054 const uint8_t SECP128R2_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x1D};
00055 //secp160k1 OID (1.3.132.0.9)
00056 const uint8_t SECP160K1_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x09};
00057 //secp160r1 OID (1.3.132.0.8)
00058 const uint8_t SECP160R1_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x08};
00059 //secp160r2 OID (1.3.132.0.30)
00060 const uint8_t SECP160R2_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x1E};
00061 //secp192k1 OID (1.3.132.0.31)
00062 const uint8_t SECP192K1_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x1F};
00063 //secp192r1 OID (1.2.840.10045.3.1.1)
00064 const uint8_t SECP192R1_OID[8] = {0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x01};
00065 //secp224k1 OID (1.3.132.0.32)
00066 const uint8_t SECP224K1_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x20};
00067 //secp224r1 OID (1.3.132.0.33)
00068 const uint8_t SECP224R1_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x21};
00069 //secp256k1 OID (1.3.132.0.10)
00070 const uint8_t SECP256K1_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x0A};
00071 //secp256r1 OID (1.2.840.10045.3.1.7)
00072 const uint8_t SECP256R1_OID[8] = {0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07};
00073 //secp384r1 OID (1.3.132.0.34)
00074 const uint8_t SECP384R1_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x22};
00075 //secp521r1 OID (1.3.132.0.35)
00076 const uint8_t SECP521R1_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x23};
00077 //brainpoolP160r1 OID (1.3.36.3.3.2.8.1.1.1)
00078 const uint8_t BRAINPOOLP160R1_OID[10] = {0x2B, 0x03, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x01};
00079 //brainpoolP192r1 OID (1.3.36.3.3.2.8.1.1.3)
00080 const uint8_t BRAINPOOLP192R1_OID[10] = {0x2B, 0x03, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x03};
00081 //brainpoolP224r1 OID (1.3.36.3.3.2.8.1.1.5)
00082 const uint8_t BRAINPOOLP224R1_OID[10] = {0x2B, 0x03, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x05};
00083 //brainpoolP256r1 OID (1.3.36.3.3.2.8.1.1.7)
00084 const uint8_t BRAINPOOLP256R1_OID[10] = {0x2B, 0x03, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x07};
00085 //brainpoolP320r1 OID (1.3.36.3.3.2.8.1.1.9)
00086 const uint8_t BRAINPOOLP320R1_OID[10] = {0x2B, 0x03, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x09};
00087 //brainpoolP384r1 OID (1.3.36.3.3.2.8.1.1.11)
00088 const uint8_t BRAINPOOLP384R1_OID[10] = {0x2B, 0x03, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0B};
00089 //brainpoolP512r1 OID (1.3.36.3.3.2.8.1.1.13)
00090 const uint8_t BRAINPOOLP512R1_OID[10] = {0x2B, 0x03, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0D};
00091 
00092 
00093 /**
00094  * @brief secp112r1 elliptic curve
00095  **/
00096 
00097 const EcCurveInfo secp112r1Curve =
00098 {
00099    //Curve name
00100    "secp112r1",
00101    //Object identifier
00102    SECP112R1_OID,
00103    sizeof(SECP112R1_OID),
00104    //Curve type
00105    EC_CURVE_TYPE_SECP_R1,
00106    //Prime modulus p
00107    {0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x66, 0x80, 0x76, 0xBE, 0xAD, 0x20, 0x8B},
00108    14,
00109    //Curve parameter a
00110    {0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x66, 0x80, 0x76, 0xBE, 0xAD, 0x20, 0x88},
00111    14,
00112    //Curve parameter b
00113    {0x65, 0x9E, 0xF8, 0xBA, 0x04, 0x39, 0x16, 0xEE, 0xDE, 0x89, 0x11, 0x70, 0x2B, 0x22},
00114    14,
00115    //x-coordinate of the base point G
00116    {0x09, 0x48, 0x72, 0x39, 0x99, 0x5A, 0x5E, 0xE7, 0x6B, 0x55, 0xF9, 0xC2, 0xF0, 0x98},
00117    14,
00118    //y-coordinate of the base point G
00119    {0xA8, 0x9C, 0xE5, 0xAF, 0x87, 0x24, 0xC0, 0xA2, 0x3E, 0x0E, 0x0F, 0xF7, 0x75, 0x00},
00120    14,
00121    //Base point order q
00122    {0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x76, 0x28, 0xDF, 0xAC, 0x65, 0x61, 0xC5},
00123    14,
00124    //Cofactor
00125    1,
00126    //Fast modular reduction
00127    NULL
00128 };
00129 
00130 
00131 /**
00132  * @brief secp112r2 elliptic curve
00133  **/
00134 
00135 const EcCurveInfo secp112r2Curve =
00136 {
00137    //Curve name
00138    "secp112r2",
00139    //Object identifier
00140    SECP112R2_OID,
00141    sizeof(SECP112R2_OID),
00142    //Curve type
00143    EC_CURVE_TYPE_SECP_R2,
00144    //Prime modulus p
00145    {0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x66, 0x80, 0x76, 0xBE, 0xAD, 0x20, 0x8B},
00146    14,
00147    //Curve parameter a
00148    {0x61, 0x27, 0xC2, 0x4C, 0x05, 0xF3, 0x8A, 0x0A, 0xAA, 0xF6, 0x5C, 0x0E, 0xF0, 0x2C},
00149    14,
00150    //Curve parameter b
00151    {0x51, 0xDE, 0xF1, 0x81, 0x5D, 0xB5, 0xED, 0x74, 0xFC, 0xC3, 0x4C, 0x85, 0xD7, 0x09},
00152    14,
00153    //x-coordinate of the base point G
00154    {0x4B, 0xA3, 0x0A, 0xB5, 0xE8, 0x92, 0xB4, 0xE1, 0x64, 0x9D, 0xD0, 0x92, 0x86, 0x43},
00155    14,
00156    //y-coordinate of the base point G
00157    {0xAD, 0xCD, 0x46, 0xF5, 0x88, 0x2E, 0x37, 0x47, 0xDE, 0xF3, 0x6E, 0x95, 0x6E, 0x97},
00158    14,
00159    //Base point order q
00160    {0x36, 0xDF, 0x0A, 0xAF, 0xD8, 0xB8, 0xD7, 0x59, 0x7C, 0xA1, 0x05, 0x20, 0xD0, 0x4B},
00161    14,
00162    //Cofactor
00163    4,
00164    //Fast modular reduction
00165    NULL
00166 };
00167 
00168 
00169 /**
00170  * @brief secp128r1 elliptic curve
00171  **/
00172 
00173 const EcCurveInfo secp128r1Curve =
00174 {
00175    //Curve name
00176    "secp128r1",
00177    //Object identifier
00178    SECP128R1_OID,
00179    sizeof(SECP128R1_OID),
00180    //Curve type
00181    EC_CURVE_TYPE_SECP_R1,
00182    //Prime modulus p
00183    {0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
00184    16,
00185    //Curve parameter a
00186    {0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC},
00187    16,
00188    //Curve parameter b
00189    {0xE8, 0x75, 0x79, 0xC1, 0x10, 0x79, 0xF4, 0x3D, 0xD8, 0x24, 0x99, 0x3C, 0x2C, 0xEE, 0x5E, 0xD3},
00190    16,
00191    //x-coordinate of the base point G
00192    {0x16, 0x1F, 0xF7, 0x52, 0x8B, 0x89, 0x9B, 0x2D, 0x0C, 0x28, 0x60, 0x7C, 0xA5, 0x2C, 0x5B, 0x86},
00193    16,
00194    //y-coordinate of the base point G
00195    {0xCF, 0x5A, 0xC8, 0x39, 0x5B, 0xAF, 0xEB, 0x13, 0xC0, 0x2D, 0xA2, 0x92, 0xDD, 0xED, 0x7A, 0x83},
00196    16,
00197    //Base point order q
00198    {0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x75, 0xA3, 0x0D, 0x1B, 0x90, 0x38, 0xA1, 0x15},
00199    16,
00200    //Cofactor
00201    1,
00202    //Fast modular reduction
00203    secp128r1Mod
00204 };
00205 
00206 
00207 /**
00208  * @brief secp128r2 elliptic curve
00209  **/
00210 
00211 const EcCurveInfo secp128r2Curve =
00212 {
00213    //Curve name
00214    "secp128r2",
00215    //Object identifier
00216    SECP128R2_OID,
00217    sizeof(SECP128R2_OID),
00218    //Curve type
00219    EC_CURVE_TYPE_SECP_R2,
00220    //Prime modulus p
00221    {0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
00222    16,
00223    //Curve parameter a
00224    {0xD6, 0x03, 0x19, 0x98, 0xD1, 0xB3, 0xBB, 0xFE, 0xBF, 0x59, 0xCC, 0x9B, 0xBF, 0xF9, 0xAE, 0xE1},
00225    16,
00226    //Curve parameter b
00227    {0x5E, 0xEE, 0xFC, 0xA3, 0x80, 0xD0, 0x29, 0x19, 0xDC, 0x2C, 0x65, 0x58, 0xBB, 0x6D, 0x8A, 0x5D},
00228    16,
00229    //x-coordinate of the base point G
00230    {0x7B, 0x6A, 0xA5, 0xD8, 0x5E, 0x57, 0x29, 0x83, 0xE6, 0xFB, 0x32, 0xA7, 0xCD, 0xEB, 0xC1, 0x40},
00231    16,
00232    //y-coordinate of the base point G
00233    {0x27, 0xB6, 0x91, 0x6A, 0x89, 0x4D, 0x3A, 0xEE, 0x71, 0x06, 0xFE, 0x80, 0x5F, 0xC3, 0x4B, 0x44},
00234    16,
00235    //Base point order q
00236    {0x3F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xBE, 0x00, 0x24, 0x72, 0x06, 0x13, 0xB5, 0xA3},
00237    16,
00238    //Cofactor
00239    4,
00240    //Fast modular reduction
00241    secp128r2Mod
00242 };
00243 
00244 
00245 /**
00246  * @brief secp160k1 elliptic curve
00247  **/
00248 
00249 const EcCurveInfo secp160k1Curve =
00250 {
00251    //Curve name
00252    "secp160k1",
00253    //Object identifier
00254    SECP160K1_OID,
00255    sizeof(SECP160K1_OID),
00256    //Curve type
00257    EC_CURVE_TYPE_SECP_K1,
00258    //Prime modulus p
00259    {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
00260     0xFF, 0xFF, 0xAC, 0x73},
00261    20,
00262    //Curve parameter a
00263    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00264     0x00, 0x00, 0x00, 0x00},
00265    20,
00266    //Curve parameter b
00267    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00268     0x00, 0x00, 0x00, 0x07},
00269    20,
00270    //x-coordinate of the base point G
00271    {0x3B, 0x4C, 0x38, 0x2C, 0xE3, 0x7A, 0xA1, 0x92, 0xA4, 0x01, 0x9E, 0x76, 0x30, 0x36, 0xF4, 0xF5,
00272     0xDD, 0x4D, 0x7E, 0xBB},
00273    20,
00274    //y-coordinate of the base point G
00275    {0x93, 0x8C, 0xF9, 0x35, 0x31, 0x8F, 0xDC, 0xED, 0x6B, 0xC2, 0x82, 0x86, 0x53, 0x17, 0x33, 0xC3,
00276     0xF0, 0x3C, 0x4F, 0xEE},
00277    20,
00278    //Base point order q
00279    {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xB8, 0xFA, 0x16, 0xDF, 0xAB,
00280     0x9A, 0xCA, 0x16, 0xB6, 0xB3},
00281    21,
00282    //Cofactor
00283    1,
00284    //Fast modular reduction
00285    secp160k1Mod
00286 };
00287 
00288 
00289 /**
00290  * @brief secp160r1 elliptic curve
00291  **/
00292 
00293 const EcCurveInfo secp160r1Curve =
00294 {
00295    //Curve name
00296    "secp160r1",
00297    //Object identifier
00298    SECP160R1_OID,
00299    sizeof(SECP160R1_OID),
00300    //Curve type
00301    EC_CURVE_TYPE_SECP_R1,
00302    //Prime modulus p
00303    {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00304     0x7F, 0xFF, 0xFF, 0xFF},
00305    20,
00306    //Curve parameter a
00307    {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00308     0x7F, 0xFF, 0xFF, 0xFC},
00309    20,
00310    //Curve parameter b
00311    {0x1C, 0x97, 0xBE, 0xFC, 0x54, 0xBD, 0x7A, 0x8B, 0x65, 0xAC, 0xF8, 0x9F, 0x81, 0xD4, 0xD4, 0xAD,
00312     0xC5, 0x65, 0xFA, 0x45},
00313    20,
00314    //x-coordinate of the base point G
00315    {0x4A, 0x96, 0xB5, 0x68, 0x8E, 0xF5, 0x73, 0x28, 0x46, 0x64, 0x69, 0x89, 0x68, 0xC3, 0x8B, 0xB9,
00316     0x13, 0xCB, 0xFC, 0x82},
00317    20,
00318    //y-coordinate of the base point G
00319    {0x23, 0xA6, 0x28, 0x55, 0x31, 0x68, 0x94, 0x7D, 0x59, 0xDC, 0xC9, 0x12, 0x04, 0x23, 0x51, 0x37,
00320     0x7A, 0xC5, 0xFB, 0x32},
00321    20,
00322    //Base point order q
00323    {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF4, 0xC8, 0xF9, 0x27, 0xAE,
00324     0xD3, 0xCA, 0x75, 0x22, 0x57},
00325    21,
00326    //Cofactor
00327    1,
00328    //Fast modular reduction
00329    secp160r1Mod
00330 };
00331 
00332 
00333 /**
00334  * @brief secp160r2 elliptic curve
00335  **/
00336 
00337 const EcCurveInfo secp160r2Curve =
00338 {
00339    //Curve name
00340    "secp160r2",
00341    //Object identifier
00342    SECP160R2_OID,
00343    sizeof(SECP160R2_OID),
00344    //Curve type
00345    EC_CURVE_TYPE_SECP_R2,
00346    //Prime modulus p
00347    {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
00348     0xFF, 0xFF, 0xAC, 0x73},
00349    20,
00350    //Curve parameter a
00351    {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
00352     0xFF, 0xFF, 0xAC, 0x70},
00353    20,
00354    //Curve parameter b
00355    {0xB4, 0xE1, 0x34, 0xD3, 0xFB, 0x59, 0xEB, 0x8B, 0xAB, 0x57, 0x27, 0x49, 0x04, 0x66, 0x4D, 0x5A,
00356     0xF5, 0x03, 0x88, 0xBA},
00357    20,
00358    //x-coordinate of the base point G
00359    {0x52, 0xDC, 0xB0, 0x34, 0x29, 0x3A, 0x11, 0x7E, 0x1F, 0x4F, 0xF1, 0x1B, 0x30, 0xF7, 0x19, 0x9D,
00360     0x31, 0x44, 0xCE, 0x6D},
00361    20,
00362    //y-coordinate of the base point G
00363    {0xFE, 0xAF, 0xFE, 0xF2, 0xE3, 0x31, 0xF2, 0x96, 0xE0, 0x71, 0xFA, 0x0D, 0xF9, 0x98, 0x2C, 0xFE,
00364     0xA7, 0xD4, 0x3F, 0x2E},
00365    20,
00366    //Base point order q
00367    {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x1E, 0xE7, 0x86, 0xA8,
00368     0x18, 0xF3, 0xA1, 0xA1, 0x6B},
00369    21,
00370    //Cofactor
00371    1,
00372    //Fast modular reduction
00373    secp160r2Mod
00374 };
00375 
00376 
00377 /**
00378  * @brief secp192k1 elliptic curve
00379  **/
00380 
00381 const EcCurveInfo secp192k1Curve =
00382 {
00383    //Curve name
00384    "secp192k1",
00385    //Object identifier
00386    SECP192K1_OID,
00387    sizeof(SECP192K1_OID),
00388    //Curve type
00389    EC_CURVE_TYPE_SECP_K1,
00390    //Prime modulus p
00391    {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00392     0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xEE, 0x37},
00393    24,
00394    //Curve parameter a
00395    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00396     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
00397    24,
00398    //Curve parameter b
00399    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00400     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03},
00401    24,
00402    //x-coordinate of the base point G
00403    {0xDB, 0x4F, 0xF1, 0x0E, 0xC0, 0x57, 0xE9, 0xAE, 0x26, 0xB0, 0x7D, 0x02, 0x80, 0xB7, 0xF4, 0x34,
00404     0x1D, 0xA5, 0xD1, 0xB1, 0xEA, 0xE0, 0x6C, 0x7D},
00405    24,
00406    //y-coordinate of the base point G
00407    {0x9B, 0x2F, 0x2F, 0x6D, 0x9C, 0x56, 0x28, 0xA7, 0x84, 0x41, 0x63, 0xD0, 0x15, 0xBE, 0x86, 0x34,
00408     0x40, 0x82, 0xAA, 0x88, 0xD9, 0x5E, 0x2F, 0x9D},
00409    24,
00410    //Base point order q
00411    {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x26, 0xF2, 0xFC, 0x17,
00412     0x0F, 0x69, 0x46, 0x6A, 0x74, 0xDE, 0xFD, 0x8D},
00413    24,
00414    //Cofactor
00415    1,
00416    //Fast modular reduction
00417    secp192k1Mod
00418 };
00419 
00420 
00421 /**
00422  * @brief secp192r1 elliptic curve
00423  **/
00424 
00425 const EcCurveInfo secp192r1Curve =
00426 {
00427    //Curve name
00428    "secp192r1",
00429    //Object identifier
00430    SECP192R1_OID,
00431    sizeof(SECP192R1_OID),
00432    //Curve type
00433    EC_CURVE_TYPE_SECP_R1,
00434    //Prime modulus p
00435    {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
00436     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
00437    24,
00438    //Curve parameter a
00439    {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
00440     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC},
00441    24,
00442    //Curve parameter b
00443    {0x64, 0x21, 0x05, 0x19, 0xE5, 0x9C, 0x80, 0xE7, 0x0F, 0xA7, 0xE9, 0xAB, 0x72, 0x24, 0x30, 0x49,
00444     0xFE, 0xB8, 0xDE, 0xEC, 0xC1, 0x46, 0xB9, 0xB1},
00445    24,
00446    //x-coordinate of the base point G
00447    {0x18, 0x8D, 0xA8, 0x0E, 0xB0, 0x30, 0x90, 0xF6, 0x7C, 0xBF, 0x20, 0xEB, 0x43, 0xA1, 0x88, 0x00,
00448     0xF4, 0xFF, 0x0A, 0xFD, 0x82, 0xFF, 0x10, 0x12},
00449    24,
00450    //y-coordinate of the base point G
00451    {0x07, 0x19, 0x2B, 0x95, 0xFF, 0xC8, 0xDA, 0x78, 0x63, 0x10, 0x11, 0xED, 0x6B, 0x24, 0xCD, 0xD5,
00452     0x73, 0xF9, 0x77, 0xA1, 0x1E, 0x79, 0x48, 0x11},
00453    24,
00454    //Base point order q
00455    {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x99, 0xDE, 0xF8, 0x36,
00456     0x14, 0x6B, 0xC9, 0xB1, 0xB4, 0xD2, 0x28, 0x31},
00457    24,
00458    //Cofactor
00459    1,
00460    //Fast modular reduction
00461    secp192r1Mod
00462 };
00463 
00464 
00465 /**
00466  * @brief secp224k1 elliptic curve
00467  **/
00468 
00469 const EcCurveInfo secp224k1Curve =
00470 {
00471    //Curve name
00472    "secp224k1",
00473    //Object identifier
00474    SECP224K1_OID,
00475    sizeof(SECP224K1_OID),
00476    //Curve type
00477    EC_CURVE_TYPE_SECP_K1,
00478    //Prime modulus p
00479    {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00480     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xE5, 0x6D},
00481    28,
00482    //Curve parameter a
00483    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00484     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
00485    28,
00486    //Curve parameter b
00487    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00488     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05},
00489    28,
00490    //x-coordinate of the base point G
00491    {0xA1, 0x45, 0x5B, 0x33, 0x4D, 0xF0, 0x99, 0xDF, 0x30, 0xFC, 0x28, 0xA1, 0x69, 0xA4, 0x67, 0xE9,
00492     0xE4, 0x70, 0x75, 0xA9, 0x0F, 0x7E, 0x65, 0x0E, 0xB6, 0xB7, 0xA4, 0x5C},
00493    28,
00494    //y-coordinate of the base point G
00495    {0x7E, 0x08, 0x9F, 0xED, 0x7F, 0xBA, 0x34, 0x42, 0x82, 0xCA, 0xFB, 0xD6, 0xF7, 0xE3, 0x19, 0xF7,
00496     0xC0, 0xB0, 0xBD, 0x59, 0xE2, 0xCA, 0x4B, 0xDB, 0x55, 0x6D, 0x61, 0xA5},
00497    28,
00498    //Base point order q
00499    {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xDC,
00500     0xE8, 0xD2, 0xEC, 0x61, 0x84, 0xCA, 0xF0, 0xA9, 0x71, 0x76, 0x9F, 0xB1, 0xF7},
00501    29,
00502    //Cofactor
00503    1,
00504    //Fast modular reduction
00505    secp224k1Mod
00506 };
00507 
00508 
00509 /**
00510  * @brief secp224r1 elliptic curve
00511  **/
00512 
00513 const EcCurveInfo secp224r1Curve =
00514 {
00515    //Curve name
00516    "secp224r1",
00517    //Object identifier
00518    SECP224R1_OID,
00519    sizeof(SECP224R1_OID),
00520    //Curve type
00521    EC_CURVE_TYPE_SECP_R1,
00522    //Prime modulus p
00523    {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00524     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
00525    28,
00526    //Curve parameter a
00527    {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
00528     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE},
00529    28,
00530    //Curve parameter b
00531    {0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56, 0x50, 0x44, 0xB0, 0xB7,
00532     0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B, 0x39, 0x43, 0x23, 0x55, 0xFF, 0xB4},
00533    28,
00534    //x-coordinate of the base point G
00535    {0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9, 0x4A, 0x03, 0xC1, 0xD3,
00536     0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6, 0x11, 0x5C, 0x1D, 0x21},
00537    28,
00538    //y-coordinate of the base point G
00539    {0xBD, 0x37, 0x63, 0x88, 0xB5, 0xF7, 0x23, 0xFB, 0x4C, 0x22, 0xDF, 0xE6, 0xCD, 0x43, 0x75, 0xA0,
00540     0x5A, 0x07, 0x47, 0x64, 0x44, 0xD5, 0x81, 0x99, 0x85, 0x00, 0x7E, 0x34},
00541    28,
00542    //Base point order q
00543    {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x16, 0xA2,
00544     0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45, 0x5C, 0x5C, 0x2A, 0x3D},
00545    28,
00546    //Cofactor
00547    1,
00548    //Fast modular reduction
00549    secp224r1Mod
00550 };
00551 
00552 
00553 /**
00554  * @brief secp256k1 elliptic curve
00555  **/
00556 
00557 const EcCurveInfo secp256k1Curve =
00558 {
00559    //Curve name
00560    "secp256k1",
00561    //Object identifier
00562    SECP256K1_OID,
00563    sizeof(SECP256K1_OID),
00564    //Curve type
00565    EC_CURVE_TYPE_SECP_K1,
00566    //Prime modulus p
00567    {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00568     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0x2F},
00569    32,
00570    //Curve parameter a
00571    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00572     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
00573    32,
00574    //Curve parameter b
00575    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00576     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07},
00577    32,
00578    //x-coordinate of the base point G
00579    {0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62, 0x95, 0xCE, 0x87, 0x0B, 0x07,
00580     0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE, 0x28, 0xD9, 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17, 0x98},
00581    32,
00582    //y-coordinate of the base point G
00583    {0x48, 0x3A, 0xDA, 0x77, 0x26, 0xA3, 0xC4, 0x65, 0x5D, 0xA4, 0xFB, 0xFC, 0x0E, 0x11, 0x08, 0xA8,
00584     0xFD, 0x17, 0xB4, 0x48, 0xA6, 0x85, 0x54, 0x19, 0x9C, 0x47, 0xD0, 0x8F, 0xFB, 0x10, 0xD4, 0xB8},
00585    32,
00586    //Base point order q
00587    {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
00588     0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41},
00589    32,
00590    //Cofactor
00591    1,
00592    //Fast modular reduction
00593    secp256k1Mod
00594 };
00595 
00596 
00597 /**
00598  * @brief secp256r1 elliptic curve
00599  **/
00600 
00601 const EcCurveInfo secp256r1Curve =
00602 {
00603    //Curve name
00604    "secp256r1",
00605    //Object identifier
00606    SECP256R1_OID,
00607    sizeof(SECP256R1_OID),
00608    //Curve type
00609    EC_CURVE_TYPE_SECP_R1,
00610    //Prime modulus p
00611    {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00612     0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
00613    32,
00614    //Curve parameter a
00615    {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00616     0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC},
00617    32,
00618    //Curve parameter b
00619    {0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55, 0x76, 0x98, 0x86, 0xBC,
00620     0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6, 0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B},
00621    32,
00622    //x-coordinate of the base point G
00623    {0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5, 0x63, 0xA4, 0x40, 0xF2,
00624     0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0, 0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96},
00625    32,
00626    //y-coordinate of the base point G
00627    {0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, 0x9B, 0x8E, 0xE7, 0xEB, 0x4A, 0x7C, 0x0F, 0x9E, 0x16,
00628     0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE, 0xCB, 0xB6, 0x40, 0x68, 0x37, 0xBF, 0x51, 0xF5},
00629    32,
00630    //Base point order q
00631    {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00632     0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84, 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51},
00633    32,
00634    //Cofactor
00635    1,
00636    //Fast modular reduction
00637    secp256r1Mod
00638 };
00639 
00640 
00641 /**
00642  * @brief secp384r1 elliptic curve
00643  **/
00644 
00645 const EcCurveInfo secp384r1Curve =
00646 {
00647    //Curve name
00648    "secp384r1",
00649    //Object identifier
00650    SECP384R1_OID,
00651    sizeof(SECP384R1_OID),
00652    //Curve type
00653    EC_CURVE_TYPE_SECP_R1,
00654    //Prime modulus p
00655    {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00656     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
00657     0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF},
00658    48,
00659    //Curve parameter a
00660    {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00661     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
00662     0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC},
00663    48,
00664    //Curve parameter b
00665    {0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B, 0xE3, 0xF8, 0x2D, 0x19,
00666     0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12, 0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A,
00667     0xC6, 0x56, 0x39, 0x8D, 0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF},
00668    48,
00669    //x-coordinate of the base point G
00670    {0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E, 0xF3, 0x20, 0xAD, 0x74,
00671     0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98, 0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38,
00672     0x55, 0x02, 0xF2, 0x5D, 0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7},
00673    48,
00674    //y-coordinate of the base point G
00675    {0x36, 0x17, 0xDE, 0x4A, 0x96, 0x26, 0x2C, 0x6F, 0x5D, 0x9E, 0x98, 0xBF, 0x92, 0x92, 0xDC, 0x29,
00676     0xF8, 0xF4, 0x1D, 0xBD, 0x28, 0x9A, 0x14, 0x7C, 0xE9, 0xDA, 0x31, 0x13, 0xB5, 0xF0, 0xB8, 0xC0,
00677     0x0A, 0x60, 0xB1, 0xCE, 0x1D, 0x7E, 0x81, 0x9D, 0x7A, 0x43, 0x1D, 0x7C, 0x90, 0xEA, 0x0E, 0x5F},
00678    48,
00679    //Base point order q
00680    {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00681     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF,
00682     0x58, 0x1A, 0x0D, 0xB2, 0x48, 0xB0, 0xA7, 0x7A, 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73},
00683    48,
00684    //Cofactor
00685    1,
00686    //Fast modular reduction
00687    secp384r1Mod
00688 };
00689 
00690 
00691 /**
00692  * @brief secp521r1 elliptic curve
00693  **/
00694 
00695 const EcCurveInfo secp521r1Curve =
00696 {
00697    //Curve name
00698    "secp521r1",
00699    //Object identifier
00700    SECP521R1_OID,
00701    sizeof(SECP521R1_OID),
00702    //Curve type
00703    EC_CURVE_TYPE_SECP_R1,
00704    //Prime modulus p
00705    {0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00706     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00707     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00708     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00709     0xFF, 0xFF},
00710    66,
00711    //Curve parameter a
00712    {0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00713     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00714     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00715     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00716     0xFF, 0xFC},
00717    66,
00718    //Curve parameter b
00719    {0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, 0x92, 0x9A, 0x21, 0xA0, 0xB6, 0x85,
00720     0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3, 0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1,
00721     0x09, 0xE1, 0x56, 0x19, 0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1,
00722     0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45, 0x1F, 0xD4, 0x6B, 0x50,
00723     0x3F, 0x00},
00724    66,
00725    //x-coordinate of the base point G
00726    {0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E, 0xCB, 0x66, 0x23, 0x95,
00727     0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F, 0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D,
00728     0x3D, 0xBA, 0xA1, 0x4B, 0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF,
00729     0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E, 0x7E, 0x31, 0xC2, 0xE5,
00730     0xBD, 0x66},
00731    66,
00732    //y-coordinate of the base point G
00733    {0x01, 0x18, 0x39, 0x29, 0x6A, 0x78, 0x9A, 0x3B, 0xC0, 0x04, 0x5C, 0x8A, 0x5F, 0xB4, 0x2C, 0x7D,
00734     0x1B, 0xD9, 0x98, 0xF5, 0x44, 0x49, 0x57, 0x9B, 0x44, 0x68, 0x17, 0xAF, 0xBD, 0x17, 0x27, 0x3E,
00735     0x66, 0x2C, 0x97, 0xEE, 0x72, 0x99, 0x5E, 0xF4, 0x26, 0x40, 0xC5, 0x50, 0xB9, 0x01, 0x3F, 0xAD,
00736     0x07, 0x61, 0x35, 0x3C, 0x70, 0x86, 0xA2, 0x72, 0xC2, 0x40, 0x88, 0xBE, 0x94, 0x76, 0x9F, 0xD1,
00737     0x66, 0x50},
00738    66,
00739    //Base point order q
00740    {0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00741     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00742     0xFF, 0xFA, 0x51, 0x86, 0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09,
00743     0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F, 0xB7, 0x1E, 0x91, 0x38,
00744     0x64, 0x09},
00745    66,
00746    //Cofactor
00747    1,
00748    //Fast modular reduction
00749    secp521r1Mod
00750 };
00751 
00752 
00753 /**
00754  * @brief brainpoolP160r1 elliptic curve
00755  **/
00756 
00757 const EcCurveInfo brainpoolP160r1Curve =
00758 {
00759    //Curve name
00760    "brainpoolP160r1",
00761    //Object identifier
00762    BRAINPOOLP160R1_OID,
00763    sizeof(BRAINPOOLP160R1_OID),
00764    //Curve type
00765    EC_CURVE_TYPE_BRAINPOOLP_R1,
00766    //Prime modulus p
00767    {0xE9, 0x5E, 0x4A, 0x5F, 0x73, 0x70, 0x59, 0xDC, 0x60, 0xDF, 0xC7, 0xAD, 0x95, 0xB3, 0xD8, 0x13,
00768     0x95, 0x15, 0x62, 0x0F},
00769    20,
00770    //Curve parameter a
00771    {0x34, 0x0E, 0x7B, 0xE2, 0xA2, 0x80, 0xEB, 0x74, 0xE2, 0xBE, 0x61, 0xBA, 0xDA, 0x74, 0x5D, 0x97,
00772     0xE8, 0xF7, 0xC3, 0x00},
00773    20,
00774    //Curve parameter b
00775    {0x1E, 0x58, 0x9A, 0x85, 0x95, 0x42, 0x34, 0x12, 0x13, 0x4F, 0xAA, 0x2D, 0xBD, 0xEC, 0x95, 0xC8,
00776     0xD8, 0x67, 0x5E, 0x58},
00777    20,
00778    //x-coordinate of the base point G
00779    {0xBE, 0xD5, 0xAF, 0x16, 0xEA, 0x3F, 0x6A, 0x4F, 0x62, 0x93, 0x8C, 0x46, 0x31, 0xEB, 0x5A, 0xF7,
00780     0xBD, 0xBC, 0xDB, 0xC3},
00781    20,
00782    //y-coordinate of the base point G
00783    {0x16, 0x67, 0xCB, 0x47, 0x7A, 0x1A, 0x8E, 0xC3, 0x38, 0xF9, 0x47, 0x41, 0x66, 0x9C, 0x97, 0x63,
00784     0x16, 0xDA, 0x63, 0x21},
00785    20,
00786    //Base point order q
00787    {0xE9, 0x5E, 0x4A, 0x5F, 0x73, 0x70, 0x59, 0xDC, 0x60, 0xDF, 0x59, 0x91, 0xD4, 0x50, 0x29, 0x40,
00788     0x9E, 0x60, 0xFC, 0x09},
00789    20,
00790    //Cofactor
00791    1,
00792    //Fast modular reduction
00793    NULL
00794 };
00795 
00796 
00797 /**
00798  * @brief brainpoolP192r1 elliptic curve
00799  **/
00800 
00801 const EcCurveInfo brainpoolP192r1Curve =
00802 {
00803    //Curve name
00804    "brainpoolP192r1",
00805    //Object identifier
00806    BRAINPOOLP192R1_OID,
00807    sizeof(BRAINPOOLP192R1_OID),
00808    //Curve type
00809    EC_CURVE_TYPE_BRAINPOOLP_R1,
00810    //Prime modulus p
00811    {0xC3, 0x02, 0xF4, 0x1D, 0x93, 0x2A, 0x36, 0xCD, 0xA7, 0xA3, 0x46, 0x30, 0x93, 0xD1, 0x8D, 0xB7,
00812     0x8F, 0xCE, 0x47, 0x6D, 0xE1, 0xA8, 0x62, 0x97},
00813    24,
00814    //Curve parameter a
00815    {0x6A, 0x91, 0x17, 0x40, 0x76, 0xB1, 0xE0, 0xE1, 0x9C, 0x39, 0xC0, 0x31, 0xFE, 0x86, 0x85, 0xC1,
00816     0xCA, 0xE0, 0x40, 0xE5, 0xC6, 0x9A, 0x28, 0xEF},
00817    24,
00818    //Curve parameter b
00819    {0x46, 0x9A, 0x28, 0xEF, 0x7C, 0x28, 0xCC, 0xA3, 0xDC, 0x72, 0x1D, 0x04, 0x4F, 0x44, 0x96, 0xBC,
00820     0xCA, 0x7E, 0xF4, 0x14, 0x6F, 0xBF, 0x25, 0xC9},
00821    24,
00822    //x-coordinate of the base point G
00823    {0xC0, 0xA0, 0x64, 0x7E, 0xAA, 0xB6, 0xA4, 0x87, 0x53, 0xB0, 0x33, 0xC5, 0x6C, 0xB0, 0xF0, 0x90,
00824     0x0A, 0x2F, 0x5C, 0x48, 0x53, 0x37, 0x5F, 0xD6},
00825    24,
00826    //y-coordinate of the base point G
00827    {0x14, 0xB6, 0x90, 0x86, 0x6A, 0xBD, 0x5B, 0xB8, 0x8B, 0x5F, 0x48, 0x28, 0xC1, 0x49, 0x00, 0x02,
00828     0xE6, 0x77, 0x3F, 0xA2, 0xFA, 0x29, 0x9B, 0x8F},
00829    24,
00830    //Base point order q
00831    {0xC3, 0x02, 0xF4, 0x1D, 0x93, 0x2A, 0x36, 0xCD, 0xA7, 0xA3, 0x46, 0x2F, 0x9E, 0x9E, 0x91, 0x6B,
00832     0x5B, 0xE8, 0xF1, 0x02, 0x9A, 0xC4, 0xAC, 0xC1},
00833    24,
00834    //Cofactor
00835    1,
00836    //Fast modular reduction
00837    NULL
00838 };
00839 
00840 
00841 /**
00842  * @brief brainpoolP224r1 elliptic curve
00843  **/
00844 
00845 const EcCurveInfo brainpoolP224r1Curve =
00846 {
00847    //Curve name
00848    "brainpoolP224r1",
00849    //Object identifier
00850    BRAINPOOLP224R1_OID,
00851    sizeof(BRAINPOOLP224R1_OID),
00852    //Curve type
00853    EC_CURVE_TYPE_BRAINPOOLP_R1,
00854    //Prime modulus p
00855    {0xD7, 0xC1, 0x34, 0xAA, 0x26, 0x43, 0x66, 0x86, 0x2A, 0x18, 0x30, 0x25, 0x75, 0xD1, 0xD7, 0x87,
00856     0xB0, 0x9F, 0x07, 0x57, 0x97, 0xDA, 0x89, 0xF5, 0x7E, 0xC8, 0xC0, 0xFF},
00857    28,
00858    //Curve parameter a
00859    {0x68, 0xA5, 0xE6, 0x2C, 0xA9, 0xCE, 0x6C, 0x1C, 0x29, 0x98, 0x03, 0xA6, 0xC1, 0x53, 0x0B, 0x51,
00860     0x4E, 0x18, 0x2A, 0xD8, 0xB0, 0x04, 0x2A, 0x59, 0xCA, 0xD2, 0x9F, 0x43},
00861    28,
00862    //Curve parameter b
00863    {0x25, 0x80, 0xF6, 0x3C, 0xCF, 0xE4, 0x41, 0x38, 0x87, 0x07, 0x13, 0xB1, 0xA9, 0x23, 0x69, 0xE3,
00864     0x3E, 0x21, 0x35, 0xD2, 0x66, 0xDB, 0xB3, 0x72, 0x38, 0x6C, 0x40, 0x0B},
00865    28,
00866    //x-coordinate of the base point G
00867    {0x0D, 0x90, 0x29, 0xAD, 0x2C, 0x7E, 0x5C, 0xF4, 0x34, 0x08, 0x23, 0xB2, 0xA8, 0x7D, 0xC6, 0x8C,
00868     0x9E, 0x4C, 0xE3, 0x17, 0x4C, 0x1E, 0x6E, 0xFD, 0xEE, 0x12, 0xC0, 0x7D},
00869    28,
00870    //y-coordinate of the base point G
00871    {0x58, 0xAA, 0x56, 0xF7, 0x72, 0xC0, 0x72, 0x6F, 0x24, 0xC6, 0xB8, 0x9E, 0x4E, 0xCD, 0xAC, 0x24,
00872     0x35, 0x4B, 0x9E, 0x99, 0xCA, 0xA3, 0xF6, 0xD3, 0x76, 0x14, 0x02, 0xCD},
00873    28,
00874    //Base point order q
00875    {0xD7, 0xC1, 0x34, 0xAA, 0x26, 0x43, 0x66, 0x86, 0x2A, 0x18, 0x30, 0x25, 0x75, 0xD0, 0xFB, 0x98,
00876     0xD1, 0x16, 0xBC, 0x4B, 0x6D, 0xDE, 0xBC, 0xA3, 0xA5, 0xA7, 0x93, 0x9F},
00877    28,
00878    //Cofactor
00879    1,
00880    //Fast modular reduction
00881    NULL
00882 };
00883 
00884 
00885 /**
00886  * @brief brainpoolP256r1 elliptic curve
00887  **/
00888 
00889 const EcCurveInfo brainpoolP256r1Curve =
00890 {
00891    //Curve name
00892    "brainpoolP256r1",
00893    //Object identifier
00894    BRAINPOOLP256R1_OID,
00895    sizeof(BRAINPOOLP256R1_OID),
00896    //Curve type
00897    EC_CURVE_TYPE_BRAINPOOLP_R1,
00898    //Prime modulus p
00899    {0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66, 0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x72,
00900     0x6E, 0x3B, 0xF6, 0x23, 0xD5, 0x26, 0x20, 0x28, 0x20, 0x13, 0x48, 0x1D, 0x1F, 0x6E, 0x53, 0x77},
00901    32,
00902    //Curve parameter a
00903    {0x7D, 0x5A, 0x09, 0x75, 0xFC, 0x2C, 0x30, 0x57, 0xEE, 0xF6, 0x75, 0x30, 0x41, 0x7A, 0xFF, 0xE7,
00904     0xFB, 0x80, 0x55, 0xC1, 0x26, 0xDC, 0x5C, 0x6C, 0xE9, 0x4A, 0x4B, 0x44, 0xF3, 0x30, 0xB5, 0xD9},
00905    32,
00906    //Curve parameter b
00907    {0x26, 0xDC, 0x5C, 0x6C, 0xE9, 0x4A, 0x4B, 0x44, 0xF3, 0x30, 0xB5, 0xD9, 0xBB, 0xD7, 0x7C, 0xBF,
00908     0x95, 0x84, 0x16, 0x29, 0x5C, 0xF7, 0xE1, 0xCE, 0x6B, 0xCC, 0xDC, 0x18, 0xFF, 0x8C, 0x07, 0xB6},
00909    32,
00910    //x-coordinate of the base point G
00911    {0x8B, 0xD2, 0xAE, 0xB9, 0xCB, 0x7E, 0x57, 0xCB, 0x2C, 0x4B, 0x48, 0x2F, 0xFC, 0x81, 0xB7, 0xAF,
00912     0xB9, 0xDE, 0x27, 0xE1, 0xE3, 0xBD, 0x23, 0xC2, 0x3A, 0x44, 0x53, 0xBD, 0x9A, 0xCE, 0x32, 0x62},
00913    32,
00914    //y-coordinate of the base point G
00915    {0x54, 0x7E, 0xF8, 0x35, 0xC3, 0xDA, 0xC4, 0xFD, 0x97, 0xF8, 0x46, 0x1A, 0x14, 0x61, 0x1D, 0xC9,
00916     0xC2, 0x77, 0x45, 0x13, 0x2D, 0xED, 0x8E, 0x54, 0x5C, 0x1D, 0x54, 0xC7, 0x2F, 0x04, 0x69, 0x97},
00917    32,
00918    //Base point order q
00919    {0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66, 0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x71,
00920     0x8C, 0x39, 0x7A, 0xA3, 0xB5, 0x61, 0xA6, 0xF7, 0x90, 0x1E, 0x0E, 0x82, 0x97, 0x48, 0x56, 0xA7},
00921    32,
00922    //Cofactor
00923    1,
00924    //Fast modular reduction
00925    NULL
00926 };
00927 
00928 
00929 /**
00930  * @brief brainpoolP320r1 elliptic curve
00931  **/
00932 
00933 const EcCurveInfo brainpoolP320r1Curve =
00934 {
00935    //Curve name
00936    "brainpoolP320r1",
00937    //Object identifier
00938    BRAINPOOLP320R1_OID,
00939    sizeof(BRAINPOOLP320R1_OID),
00940    //Curve type
00941    EC_CURVE_TYPE_BRAINPOOLP_R1,
00942    //Prime modulus p
00943    {0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C, 0x78, 0x5E, 0xD2, 0x01, 0xE0, 0x65,
00944     0xF9, 0x8F, 0xCF, 0xA6, 0xF6, 0xF4, 0x0D, 0xEF, 0x4F, 0x92, 0xB9, 0xEC, 0x78, 0x93, 0xEC, 0x28,
00945     0xFC, 0xD4, 0x12, 0xB1, 0xF1, 0xB3, 0x2E, 0x27},
00946    40,
00947    //Curve parameter a
00948    {0x3E, 0xE3, 0x0B, 0x56, 0x8F, 0xBA, 0xB0, 0xF8, 0x83, 0xCC, 0xEB, 0xD4, 0x6D, 0x3F, 0x3B, 0xB8,
00949     0xA2, 0xA7, 0x35, 0x13, 0xF5, 0xEB, 0x79, 0xDA, 0x66, 0x19, 0x0E, 0xB0, 0x85, 0xFF, 0xA9, 0xF4,
00950     0x92, 0xF3, 0x75, 0xA9, 0x7D, 0x86, 0x0E, 0xB4},
00951    40,
00952    //Curve parameter b
00953    {0x52, 0x08, 0x83, 0x94, 0x9D, 0xFD, 0xBC, 0x42, 0xD3, 0xAD, 0x19, 0x86, 0x40, 0x68, 0x8A, 0x6F,
00954     0xE1, 0x3F, 0x41, 0x34, 0x95, 0x54, 0xB4, 0x9A, 0xCC, 0x31, 0xDC, 0xCD, 0x88, 0x45, 0x39, 0x81,
00955     0x6F, 0x5E, 0xB4, 0xAC, 0x8F, 0xB1, 0xF1, 0xA6},
00956    40,
00957    //x-coordinate of the base point G
00958    {0x43, 0xBD, 0x7E, 0x9A, 0xFB, 0x53, 0xD8, 0xB8, 0x52, 0x89, 0xBC, 0xC4, 0x8E, 0xE5, 0xBF, 0xE6,
00959     0xF2, 0x01, 0x37, 0xD1, 0x0A, 0x08, 0x7E, 0xB6, 0xE7, 0x87, 0x1E, 0x2A, 0x10, 0xA5, 0x99, 0xC7,
00960     0x10, 0xAF, 0x8D, 0x0D, 0x39, 0xE2, 0x06, 0x11},
00961    40,
00962    //y-coordinate of the base point G
00963    {0x14, 0xFD, 0xD0, 0x55, 0x45, 0xEC, 0x1C, 0xC8, 0xAB, 0x40, 0x93, 0x24, 0x7F, 0x77, 0x27, 0x5E,
00964     0x07, 0x43, 0xFF, 0xED, 0x11, 0x71, 0x82, 0xEA, 0xA9, 0xC7, 0x78, 0x77, 0xAA, 0xAC, 0x6A, 0xC7,
00965     0xD3, 0x52, 0x45, 0xD1, 0x69, 0x2E, 0x8E, 0xE1},
00966    40,
00967    //Base point order q
00968    {0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C, 0x78, 0x5E, 0xD2, 0x01, 0xE0, 0x65,
00969     0xF9, 0x8F, 0xCF, 0xA5, 0xB6, 0x8F, 0x12, 0xA3, 0x2D, 0x48, 0x2E, 0xC7, 0xEE, 0x86, 0x58, 0xE9,
00970     0x86, 0x91, 0x55, 0x5B, 0x44, 0xC5, 0x93, 0x11},
00971    40,
00972    //Cofactor
00973    1,
00974    //Fast modular reduction
00975    NULL
00976 };
00977 
00978 
00979 /**
00980  * @brief brainpoolP384r1 elliptic curve
00981  **/
00982 
00983 const EcCurveInfo brainpoolP384r1Curve =
00984 {
00985    //Curve name
00986    "brainpoolP384r1",
00987    //Object identifier
00988    BRAINPOOLP384R1_OID,
00989    sizeof(BRAINPOOLP384R1_OID),
00990    //Curve type
00991    EC_CURVE_TYPE_BRAINPOOLP_R1,
00992    //Prime modulus p
00993    {0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D, 0x6F, 0x7E, 0x50, 0xE6, 0x41, 0xDF,
00994     0x15, 0x2F, 0x71, 0x09, 0xED, 0x54, 0x56, 0xB4, 0x12, 0xB1, 0xDA, 0x19, 0x7F, 0xB7, 0x11, 0x23,
00995     0xAC, 0xD3, 0xA7, 0x29, 0x90, 0x1D, 0x1A, 0x71, 0x87, 0x47, 0x00, 0x13, 0x31, 0x07, 0xEC, 0x53},
00996    48,
00997    //Curve parameter a
00998    {0x7B, 0xC3, 0x82, 0xC6, 0x3D, 0x8C, 0x15, 0x0C, 0x3C, 0x72, 0x08, 0x0A, 0xCE, 0x05, 0xAF, 0xA0,
00999     0xC2, 0xBE, 0xA2, 0x8E, 0x4F, 0xB2, 0x27, 0x87, 0x13, 0x91, 0x65, 0xEF, 0xBA, 0x91, 0xF9, 0x0F,
01000     0x8A, 0xA5, 0x81, 0x4A, 0x50, 0x3A, 0xD4, 0xEB, 0x04, 0xA8, 0xC7, 0xDD, 0x22, 0xCE, 0x28, 0x26},
01001    48,
01002    //Curve parameter b
01003    {0x04, 0xA8, 0xC7, 0xDD, 0x22, 0xCE, 0x28, 0x26, 0x8B, 0x39, 0xB5, 0x54, 0x16, 0xF0, 0x44, 0x7C,
01004     0x2F, 0xB7, 0x7D, 0xE1, 0x07, 0xDC, 0xD2, 0xA6, 0x2E, 0x88, 0x0E, 0xA5, 0x3E, 0xEB, 0x62, 0xD5,
01005     0x7C, 0xB4, 0x39, 0x02, 0x95, 0xDB, 0xC9, 0x94, 0x3A, 0xB7, 0x86, 0x96, 0xFA, 0x50, 0x4C, 0x11},
01006    48,
01007    //x-coordinate of the base point G
01008    {0x1D, 0x1C, 0x64, 0xF0, 0x68, 0xCF, 0x45, 0xFF, 0xA2, 0xA6, 0x3A, 0x81, 0xB7, 0xC1, 0x3F, 0x6B,
01009     0x88, 0x47, 0xA3, 0xE7, 0x7E, 0xF1, 0x4F, 0xE3, 0xDB, 0x7F, 0xCA, 0xFE, 0x0C, 0xBD, 0x10, 0xE8,
01010     0xE8, 0x26, 0xE0, 0x34, 0x36, 0xD6, 0x46, 0xAA, 0xEF, 0x87, 0xB2, 0xE2, 0x47, 0xD4, 0xAF, 0x1E},
01011    48,
01012    //y-coordinate of the base point G
01013    {0x8A, 0xBE, 0x1D, 0x75, 0x20, 0xF9, 0xC2, 0xA4, 0x5C, 0xB1, 0xEB, 0x8E, 0x95, 0xCF, 0xD5, 0x52,
01014     0x62, 0xB7, 0x0B, 0x29, 0xFE, 0xEC, 0x58, 0x64, 0xE1, 0x9C, 0x05, 0x4F, 0xF9, 0x91, 0x29, 0x28,
01015     0x0E, 0x46, 0x46, 0x21, 0x77, 0x91, 0x81, 0x11, 0x42, 0x82, 0x03, 0x41, 0x26, 0x3C, 0x53, 0x15},
01016    48,
01017    //Base point order q
01018    {0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D, 0x6F, 0x7E, 0x50, 0xE6, 0x41, 0xDF,
01019     0x15, 0x2F, 0x71, 0x09, 0xED, 0x54, 0x56, 0xB3, 0x1F, 0x16, 0x6E, 0x6C, 0xAC, 0x04, 0x25, 0xA7,
01020     0xCF, 0x3A, 0xB6, 0xAF, 0x6B, 0x7F, 0xC3, 0x10, 0x3B, 0x88, 0x32, 0x02, 0xE9, 0x04, 0x65, 0x65},
01021    48,
01022    //Cofactor
01023    1,
01024    //Fast modular reduction
01025    NULL
01026 };
01027 
01028 
01029 /**
01030  * @brief brainpoolP512r1 elliptic curve
01031  **/
01032 
01033 const EcCurveInfo brainpoolP512r1Curve =
01034 {
01035    //Curve name
01036    "brainpoolP512r1",
01037    //Object identifier
01038    BRAINPOOLP512R1_OID,
01039    sizeof(BRAINPOOLP512R1_OID),
01040    //Curve type
01041    EC_CURVE_TYPE_BRAINPOOLP_R1,
01042    //Prime modulus p
01043    {0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4, 0xE6, 0xAE, 0x33, 0xC9, 0xFC, 0x07,
01044     0xCB, 0x30, 0x8D, 0xB3, 0xB3, 0xC9, 0xD2, 0x0E, 0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33, 0x08, 0x71,
01045     0x7D, 0x4D, 0x9B, 0x00, 0x9B, 0xC6, 0x68, 0x42, 0xAE, 0xCD, 0xA1, 0x2A, 0xE6, 0xA3, 0x80, 0xE6,
01046     0x28, 0x81, 0xFF, 0x2F, 0x2D, 0x82, 0xC6, 0x85, 0x28, 0xAA, 0x60, 0x56, 0x58, 0x3A, 0x48, 0xF3},
01047    64,
01048    //Curve parameter a
01049    {0x78, 0x30, 0xA3, 0x31, 0x8B, 0x60, 0x3B, 0x89, 0xE2, 0x32, 0x71, 0x45, 0xAC, 0x23, 0x4C, 0xC5,
01050     0x94, 0xCB, 0xDD, 0x8D, 0x3D, 0xF9, 0x16, 0x10, 0xA8, 0x34, 0x41, 0xCA, 0xEA, 0x98, 0x63, 0xBC,
01051     0x2D, 0xED, 0x5D, 0x5A, 0xA8, 0x25, 0x3A, 0xA1, 0x0A, 0x2E, 0xF1, 0xC9, 0x8B, 0x9A, 0xC8, 0xB5,
01052     0x7F, 0x11, 0x17, 0xA7, 0x2B, 0xF2, 0xC7, 0xB9, 0xE7, 0xC1, 0xAC, 0x4D, 0x77, 0xFC, 0x94, 0xCA},
01053    64,
01054    //Curve parameter b
01055    {0x3D, 0xF9, 0x16, 0x10, 0xA8, 0x34, 0x41, 0xCA, 0xEA, 0x98, 0x63, 0xBC, 0x2D, 0xED, 0x5D, 0x5A,
01056     0xA8, 0x25, 0x3A, 0xA1, 0x0A, 0x2E, 0xF1, 0xC9, 0x8B, 0x9A, 0xC8, 0xB5, 0x7F, 0x11, 0x17, 0xA7,
01057     0x2B, 0xF2, 0xC7, 0xB9, 0xE7, 0xC1, 0xAC, 0x4D, 0x77, 0xFC, 0x94, 0xCA, 0xDC, 0x08, 0x3E, 0x67,
01058     0x98, 0x40, 0x50, 0xB7, 0x5E, 0xBA, 0xE5, 0xDD, 0x28, 0x09, 0xBD, 0x63, 0x80, 0x16, 0xF7, 0x23},
01059    64,
01060    //x-coordinate of the base point G
01061    {0x81, 0xAE, 0xE4, 0xBD, 0xD8, 0x2E, 0xD9, 0x64, 0x5A, 0x21, 0x32, 0x2E, 0x9C, 0x4C, 0x6A, 0x93,
01062     0x85, 0xED, 0x9F, 0x70, 0xB5, 0xD9, 0x16, 0xC1, 0xB4, 0x3B, 0x62, 0xEE, 0xF4, 0xD0, 0x09, 0x8E,
01063     0xFF, 0x3B, 0x1F, 0x78, 0xE2, 0xD0, 0xD4, 0x8D, 0x50, 0xD1, 0x68, 0x7B, 0x93, 0xB9, 0x7D, 0x5F,
01064     0x7C, 0x6D, 0x50, 0x47, 0x40, 0x6A, 0x5E, 0x68, 0x8B, 0x35, 0x22, 0x09, 0xBC, 0xB9, 0xF8, 0x22},
01065    64,
01066    //y-coordinate of the base point G
01067    {0x7D, 0xDE, 0x38, 0x5D, 0x56, 0x63, 0x32, 0xEC, 0xC0, 0xEA, 0xBF, 0xA9, 0xCF, 0x78, 0x22, 0xFD,
01068     0xF2, 0x09, 0xF7, 0x00, 0x24, 0xA5, 0x7B, 0x1A, 0xA0, 0x00, 0xC5, 0x5B, 0x88, 0x1F, 0x81, 0x11,
01069     0xB2, 0xDC, 0xDE, 0x49, 0x4A, 0x5F, 0x48, 0x5E, 0x5B, 0xCA, 0x4B, 0xD8, 0x8A, 0x27, 0x63, 0xAE,
01070     0xD1, 0xCA, 0x2B, 0x2F, 0xA8, 0xF0, 0x54, 0x06, 0x78, 0xCD, 0x1E, 0x0F, 0x3A, 0xD8, 0x08, 0x92},
01071    64,
01072    //Base point order q
01073    {0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4, 0xE6, 0xAE, 0x33, 0xC9, 0xFC, 0x07,
01074     0xCB, 0x30, 0x8D, 0xB3, 0xB3, 0xC9, 0xD2, 0x0E, 0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33, 0x08, 0x70,
01075     0x55, 0x3E, 0x5C, 0x41, 0x4C, 0xA9, 0x26, 0x19, 0x41, 0x86, 0x61, 0x19, 0x7F, 0xAC, 0x10, 0x47,
01076     0x1D, 0xB1, 0xD3, 0x81, 0x08, 0x5D, 0xDA, 0xDD, 0xB5, 0x87, 0x96, 0x82, 0x9C, 0xA9, 0x00, 0x69},
01077    64,
01078    //Cofactor
01079    1,
01080    //Fast modular reduction
01081    NULL
01082 };
01083 
01084 
01085 /**
01086  * @brief Fast modular reduction (secp128r1 curve)
01087  * @param[in,out] a This function accept an integer less than p^2 as
01088  *   input and return (a mod p) as output
01089  * @param[in] p Prime modulus
01090  **/
01091 
01092 error_t secp128r1Mod(Mpi *a, const Mpi *p)
01093 {
01094    error_t error;
01095    Mpi t;
01096 
01097    //Initialize multiple precision integers
01098    mpiInit(&t);
01099 
01100    //Ajust the size of the integers
01101    MPI_CHECK(mpiGrow(a, 32 / MPI_INT_SIZE));
01102    MPI_CHECK(mpiGrow(&t, 32 / MPI_INT_SIZE));
01103 
01104    //Perform modular reduction
01105    do
01106    {
01107       //Compute T = 0 | 0 | 0 | 0 | A7 | A6 | A5 | A4
01108       COPY_WORD32(&t, 0, a, 4, 4);
01109       CLEAR_WORD32(&t, 4, 4);
01110 
01111       //Clear A7 | A6 | A5 | A4
01112       CLEAR_WORD32(a, 4, 4);
01113 
01114       //Compute A = A + T + (T << 97)
01115       MPI_CHECK(mpiAdd(a, a, &t));
01116       MPI_CHECK(mpiShiftLeft(&t, 97));
01117       MPI_CHECK(mpiAdd(a, a, &t));
01118 
01119       //Check for end condition
01120    } while(mpiComp(a, p) > 0);
01121 
01122 end:
01123    //Release multiple precision integers
01124    mpiFree(&t);
01125 
01126    //Return status code
01127    return error;
01128 }
01129 
01130 
01131 /**
01132  * @brief Fast modular reduction (secp128r2 curve)
01133  * @param[in,out] a This function accept an integer less than p^2 as
01134  *   input and return (a mod p) as output
01135  * @param[in] p Prime modulus
01136  **/
01137 
01138 error_t secp128r2Mod(Mpi *a, const Mpi *p)
01139 {
01140    error_t error;
01141    Mpi t;
01142 
01143    //Initialize multiple precision integers
01144    mpiInit(&t);
01145 
01146    //Ajust the size of the integers
01147    MPI_CHECK(mpiGrow(a, 32 / MPI_INT_SIZE));
01148    MPI_CHECK(mpiGrow(&t, 32 / MPI_INT_SIZE));
01149 
01150    //Perform modular reduction
01151    do
01152    {
01153       //Compute T = 0 | 0 | 0 | 0 | A7 | A6 | A5 | A4
01154       COPY_WORD32(&t, 0, a, 4, 4);
01155       CLEAR_WORD32(&t, 4, 4);
01156 
01157       //Clear A7 | A6 | A5 | A4
01158       CLEAR_WORD32(a, 4, 4);
01159 
01160       //Compute A = A + T + (T << 97)
01161       MPI_CHECK(mpiAdd(a, a, &t));
01162       MPI_CHECK(mpiShiftLeft(&t, 97));
01163       MPI_CHECK(mpiAdd(a, a, &t));
01164 
01165       //Check for end condition
01166    } while(mpiComp(a, p) > 0);
01167 
01168 end:
01169    //Release multiple precision integers
01170    mpiFree(&t);
01171 
01172    //Return status code
01173    return error;
01174 }
01175 
01176 
01177 /**
01178  * @brief Fast modular reduction (secp160k1 curve)
01179  * @param[in,out] a This function accept an integer less than p^2 as
01180  *   input and return (a mod p) as output
01181  * @param[in] p Prime modulus
01182  **/
01183 
01184 error_t secp160k1Mod(Mpi *a, const Mpi *p)
01185 {
01186    error_t error;
01187    Mpi t;
01188 
01189    //Initialize multiple precision integers
01190    mpiInit(&t);
01191 
01192    //Ajust the size of the integers
01193    MPI_CHECK(mpiGrow(a, 40 / MPI_INT_SIZE));
01194    MPI_CHECK(mpiGrow(&t, 24 / MPI_INT_SIZE));
01195 
01196    //Perform modular reduction
01197    do
01198    {
01199       //Compute T = A9 | A8 | A7 | A6 | A5 | 0
01200       CLEAR_WORD32(&t, 0, 1);
01201       COPY_WORD32(&t, 1, a, 5, 5);
01202 
01203       //Clear A9 | A8 | A7 | A6 | A5
01204       CLEAR_WORD32(a, 5, 5);
01205 
01206       //Compute A = A + T
01207       MPI_CHECK(mpiAdd(a, a, &t));
01208       //Compute T = T >> 32
01209       MPI_CHECK(mpiShiftRight(&t, 32));
01210       //Compute A = A + (21389 * T)
01211       MPI_CHECK(mpiMulInt(&t, &t, 21389));
01212       MPI_CHECK(mpiAdd(a, a, &t));
01213 
01214       //Check for end condition
01215    } while(mpiComp(a, p) > 0);
01216 
01217 end:
01218    //Release multiple precision integers
01219    mpiFree(&t);
01220 
01221    //Return status code
01222    return error;
01223 }
01224 
01225 
01226 /**
01227  * @brief Fast modular reduction (secp160r1 curve)
01228  * @param[in,out] a This function accept an integer less than p^2 as
01229  *   input and return (a mod p) as output
01230  * @param[in] p Prime modulus
01231  **/
01232 
01233 error_t secp160r1Mod(Mpi *a, const Mpi *p)
01234 {
01235    error_t error;
01236    Mpi t;
01237 
01238    //Initialize multiple precision integers
01239    mpiInit(&t);
01240 
01241    //Ajust the size of the integers
01242    MPI_CHECK(mpiGrow(a, 40 / MPI_INT_SIZE));
01243    MPI_CHECK(mpiGrow(&t, 24 / MPI_INT_SIZE));
01244 
01245    //Perform modular reduction
01246    do
01247    {
01248       //Compute T = 0 | A9 | A8 | A7 | A6 | A5
01249       COPY_WORD32(&t, 0, a, 5, 5);
01250       CLEAR_WORD32(&t, 5, 1);
01251 
01252       //Clear A9 | A8 | A7 | A6 | A5
01253       CLEAR_WORD32(a, 5, 5);
01254 
01255       //Compute A = A + T + (T << 31)
01256       MPI_CHECK(mpiAdd(a, a, &t));
01257       MPI_CHECK(mpiShiftLeft(&t, 31));
01258       MPI_CHECK(mpiAdd(a, a, &t));
01259 
01260       //Check for end condition
01261    } while(mpiComp(a, p) > 0);
01262 
01263 end:
01264    //Release multiple precision integers
01265    mpiFree(&t);
01266 
01267    //Return status code
01268    return error;
01269 }
01270 
01271 
01272 /**
01273  * @brief Fast modular reduction (secp160r2 curve)
01274  * @param[in,out] a This function accept an integer less than p^2 as
01275  *   input and return (a mod p) as output
01276  * @param[in] p Prime modulus
01277  **/
01278 
01279 error_t secp160r2Mod(Mpi *a, const Mpi *p)
01280 {
01281    error_t error;
01282    Mpi t;
01283 
01284    //Initialize multiple precision integers
01285    mpiInit(&t);
01286 
01287    //Ajust the size of the integers
01288    MPI_CHECK(mpiGrow(a, 40 / MPI_INT_SIZE));
01289    MPI_CHECK(mpiGrow(&t, 24 / MPI_INT_SIZE));
01290 
01291    //Perform modular reduction
01292    do
01293    {
01294       //Compute T = A9 | A8 | A7 | A6 | A5 | 0
01295       CLEAR_WORD32(&t, 0, 1);
01296       COPY_WORD32(&t, 1, a, 5, 5);
01297 
01298       //Clear A9 | A8 | A7 | A6 | A5
01299       CLEAR_WORD32(a, 5, 5);
01300 
01301       //Compute A = A + T
01302       MPI_CHECK(mpiAdd(a, a, &t));
01303       //Compute T = T >> 32
01304       MPI_CHECK(mpiShiftRight(&t, 32));
01305       //Compute A = A + (21389 * T)
01306       MPI_CHECK(mpiMulInt(&t, &t, 21389));
01307       MPI_CHECK(mpiAdd(a, a, &t));
01308 
01309       //Check for end condition
01310    } while(mpiComp(a, p) > 0);
01311 
01312 end:
01313    //Release multiple precision integers
01314    mpiFree(&t);
01315 
01316    //Return status code
01317    return error;
01318 }
01319 
01320 
01321 /**
01322  * @brief Fast modular reduction (secp192k1 curve)
01323  * @param[in,out] a This function accept an integer less than p^2 as
01324  *   input and return (a mod p) as output
01325  * @param[in] p Prime modulus
01326  **/
01327 
01328 error_t secp192k1Mod(Mpi *a, const Mpi *p)
01329 {
01330    error_t error;
01331    Mpi t;
01332 
01333    //Initialize multiple precision integers
01334    mpiInit(&t);
01335 
01336    //Ajust the size of the integers
01337    MPI_CHECK(mpiGrow(a, 48 / MPI_INT_SIZE));
01338    MPI_CHECK(mpiGrow(&t, 28 / MPI_INT_SIZE));
01339 
01340    //Perform modular reduction
01341    do
01342    {
01343       //Compute T = A11 | A10 | A9 | A8 | A7 | A6 | 0
01344       CLEAR_WORD32(&t, 0, 1);
01345       COPY_WORD32(&t, 1, a, 6, 6);
01346 
01347       //Clear A11 | A10 | A9 | A8 | A7 | A6
01348       CLEAR_WORD32(a, 6, 6);
01349 
01350       //Compute A = A + T
01351       MPI_CHECK(mpiAdd(a, a, &t));
01352       //Compute T = T >> 32
01353       MPI_CHECK(mpiShiftRight(&t, 32));
01354       //Compute A = A + (4553 * T)
01355       MPI_CHECK(mpiMulInt(&t, &t, 4553));
01356       MPI_CHECK(mpiAdd(a, a, &t));
01357 
01358       //Check for end condition
01359    } while(mpiComp(a, p) > 0);
01360 
01361 end:
01362    //Release multiple precision integers
01363    mpiFree(&t);
01364 
01365    //Return status code
01366    return error;
01367 }
01368 
01369 
01370 /**
01371  * @brief Fast modular reduction (secp192r1 curve)
01372  * @param[in,out] a This function accept an integer less than p^2 as
01373  *   input and return (a mod p) as output
01374  * @param[in] p Prime modulus
01375  **/
01376 
01377 error_t secp192r1Mod(Mpi *a, const Mpi *p)
01378 {
01379    error_t error;
01380    Mpi s;
01381    Mpi t;
01382 
01383    //Initialize multiple precision integers
01384    mpiInit(&s);
01385    mpiInit(&t);
01386 
01387    //Ajust the size of the integers
01388    MPI_CHECK(mpiGrow(a, 48 / MPI_INT_SIZE));
01389    MPI_CHECK(mpiGrow(&s, 24 / MPI_INT_SIZE));
01390    MPI_CHECK(mpiGrow(&t, 24 / MPI_INT_SIZE));
01391 
01392    //Compute T = A5 | A4 | A3 | A2 | A1 | A0
01393    COPY_WORD32(&t, 0, a, 0, 6);
01394 
01395    //Compute S1 = 0 | 0 | A7 | A6 | A7 | A6
01396    COPY_WORD32(&s, 0, a, 6, 2);
01397    COPY_WORD32(&s, 2, a, 6, 2);
01398    CLEAR_WORD32(&s, 4, 2);
01399    //Compute T = T + S1
01400    MPI_CHECK(mpiAdd(&t, &t, &s));
01401 
01402    //Compute S2 = A9 | A8 | A9 | A8 | 0 | 0
01403    CLEAR_WORD32(&s, 0, 2);
01404    COPY_WORD32(&s, 2, a, 8, 2);
01405    COPY_WORD32(&s, 4, a, 8, 2);
01406    //Compute T = T + S2
01407    MPI_CHECK(mpiAdd(&t, &t, &s));
01408 
01409    //Compute S3 = A11 | A10 | A11 | A10 | A11 | A10
01410    COPY_WORD32(&s, 0, a, 10, 2);
01411    COPY_WORD32(&s, 2, a, 10, 2);
01412    COPY_WORD32(&s, 4, a, 10, 2);
01413    //Compute T = T + S3
01414    MPI_CHECK(mpiAdd(&t, &t, &s));
01415 
01416    //Compute (T + S1 + S2 + S3) mod p
01417    while(mpiComp(&t, p) >= 0)
01418    {
01419        MPI_CHECK(mpiSub(&t, &t, p));
01420    }
01421 
01422    //Save result
01423    MPI_CHECK(mpiCopy(a, &t));
01424 
01425 end:
01426    //Release multiple precision integers
01427    mpiFree(&s);
01428    mpiFree(&t);
01429 
01430    //Return status code
01431    return error;
01432 }
01433 
01434 
01435 /**
01436  * @brief Fast modular reduction (secp224k1 curve)
01437  * @param[in,out] a This function accept an integer less than p^2 as
01438  *   input and return (a mod p) as output
01439  * @param[in] p Prime modulus
01440  **/
01441 
01442 error_t secp224k1Mod(Mpi *a, const Mpi *p)
01443 {
01444    error_t error;
01445    Mpi t;
01446 
01447    //Initialize multiple precision integers
01448    mpiInit(&t);
01449 
01450    //Ajust the size of the integers
01451    MPI_CHECK(mpiGrow(a, 56 / MPI_INT_SIZE));
01452    MPI_CHECK(mpiGrow(&t, 32 / MPI_INT_SIZE));
01453 
01454    //Perform modular reduction
01455    do
01456    {
01457       //Compute T = A13 | A12 | A11 | A10 | A9 | A8 | A7 | 0
01458       CLEAR_WORD32(&t, 0, 1);
01459       COPY_WORD32(&t, 1, a, 7, 7);
01460 
01461       //Clear A13 | A12 | A11 | A10 | A9 | A8 | A7
01462       CLEAR_WORD32(a, 7, 7);
01463 
01464       //Compute A = A + T
01465       MPI_CHECK(mpiAdd(a, a, &t));
01466       //Compute T = T >> 32
01467       MPI_CHECK(mpiShiftRight(&t, 32));
01468       //Compute A = A + (6803 * T)
01469       MPI_CHECK(mpiMulInt(&t, &t, 6803));
01470       MPI_CHECK(mpiAdd(a, a, &t));
01471 
01472       //Check for end condition
01473    } while(mpiComp(a, p) > 0);
01474 
01475 end:
01476    //Release multiple precision integers
01477    mpiFree(&t);
01478 
01479    //Return status code
01480    return error;
01481 }
01482 
01483 
01484 /**
01485  * @brief Fast modular reduction (secp224r1 curve)
01486  * @param[in,out] a This function accept an integer less than p^2 as
01487  *   input and return (a mod p) as output
01488  * @param[in] p Prime modulus
01489  **/
01490 
01491 error_t secp224r1Mod(Mpi *a, const Mpi *p)
01492 {
01493    error_t error;
01494    Mpi s;
01495    Mpi t;
01496 
01497    //Initialize multiple precision integers
01498    mpiInit(&s);
01499    mpiInit(&t);
01500 
01501    //Ajust the size of the integers
01502    MPI_CHECK(mpiGrow(a, 56 / MPI_INT_SIZE));
01503    MPI_CHECK(mpiGrow(&s, 28 / MPI_INT_SIZE));
01504    MPI_CHECK(mpiGrow(&t, 28 / MPI_INT_SIZE));
01505 
01506    //Compute T = A6 | A5 | A4 | A3 | A2 | A1 | A0
01507    COPY_WORD32(&t, 0, a, 0, 7);
01508 
01509    //Compute S1 = A10 | A9 | A8 | A7 | 0 | 0 | 0
01510    CLEAR_WORD32(&s, 0, 3);
01511    COPY_WORD32(&s, 3, a, 7, 4);
01512    //Compute T = T + S1
01513    MPI_CHECK(mpiAdd(&t, &t, &s));
01514 
01515    //Compute S2 = 0 | A13 | A12 | A11 | 0 | 0 | 0
01516    CLEAR_WORD32(&s, 0, 3);
01517    COPY_WORD32(&s, 3, a, 11, 3);
01518    CLEAR_WORD32(&s, 6, 1);
01519    //Compute T = T + S2
01520    MPI_CHECK(mpiAdd(&t, &t, &s));
01521 
01522    //Compute D1 = A13 | A12 | A11 | A10 | A9 | A8 | A7
01523    COPY_WORD32(&s, 0, a, 7, 7);
01524    //Compute T = T - D1
01525    MPI_CHECK(mpiSub(&t, &t, &s));
01526 
01527    //Compute D2 = 0 | 0 | 0 | 0 | A13 | A12 | A11
01528    COPY_WORD32(&s, 0, a, 11, 3);
01529    CLEAR_WORD32(&s, 3, 4);
01530    //Compute T = T - D2
01531    MPI_CHECK(mpiSub(&t, &t, &s));
01532 
01533    //Compute (T + S1 + S2 - D1 - D2) mod p
01534    while(mpiComp(&t, p) >= 0)
01535    {
01536        MPI_CHECK(mpiSub(&t, &t, p));
01537    }
01538 
01539    while(mpiCompInt(&t, 0) < 0)
01540    {
01541        MPI_CHECK(mpiAdd(&t, &t, p));
01542    }
01543 
01544    //Save result
01545    MPI_CHECK(mpiCopy(a, &t));
01546 
01547 end:
01548    //Release multiple precision integers
01549    mpiFree(&s);
01550    mpiFree(&t);
01551 
01552    //Return status code
01553    return error;
01554 }
01555 
01556 
01557 /**
01558  * @brief Fast modular reduction (secp256k1 curve)
01559  * @param[in,out] a This function accept an integer less than p^2 as
01560  *   input and return (a mod p) as output
01561  * @param[in] p Prime modulus
01562  **/
01563 
01564 error_t secp256k1Mod(Mpi *a, const Mpi *p)
01565 {
01566    error_t error;
01567    Mpi t;
01568 
01569    //Initialize multiple precision integers
01570    mpiInit(&t);
01571 
01572    //Ajust the size of the integers
01573    MPI_CHECK(mpiGrow(a, 64 / MPI_INT_SIZE));
01574    MPI_CHECK(mpiGrow(&t, 36 / MPI_INT_SIZE));
01575 
01576    //Perform modular reduction
01577    do
01578    {
01579       //Compute T = A15 | A14 | A13 | A12 | A11 | A10 | A9 | A8 | 0
01580       CLEAR_WORD32(&t, 0, 1);
01581       COPY_WORD32(&t, 1, a, 8, 8);
01582 
01583       //Clear A15 | A14 | A13 | A12 | A11 | A10 | A9 | A8
01584       CLEAR_WORD32(a, 8, 8);
01585 
01586       //Compute A = A + T
01587       MPI_CHECK(mpiAdd(a, a, &t));
01588       //Compute T = T >> 32
01589       MPI_CHECK(mpiShiftRight(&t, 32));
01590       //Compute A = A + (977 * T)
01591       MPI_CHECK(mpiMulInt(&t, &t, 977));
01592       MPI_CHECK(mpiAdd(a, a, &t));
01593 
01594       //Check for end condition
01595    } while(mpiComp(a, p) > 0);
01596 
01597 end:
01598    //Release multiple precision integers
01599    mpiFree(&t);
01600 
01601    //Return status code
01602    return error;
01603 }
01604 
01605 
01606 /**
01607  * @brief Fast modular reduction (secp256r1 curve)
01608  * @param[in,out] a This function accept an integer less than p^2 as
01609  *   input and return (a mod p) as output
01610  * @param[in] p Prime modulus
01611  **/
01612 
01613 error_t secp256r1Mod(Mpi *a, const Mpi *p)
01614 {
01615    error_t error;
01616    Mpi s;
01617    Mpi t;
01618    Mpi b;
01619 
01620    //Initialize multiple precision integers
01621    mpiInit(&s);
01622    mpiInit(&t);
01623    mpiInit(&b);
01624 
01625    //Ajust the size of the integers
01626    MPI_CHECK(mpiGrow(a, 64 / MPI_INT_SIZE));
01627    MPI_CHECK(mpiGrow(&s, 32 / MPI_INT_SIZE));
01628    MPI_CHECK(mpiGrow(&t, 32 / MPI_INT_SIZE));
01629 
01630    //Compute T = A7 | A6 | A5 | A4 | A3 | A2 | A1 | A0
01631    COPY_WORD32(&t, 0, a, 0, 8);
01632 
01633    //Compute S1 = A15 | A14 | A13 | A12 | A11 | 0 | 0 | 0
01634    CLEAR_WORD32(&s, 0, 3);
01635    COPY_WORD32(&s, 3, a, 11, 5);
01636    //Compute T = T + 2 * S1
01637    MPI_CHECK(mpiAdd(&t, &t, &s));
01638    MPI_CHECK(mpiAdd(&t, &t, &s));
01639 
01640    //Compute S2 = 0 | A15 | A14 | A13 | A12 | 0 | 0 | 0
01641    CLEAR_WORD32(&s, 0, 3);
01642    COPY_WORD32(&s, 3, a, 12, 4);
01643    CLEAR_WORD32(&s, 7, 1);
01644    //Compute T = T + 2 * S2
01645    MPI_CHECK(mpiAdd(&t, &t, &s));
01646    MPI_CHECK(mpiAdd(&t, &t, &s));
01647 
01648    //Compute S3 = A15 | A14 | 0 | 0 | 0 | A10 | A9 | A8
01649    COPY_WORD32(&s, 0, a, 8, 3);
01650    CLEAR_WORD32(&s, 3, 3);
01651    COPY_WORD32(&s, 6, a, 14, 2);
01652    //Compute T = T + S3
01653    MPI_CHECK(mpiAdd(&t, &t, &s));
01654 
01655    //Compute S4 = A8 | A13 | A15 | A14 | A13 | A11 | A10 | A9
01656    COPY_WORD32(&s, 0, a, 9, 3);
01657    COPY_WORD32(&s, 3, a, 13, 3);
01658    COPY_WORD32(&s, 6, a, 13, 1);
01659    COPY_WORD32(&s, 7, a, 8, 1);
01660    //Compute T = T + S4
01661    MPI_CHECK(mpiAdd(&t, &t, &s));
01662 
01663    //Compute D1 = A10 | A8 | 0 | 0 | 0 | A13 | A12 | A11
01664    COPY_WORD32(&s, 0, a, 11, 3);
01665    CLEAR_WORD32(&s, 3, 3);
01666    COPY_WORD32(&s, 6, a, 8, 1);
01667    COPY_WORD32(&s, 7, a, 10, 1);
01668    //Compute T = T - D1
01669    MPI_CHECK(mpiSub(&t, &t, &s));
01670 
01671    //Compute D2 = A11 | A9 | 0 | 0 | A15 | A14 | A13 | A12
01672    COPY_WORD32(&s, 0, a, 12, 4);
01673    CLEAR_WORD32(&s, 4, 2);
01674    COPY_WORD32(&s, 6, a, 9, 1);
01675    COPY_WORD32(&s, 7, a, 11, 1);
01676    //Compute T = T - D2
01677    MPI_CHECK(mpiSub(&t, &t, &s));
01678 
01679    //Compute D3 = A12 | 0 | A10 | A9 | A8 | A15 | A14 | A13
01680    COPY_WORD32(&s, 0, a, 13, 3);
01681    COPY_WORD32(&s, 3, a, 8, 3);
01682    CLEAR_WORD32(&s, 6, 1);
01683    COPY_WORD32(&s, 7, a, 12, 1);
01684    //Compute T = T - D3
01685    MPI_CHECK(mpiSub(&t, &t, &s));
01686 
01687    //Compute D4 = A13 | 0 | A11 | A10 | A9 | 0 | A15 | A14
01688    COPY_WORD32(&s, 0, a, 14, 2);
01689    CLEAR_WORD32(&s, 2, 1);
01690    COPY_WORD32(&s, 3, a, 9, 3);
01691    CLEAR_WORD32(&s, 6, 1);
01692    COPY_WORD32(&s, 7, a, 13, 1);
01693    //Compute T = T - D4
01694    MPI_CHECK(mpiSub(&t, &t, &s));
01695 
01696    //Compute (T + 2 * S1 + 2 * S2 + S3 + S4 - D1 - D2 - D3 - D4) mod p
01697    while(mpiComp(&t, p) >= 0)
01698    {
01699        MPI_CHECK(mpiSub(&t, &t, p));
01700    }
01701 
01702    while(mpiCompInt(&t, 0) < 0)
01703    {
01704        MPI_CHECK(mpiAdd(&t, &t, p));
01705    }
01706 
01707    //Save result
01708    MPI_CHECK(mpiCopy(a, &t));
01709 
01710 end:
01711    //Release multiple precision integers
01712    mpiFree(&s);
01713    mpiFree(&t);
01714 
01715    //Return status code
01716    return error;
01717 }
01718 
01719 
01720 /**
01721  * @brief Fast modular reduction (secp384r1 curve)
01722  * @param[in,out] a This function accept an integer less than p^2 as
01723  *   input and return (a mod p) as output
01724  * @param[in] p Prime modulus
01725  **/
01726 
01727 error_t secp384r1Mod(Mpi *a, const Mpi *p)
01728 {
01729    error_t error;
01730    Mpi s;
01731    Mpi t;
01732 
01733    //Initialize multiple precision integers
01734    mpiInit(&s);
01735    mpiInit(&t);
01736 
01737    //Ajust the size of the integers
01738    MPI_CHECK(mpiGrow(a, 96 / MPI_INT_SIZE));
01739    MPI_CHECK(mpiGrow(&s, 48 / MPI_INT_SIZE));
01740    MPI_CHECK(mpiGrow(&t, 48 / MPI_INT_SIZE));
01741 
01742    //Compute T = A11 | A10 | A9 | A8 | A7 | A6 | A5 | A4 | A3 | A2 | A1 | A0
01743    COPY_WORD32(&t, 0, a, 0, 12);
01744 
01745    //Compute S1 = 0 | 0 | 0 | 0 | 0 | A23 | A22 | A21 | 0 | 0 | 0 | 0
01746    CLEAR_WORD32(&s, 0, 4);
01747    COPY_WORD32(&s, 4, a, 21, 3);
01748    CLEAR_WORD32(&s, 7, 5);
01749    //Compute T = T + 2 * S1
01750    MPI_CHECK(mpiAdd(&t, &t, &s));
01751    MPI_CHECK(mpiAdd(&t, &t, &s));
01752 
01753    //Compute S2 = A23 | A22 | A21 | A20 | A19 | A18 | A17 | A16 | A15 | A14 | A13 | A12
01754    COPY_WORD32(&s, 0, a, 12, 12);
01755    //Compute T = T + S2
01756    MPI_CHECK(mpiAdd(&t, &t, &s));
01757 
01758    //Compute S3 = A20 | A19 | A18 | A17 | A16 | A15 | A14 | A13 | A12 | A23| A22 | A21
01759    COPY_WORD32(&s, 0, a, 21, 3);
01760    COPY_WORD32(&s, 3, a, 12, 9);
01761    //Compute T = T + S3
01762    MPI_CHECK(mpiAdd(&t, &t, &s));
01763 
01764    //Compute S4 = A19 | A18 | A17 | A16 | A15 | A14 | A13 | A12 | A20 | 0 | A23 | 0
01765    CLEAR_WORD32(&s, 0, 1);
01766    COPY_WORD32(&s, 1, a, 23, 1);
01767    CLEAR_WORD32(&s, 2, 1);
01768    COPY_WORD32(&s, 3, a, 20, 1);
01769    COPY_WORD32(&s, 4, a, 12, 8);
01770    //Compute T = T + S4
01771    MPI_CHECK(mpiAdd(&t, &t, &s));
01772 
01773    //Compute S5 = 0 | 0 | 0 | 0 | A23 | A22 | A21 | A20 | 0 | 0 | 0 | 0
01774    CLEAR_WORD32(&s, 0, 4);
01775    COPY_WORD32(&s, 4, a, 20, 4);
01776    CLEAR_WORD32(&s, 8, 4);
01777    //Compute T = T + S5
01778    MPI_CHECK(mpiAdd(&t, &t, &s));
01779 
01780    //Compute S6 = 0 | 0 | 0 | 0 | 0 | 0 | A23 | A22 | A21 | 0 | 0 | A20
01781    COPY_WORD32(&s, 0, a, 20, 1);
01782    CLEAR_WORD32(&s, 1, 2);
01783    COPY_WORD32(&s, 3, a, 21, 3);
01784    CLEAR_WORD32(&s, 6, 6);
01785    //Compute T = T + S6
01786    MPI_CHECK(mpiAdd(&t, &t, &s));
01787 
01788    //Compute D1 = A22 | A21 | A20 | A19 | A18 | A17 | A16 | A15 | A14 | A13 | A12 | A23
01789    COPY_WORD32(&s, 0, a, 23, 1);
01790    COPY_WORD32(&s, 1, a, 12, 11);
01791    //Compute T = T - D1
01792    MPI_CHECK(mpiSub(&t, &t, &s));
01793 
01794    //Compute D2 = 0 | 0 | 0 | 0 | 0 | 0 | 0 | A23 | A22 | A21 | A20 | 0
01795    CLEAR_WORD32(&s, 0, 1);
01796    COPY_WORD32(&s, 1, a, 20, 4);
01797    CLEAR_WORD32(&s, 5, 7);
01798    //Compute T = T - D2
01799    MPI_CHECK(mpiSub(&t, &t, &s));
01800 
01801    //Compute D3 = 0 | 0 | 0 | 0 | 0 | 0 | 0 | A23 | A23 | 0 | 0 | 0
01802    CLEAR_WORD32(&s, 0, 3);
01803    COPY_WORD32(&s, 3, a, 23, 1);
01804    COPY_WORD32(&s, 4, a, 23, 1);
01805    CLEAR_WORD32(&s, 5, 7);
01806    //Compute T = T - D3
01807    MPI_CHECK(mpiSub(&t, &t, &s));
01808 
01809    //Compute (T + 2 * S1 + S2 + S3 + S4 + S5 + S6 - D1 - D2 - D3) mod p
01810    while(mpiComp(&t, p) >= 0)
01811    {
01812        MPI_CHECK(mpiSub(&t, &t, p));
01813    }
01814 
01815    while(mpiCompInt(&t, 0) < 0)
01816    {
01817        MPI_CHECK(mpiAdd(&t, &t, p));
01818    }
01819 
01820    //Save result
01821    MPI_CHECK(mpiCopy(a, &t));
01822 
01823 end:
01824    //Release multiple precision integers
01825    mpiFree(&s);
01826    mpiFree(&t);
01827 
01828    //Return status code
01829    return error;
01830 }
01831 
01832 
01833 /**
01834  * @brief Fast modular reduction (secp521r1 curve)
01835  * @param[in,out] a This function accept an integer less than p^2 as
01836  *   input and return (a mod p) as output
01837  * @param[in] p Prime modulus
01838  **/
01839 
01840 error_t secp521r1Mod(Mpi *a, const Mpi *p)
01841 {
01842    error_t error;
01843    Mpi t;
01844 
01845    //Initialize multiple precision integer
01846    mpiInit(&t);
01847 
01848    //Ajust the size of the integers
01849    MPI_CHECK(mpiGrow(a, 132 / MPI_INT_SIZE));
01850    MPI_CHECK(mpiGrow(&t, 68 / MPI_INT_SIZE));
01851 
01852    //Compute A0
01853    COPY_WORD32(&t, 0, a, 0, 17);
01854    t.data[16] &= 0x000001FF;
01855 
01856    //Compute A1
01857    MPI_CHECK(mpiShiftRight(a, 521));
01858 
01859    //Compute A0 + A1
01860    MPI_CHECK(mpiAdd(a, a, &t));
01861 
01862    //Compute (A0 + A1) mod p
01863    while(mpiComp(a, p) >= 0)
01864    {
01865        MPI_CHECK(mpiSub(a, a, p));
01866    }
01867 
01868 end:
01869    //Release multiple precision integer
01870    mpiFree(&t);
01871 
01872    //Return status code
01873    return error;
01874 }
01875 
01876 
01877 /**
01878  * @brief Get the elliptic curve that matches the specified OID
01879  * @param[in] oid Object identifier
01880  * @param[in] length OID length
01881  * @return Elliptic curve domain parameters
01882  **/
01883 
01884 const EcCurveInfo *ecGetCurveInfo(const uint8_t *oid, size_t length)
01885 {
01886    //secp112r1 elliptic curve?
01887    if(!oidComp(oid, length, SECP112R1_OID, sizeof(SECP112R1_OID)))
01888       return SECP112R1_CURVE;
01889    //secp112r2 elliptic curve?
01890    if(!oidComp(oid, length, SECP112R2_OID, sizeof(SECP112R2_OID)))
01891       return SECP112R2_CURVE;
01892    //secp128r1 elliptic curve?
01893    if(!oidComp(oid, length, SECP128R1_OID, sizeof(SECP128R1_OID)))
01894       return SECP128R1_CURVE;
01895    //secp128r2 elliptic curve?
01896    if(!oidComp(oid, length, SECP128R2_OID, sizeof(SECP128R2_OID)))
01897       return SECP128R2_CURVE;
01898    //secp160k1 elliptic curve?
01899    if(!oidComp(oid, length, SECP160K1_OID, sizeof(SECP160K1_OID)))
01900       return SECP160K1_CURVE;
01901    //secp160r1 elliptic curve?
01902    else if(!oidComp(oid, length, SECP160R1_OID, sizeof(SECP160R1_OID)))
01903       return SECP160R1_CURVE;
01904    //secp160r2 elliptic curve?
01905    else if(!oidComp(oid, length, SECP160R2_OID, sizeof(SECP160R2_OID)))
01906       return SECP160R2_CURVE;
01907    //secp192k1 elliptic curve?
01908    else if(!oidComp(oid, length, SECP192K1_OID, sizeof(SECP192K1_OID)))
01909       return SECP192K1_CURVE;
01910    //secp192r1 elliptic curve?
01911    else if(!oidComp(oid, length, SECP192R1_OID, sizeof(SECP192R1_OID)))
01912       return SECP192R1_CURVE;
01913    //secp224k1 elliptic curve?
01914    else if(!oidComp(oid, length, SECP224K1_OID, sizeof(SECP224K1_OID)))
01915       return SECP224K1_CURVE;
01916    //secp224r1 elliptic curve?
01917    else if(!oidComp(oid, length, SECP224R1_OID, sizeof(SECP224R1_OID)))
01918       return SECP224R1_CURVE;
01919    //secp256k1 elliptic curve?
01920    else if(!oidComp(oid, length, SECP256K1_OID, sizeof(SECP256K1_OID)))
01921       return SECP256K1_CURVE;
01922    //secp256r1 elliptic curve?
01923    else if(!oidComp(oid, length, SECP256R1_OID, sizeof(SECP256R1_OID)))
01924       return SECP256R1_CURVE;
01925    //secp384r1 elliptic curve?
01926    else if(!oidComp(oid, length, SECP384R1_OID, sizeof(SECP384R1_OID)))
01927       return SECP384R1_CURVE;
01928    //secp521r1 elliptic curve?
01929    else if(!oidComp(oid, length, SECP521R1_OID, sizeof(SECP521R1_OID)))
01930       return SECP521R1_CURVE;
01931    //brainpoolP160r1 elliptic curve?
01932    else if(!oidComp(oid, length, BRAINPOOLP160R1_OID, sizeof(BRAINPOOLP160R1_OID)))
01933       return BRAINPOOLP160R1_CURVE;
01934    //brainpoolP192r1 elliptic curve?
01935    else if(!oidComp(oid, length, BRAINPOOLP192R1_OID, sizeof(BRAINPOOLP192R1_OID)))
01936       return BRAINPOOLP192R1_CURVE;
01937    //brainpoolP224r1 elliptic curve?
01938    else if(!oidComp(oid, length, BRAINPOOLP224R1_OID, sizeof(BRAINPOOLP224R1_OID)))
01939       return BRAINPOOLP224R1_CURVE;
01940    //brainpoolP256r1 elliptic curve?
01941    else if(!oidComp(oid, length, BRAINPOOLP256R1_OID, sizeof(BRAINPOOLP256R1_OID)))
01942       return BRAINPOOLP256R1_CURVE;
01943    //brainpoolP320r1 elliptic curve?
01944    else if(!oidComp(oid, length, BRAINPOOLP320R1_OID, sizeof(BRAINPOOLP320R1_OID)))
01945       return BRAINPOOLP320R1_CURVE;
01946    //brainpoolP384r1 elliptic curve?
01947    else if(!oidComp(oid, length, BRAINPOOLP384R1_OID, sizeof(BRAINPOOLP384R1_OID)))
01948       return BRAINPOOLP384R1_CURVE;
01949    //brainpoolP512r1 elliptic curve?
01950    else if(!oidComp(oid, length, BRAINPOOLP512R1_OID, sizeof(BRAINPOOLP512R1_OID)))
01951       return BRAINPOOLP512R1_CURVE;
01952    //Unknown identifier?
01953    else
01954       return NULL;
01955 }
01956 
01957 #endif
01958