Webserver+3d print
Diff: cyclone_crypto/ec_curves.c
- Revision:
- 0:8918a71cdbe9
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cyclone_crypto/ec_curves.c Sat Feb 04 18:15:49 2017 +0000 @@ -0,0 +1,1958 @@ +/** + * @file ec_curves.c + * @brief Elliptic curves + * + * @section License + * + * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved. + * + * This file is part of CycloneCrypto Open. + * + * 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. + * + * @author Oryx Embedded SARL (www.oryx-embedded.com) + * @version 1.7.6 + **/ + +//Switch to the appropriate trace level +#define TRACE_LEVEL CRYPTO_TRACE_LEVEL + +//Dependencies +#include <stdlib.h> +#include <string.h> +#include "crypto.h" +#include "ec_curves.h" +#include "oid.h" +#include "debug.h" + +//Check crypto library configuration +#if (EC_SUPPORT == ENABLED) + +//Macro definition +#define CLEAR_WORD32(a, i, n) memset((a)->data + i, 0, n * MPI_INT_SIZE); +#define COPY_WORD32(a, i, b, j, n) memcpy((a)->data + i, (b)->data + j, n * MPI_INT_SIZE); + +//secp112r1 OID (1.3.132.0.6) +const uint8_t SECP112R1_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x06}; +//secp112r2 OID (1.3.132.0.7) +const uint8_t SECP112R2_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x07}; +//secp128r1 OID (1.3.132.0.28) +const uint8_t SECP128R1_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x1C}; +//secp128r2 OID (1.3.132.0.29) +const uint8_t SECP128R2_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x1D}; +//secp160k1 OID (1.3.132.0.9) +const uint8_t SECP160K1_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x09}; +//secp160r1 OID (1.3.132.0.8) +const uint8_t SECP160R1_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x08}; +//secp160r2 OID (1.3.132.0.30) +const uint8_t SECP160R2_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x1E}; +//secp192k1 OID (1.3.132.0.31) +const uint8_t SECP192K1_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x1F}; +//secp192r1 OID (1.2.840.10045.3.1.1) +const uint8_t SECP192R1_OID[8] = {0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x01}; +//secp224k1 OID (1.3.132.0.32) +const uint8_t SECP224K1_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x20}; +//secp224r1 OID (1.3.132.0.33) +const uint8_t SECP224R1_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x21}; +//secp256k1 OID (1.3.132.0.10) +const uint8_t SECP256K1_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x0A}; +//secp256r1 OID (1.2.840.10045.3.1.7) +const uint8_t SECP256R1_OID[8] = {0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07}; +//secp384r1 OID (1.3.132.0.34) +const uint8_t SECP384R1_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x22}; +//secp521r1 OID (1.3.132.0.35) +const uint8_t SECP521R1_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x23}; +//brainpoolP160r1 OID (1.3.36.3.3.2.8.1.1.1) +const uint8_t BRAINPOOLP160R1_OID[10] = {0x2B, 0x03, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x01}; +//brainpoolP192r1 OID (1.3.36.3.3.2.8.1.1.3) +const uint8_t BRAINPOOLP192R1_OID[10] = {0x2B, 0x03, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x03}; +//brainpoolP224r1 OID (1.3.36.3.3.2.8.1.1.5) +const uint8_t BRAINPOOLP224R1_OID[10] = {0x2B, 0x03, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x05}; +//brainpoolP256r1 OID (1.3.36.3.3.2.8.1.1.7) +const uint8_t BRAINPOOLP256R1_OID[10] = {0x2B, 0x03, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x07}; +//brainpoolP320r1 OID (1.3.36.3.3.2.8.1.1.9) +const uint8_t BRAINPOOLP320R1_OID[10] = {0x2B, 0x03, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x09}; +//brainpoolP384r1 OID (1.3.36.3.3.2.8.1.1.11) +const uint8_t BRAINPOOLP384R1_OID[10] = {0x2B, 0x03, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0B}; +//brainpoolP512r1 OID (1.3.36.3.3.2.8.1.1.13) +const uint8_t BRAINPOOLP512R1_OID[10] = {0x2B, 0x03, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0D}; + + +/** + * @brief secp112r1 elliptic curve + **/ + +const EcCurveInfo secp112r1Curve = +{ + //Curve name + "secp112r1", + //Object identifier + SECP112R1_OID, + sizeof(SECP112R1_OID), + //Curve type + EC_CURVE_TYPE_SECP_R1, + //Prime modulus p + {0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x66, 0x80, 0x76, 0xBE, 0xAD, 0x20, 0x8B}, + 14, + //Curve parameter a + {0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x66, 0x80, 0x76, 0xBE, 0xAD, 0x20, 0x88}, + 14, + //Curve parameter b + {0x65, 0x9E, 0xF8, 0xBA, 0x04, 0x39, 0x16, 0xEE, 0xDE, 0x89, 0x11, 0x70, 0x2B, 0x22}, + 14, + //x-coordinate of the base point G + {0x09, 0x48, 0x72, 0x39, 0x99, 0x5A, 0x5E, 0xE7, 0x6B, 0x55, 0xF9, 0xC2, 0xF0, 0x98}, + 14, + //y-coordinate of the base point G + {0xA8, 0x9C, 0xE5, 0xAF, 0x87, 0x24, 0xC0, 0xA2, 0x3E, 0x0E, 0x0F, 0xF7, 0x75, 0x00}, + 14, + //Base point order q + {0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x76, 0x28, 0xDF, 0xAC, 0x65, 0x61, 0xC5}, + 14, + //Cofactor + 1, + //Fast modular reduction + NULL +}; + + +/** + * @brief secp112r2 elliptic curve + **/ + +const EcCurveInfo secp112r2Curve = +{ + //Curve name + "secp112r2", + //Object identifier + SECP112R2_OID, + sizeof(SECP112R2_OID), + //Curve type + EC_CURVE_TYPE_SECP_R2, + //Prime modulus p + {0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x66, 0x80, 0x76, 0xBE, 0xAD, 0x20, 0x8B}, + 14, + //Curve parameter a + {0x61, 0x27, 0xC2, 0x4C, 0x05, 0xF3, 0x8A, 0x0A, 0xAA, 0xF6, 0x5C, 0x0E, 0xF0, 0x2C}, + 14, + //Curve parameter b + {0x51, 0xDE, 0xF1, 0x81, 0x5D, 0xB5, 0xED, 0x74, 0xFC, 0xC3, 0x4C, 0x85, 0xD7, 0x09}, + 14, + //x-coordinate of the base point G + {0x4B, 0xA3, 0x0A, 0xB5, 0xE8, 0x92, 0xB4, 0xE1, 0x64, 0x9D, 0xD0, 0x92, 0x86, 0x43}, + 14, + //y-coordinate of the base point G + {0xAD, 0xCD, 0x46, 0xF5, 0x88, 0x2E, 0x37, 0x47, 0xDE, 0xF3, 0x6E, 0x95, 0x6E, 0x97}, + 14, + //Base point order q + {0x36, 0xDF, 0x0A, 0xAF, 0xD8, 0xB8, 0xD7, 0x59, 0x7C, 0xA1, 0x05, 0x20, 0xD0, 0x4B}, + 14, + //Cofactor + 4, + //Fast modular reduction + NULL +}; + + +/** + * @brief secp128r1 elliptic curve + **/ + +const EcCurveInfo secp128r1Curve = +{ + //Curve name + "secp128r1", + //Object identifier + SECP128R1_OID, + sizeof(SECP128R1_OID), + //Curve type + EC_CURVE_TYPE_SECP_R1, + //Prime modulus p + {0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + 16, + //Curve parameter a + {0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC}, + 16, + //Curve parameter b + {0xE8, 0x75, 0x79, 0xC1, 0x10, 0x79, 0xF4, 0x3D, 0xD8, 0x24, 0x99, 0x3C, 0x2C, 0xEE, 0x5E, 0xD3}, + 16, + //x-coordinate of the base point G + {0x16, 0x1F, 0xF7, 0x52, 0x8B, 0x89, 0x9B, 0x2D, 0x0C, 0x28, 0x60, 0x7C, 0xA5, 0x2C, 0x5B, 0x86}, + 16, + //y-coordinate of the base point G + {0xCF, 0x5A, 0xC8, 0x39, 0x5B, 0xAF, 0xEB, 0x13, 0xC0, 0x2D, 0xA2, 0x92, 0xDD, 0xED, 0x7A, 0x83}, + 16, + //Base point order q + {0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x75, 0xA3, 0x0D, 0x1B, 0x90, 0x38, 0xA1, 0x15}, + 16, + //Cofactor + 1, + //Fast modular reduction + secp128r1Mod +}; + + +/** + * @brief secp128r2 elliptic curve + **/ + +const EcCurveInfo secp128r2Curve = +{ + //Curve name + "secp128r2", + //Object identifier + SECP128R2_OID, + sizeof(SECP128R2_OID), + //Curve type + EC_CURVE_TYPE_SECP_R2, + //Prime modulus p + {0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + 16, + //Curve parameter a + {0xD6, 0x03, 0x19, 0x98, 0xD1, 0xB3, 0xBB, 0xFE, 0xBF, 0x59, 0xCC, 0x9B, 0xBF, 0xF9, 0xAE, 0xE1}, + 16, + //Curve parameter b + {0x5E, 0xEE, 0xFC, 0xA3, 0x80, 0xD0, 0x29, 0x19, 0xDC, 0x2C, 0x65, 0x58, 0xBB, 0x6D, 0x8A, 0x5D}, + 16, + //x-coordinate of the base point G + {0x7B, 0x6A, 0xA5, 0xD8, 0x5E, 0x57, 0x29, 0x83, 0xE6, 0xFB, 0x32, 0xA7, 0xCD, 0xEB, 0xC1, 0x40}, + 16, + //y-coordinate of the base point G + {0x27, 0xB6, 0x91, 0x6A, 0x89, 0x4D, 0x3A, 0xEE, 0x71, 0x06, 0xFE, 0x80, 0x5F, 0xC3, 0x4B, 0x44}, + 16, + //Base point order q + {0x3F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xBE, 0x00, 0x24, 0x72, 0x06, 0x13, 0xB5, 0xA3}, + 16, + //Cofactor + 4, + //Fast modular reduction + secp128r2Mod +}; + + +/** + * @brief secp160k1 elliptic curve + **/ + +const EcCurveInfo secp160k1Curve = +{ + //Curve name + "secp160k1", + //Object identifier + SECP160K1_OID, + sizeof(SECP160K1_OID), + //Curve type + EC_CURVE_TYPE_SECP_K1, + //Prime modulus p + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0xFF, 0xFF, 0xAC, 0x73}, + 20, + //Curve parameter a + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, + 20, + //Curve parameter b + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07}, + 20, + //x-coordinate of the base point G + {0x3B, 0x4C, 0x38, 0x2C, 0xE3, 0x7A, 0xA1, 0x92, 0xA4, 0x01, 0x9E, 0x76, 0x30, 0x36, 0xF4, 0xF5, + 0xDD, 0x4D, 0x7E, 0xBB}, + 20, + //y-coordinate of the base point G + {0x93, 0x8C, 0xF9, 0x35, 0x31, 0x8F, 0xDC, 0xED, 0x6B, 0xC2, 0x82, 0x86, 0x53, 0x17, 0x33, 0xC3, + 0xF0, 0x3C, 0x4F, 0xEE}, + 20, + //Base point order q + {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xB8, 0xFA, 0x16, 0xDF, 0xAB, + 0x9A, 0xCA, 0x16, 0xB6, 0xB3}, + 21, + //Cofactor + 1, + //Fast modular reduction + secp160k1Mod +}; + + +/** + * @brief secp160r1 elliptic curve + **/ + +const EcCurveInfo secp160r1Curve = +{ + //Curve name + "secp160r1", + //Object identifier + SECP160R1_OID, + sizeof(SECP160R1_OID), + //Curve type + EC_CURVE_TYPE_SECP_R1, + //Prime modulus p + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x7F, 0xFF, 0xFF, 0xFF}, + 20, + //Curve parameter a + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x7F, 0xFF, 0xFF, 0xFC}, + 20, + //Curve parameter b + {0x1C, 0x97, 0xBE, 0xFC, 0x54, 0xBD, 0x7A, 0x8B, 0x65, 0xAC, 0xF8, 0x9F, 0x81, 0xD4, 0xD4, 0xAD, + 0xC5, 0x65, 0xFA, 0x45}, + 20, + //x-coordinate of the base point G + {0x4A, 0x96, 0xB5, 0x68, 0x8E, 0xF5, 0x73, 0x28, 0x46, 0x64, 0x69, 0x89, 0x68, 0xC3, 0x8B, 0xB9, + 0x13, 0xCB, 0xFC, 0x82}, + 20, + //y-coordinate of the base point G + {0x23, 0xA6, 0x28, 0x55, 0x31, 0x68, 0x94, 0x7D, 0x59, 0xDC, 0xC9, 0x12, 0x04, 0x23, 0x51, 0x37, + 0x7A, 0xC5, 0xFB, 0x32}, + 20, + //Base point order q + {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF4, 0xC8, 0xF9, 0x27, 0xAE, + 0xD3, 0xCA, 0x75, 0x22, 0x57}, + 21, + //Cofactor + 1, + //Fast modular reduction + secp160r1Mod +}; + + +/** + * @brief secp160r2 elliptic curve + **/ + +const EcCurveInfo secp160r2Curve = +{ + //Curve name + "secp160r2", + //Object identifier + SECP160R2_OID, + sizeof(SECP160R2_OID), + //Curve type + EC_CURVE_TYPE_SECP_R2, + //Prime modulus p + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0xFF, 0xFF, 0xAC, 0x73}, + 20, + //Curve parameter a + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0xFF, 0xFF, 0xAC, 0x70}, + 20, + //Curve parameter b + {0xB4, 0xE1, 0x34, 0xD3, 0xFB, 0x59, 0xEB, 0x8B, 0xAB, 0x57, 0x27, 0x49, 0x04, 0x66, 0x4D, 0x5A, + 0xF5, 0x03, 0x88, 0xBA}, + 20, + //x-coordinate of the base point G + {0x52, 0xDC, 0xB0, 0x34, 0x29, 0x3A, 0x11, 0x7E, 0x1F, 0x4F, 0xF1, 0x1B, 0x30, 0xF7, 0x19, 0x9D, + 0x31, 0x44, 0xCE, 0x6D}, + 20, + //y-coordinate of the base point G + {0xFE, 0xAF, 0xFE, 0xF2, 0xE3, 0x31, 0xF2, 0x96, 0xE0, 0x71, 0xFA, 0x0D, 0xF9, 0x98, 0x2C, 0xFE, + 0xA7, 0xD4, 0x3F, 0x2E}, + 20, + //Base point order q + {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x1E, 0xE7, 0x86, 0xA8, + 0x18, 0xF3, 0xA1, 0xA1, 0x6B}, + 21, + //Cofactor + 1, + //Fast modular reduction + secp160r2Mod +}; + + +/** + * @brief secp192k1 elliptic curve + **/ + +const EcCurveInfo secp192k1Curve = +{ + //Curve name + "secp192k1", + //Object identifier + SECP192K1_OID, + sizeof(SECP192K1_OID), + //Curve type + EC_CURVE_TYPE_SECP_K1, + //Prime modulus p + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xEE, 0x37}, + 24, + //Curve parameter a + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + 24, + //Curve parameter b + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03}, + 24, + //x-coordinate of the base point G + {0xDB, 0x4F, 0xF1, 0x0E, 0xC0, 0x57, 0xE9, 0xAE, 0x26, 0xB0, 0x7D, 0x02, 0x80, 0xB7, 0xF4, 0x34, + 0x1D, 0xA5, 0xD1, 0xB1, 0xEA, 0xE0, 0x6C, 0x7D}, + 24, + //y-coordinate of the base point G + {0x9B, 0x2F, 0x2F, 0x6D, 0x9C, 0x56, 0x28, 0xA7, 0x84, 0x41, 0x63, 0xD0, 0x15, 0xBE, 0x86, 0x34, + 0x40, 0x82, 0xAA, 0x88, 0xD9, 0x5E, 0x2F, 0x9D}, + 24, + //Base point order q + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x26, 0xF2, 0xFC, 0x17, + 0x0F, 0x69, 0x46, 0x6A, 0x74, 0xDE, 0xFD, 0x8D}, + 24, + //Cofactor + 1, + //Fast modular reduction + secp192k1Mod +}; + + +/** + * @brief secp192r1 elliptic curve + **/ + +const EcCurveInfo secp192r1Curve = +{ + //Curve name + "secp192r1", + //Object identifier + SECP192R1_OID, + sizeof(SECP192R1_OID), + //Curve type + EC_CURVE_TYPE_SECP_R1, + //Prime modulus p + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + 24, + //Curve parameter a + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC}, + 24, + //Curve parameter b + {0x64, 0x21, 0x05, 0x19, 0xE5, 0x9C, 0x80, 0xE7, 0x0F, 0xA7, 0xE9, 0xAB, 0x72, 0x24, 0x30, 0x49, + 0xFE, 0xB8, 0xDE, 0xEC, 0xC1, 0x46, 0xB9, 0xB1}, + 24, + //x-coordinate of the base point G + {0x18, 0x8D, 0xA8, 0x0E, 0xB0, 0x30, 0x90, 0xF6, 0x7C, 0xBF, 0x20, 0xEB, 0x43, 0xA1, 0x88, 0x00, + 0xF4, 0xFF, 0x0A, 0xFD, 0x82, 0xFF, 0x10, 0x12}, + 24, + //y-coordinate of the base point G + {0x07, 0x19, 0x2B, 0x95, 0xFF, 0xC8, 0xDA, 0x78, 0x63, 0x10, 0x11, 0xED, 0x6B, 0x24, 0xCD, 0xD5, + 0x73, 0xF9, 0x77, 0xA1, 0x1E, 0x79, 0x48, 0x11}, + 24, + //Base point order q + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x99, 0xDE, 0xF8, 0x36, + 0x14, 0x6B, 0xC9, 0xB1, 0xB4, 0xD2, 0x28, 0x31}, + 24, + //Cofactor + 1, + //Fast modular reduction + secp192r1Mod +}; + + +/** + * @brief secp224k1 elliptic curve + **/ + +const EcCurveInfo secp224k1Curve = +{ + //Curve name + "secp224k1", + //Object identifier + SECP224K1_OID, + sizeof(SECP224K1_OID), + //Curve type + EC_CURVE_TYPE_SECP_K1, + //Prime modulus p + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xE5, 0x6D}, + 28, + //Curve parameter a + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + 28, + //Curve parameter b + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05}, + 28, + //x-coordinate of the base point G + {0xA1, 0x45, 0x5B, 0x33, 0x4D, 0xF0, 0x99, 0xDF, 0x30, 0xFC, 0x28, 0xA1, 0x69, 0xA4, 0x67, 0xE9, + 0xE4, 0x70, 0x75, 0xA9, 0x0F, 0x7E, 0x65, 0x0E, 0xB6, 0xB7, 0xA4, 0x5C}, + 28, + //y-coordinate of the base point G + {0x7E, 0x08, 0x9F, 0xED, 0x7F, 0xBA, 0x34, 0x42, 0x82, 0xCA, 0xFB, 0xD6, 0xF7, 0xE3, 0x19, 0xF7, + 0xC0, 0xB0, 0xBD, 0x59, 0xE2, 0xCA, 0x4B, 0xDB, 0x55, 0x6D, 0x61, 0xA5}, + 28, + //Base point order q + {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xDC, + 0xE8, 0xD2, 0xEC, 0x61, 0x84, 0xCA, 0xF0, 0xA9, 0x71, 0x76, 0x9F, 0xB1, 0xF7}, + 29, + //Cofactor + 1, + //Fast modular reduction + secp224k1Mod +}; + + +/** + * @brief secp224r1 elliptic curve + **/ + +const EcCurveInfo secp224r1Curve = +{ + //Curve name + "secp224r1", + //Object identifier + SECP224R1_OID, + sizeof(SECP224R1_OID), + //Curve type + EC_CURVE_TYPE_SECP_R1, + //Prime modulus p + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + 28, + //Curve parameter a + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE}, + 28, + //Curve parameter b + {0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56, 0x50, 0x44, 0xB0, 0xB7, + 0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B, 0x39, 0x43, 0x23, 0x55, 0xFF, 0xB4}, + 28, + //x-coordinate of the base point G + {0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9, 0x4A, 0x03, 0xC1, 0xD3, + 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6, 0x11, 0x5C, 0x1D, 0x21}, + 28, + //y-coordinate of the base point G + {0xBD, 0x37, 0x63, 0x88, 0xB5, 0xF7, 0x23, 0xFB, 0x4C, 0x22, 0xDF, 0xE6, 0xCD, 0x43, 0x75, 0xA0, + 0x5A, 0x07, 0x47, 0x64, 0x44, 0xD5, 0x81, 0x99, 0x85, 0x00, 0x7E, 0x34}, + 28, + //Base point order q + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x16, 0xA2, + 0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45, 0x5C, 0x5C, 0x2A, 0x3D}, + 28, + //Cofactor + 1, + //Fast modular reduction + secp224r1Mod +}; + + +/** + * @brief secp256k1 elliptic curve + **/ + +const EcCurveInfo secp256k1Curve = +{ + //Curve name + "secp256k1", + //Object identifier + SECP256K1_OID, + sizeof(SECP256K1_OID), + //Curve type + EC_CURVE_TYPE_SECP_K1, + //Prime modulus p + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0x2F}, + 32, + //Curve parameter a + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + 32, + //Curve parameter b + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07}, + 32, + //x-coordinate of the base point G + {0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62, 0x95, 0xCE, 0x87, 0x0B, 0x07, + 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE, 0x28, 0xD9, 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17, 0x98}, + 32, + //y-coordinate of the base point G + {0x48, 0x3A, 0xDA, 0x77, 0x26, 0xA3, 0xC4, 0x65, 0x5D, 0xA4, 0xFB, 0xFC, 0x0E, 0x11, 0x08, 0xA8, + 0xFD, 0x17, 0xB4, 0x48, 0xA6, 0x85, 0x54, 0x19, 0x9C, 0x47, 0xD0, 0x8F, 0xFB, 0x10, 0xD4, 0xB8}, + 32, + //Base point order q + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41}, + 32, + //Cofactor + 1, + //Fast modular reduction + secp256k1Mod +}; + + +/** + * @brief secp256r1 elliptic curve + **/ + +const EcCurveInfo secp256r1Curve = +{ + //Curve name + "secp256r1", + //Object identifier + SECP256R1_OID, + sizeof(SECP256R1_OID), + //Curve type + EC_CURVE_TYPE_SECP_R1, + //Prime modulus p + {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + 32, + //Curve parameter a + {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC}, + 32, + //Curve parameter b + {0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55, 0x76, 0x98, 0x86, 0xBC, + 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6, 0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B}, + 32, + //x-coordinate of the base point G + {0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5, 0x63, 0xA4, 0x40, 0xF2, + 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0, 0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96}, + 32, + //y-coordinate of the base point G + {0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, 0x9B, 0x8E, 0xE7, 0xEB, 0x4A, 0x7C, 0x0F, 0x9E, 0x16, + 0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE, 0xCB, 0xB6, 0x40, 0x68, 0x37, 0xBF, 0x51, 0xF5}, + 32, + //Base point order q + {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84, 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51}, + 32, + //Cofactor + 1, + //Fast modular reduction + secp256r1Mod +}; + + +/** + * @brief secp384r1 elliptic curve + **/ + +const EcCurveInfo secp384r1Curve = +{ + //Curve name + "secp384r1", + //Object identifier + SECP384R1_OID, + sizeof(SECP384R1_OID), + //Curve type + EC_CURVE_TYPE_SECP_R1, + //Prime modulus p + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF}, + 48, + //Curve parameter a + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC}, + 48, + //Curve parameter b + {0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B, 0xE3, 0xF8, 0x2D, 0x19, + 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12, 0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, + 0xC6, 0x56, 0x39, 0x8D, 0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF}, + 48, + //x-coordinate of the base point G + {0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E, 0xF3, 0x20, 0xAD, 0x74, + 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98, 0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, + 0x55, 0x02, 0xF2, 0x5D, 0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7}, + 48, + //y-coordinate of the base point G + {0x36, 0x17, 0xDE, 0x4A, 0x96, 0x26, 0x2C, 0x6F, 0x5D, 0x9E, 0x98, 0xBF, 0x92, 0x92, 0xDC, 0x29, + 0xF8, 0xF4, 0x1D, 0xBD, 0x28, 0x9A, 0x14, 0x7C, 0xE9, 0xDA, 0x31, 0x13, 0xB5, 0xF0, 0xB8, 0xC0, + 0x0A, 0x60, 0xB1, 0xCE, 0x1D, 0x7E, 0x81, 0x9D, 0x7A, 0x43, 0x1D, 0x7C, 0x90, 0xEA, 0x0E, 0x5F}, + 48, + //Base point order q + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, + 0x58, 0x1A, 0x0D, 0xB2, 0x48, 0xB0, 0xA7, 0x7A, 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73}, + 48, + //Cofactor + 1, + //Fast modular reduction + secp384r1Mod +}; + + +/** + * @brief secp521r1 elliptic curve + **/ + +const EcCurveInfo secp521r1Curve = +{ + //Curve name + "secp521r1", + //Object identifier + SECP521R1_OID, + sizeof(SECP521R1_OID), + //Curve type + EC_CURVE_TYPE_SECP_R1, + //Prime modulus p + {0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF}, + 66, + //Curve parameter a + {0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFC}, + 66, + //Curve parameter b + {0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, 0x92, 0x9A, 0x21, 0xA0, 0xB6, 0x85, + 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3, 0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, + 0x09, 0xE1, 0x56, 0x19, 0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1, + 0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45, 0x1F, 0xD4, 0x6B, 0x50, + 0x3F, 0x00}, + 66, + //x-coordinate of the base point G + {0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E, 0xCB, 0x66, 0x23, 0x95, + 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F, 0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, + 0x3D, 0xBA, 0xA1, 0x4B, 0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF, + 0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E, 0x7E, 0x31, 0xC2, 0xE5, + 0xBD, 0x66}, + 66, + //y-coordinate of the base point G + {0x01, 0x18, 0x39, 0x29, 0x6A, 0x78, 0x9A, 0x3B, 0xC0, 0x04, 0x5C, 0x8A, 0x5F, 0xB4, 0x2C, 0x7D, + 0x1B, 0xD9, 0x98, 0xF5, 0x44, 0x49, 0x57, 0x9B, 0x44, 0x68, 0x17, 0xAF, 0xBD, 0x17, 0x27, 0x3E, + 0x66, 0x2C, 0x97, 0xEE, 0x72, 0x99, 0x5E, 0xF4, 0x26, 0x40, 0xC5, 0x50, 0xB9, 0x01, 0x3F, 0xAD, + 0x07, 0x61, 0x35, 0x3C, 0x70, 0x86, 0xA2, 0x72, 0xC2, 0x40, 0x88, 0xBE, 0x94, 0x76, 0x9F, 0xD1, + 0x66, 0x50}, + 66, + //Base point order q + {0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFA, 0x51, 0x86, 0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09, + 0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F, 0xB7, 0x1E, 0x91, 0x38, + 0x64, 0x09}, + 66, + //Cofactor + 1, + //Fast modular reduction + secp521r1Mod +}; + + +/** + * @brief brainpoolP160r1 elliptic curve + **/ + +const EcCurveInfo brainpoolP160r1Curve = +{ + //Curve name + "brainpoolP160r1", + //Object identifier + BRAINPOOLP160R1_OID, + sizeof(BRAINPOOLP160R1_OID), + //Curve type + EC_CURVE_TYPE_BRAINPOOLP_R1, + //Prime modulus p + {0xE9, 0x5E, 0x4A, 0x5F, 0x73, 0x70, 0x59, 0xDC, 0x60, 0xDF, 0xC7, 0xAD, 0x95, 0xB3, 0xD8, 0x13, + 0x95, 0x15, 0x62, 0x0F}, + 20, + //Curve parameter a + {0x34, 0x0E, 0x7B, 0xE2, 0xA2, 0x80, 0xEB, 0x74, 0xE2, 0xBE, 0x61, 0xBA, 0xDA, 0x74, 0x5D, 0x97, + 0xE8, 0xF7, 0xC3, 0x00}, + 20, + //Curve parameter b + {0x1E, 0x58, 0x9A, 0x85, 0x95, 0x42, 0x34, 0x12, 0x13, 0x4F, 0xAA, 0x2D, 0xBD, 0xEC, 0x95, 0xC8, + 0xD8, 0x67, 0x5E, 0x58}, + 20, + //x-coordinate of the base point G + {0xBE, 0xD5, 0xAF, 0x16, 0xEA, 0x3F, 0x6A, 0x4F, 0x62, 0x93, 0x8C, 0x46, 0x31, 0xEB, 0x5A, 0xF7, + 0xBD, 0xBC, 0xDB, 0xC3}, + 20, + //y-coordinate of the base point G + {0x16, 0x67, 0xCB, 0x47, 0x7A, 0x1A, 0x8E, 0xC3, 0x38, 0xF9, 0x47, 0x41, 0x66, 0x9C, 0x97, 0x63, + 0x16, 0xDA, 0x63, 0x21}, + 20, + //Base point order q + {0xE9, 0x5E, 0x4A, 0x5F, 0x73, 0x70, 0x59, 0xDC, 0x60, 0xDF, 0x59, 0x91, 0xD4, 0x50, 0x29, 0x40, + 0x9E, 0x60, 0xFC, 0x09}, + 20, + //Cofactor + 1, + //Fast modular reduction + NULL +}; + + +/** + * @brief brainpoolP192r1 elliptic curve + **/ + +const EcCurveInfo brainpoolP192r1Curve = +{ + //Curve name + "brainpoolP192r1", + //Object identifier + BRAINPOOLP192R1_OID, + sizeof(BRAINPOOLP192R1_OID), + //Curve type + EC_CURVE_TYPE_BRAINPOOLP_R1, + //Prime modulus p + {0xC3, 0x02, 0xF4, 0x1D, 0x93, 0x2A, 0x36, 0xCD, 0xA7, 0xA3, 0x46, 0x30, 0x93, 0xD1, 0x8D, 0xB7, + 0x8F, 0xCE, 0x47, 0x6D, 0xE1, 0xA8, 0x62, 0x97}, + 24, + //Curve parameter a + {0x6A, 0x91, 0x17, 0x40, 0x76, 0xB1, 0xE0, 0xE1, 0x9C, 0x39, 0xC0, 0x31, 0xFE, 0x86, 0x85, 0xC1, + 0xCA, 0xE0, 0x40, 0xE5, 0xC6, 0x9A, 0x28, 0xEF}, + 24, + //Curve parameter b + {0x46, 0x9A, 0x28, 0xEF, 0x7C, 0x28, 0xCC, 0xA3, 0xDC, 0x72, 0x1D, 0x04, 0x4F, 0x44, 0x96, 0xBC, + 0xCA, 0x7E, 0xF4, 0x14, 0x6F, 0xBF, 0x25, 0xC9}, + 24, + //x-coordinate of the base point G + {0xC0, 0xA0, 0x64, 0x7E, 0xAA, 0xB6, 0xA4, 0x87, 0x53, 0xB0, 0x33, 0xC5, 0x6C, 0xB0, 0xF0, 0x90, + 0x0A, 0x2F, 0x5C, 0x48, 0x53, 0x37, 0x5F, 0xD6}, + 24, + //y-coordinate of the base point G + {0x14, 0xB6, 0x90, 0x86, 0x6A, 0xBD, 0x5B, 0xB8, 0x8B, 0x5F, 0x48, 0x28, 0xC1, 0x49, 0x00, 0x02, + 0xE6, 0x77, 0x3F, 0xA2, 0xFA, 0x29, 0x9B, 0x8F}, + 24, + //Base point order q + {0xC3, 0x02, 0xF4, 0x1D, 0x93, 0x2A, 0x36, 0xCD, 0xA7, 0xA3, 0x46, 0x2F, 0x9E, 0x9E, 0x91, 0x6B, + 0x5B, 0xE8, 0xF1, 0x02, 0x9A, 0xC4, 0xAC, 0xC1}, + 24, + //Cofactor + 1, + //Fast modular reduction + NULL +}; + + +/** + * @brief brainpoolP224r1 elliptic curve + **/ + +const EcCurveInfo brainpoolP224r1Curve = +{ + //Curve name + "brainpoolP224r1", + //Object identifier + BRAINPOOLP224R1_OID, + sizeof(BRAINPOOLP224R1_OID), + //Curve type + EC_CURVE_TYPE_BRAINPOOLP_R1, + //Prime modulus p + {0xD7, 0xC1, 0x34, 0xAA, 0x26, 0x43, 0x66, 0x86, 0x2A, 0x18, 0x30, 0x25, 0x75, 0xD1, 0xD7, 0x87, + 0xB0, 0x9F, 0x07, 0x57, 0x97, 0xDA, 0x89, 0xF5, 0x7E, 0xC8, 0xC0, 0xFF}, + 28, + //Curve parameter a + {0x68, 0xA5, 0xE6, 0x2C, 0xA9, 0xCE, 0x6C, 0x1C, 0x29, 0x98, 0x03, 0xA6, 0xC1, 0x53, 0x0B, 0x51, + 0x4E, 0x18, 0x2A, 0xD8, 0xB0, 0x04, 0x2A, 0x59, 0xCA, 0xD2, 0x9F, 0x43}, + 28, + //Curve parameter b + {0x25, 0x80, 0xF6, 0x3C, 0xCF, 0xE4, 0x41, 0x38, 0x87, 0x07, 0x13, 0xB1, 0xA9, 0x23, 0x69, 0xE3, + 0x3E, 0x21, 0x35, 0xD2, 0x66, 0xDB, 0xB3, 0x72, 0x38, 0x6C, 0x40, 0x0B}, + 28, + //x-coordinate of the base point G + {0x0D, 0x90, 0x29, 0xAD, 0x2C, 0x7E, 0x5C, 0xF4, 0x34, 0x08, 0x23, 0xB2, 0xA8, 0x7D, 0xC6, 0x8C, + 0x9E, 0x4C, 0xE3, 0x17, 0x4C, 0x1E, 0x6E, 0xFD, 0xEE, 0x12, 0xC0, 0x7D}, + 28, + //y-coordinate of the base point G + {0x58, 0xAA, 0x56, 0xF7, 0x72, 0xC0, 0x72, 0x6F, 0x24, 0xC6, 0xB8, 0x9E, 0x4E, 0xCD, 0xAC, 0x24, + 0x35, 0x4B, 0x9E, 0x99, 0xCA, 0xA3, 0xF6, 0xD3, 0x76, 0x14, 0x02, 0xCD}, + 28, + //Base point order q + {0xD7, 0xC1, 0x34, 0xAA, 0x26, 0x43, 0x66, 0x86, 0x2A, 0x18, 0x30, 0x25, 0x75, 0xD0, 0xFB, 0x98, + 0xD1, 0x16, 0xBC, 0x4B, 0x6D, 0xDE, 0xBC, 0xA3, 0xA5, 0xA7, 0x93, 0x9F}, + 28, + //Cofactor + 1, + //Fast modular reduction + NULL +}; + + +/** + * @brief brainpoolP256r1 elliptic curve + **/ + +const EcCurveInfo brainpoolP256r1Curve = +{ + //Curve name + "brainpoolP256r1", + //Object identifier + BRAINPOOLP256R1_OID, + sizeof(BRAINPOOLP256R1_OID), + //Curve type + EC_CURVE_TYPE_BRAINPOOLP_R1, + //Prime modulus p + {0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66, 0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x72, + 0x6E, 0x3B, 0xF6, 0x23, 0xD5, 0x26, 0x20, 0x28, 0x20, 0x13, 0x48, 0x1D, 0x1F, 0x6E, 0x53, 0x77}, + 32, + //Curve parameter a + {0x7D, 0x5A, 0x09, 0x75, 0xFC, 0x2C, 0x30, 0x57, 0xEE, 0xF6, 0x75, 0x30, 0x41, 0x7A, 0xFF, 0xE7, + 0xFB, 0x80, 0x55, 0xC1, 0x26, 0xDC, 0x5C, 0x6C, 0xE9, 0x4A, 0x4B, 0x44, 0xF3, 0x30, 0xB5, 0xD9}, + 32, + //Curve parameter b + {0x26, 0xDC, 0x5C, 0x6C, 0xE9, 0x4A, 0x4B, 0x44, 0xF3, 0x30, 0xB5, 0xD9, 0xBB, 0xD7, 0x7C, 0xBF, + 0x95, 0x84, 0x16, 0x29, 0x5C, 0xF7, 0xE1, 0xCE, 0x6B, 0xCC, 0xDC, 0x18, 0xFF, 0x8C, 0x07, 0xB6}, + 32, + //x-coordinate of the base point G + {0x8B, 0xD2, 0xAE, 0xB9, 0xCB, 0x7E, 0x57, 0xCB, 0x2C, 0x4B, 0x48, 0x2F, 0xFC, 0x81, 0xB7, 0xAF, + 0xB9, 0xDE, 0x27, 0xE1, 0xE3, 0xBD, 0x23, 0xC2, 0x3A, 0x44, 0x53, 0xBD, 0x9A, 0xCE, 0x32, 0x62}, + 32, + //y-coordinate of the base point G + {0x54, 0x7E, 0xF8, 0x35, 0xC3, 0xDA, 0xC4, 0xFD, 0x97, 0xF8, 0x46, 0x1A, 0x14, 0x61, 0x1D, 0xC9, + 0xC2, 0x77, 0x45, 0x13, 0x2D, 0xED, 0x8E, 0x54, 0x5C, 0x1D, 0x54, 0xC7, 0x2F, 0x04, 0x69, 0x97}, + 32, + //Base point order q + {0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66, 0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x71, + 0x8C, 0x39, 0x7A, 0xA3, 0xB5, 0x61, 0xA6, 0xF7, 0x90, 0x1E, 0x0E, 0x82, 0x97, 0x48, 0x56, 0xA7}, + 32, + //Cofactor + 1, + //Fast modular reduction + NULL +}; + + +/** + * @brief brainpoolP320r1 elliptic curve + **/ + +const EcCurveInfo brainpoolP320r1Curve = +{ + //Curve name + "brainpoolP320r1", + //Object identifier + BRAINPOOLP320R1_OID, + sizeof(BRAINPOOLP320R1_OID), + //Curve type + EC_CURVE_TYPE_BRAINPOOLP_R1, + //Prime modulus p + {0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C, 0x78, 0x5E, 0xD2, 0x01, 0xE0, 0x65, + 0xF9, 0x8F, 0xCF, 0xA6, 0xF6, 0xF4, 0x0D, 0xEF, 0x4F, 0x92, 0xB9, 0xEC, 0x78, 0x93, 0xEC, 0x28, + 0xFC, 0xD4, 0x12, 0xB1, 0xF1, 0xB3, 0x2E, 0x27}, + 40, + //Curve parameter a + {0x3E, 0xE3, 0x0B, 0x56, 0x8F, 0xBA, 0xB0, 0xF8, 0x83, 0xCC, 0xEB, 0xD4, 0x6D, 0x3F, 0x3B, 0xB8, + 0xA2, 0xA7, 0x35, 0x13, 0xF5, 0xEB, 0x79, 0xDA, 0x66, 0x19, 0x0E, 0xB0, 0x85, 0xFF, 0xA9, 0xF4, + 0x92, 0xF3, 0x75, 0xA9, 0x7D, 0x86, 0x0E, 0xB4}, + 40, + //Curve parameter b + {0x52, 0x08, 0x83, 0x94, 0x9D, 0xFD, 0xBC, 0x42, 0xD3, 0xAD, 0x19, 0x86, 0x40, 0x68, 0x8A, 0x6F, + 0xE1, 0x3F, 0x41, 0x34, 0x95, 0x54, 0xB4, 0x9A, 0xCC, 0x31, 0xDC, 0xCD, 0x88, 0x45, 0x39, 0x81, + 0x6F, 0x5E, 0xB4, 0xAC, 0x8F, 0xB1, 0xF1, 0xA6}, + 40, + //x-coordinate of the base point G + {0x43, 0xBD, 0x7E, 0x9A, 0xFB, 0x53, 0xD8, 0xB8, 0x52, 0x89, 0xBC, 0xC4, 0x8E, 0xE5, 0xBF, 0xE6, + 0xF2, 0x01, 0x37, 0xD1, 0x0A, 0x08, 0x7E, 0xB6, 0xE7, 0x87, 0x1E, 0x2A, 0x10, 0xA5, 0x99, 0xC7, + 0x10, 0xAF, 0x8D, 0x0D, 0x39, 0xE2, 0x06, 0x11}, + 40, + //y-coordinate of the base point G + {0x14, 0xFD, 0xD0, 0x55, 0x45, 0xEC, 0x1C, 0xC8, 0xAB, 0x40, 0x93, 0x24, 0x7F, 0x77, 0x27, 0x5E, + 0x07, 0x43, 0xFF, 0xED, 0x11, 0x71, 0x82, 0xEA, 0xA9, 0xC7, 0x78, 0x77, 0xAA, 0xAC, 0x6A, 0xC7, + 0xD3, 0x52, 0x45, 0xD1, 0x69, 0x2E, 0x8E, 0xE1}, + 40, + //Base point order q + {0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C, 0x78, 0x5E, 0xD2, 0x01, 0xE0, 0x65, + 0xF9, 0x8F, 0xCF, 0xA5, 0xB6, 0x8F, 0x12, 0xA3, 0x2D, 0x48, 0x2E, 0xC7, 0xEE, 0x86, 0x58, 0xE9, + 0x86, 0x91, 0x55, 0x5B, 0x44, 0xC5, 0x93, 0x11}, + 40, + //Cofactor + 1, + //Fast modular reduction + NULL +}; + + +/** + * @brief brainpoolP384r1 elliptic curve + **/ + +const EcCurveInfo brainpoolP384r1Curve = +{ + //Curve name + "brainpoolP384r1", + //Object identifier + BRAINPOOLP384R1_OID, + sizeof(BRAINPOOLP384R1_OID), + //Curve type + EC_CURVE_TYPE_BRAINPOOLP_R1, + //Prime modulus p + {0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D, 0x6F, 0x7E, 0x50, 0xE6, 0x41, 0xDF, + 0x15, 0x2F, 0x71, 0x09, 0xED, 0x54, 0x56, 0xB4, 0x12, 0xB1, 0xDA, 0x19, 0x7F, 0xB7, 0x11, 0x23, + 0xAC, 0xD3, 0xA7, 0x29, 0x90, 0x1D, 0x1A, 0x71, 0x87, 0x47, 0x00, 0x13, 0x31, 0x07, 0xEC, 0x53}, + 48, + //Curve parameter a + {0x7B, 0xC3, 0x82, 0xC6, 0x3D, 0x8C, 0x15, 0x0C, 0x3C, 0x72, 0x08, 0x0A, 0xCE, 0x05, 0xAF, 0xA0, + 0xC2, 0xBE, 0xA2, 0x8E, 0x4F, 0xB2, 0x27, 0x87, 0x13, 0x91, 0x65, 0xEF, 0xBA, 0x91, 0xF9, 0x0F, + 0x8A, 0xA5, 0x81, 0x4A, 0x50, 0x3A, 0xD4, 0xEB, 0x04, 0xA8, 0xC7, 0xDD, 0x22, 0xCE, 0x28, 0x26}, + 48, + //Curve parameter b + {0x04, 0xA8, 0xC7, 0xDD, 0x22, 0xCE, 0x28, 0x26, 0x8B, 0x39, 0xB5, 0x54, 0x16, 0xF0, 0x44, 0x7C, + 0x2F, 0xB7, 0x7D, 0xE1, 0x07, 0xDC, 0xD2, 0xA6, 0x2E, 0x88, 0x0E, 0xA5, 0x3E, 0xEB, 0x62, 0xD5, + 0x7C, 0xB4, 0x39, 0x02, 0x95, 0xDB, 0xC9, 0x94, 0x3A, 0xB7, 0x86, 0x96, 0xFA, 0x50, 0x4C, 0x11}, + 48, + //x-coordinate of the base point G + {0x1D, 0x1C, 0x64, 0xF0, 0x68, 0xCF, 0x45, 0xFF, 0xA2, 0xA6, 0x3A, 0x81, 0xB7, 0xC1, 0x3F, 0x6B, + 0x88, 0x47, 0xA3, 0xE7, 0x7E, 0xF1, 0x4F, 0xE3, 0xDB, 0x7F, 0xCA, 0xFE, 0x0C, 0xBD, 0x10, 0xE8, + 0xE8, 0x26, 0xE0, 0x34, 0x36, 0xD6, 0x46, 0xAA, 0xEF, 0x87, 0xB2, 0xE2, 0x47, 0xD4, 0xAF, 0x1E}, + 48, + //y-coordinate of the base point G + {0x8A, 0xBE, 0x1D, 0x75, 0x20, 0xF9, 0xC2, 0xA4, 0x5C, 0xB1, 0xEB, 0x8E, 0x95, 0xCF, 0xD5, 0x52, + 0x62, 0xB7, 0x0B, 0x29, 0xFE, 0xEC, 0x58, 0x64, 0xE1, 0x9C, 0x05, 0x4F, 0xF9, 0x91, 0x29, 0x28, + 0x0E, 0x46, 0x46, 0x21, 0x77, 0x91, 0x81, 0x11, 0x42, 0x82, 0x03, 0x41, 0x26, 0x3C, 0x53, 0x15}, + 48, + //Base point order q + {0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D, 0x6F, 0x7E, 0x50, 0xE6, 0x41, 0xDF, + 0x15, 0x2F, 0x71, 0x09, 0xED, 0x54, 0x56, 0xB3, 0x1F, 0x16, 0x6E, 0x6C, 0xAC, 0x04, 0x25, 0xA7, + 0xCF, 0x3A, 0xB6, 0xAF, 0x6B, 0x7F, 0xC3, 0x10, 0x3B, 0x88, 0x32, 0x02, 0xE9, 0x04, 0x65, 0x65}, + 48, + //Cofactor + 1, + //Fast modular reduction + NULL +}; + + +/** + * @brief brainpoolP512r1 elliptic curve + **/ + +const EcCurveInfo brainpoolP512r1Curve = +{ + //Curve name + "brainpoolP512r1", + //Object identifier + BRAINPOOLP512R1_OID, + sizeof(BRAINPOOLP512R1_OID), + //Curve type + EC_CURVE_TYPE_BRAINPOOLP_R1, + //Prime modulus p + {0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4, 0xE6, 0xAE, 0x33, 0xC9, 0xFC, 0x07, + 0xCB, 0x30, 0x8D, 0xB3, 0xB3, 0xC9, 0xD2, 0x0E, 0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33, 0x08, 0x71, + 0x7D, 0x4D, 0x9B, 0x00, 0x9B, 0xC6, 0x68, 0x42, 0xAE, 0xCD, 0xA1, 0x2A, 0xE6, 0xA3, 0x80, 0xE6, + 0x28, 0x81, 0xFF, 0x2F, 0x2D, 0x82, 0xC6, 0x85, 0x28, 0xAA, 0x60, 0x56, 0x58, 0x3A, 0x48, 0xF3}, + 64, + //Curve parameter a + {0x78, 0x30, 0xA3, 0x31, 0x8B, 0x60, 0x3B, 0x89, 0xE2, 0x32, 0x71, 0x45, 0xAC, 0x23, 0x4C, 0xC5, + 0x94, 0xCB, 0xDD, 0x8D, 0x3D, 0xF9, 0x16, 0x10, 0xA8, 0x34, 0x41, 0xCA, 0xEA, 0x98, 0x63, 0xBC, + 0x2D, 0xED, 0x5D, 0x5A, 0xA8, 0x25, 0x3A, 0xA1, 0x0A, 0x2E, 0xF1, 0xC9, 0x8B, 0x9A, 0xC8, 0xB5, + 0x7F, 0x11, 0x17, 0xA7, 0x2B, 0xF2, 0xC7, 0xB9, 0xE7, 0xC1, 0xAC, 0x4D, 0x77, 0xFC, 0x94, 0xCA}, + 64, + //Curve parameter b + {0x3D, 0xF9, 0x16, 0x10, 0xA8, 0x34, 0x41, 0xCA, 0xEA, 0x98, 0x63, 0xBC, 0x2D, 0xED, 0x5D, 0x5A, + 0xA8, 0x25, 0x3A, 0xA1, 0x0A, 0x2E, 0xF1, 0xC9, 0x8B, 0x9A, 0xC8, 0xB5, 0x7F, 0x11, 0x17, 0xA7, + 0x2B, 0xF2, 0xC7, 0xB9, 0xE7, 0xC1, 0xAC, 0x4D, 0x77, 0xFC, 0x94, 0xCA, 0xDC, 0x08, 0x3E, 0x67, + 0x98, 0x40, 0x50, 0xB7, 0x5E, 0xBA, 0xE5, 0xDD, 0x28, 0x09, 0xBD, 0x63, 0x80, 0x16, 0xF7, 0x23}, + 64, + //x-coordinate of the base point G + {0x81, 0xAE, 0xE4, 0xBD, 0xD8, 0x2E, 0xD9, 0x64, 0x5A, 0x21, 0x32, 0x2E, 0x9C, 0x4C, 0x6A, 0x93, + 0x85, 0xED, 0x9F, 0x70, 0xB5, 0xD9, 0x16, 0xC1, 0xB4, 0x3B, 0x62, 0xEE, 0xF4, 0xD0, 0x09, 0x8E, + 0xFF, 0x3B, 0x1F, 0x78, 0xE2, 0xD0, 0xD4, 0x8D, 0x50, 0xD1, 0x68, 0x7B, 0x93, 0xB9, 0x7D, 0x5F, + 0x7C, 0x6D, 0x50, 0x47, 0x40, 0x6A, 0x5E, 0x68, 0x8B, 0x35, 0x22, 0x09, 0xBC, 0xB9, 0xF8, 0x22}, + 64, + //y-coordinate of the base point G + {0x7D, 0xDE, 0x38, 0x5D, 0x56, 0x63, 0x32, 0xEC, 0xC0, 0xEA, 0xBF, 0xA9, 0xCF, 0x78, 0x22, 0xFD, + 0xF2, 0x09, 0xF7, 0x00, 0x24, 0xA5, 0x7B, 0x1A, 0xA0, 0x00, 0xC5, 0x5B, 0x88, 0x1F, 0x81, 0x11, + 0xB2, 0xDC, 0xDE, 0x49, 0x4A, 0x5F, 0x48, 0x5E, 0x5B, 0xCA, 0x4B, 0xD8, 0x8A, 0x27, 0x63, 0xAE, + 0xD1, 0xCA, 0x2B, 0x2F, 0xA8, 0xF0, 0x54, 0x06, 0x78, 0xCD, 0x1E, 0x0F, 0x3A, 0xD8, 0x08, 0x92}, + 64, + //Base point order q + {0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4, 0xE6, 0xAE, 0x33, 0xC9, 0xFC, 0x07, + 0xCB, 0x30, 0x8D, 0xB3, 0xB3, 0xC9, 0xD2, 0x0E, 0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33, 0x08, 0x70, + 0x55, 0x3E, 0x5C, 0x41, 0x4C, 0xA9, 0x26, 0x19, 0x41, 0x86, 0x61, 0x19, 0x7F, 0xAC, 0x10, 0x47, + 0x1D, 0xB1, 0xD3, 0x81, 0x08, 0x5D, 0xDA, 0xDD, 0xB5, 0x87, 0x96, 0x82, 0x9C, 0xA9, 0x00, 0x69}, + 64, + //Cofactor + 1, + //Fast modular reduction + NULL +}; + + +/** + * @brief Fast modular reduction (secp128r1 curve) + * @param[in,out] a This function accept an integer less than p^2 as + * input and return (a mod p) as output + * @param[in] p Prime modulus + **/ + +error_t secp128r1Mod(Mpi *a, const Mpi *p) +{ + error_t error; + Mpi t; + + //Initialize multiple precision integers + mpiInit(&t); + + //Ajust the size of the integers + MPI_CHECK(mpiGrow(a, 32 / MPI_INT_SIZE)); + MPI_CHECK(mpiGrow(&t, 32 / MPI_INT_SIZE)); + + //Perform modular reduction + do + { + //Compute T = 0 | 0 | 0 | 0 | A7 | A6 | A5 | A4 + COPY_WORD32(&t, 0, a, 4, 4); + CLEAR_WORD32(&t, 4, 4); + + //Clear A7 | A6 | A5 | A4 + CLEAR_WORD32(a, 4, 4); + + //Compute A = A + T + (T << 97) + MPI_CHECK(mpiAdd(a, a, &t)); + MPI_CHECK(mpiShiftLeft(&t, 97)); + MPI_CHECK(mpiAdd(a, a, &t)); + + //Check for end condition + } while(mpiComp(a, p) > 0); + +end: + //Release multiple precision integers + mpiFree(&t); + + //Return status code + return error; +} + + +/** + * @brief Fast modular reduction (secp128r2 curve) + * @param[in,out] a This function accept an integer less than p^2 as + * input and return (a mod p) as output + * @param[in] p Prime modulus + **/ + +error_t secp128r2Mod(Mpi *a, const Mpi *p) +{ + error_t error; + Mpi t; + + //Initialize multiple precision integers + mpiInit(&t); + + //Ajust the size of the integers + MPI_CHECK(mpiGrow(a, 32 / MPI_INT_SIZE)); + MPI_CHECK(mpiGrow(&t, 32 / MPI_INT_SIZE)); + + //Perform modular reduction + do + { + //Compute T = 0 | 0 | 0 | 0 | A7 | A6 | A5 | A4 + COPY_WORD32(&t, 0, a, 4, 4); + CLEAR_WORD32(&t, 4, 4); + + //Clear A7 | A6 | A5 | A4 + CLEAR_WORD32(a, 4, 4); + + //Compute A = A + T + (T << 97) + MPI_CHECK(mpiAdd(a, a, &t)); + MPI_CHECK(mpiShiftLeft(&t, 97)); + MPI_CHECK(mpiAdd(a, a, &t)); + + //Check for end condition + } while(mpiComp(a, p) > 0); + +end: + //Release multiple precision integers + mpiFree(&t); + + //Return status code + return error; +} + + +/** + * @brief Fast modular reduction (secp160k1 curve) + * @param[in,out] a This function accept an integer less than p^2 as + * input and return (a mod p) as output + * @param[in] p Prime modulus + **/ + +error_t secp160k1Mod(Mpi *a, const Mpi *p) +{ + error_t error; + Mpi t; + + //Initialize multiple precision integers + mpiInit(&t); + + //Ajust the size of the integers + MPI_CHECK(mpiGrow(a, 40 / MPI_INT_SIZE)); + MPI_CHECK(mpiGrow(&t, 24 / MPI_INT_SIZE)); + + //Perform modular reduction + do + { + //Compute T = A9 | A8 | A7 | A6 | A5 | 0 + CLEAR_WORD32(&t, 0, 1); + COPY_WORD32(&t, 1, a, 5, 5); + + //Clear A9 | A8 | A7 | A6 | A5 + CLEAR_WORD32(a, 5, 5); + + //Compute A = A + T + MPI_CHECK(mpiAdd(a, a, &t)); + //Compute T = T >> 32 + MPI_CHECK(mpiShiftRight(&t, 32)); + //Compute A = A + (21389 * T) + MPI_CHECK(mpiMulInt(&t, &t, 21389)); + MPI_CHECK(mpiAdd(a, a, &t)); + + //Check for end condition + } while(mpiComp(a, p) > 0); + +end: + //Release multiple precision integers + mpiFree(&t); + + //Return status code + return error; +} + + +/** + * @brief Fast modular reduction (secp160r1 curve) + * @param[in,out] a This function accept an integer less than p^2 as + * input and return (a mod p) as output + * @param[in] p Prime modulus + **/ + +error_t secp160r1Mod(Mpi *a, const Mpi *p) +{ + error_t error; + Mpi t; + + //Initialize multiple precision integers + mpiInit(&t); + + //Ajust the size of the integers + MPI_CHECK(mpiGrow(a, 40 / MPI_INT_SIZE)); + MPI_CHECK(mpiGrow(&t, 24 / MPI_INT_SIZE)); + + //Perform modular reduction + do + { + //Compute T = 0 | A9 | A8 | A7 | A6 | A5 + COPY_WORD32(&t, 0, a, 5, 5); + CLEAR_WORD32(&t, 5, 1); + + //Clear A9 | A8 | A7 | A6 | A5 + CLEAR_WORD32(a, 5, 5); + + //Compute A = A + T + (T << 31) + MPI_CHECK(mpiAdd(a, a, &t)); + MPI_CHECK(mpiShiftLeft(&t, 31)); + MPI_CHECK(mpiAdd(a, a, &t)); + + //Check for end condition + } while(mpiComp(a, p) > 0); + +end: + //Release multiple precision integers + mpiFree(&t); + + //Return status code + return error; +} + + +/** + * @brief Fast modular reduction (secp160r2 curve) + * @param[in,out] a This function accept an integer less than p^2 as + * input and return (a mod p) as output + * @param[in] p Prime modulus + **/ + +error_t secp160r2Mod(Mpi *a, const Mpi *p) +{ + error_t error; + Mpi t; + + //Initialize multiple precision integers + mpiInit(&t); + + //Ajust the size of the integers + MPI_CHECK(mpiGrow(a, 40 / MPI_INT_SIZE)); + MPI_CHECK(mpiGrow(&t, 24 / MPI_INT_SIZE)); + + //Perform modular reduction + do + { + //Compute T = A9 | A8 | A7 | A6 | A5 | 0 + CLEAR_WORD32(&t, 0, 1); + COPY_WORD32(&t, 1, a, 5, 5); + + //Clear A9 | A8 | A7 | A6 | A5 + CLEAR_WORD32(a, 5, 5); + + //Compute A = A + T + MPI_CHECK(mpiAdd(a, a, &t)); + //Compute T = T >> 32 + MPI_CHECK(mpiShiftRight(&t, 32)); + //Compute A = A + (21389 * T) + MPI_CHECK(mpiMulInt(&t, &t, 21389)); + MPI_CHECK(mpiAdd(a, a, &t)); + + //Check for end condition + } while(mpiComp(a, p) > 0); + +end: + //Release multiple precision integers + mpiFree(&t); + + //Return status code + return error; +} + + +/** + * @brief Fast modular reduction (secp192k1 curve) + * @param[in,out] a This function accept an integer less than p^2 as + * input and return (a mod p) as output + * @param[in] p Prime modulus + **/ + +error_t secp192k1Mod(Mpi *a, const Mpi *p) +{ + error_t error; + Mpi t; + + //Initialize multiple precision integers + mpiInit(&t); + + //Ajust the size of the integers + MPI_CHECK(mpiGrow(a, 48 / MPI_INT_SIZE)); + MPI_CHECK(mpiGrow(&t, 28 / MPI_INT_SIZE)); + + //Perform modular reduction + do + { + //Compute T = A11 | A10 | A9 | A8 | A7 | A6 | 0 + CLEAR_WORD32(&t, 0, 1); + COPY_WORD32(&t, 1, a, 6, 6); + + //Clear A11 | A10 | A9 | A8 | A7 | A6 + CLEAR_WORD32(a, 6, 6); + + //Compute A = A + T + MPI_CHECK(mpiAdd(a, a, &t)); + //Compute T = T >> 32 + MPI_CHECK(mpiShiftRight(&t, 32)); + //Compute A = A + (4553 * T) + MPI_CHECK(mpiMulInt(&t, &t, 4553)); + MPI_CHECK(mpiAdd(a, a, &t)); + + //Check for end condition + } while(mpiComp(a, p) > 0); + +end: + //Release multiple precision integers + mpiFree(&t); + + //Return status code + return error; +} + + +/** + * @brief Fast modular reduction (secp192r1 curve) + * @param[in,out] a This function accept an integer less than p^2 as + * input and return (a mod p) as output + * @param[in] p Prime modulus + **/ + +error_t secp192r1Mod(Mpi *a, const Mpi *p) +{ + error_t error; + Mpi s; + Mpi t; + + //Initialize multiple precision integers + mpiInit(&s); + mpiInit(&t); + + //Ajust the size of the integers + MPI_CHECK(mpiGrow(a, 48 / MPI_INT_SIZE)); + MPI_CHECK(mpiGrow(&s, 24 / MPI_INT_SIZE)); + MPI_CHECK(mpiGrow(&t, 24 / MPI_INT_SIZE)); + + //Compute T = A5 | A4 | A3 | A2 | A1 | A0 + COPY_WORD32(&t, 0, a, 0, 6); + + //Compute S1 = 0 | 0 | A7 | A6 | A7 | A6 + COPY_WORD32(&s, 0, a, 6, 2); + COPY_WORD32(&s, 2, a, 6, 2); + CLEAR_WORD32(&s, 4, 2); + //Compute T = T + S1 + MPI_CHECK(mpiAdd(&t, &t, &s)); + + //Compute S2 = A9 | A8 | A9 | A8 | 0 | 0 + CLEAR_WORD32(&s, 0, 2); + COPY_WORD32(&s, 2, a, 8, 2); + COPY_WORD32(&s, 4, a, 8, 2); + //Compute T = T + S2 + MPI_CHECK(mpiAdd(&t, &t, &s)); + + //Compute S3 = A11 | A10 | A11 | A10 | A11 | A10 + COPY_WORD32(&s, 0, a, 10, 2); + COPY_WORD32(&s, 2, a, 10, 2); + COPY_WORD32(&s, 4, a, 10, 2); + //Compute T = T + S3 + MPI_CHECK(mpiAdd(&t, &t, &s)); + + //Compute (T + S1 + S2 + S3) mod p + while(mpiComp(&t, p) >= 0) + { + MPI_CHECK(mpiSub(&t, &t, p)); + } + + //Save result + MPI_CHECK(mpiCopy(a, &t)); + +end: + //Release multiple precision integers + mpiFree(&s); + mpiFree(&t); + + //Return status code + return error; +} + + +/** + * @brief Fast modular reduction (secp224k1 curve) + * @param[in,out] a This function accept an integer less than p^2 as + * input and return (a mod p) as output + * @param[in] p Prime modulus + **/ + +error_t secp224k1Mod(Mpi *a, const Mpi *p) +{ + error_t error; + Mpi t; + + //Initialize multiple precision integers + mpiInit(&t); + + //Ajust the size of the integers + MPI_CHECK(mpiGrow(a, 56 / MPI_INT_SIZE)); + MPI_CHECK(mpiGrow(&t, 32 / MPI_INT_SIZE)); + + //Perform modular reduction + do + { + //Compute T = A13 | A12 | A11 | A10 | A9 | A8 | A7 | 0 + CLEAR_WORD32(&t, 0, 1); + COPY_WORD32(&t, 1, a, 7, 7); + + //Clear A13 | A12 | A11 | A10 | A9 | A8 | A7 + CLEAR_WORD32(a, 7, 7); + + //Compute A = A + T + MPI_CHECK(mpiAdd(a, a, &t)); + //Compute T = T >> 32 + MPI_CHECK(mpiShiftRight(&t, 32)); + //Compute A = A + (6803 * T) + MPI_CHECK(mpiMulInt(&t, &t, 6803)); + MPI_CHECK(mpiAdd(a, a, &t)); + + //Check for end condition + } while(mpiComp(a, p) > 0); + +end: + //Release multiple precision integers + mpiFree(&t); + + //Return status code + return error; +} + + +/** + * @brief Fast modular reduction (secp224r1 curve) + * @param[in,out] a This function accept an integer less than p^2 as + * input and return (a mod p) as output + * @param[in] p Prime modulus + **/ + +error_t secp224r1Mod(Mpi *a, const Mpi *p) +{ + error_t error; + Mpi s; + Mpi t; + + //Initialize multiple precision integers + mpiInit(&s); + mpiInit(&t); + + //Ajust the size of the integers + MPI_CHECK(mpiGrow(a, 56 / MPI_INT_SIZE)); + MPI_CHECK(mpiGrow(&s, 28 / MPI_INT_SIZE)); + MPI_CHECK(mpiGrow(&t, 28 / MPI_INT_SIZE)); + + //Compute T = A6 | A5 | A4 | A3 | A2 | A1 | A0 + COPY_WORD32(&t, 0, a, 0, 7); + + //Compute S1 = A10 | A9 | A8 | A7 | 0 | 0 | 0 + CLEAR_WORD32(&s, 0, 3); + COPY_WORD32(&s, 3, a, 7, 4); + //Compute T = T + S1 + MPI_CHECK(mpiAdd(&t, &t, &s)); + + //Compute S2 = 0 | A13 | A12 | A11 | 0 | 0 | 0 + CLEAR_WORD32(&s, 0, 3); + COPY_WORD32(&s, 3, a, 11, 3); + CLEAR_WORD32(&s, 6, 1); + //Compute T = T + S2 + MPI_CHECK(mpiAdd(&t, &t, &s)); + + //Compute D1 = A13 | A12 | A11 | A10 | A9 | A8 | A7 + COPY_WORD32(&s, 0, a, 7, 7); + //Compute T = T - D1 + MPI_CHECK(mpiSub(&t, &t, &s)); + + //Compute D2 = 0 | 0 | 0 | 0 | A13 | A12 | A11 + COPY_WORD32(&s, 0, a, 11, 3); + CLEAR_WORD32(&s, 3, 4); + //Compute T = T - D2 + MPI_CHECK(mpiSub(&t, &t, &s)); + + //Compute (T + S1 + S2 - D1 - D2) mod p + while(mpiComp(&t, p) >= 0) + { + MPI_CHECK(mpiSub(&t, &t, p)); + } + + while(mpiCompInt(&t, 0) < 0) + { + MPI_CHECK(mpiAdd(&t, &t, p)); + } + + //Save result + MPI_CHECK(mpiCopy(a, &t)); + +end: + //Release multiple precision integers + mpiFree(&s); + mpiFree(&t); + + //Return status code + return error; +} + + +/** + * @brief Fast modular reduction (secp256k1 curve) + * @param[in,out] a This function accept an integer less than p^2 as + * input and return (a mod p) as output + * @param[in] p Prime modulus + **/ + +error_t secp256k1Mod(Mpi *a, const Mpi *p) +{ + error_t error; + Mpi t; + + //Initialize multiple precision integers + mpiInit(&t); + + //Ajust the size of the integers + MPI_CHECK(mpiGrow(a, 64 / MPI_INT_SIZE)); + MPI_CHECK(mpiGrow(&t, 36 / MPI_INT_SIZE)); + + //Perform modular reduction + do + { + //Compute T = A15 | A14 | A13 | A12 | A11 | A10 | A9 | A8 | 0 + CLEAR_WORD32(&t, 0, 1); + COPY_WORD32(&t, 1, a, 8, 8); + + //Clear A15 | A14 | A13 | A12 | A11 | A10 | A9 | A8 + CLEAR_WORD32(a, 8, 8); + + //Compute A = A + T + MPI_CHECK(mpiAdd(a, a, &t)); + //Compute T = T >> 32 + MPI_CHECK(mpiShiftRight(&t, 32)); + //Compute A = A + (977 * T) + MPI_CHECK(mpiMulInt(&t, &t, 977)); + MPI_CHECK(mpiAdd(a, a, &t)); + + //Check for end condition + } while(mpiComp(a, p) > 0); + +end: + //Release multiple precision integers + mpiFree(&t); + + //Return status code + return error; +} + + +/** + * @brief Fast modular reduction (secp256r1 curve) + * @param[in,out] a This function accept an integer less than p^2 as + * input and return (a mod p) as output + * @param[in] p Prime modulus + **/ + +error_t secp256r1Mod(Mpi *a, const Mpi *p) +{ + error_t error; + Mpi s; + Mpi t; + Mpi b; + + //Initialize multiple precision integers + mpiInit(&s); + mpiInit(&t); + mpiInit(&b); + + //Ajust the size of the integers + MPI_CHECK(mpiGrow(a, 64 / MPI_INT_SIZE)); + MPI_CHECK(mpiGrow(&s, 32 / MPI_INT_SIZE)); + MPI_CHECK(mpiGrow(&t, 32 / MPI_INT_SIZE)); + + //Compute T = A7 | A6 | A5 | A4 | A3 | A2 | A1 | A0 + COPY_WORD32(&t, 0, a, 0, 8); + + //Compute S1 = A15 | A14 | A13 | A12 | A11 | 0 | 0 | 0 + CLEAR_WORD32(&s, 0, 3); + COPY_WORD32(&s, 3, a, 11, 5); + //Compute T = T + 2 * S1 + MPI_CHECK(mpiAdd(&t, &t, &s)); + MPI_CHECK(mpiAdd(&t, &t, &s)); + + //Compute S2 = 0 | A15 | A14 | A13 | A12 | 0 | 0 | 0 + CLEAR_WORD32(&s, 0, 3); + COPY_WORD32(&s, 3, a, 12, 4); + CLEAR_WORD32(&s, 7, 1); + //Compute T = T + 2 * S2 + MPI_CHECK(mpiAdd(&t, &t, &s)); + MPI_CHECK(mpiAdd(&t, &t, &s)); + + //Compute S3 = A15 | A14 | 0 | 0 | 0 | A10 | A9 | A8 + COPY_WORD32(&s, 0, a, 8, 3); + CLEAR_WORD32(&s, 3, 3); + COPY_WORD32(&s, 6, a, 14, 2); + //Compute T = T + S3 + MPI_CHECK(mpiAdd(&t, &t, &s)); + + //Compute S4 = A8 | A13 | A15 | A14 | A13 | A11 | A10 | A9 + COPY_WORD32(&s, 0, a, 9, 3); + COPY_WORD32(&s, 3, a, 13, 3); + COPY_WORD32(&s, 6, a, 13, 1); + COPY_WORD32(&s, 7, a, 8, 1); + //Compute T = T + S4 + MPI_CHECK(mpiAdd(&t, &t, &s)); + + //Compute D1 = A10 | A8 | 0 | 0 | 0 | A13 | A12 | A11 + COPY_WORD32(&s, 0, a, 11, 3); + CLEAR_WORD32(&s, 3, 3); + COPY_WORD32(&s, 6, a, 8, 1); + COPY_WORD32(&s, 7, a, 10, 1); + //Compute T = T - D1 + MPI_CHECK(mpiSub(&t, &t, &s)); + + //Compute D2 = A11 | A9 | 0 | 0 | A15 | A14 | A13 | A12 + COPY_WORD32(&s, 0, a, 12, 4); + CLEAR_WORD32(&s, 4, 2); + COPY_WORD32(&s, 6, a, 9, 1); + COPY_WORD32(&s, 7, a, 11, 1); + //Compute T = T - D2 + MPI_CHECK(mpiSub(&t, &t, &s)); + + //Compute D3 = A12 | 0 | A10 | A9 | A8 | A15 | A14 | A13 + COPY_WORD32(&s, 0, a, 13, 3); + COPY_WORD32(&s, 3, a, 8, 3); + CLEAR_WORD32(&s, 6, 1); + COPY_WORD32(&s, 7, a, 12, 1); + //Compute T = T - D3 + MPI_CHECK(mpiSub(&t, &t, &s)); + + //Compute D4 = A13 | 0 | A11 | A10 | A9 | 0 | A15 | A14 + COPY_WORD32(&s, 0, a, 14, 2); + CLEAR_WORD32(&s, 2, 1); + COPY_WORD32(&s, 3, a, 9, 3); + CLEAR_WORD32(&s, 6, 1); + COPY_WORD32(&s, 7, a, 13, 1); + //Compute T = T - D4 + MPI_CHECK(mpiSub(&t, &t, &s)); + + //Compute (T + 2 * S1 + 2 * S2 + S3 + S4 - D1 - D2 - D3 - D4) mod p + while(mpiComp(&t, p) >= 0) + { + MPI_CHECK(mpiSub(&t, &t, p)); + } + + while(mpiCompInt(&t, 0) < 0) + { + MPI_CHECK(mpiAdd(&t, &t, p)); + } + + //Save result + MPI_CHECK(mpiCopy(a, &t)); + +end: + //Release multiple precision integers + mpiFree(&s); + mpiFree(&t); + + //Return status code + return error; +} + + +/** + * @brief Fast modular reduction (secp384r1 curve) + * @param[in,out] a This function accept an integer less than p^2 as + * input and return (a mod p) as output + * @param[in] p Prime modulus + **/ + +error_t secp384r1Mod(Mpi *a, const Mpi *p) +{ + error_t error; + Mpi s; + Mpi t; + + //Initialize multiple precision integers + mpiInit(&s); + mpiInit(&t); + + //Ajust the size of the integers + MPI_CHECK(mpiGrow(a, 96 / MPI_INT_SIZE)); + MPI_CHECK(mpiGrow(&s, 48 / MPI_INT_SIZE)); + MPI_CHECK(mpiGrow(&t, 48 / MPI_INT_SIZE)); + + //Compute T = A11 | A10 | A9 | A8 | A7 | A6 | A5 | A4 | A3 | A2 | A1 | A0 + COPY_WORD32(&t, 0, a, 0, 12); + + //Compute S1 = 0 | 0 | 0 | 0 | 0 | A23 | A22 | A21 | 0 | 0 | 0 | 0 + CLEAR_WORD32(&s, 0, 4); + COPY_WORD32(&s, 4, a, 21, 3); + CLEAR_WORD32(&s, 7, 5); + //Compute T = T + 2 * S1 + MPI_CHECK(mpiAdd(&t, &t, &s)); + MPI_CHECK(mpiAdd(&t, &t, &s)); + + //Compute S2 = A23 | A22 | A21 | A20 | A19 | A18 | A17 | A16 | A15 | A14 | A13 | A12 + COPY_WORD32(&s, 0, a, 12, 12); + //Compute T = T + S2 + MPI_CHECK(mpiAdd(&t, &t, &s)); + + //Compute S3 = A20 | A19 | A18 | A17 | A16 | A15 | A14 | A13 | A12 | A23| A22 | A21 + COPY_WORD32(&s, 0, a, 21, 3); + COPY_WORD32(&s, 3, a, 12, 9); + //Compute T = T + S3 + MPI_CHECK(mpiAdd(&t, &t, &s)); + + //Compute S4 = A19 | A18 | A17 | A16 | A15 | A14 | A13 | A12 | A20 | 0 | A23 | 0 + CLEAR_WORD32(&s, 0, 1); + COPY_WORD32(&s, 1, a, 23, 1); + CLEAR_WORD32(&s, 2, 1); + COPY_WORD32(&s, 3, a, 20, 1); + COPY_WORD32(&s, 4, a, 12, 8); + //Compute T = T + S4 + MPI_CHECK(mpiAdd(&t, &t, &s)); + + //Compute S5 = 0 | 0 | 0 | 0 | A23 | A22 | A21 | A20 | 0 | 0 | 0 | 0 + CLEAR_WORD32(&s, 0, 4); + COPY_WORD32(&s, 4, a, 20, 4); + CLEAR_WORD32(&s, 8, 4); + //Compute T = T + S5 + MPI_CHECK(mpiAdd(&t, &t, &s)); + + //Compute S6 = 0 | 0 | 0 | 0 | 0 | 0 | A23 | A22 | A21 | 0 | 0 | A20 + COPY_WORD32(&s, 0, a, 20, 1); + CLEAR_WORD32(&s, 1, 2); + COPY_WORD32(&s, 3, a, 21, 3); + CLEAR_WORD32(&s, 6, 6); + //Compute T = T + S6 + MPI_CHECK(mpiAdd(&t, &t, &s)); + + //Compute D1 = A22 | A21 | A20 | A19 | A18 | A17 | A16 | A15 | A14 | A13 | A12 | A23 + COPY_WORD32(&s, 0, a, 23, 1); + COPY_WORD32(&s, 1, a, 12, 11); + //Compute T = T - D1 + MPI_CHECK(mpiSub(&t, &t, &s)); + + //Compute D2 = 0 | 0 | 0 | 0 | 0 | 0 | 0 | A23 | A22 | A21 | A20 | 0 + CLEAR_WORD32(&s, 0, 1); + COPY_WORD32(&s, 1, a, 20, 4); + CLEAR_WORD32(&s, 5, 7); + //Compute T = T - D2 + MPI_CHECK(mpiSub(&t, &t, &s)); + + //Compute D3 = 0 | 0 | 0 | 0 | 0 | 0 | 0 | A23 | A23 | 0 | 0 | 0 + CLEAR_WORD32(&s, 0, 3); + COPY_WORD32(&s, 3, a, 23, 1); + COPY_WORD32(&s, 4, a, 23, 1); + CLEAR_WORD32(&s, 5, 7); + //Compute T = T - D3 + MPI_CHECK(mpiSub(&t, &t, &s)); + + //Compute (T + 2 * S1 + S2 + S3 + S4 + S5 + S6 - D1 - D2 - D3) mod p + while(mpiComp(&t, p) >= 0) + { + MPI_CHECK(mpiSub(&t, &t, p)); + } + + while(mpiCompInt(&t, 0) < 0) + { + MPI_CHECK(mpiAdd(&t, &t, p)); + } + + //Save result + MPI_CHECK(mpiCopy(a, &t)); + +end: + //Release multiple precision integers + mpiFree(&s); + mpiFree(&t); + + //Return status code + return error; +} + + +/** + * @brief Fast modular reduction (secp521r1 curve) + * @param[in,out] a This function accept an integer less than p^2 as + * input and return (a mod p) as output + * @param[in] p Prime modulus + **/ + +error_t secp521r1Mod(Mpi *a, const Mpi *p) +{ + error_t error; + Mpi t; + + //Initialize multiple precision integer + mpiInit(&t); + + //Ajust the size of the integers + MPI_CHECK(mpiGrow(a, 132 / MPI_INT_SIZE)); + MPI_CHECK(mpiGrow(&t, 68 / MPI_INT_SIZE)); + + //Compute A0 + COPY_WORD32(&t, 0, a, 0, 17); + t.data[16] &= 0x000001FF; + + //Compute A1 + MPI_CHECK(mpiShiftRight(a, 521)); + + //Compute A0 + A1 + MPI_CHECK(mpiAdd(a, a, &t)); + + //Compute (A0 + A1) mod p + while(mpiComp(a, p) >= 0) + { + MPI_CHECK(mpiSub(a, a, p)); + } + +end: + //Release multiple precision integer + mpiFree(&t); + + //Return status code + return error; +} + + +/** + * @brief Get the elliptic curve that matches the specified OID + * @param[in] oid Object identifier + * @param[in] length OID length + * @return Elliptic curve domain parameters + **/ + +const EcCurveInfo *ecGetCurveInfo(const uint8_t *oid, size_t length) +{ + //secp112r1 elliptic curve? + if(!oidComp(oid, length, SECP112R1_OID, sizeof(SECP112R1_OID))) + return SECP112R1_CURVE; + //secp112r2 elliptic curve? + if(!oidComp(oid, length, SECP112R2_OID, sizeof(SECP112R2_OID))) + return SECP112R2_CURVE; + //secp128r1 elliptic curve? + if(!oidComp(oid, length, SECP128R1_OID, sizeof(SECP128R1_OID))) + return SECP128R1_CURVE; + //secp128r2 elliptic curve? + if(!oidComp(oid, length, SECP128R2_OID, sizeof(SECP128R2_OID))) + return SECP128R2_CURVE; + //secp160k1 elliptic curve? + if(!oidComp(oid, length, SECP160K1_OID, sizeof(SECP160K1_OID))) + return SECP160K1_CURVE; + //secp160r1 elliptic curve? + else if(!oidComp(oid, length, SECP160R1_OID, sizeof(SECP160R1_OID))) + return SECP160R1_CURVE; + //secp160r2 elliptic curve? + else if(!oidComp(oid, length, SECP160R2_OID, sizeof(SECP160R2_OID))) + return SECP160R2_CURVE; + //secp192k1 elliptic curve? + else if(!oidComp(oid, length, SECP192K1_OID, sizeof(SECP192K1_OID))) + return SECP192K1_CURVE; + //secp192r1 elliptic curve? + else if(!oidComp(oid, length, SECP192R1_OID, sizeof(SECP192R1_OID))) + return SECP192R1_CURVE; + //secp224k1 elliptic curve? + else if(!oidComp(oid, length, SECP224K1_OID, sizeof(SECP224K1_OID))) + return SECP224K1_CURVE; + //secp224r1 elliptic curve? + else if(!oidComp(oid, length, SECP224R1_OID, sizeof(SECP224R1_OID))) + return SECP224R1_CURVE; + //secp256k1 elliptic curve? + else if(!oidComp(oid, length, SECP256K1_OID, sizeof(SECP256K1_OID))) + return SECP256K1_CURVE; + //secp256r1 elliptic curve? + else if(!oidComp(oid, length, SECP256R1_OID, sizeof(SECP256R1_OID))) + return SECP256R1_CURVE; + //secp384r1 elliptic curve? + else if(!oidComp(oid, length, SECP384R1_OID, sizeof(SECP384R1_OID))) + return SECP384R1_CURVE; + //secp521r1 elliptic curve? + else if(!oidComp(oid, length, SECP521R1_OID, sizeof(SECP521R1_OID))) + return SECP521R1_CURVE; + //brainpoolP160r1 elliptic curve? + else if(!oidComp(oid, length, BRAINPOOLP160R1_OID, sizeof(BRAINPOOLP160R1_OID))) + return BRAINPOOLP160R1_CURVE; + //brainpoolP192r1 elliptic curve? + else if(!oidComp(oid, length, BRAINPOOLP192R1_OID, sizeof(BRAINPOOLP192R1_OID))) + return BRAINPOOLP192R1_CURVE; + //brainpoolP224r1 elliptic curve? + else if(!oidComp(oid, length, BRAINPOOLP224R1_OID, sizeof(BRAINPOOLP224R1_OID))) + return BRAINPOOLP224R1_CURVE; + //brainpoolP256r1 elliptic curve? + else if(!oidComp(oid, length, BRAINPOOLP256R1_OID, sizeof(BRAINPOOLP256R1_OID))) + return BRAINPOOLP256R1_CURVE; + //brainpoolP320r1 elliptic curve? + else if(!oidComp(oid, length, BRAINPOOLP320R1_OID, sizeof(BRAINPOOLP320R1_OID))) + return BRAINPOOLP320R1_CURVE; + //brainpoolP384r1 elliptic curve? + else if(!oidComp(oid, length, BRAINPOOLP384R1_OID, sizeof(BRAINPOOLP384R1_OID))) + return BRAINPOOLP384R1_CURVE; + //brainpoolP512r1 elliptic curve? + else if(!oidComp(oid, length, BRAINPOOLP512R1_OID, sizeof(BRAINPOOLP512R1_OID))) + return BRAINPOOLP512R1_CURVE; + //Unknown identifier? + else + return NULL; +} + +#endif +