47#if !defined(MBEDTLS_CONFIG_FILE)
50#include MBEDTLS_CONFIG_FILE
53#if defined(MBEDTLS_ECP_C)
61#if !defined(MBEDTLS_ECP_ALT)
64#define ECP_VALIDATE_RET( cond ) \
65 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA )
66#define ECP_VALIDATE( cond ) \
67 MBEDTLS_INTERNAL_VALIDATE( cond )
69#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
70 !defined(inline) && !defined(__cplusplus)
71#define inline __inline
74#define ECP_MPI_INIT(s, n, p) {s, (n), (mbedtls_mpi_uint *)(p)}
76#define ECP_MPI_INIT_ARRAY(x) \
77 ECP_MPI_INIT(1, sizeof(x) / sizeof(mbedtls_mpi_uint), x)
87#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
118#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
154#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
190#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
236#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
294#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
323#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
356#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
392#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
434#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
488#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
584 ecp_mpi_load( &grp->
P,
p, plen );
586 ecp_mpi_load( &grp->
A,
a, alen );
587 ecp_mpi_load( &grp->
B,
b, blen );
588 ecp_mpi_load( &grp->
N,
n, nlen );
590 ecp_mpi_load( &grp->
G.
X, gx, gxlen );
591 ecp_mpi_load( &grp->
G.
Y, gy, gylen );
592 ecp_mpi_set1( &grp->
G.
Z );
602#if defined(MBEDTLS_ECP_NIST_OPTIM)
604#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
607#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
610#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
613#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
616#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
620#define NIST_MODP( P ) grp->modp = ecp_mod_ ## P;
622#define NIST_MODP( P )
626#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
629#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
632#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
635#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
638#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
642#define LOAD_GROUP_A( G ) ecp_group_load( grp, \
643 G ## _p, sizeof( G ## _p ), \
644 G ## _a, sizeof( G ## _a ), \
645 G ## _b, sizeof( G ## _b ), \
646 G ## _gx, sizeof( G ## _gx ), \
647 G ## _gy, sizeof( G ## _gy ), \
648 G ## _n, sizeof( G ## _n ) )
650#define LOAD_GROUP( G ) ecp_group_load( grp, \
651 G ## _p, sizeof( G ## _p ), \
653 G ## _b, sizeof( G ## _b ), \
654 G ## _gx, sizeof( G ## _gx ), \
655 G ## _gy, sizeof( G ## _gy ), \
656 G ## _n, sizeof( G ## _n ) )
658#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
661static const unsigned char curve25519_part_of_n[] = {
662 0x14, 0xDE, 0xF9, 0xDE, 0xA2, 0xF7, 0x9C, 0xD6,
663 0x58, 0x12, 0x63, 0x1A, 0x5C, 0xF5, 0xD3, 0xED,
684 curve25519_part_of_n,
sizeof( curve25519_part_of_n ) ) );
704#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
707static const unsigned char curve448_part_of_n[] = {
708 0x83, 0x35, 0xDC, 0x16, 0x3B, 0xB1, 0x24,
709 0xB6, 0x51, 0x29, 0xC9, 0x6F, 0xDE, 0x93,
710 0x3D, 0x8D, 0x72, 0x3A, 0x70, 0xAA, 0xDC,
711 0x87, 0x3D, 0x6D, 0x54, 0xA7, 0xBB, 0x0D,
744 curve448_part_of_n,
sizeof( curve448_part_of_n ) ) );
764 ECP_VALIDATE_RET( grp !=
NULL );
771#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
774 return( LOAD_GROUP( secp192r1 ) );
777#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
780 return( LOAD_GROUP( secp224r1 ) );
783#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
786 return( LOAD_GROUP( secp256r1 ) );
789#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
792 return( LOAD_GROUP( secp384r1 ) );
795#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
798 return( LOAD_GROUP( secp521r1 ) );
801#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
803 grp->
modp = ecp_mod_p192k1;
804 return( LOAD_GROUP_A( secp192k1 ) );
807#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
809 grp->
modp = ecp_mod_p224k1;
810 return( LOAD_GROUP_A( secp224k1 ) );
813#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
815 grp->
modp = ecp_mod_p256k1;
816 return( LOAD_GROUP_A( secp256k1 ) );
819#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
821 return( LOAD_GROUP_A( brainpoolP256r1 ) );
824#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
826 return( LOAD_GROUP_A( brainpoolP384r1 ) );
829#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
831 return( LOAD_GROUP_A( brainpoolP512r1 ) );
834#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
836 grp->
modp = ecp_mod_p255;
837 return( ecp_use_curve25519( grp ) );
840#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
842 grp->
modp = ecp_mod_p448;
843 return( ecp_use_curve448( grp ) );
852#if defined(MBEDTLS_ECP_NIST_OPTIM)
863#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
896 *carry = ( *
dst < *carry );
900#define WIDTH 8 / sizeof( mbedtls_mpi_uint )
901#define A( i ) N->p + (i) * WIDTH
902#define ADD( i ) add64( p, A( i ), &c )
903#define NEXT p += WIDTH; carry64( p, &c )
904#define LAST p += WIDTH; *p = c; while( ++p < end ) *p = 0
921 ADD( 3 ); ADD( 5 );
NEXT;
922 ADD( 3 ); ADD( 4 ); ADD( 5 );
NEXT;
923 ADD( 4 ); ADD( 5 ); LAST;
936#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
937 defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
938 defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
955#define LOAD32 cur = A( i );
957#if defined(MBEDTLS_HAVE_INT32)
960#define A( j ) N->p[j]
961#define STORE32 N->p[i] = cur;
965#define MAX32 N->n * 2
966#define A( j ) (j) % 2 ? (uint32_t)( N->p[(j)/2] >> 32 ) : \
967 (uint32_t)( N->p[(j)/2] )
970 N->p[i/2] &= 0x00000000FFFFFFFF; \
971 N->p[i/2] |= ((mbedtls_mpi_uint) cur) << 32; \
973 N->p[i/2] &= 0xFFFFFFFF00000000; \
974 N->p[i/2] |= (mbedtls_mpi_uint) cur; \
994#define ADD( j ) add32( &cur, A( j ), &c );
995#define SUB( j ) sub32( &cur, A( j ), &c );
1003 signed char c = 0, cc; \
1005 size_t i = 0, bits = (b); \
1007 mbedtls_mpi_uint Cp[ (b) / 8 / sizeof( mbedtls_mpi_uint) + 1 ]; \
1010 C.n = (b) / 8 / sizeof( mbedtls_mpi_uint) + 1; \
1012 memset( Cp, 0, C.n * sizeof( mbedtls_mpi_uint ) ); \
1014 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, (b) * 2 / 8 / \
1015 sizeof( mbedtls_mpi_uint ) ) ); \
1019 STORE32; i++; LOAD32; \
1022 sub32( &cur, -cc, &c ); \
1024 add32( &cur, cc, &c ); \
1028 cur = c > 0 ? c : 0; STORE32; \
1029 cur = 0; while( ++i < MAX32 ) { STORE32; } \
1030 if( c < 0 ) MBEDTLS_MPI_CHK( fix_negative( N, c, &C, bits ) );
1041#if !defined(MBEDTLS_HAVE_INT64)
1059#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
1067 SUB( 7 ); SUB( 11 );
NEXT;
1068 SUB( 8 ); SUB( 12 );
NEXT;
1069 SUB( 9 ); SUB( 13 );
NEXT;
1070 SUB( 10 ); ADD( 7 ); ADD( 11 );
NEXT;
1071 SUB( 11 ); ADD( 8 ); ADD( 12 );
NEXT;
1072 SUB( 12 ); ADD( 9 ); ADD( 13 );
NEXT;
1073 SUB( 13 ); ADD( 10 ); LAST;
1080#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
1089 SUB( 11 ); SUB( 12 ); SUB( 13 ); SUB( 14 );
NEXT;
1091 ADD( 9 ); ADD( 10 );
1092 SUB( 12 ); SUB( 13 ); SUB( 14 ); SUB( 15 );
NEXT;
1094 ADD( 10 ); ADD( 11 );
1095 SUB( 13 ); SUB( 14 ); SUB( 15 );
NEXT;
1097 ADD( 11 ); ADD( 11 ); ADD( 12 ); ADD( 12 ); ADD( 13 );
1098 SUB( 15 ); SUB( 8 ); SUB( 9 );
NEXT;
1100 ADD( 12 ); ADD( 12 ); ADD( 13 ); ADD( 13 ); ADD( 14 );
1101 SUB( 9 ); SUB( 10 );
NEXT;
1103 ADD( 13 ); ADD( 13 ); ADD( 14 ); ADD( 14 ); ADD( 15 );
1104 SUB( 10 ); SUB( 11 );
NEXT;
1106 ADD( 14 ); ADD( 14 ); ADD( 15 ); ADD( 15 ); ADD( 14 ); ADD( 13 );
1107 SUB( 8 ); SUB( 9 );
NEXT;
1109 ADD( 15 ); ADD( 15 ); ADD( 15 ); ADD( 8 );
1110 SUB( 10 ); SUB( 11 ); SUB( 12 ); SUB( 13 ); LAST;
1117#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
1125 ADD( 12 ); ADD( 21 ); ADD( 20 );
1128 ADD( 13 ); ADD( 22 ); ADD( 23 );
1129 SUB( 12 ); SUB( 20 );
NEXT;
1131 ADD( 14 ); ADD( 23 );
1132 SUB( 13 ); SUB( 21 );
NEXT;
1134 ADD( 15 ); ADD( 12 ); ADD( 20 ); ADD( 21 );
1135 SUB( 14 ); SUB( 22 ); SUB( 23 );
NEXT;
1137 ADD( 21 ); ADD( 21 ); ADD( 16 ); ADD( 13 ); ADD( 12 ); ADD( 20 ); ADD( 22 );
1138 SUB( 15 ); SUB( 23 ); SUB( 23 );
NEXT;
1140 ADD( 22 ); ADD( 22 ); ADD( 17 ); ADD( 14 ); ADD( 13 ); ADD( 21 ); ADD( 23 );
1143 ADD( 23 ); ADD( 23 ); ADD( 18 ); ADD( 15 ); ADD( 14 ); ADD( 22 );
1146 ADD( 19 ); ADD( 16 ); ADD( 15 ); ADD( 23 );
1149 ADD( 20 ); ADD( 17 ); ADD( 16 );
1152 ADD( 21 ); ADD( 18 ); ADD( 17 );
1155 ADD( 22 ); ADD( 19 ); ADD( 18 );
1158 ADD( 23 ); ADD( 20 ); ADD( 19 );
1178#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
1185#define P521_WIDTH ( 521 / 8 / sizeof( mbedtls_mpi_uint ) + 1 )
1188#define P521_MASK 0x01FF
1204 if(
N->n < P521_WIDTH )
1209 M.n =
N->n - ( P521_WIDTH - 1 );
1210 if(
M.n > P521_WIDTH + 1 )
1211 M.n = P521_WIDTH + 1;
1217 N->p[P521_WIDTH - 1] &= P521_MASK;
1218 for(
i = P521_WIDTH;
i <
N->n;
i++ )
1234#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
1237#define P255_WIDTH ( 255 / 8 / sizeof( mbedtls_mpi_uint ) + 1 )
1250 if(
N->n < P255_WIDTH )
1255 M.n =
N->n - ( P255_WIDTH - 1 );
1256 if(
M.n > P255_WIDTH + 1 )
1266 for(
i = P255_WIDTH;
i <
N->n;
i++ )
1278#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
1281#define P448_WIDTH ( 448 / 8 / sizeof( mbedtls_mpi_uint ) )
1284#define DIV_ROUND_UP( X, Y ) ( ( ( X ) + ( Y ) - 1 ) / ( Y ) )
1285#define P224_WIDTH_MIN ( 28 / sizeof( mbedtls_mpi_uint ) )
1286#define P224_WIDTH_MAX DIV_ROUND_UP( 28, sizeof( mbedtls_mpi_uint ) )
1287#define P224_UNUSED_BITS ( ( P224_WIDTH_MAX * sizeof( mbedtls_mpi_uint ) * 8 ) - 224 )
1307 if(
N->n <= P448_WIDTH )
1312 M.n =
N->n - ( P448_WIDTH );
1313 if(
M.n > P448_WIDTH )
1321 for(
i = P448_WIDTH;
i <
N->n;
i++ )
1337 for(
i = P224_WIDTH_MAX;
i <
M.n; ++
i )
1340 M.n = P448_WIDTH + 1;
1349#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
1350 defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
1351 defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
1359#define P_KOBLITZ_MAX ( 256 / 8 / sizeof( mbedtls_mpi_uint ) )
1360#define P_KOBLITZ_R ( 8 / sizeof( mbedtls_mpi_uint ) )
1369 if(
N->n < p_limbs )
1382 M.n =
N->n - ( p_limbs - adjust );
1383 if(
M.n > p_limbs + adjust )
1384 M.n = p_limbs + adjust;
1393 N->p[p_limbs - 1] &=
mask;
1394 for(
i = p_limbs;
i <
N->n;
i++ )
1404 M.n =
N->n - ( p_limbs - adjust );
1405 if(
M.n > p_limbs + adjust )
1406 M.n = p_limbs + adjust;
1415 N->p[p_limbs - 1] &=
mask;
1416 for(
i = p_limbs;
i <
N->n;
i++ )
1430#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
1446#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
1457#if defined(MBEDTLS_HAVE_INT64)
1458 return( ecp_mod_koblitz(
N, Rp, 4, 1, 32, 0xFFFFFFFF ) );
1467#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
int mbedtls_mpi_sub_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)
Perform a signed subtraction of MPIs: X = A - B.
int mbedtls_mpi_sub_int(mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b)
Perform a signed subtraction of an MPI and an integer: X = A - b.
int mbedtls_mpi_grow(mbedtls_mpi *X, size_t nblimbs)
Enlarge an MPI to the specified number of limbs.
int mbedtls_mpi_set_bit(mbedtls_mpi *X, size_t pos, unsigned char val)
Modify a specific bit in an MPI.
int mbedtls_mpi_add_abs(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)
Perform an unsigned addition of MPIs: X = |A| + |B|.
int mbedtls_mpi_add_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)
Perform a signed addition of MPIs: X = A + B.
int mbedtls_mpi_lset(mbedtls_mpi *X, mbedtls_mpi_sint z)
Store integer value in MPI.
size_t mbedtls_mpi_bitlen(const mbedtls_mpi *X)
Return the number of bits up to and including the most significant bit of value 1.
int mbedtls_mpi_read_binary(mbedtls_mpi *X, const unsigned char *buf, size_t buflen)
Import an MPI from unsigned big endian binary data.
int mbedtls_mpi_shift_l(mbedtls_mpi *X, size_t count)
Perform a left-shift on an MPI: X <<= count.
void mbedtls_mpi_init(mbedtls_mpi *X)
Initialize an MPI context.
int mbedtls_mpi_mul_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)
Perform a multiplication of two MPIs: X = A * B.
#define MBEDTLS_MPI_CHK(f)
void mbedtls_mpi_free(mbedtls_mpi *X)
This function frees the components of an MPI context.
int mbedtls_mpi_mul_int(mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b)
Perform a multiplication of an MPI with an unsigned integer: X = A * b.
int mbedtls_mpi_sub_abs(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)
Perform an unsigned subtraction of MPIs: X = |A| - |B|.
uint32_t mbedtls_mpi_uint
int mbedtls_mpi_shift_r(mbedtls_mpi *X, size_t count)
Perform a right-shift on an MPI: X >>= count.
Multi-precision integer library.
#define MBEDTLS_BYTES_TO_T_UINT_4(a, b, c, d)
#define MBEDTLS_BYTES_TO_T_UINT_2(a, b)
#define MBEDTLS_BYTES_TO_T_UINT_8(a, b, c, d, e, f, g, h)
static void cleanup(void)
GLboolean GLboolean GLboolean b
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * bits
GLboolean GLboolean GLboolean GLboolean a
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
#define memcpy(s1, s2, n)
Configuration options (set of defines)
This file provides an API for Elliptic Curves over GF(P) (ECP).
int mbedtls_ecp_group_load(mbedtls_ecp_group *grp, mbedtls_ecp_group_id id)
This function sets up an ECP group context from a standardized set of domain parameters.
void mbedtls_ecp_group_free(mbedtls_ecp_group *grp)
This function frees the components of an ECP group.
#define MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE
#define MBEDTLS_ERR_ECP_BAD_INPUT_DATA
@ MBEDTLS_ECP_DP_SECP192K1
@ MBEDTLS_ECP_DP_SECP384R1
@ MBEDTLS_ECP_DP_CURVE448
@ MBEDTLS_ECP_DP_CURVE25519
@ MBEDTLS_ECP_DP_SECP256K1
@ MBEDTLS_ECP_DP_SECP224R1
@ MBEDTLS_ECP_DP_SECP521R1
@ MBEDTLS_ECP_DP_SECP224K1
@ MBEDTLS_ECP_DP_SECP192R1
@ MBEDTLS_ECP_DP_SECP256R1
int(* modp)(mbedtls_mpi *)