blob: b1bb47c48f8d929f88ac459d6579313ddb7835a3 [file] [log] [blame]
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001/*
2 * Copyright (C) 2012 Werner Dittmann
3 * All rights reserved. For licensing and other legal details, see the file legal.c.
4 *
5 * @author Werner Dittmann <Werner.Dittmann@t-online.de>
6 *
7 */
8#ifndef _EC_H_
9#define _EC_H_
10
11#include <bn.h>
12
13/**
14 * @file ec.h
15 * @brief Elliptic curve functions for bnlib
16 * @defgroup BNLIB_EC Elliptic curve functions
17 * @{
18 */
19
20#ifdef __cplusplus
21extern "C"
22{
23#endif
24
25typedef struct BigNum BigNum;
26
27typedef enum {
28 NIST192P = 1,
29 NIST224P = 2,
30 NIST256P = 3,
31 NIST384P = 4,
Alexandre Lisionddd731e2014-01-31 11:50:08 -050032 NIST521P = 5
33} NistCurves;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050034
35/**
Alexandre Lisionddd731e2014-01-31 11:50:08 -050036 * @brief This structure contains the value of NIST EC curves over Prime Fields.
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050037 *
Alexandre Lisionddd731e2014-01-31 11:50:08 -050038 * The <b>a</b> curve parameter is the constant -3 and is computed during initialization
39 * of the curve structure.
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050040 *
Alexandre Lisionddd731e2014-01-31 11:50:08 -050041 * The field names correspond to the variable names defined in NIST FIPS 186-3, E.1.2
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050042 */
Alexandre Lisionddd731e2014-01-31 11:50:08 -050043typedef struct {
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050044 BigNum _p;
45 BigNum _n;
46 BigNum _SEED;
47 BigNum _c;
48 BigNum _a;
49 BigNum _b;
50 BigNum _Gx;
51 BigNum _Gy;
52 /* Pointers to the BigNum structures, for better readability mainly */
53 BigNum *p;
54 BigNum *n;
55 BigNum *SEED;
56 BigNum *c;
57 BigNum *a;
58 BigNum *b;
59 BigNum *Gx;
60 BigNum *Gy;
61 /* some scratch pad variables, the EC algorithms use them to
62 avoid to much memory allocation/deallocatio0n overhead */
63 BigNum _S1, _U1, _H, _R, _t0, _t1, _t2, _t3;
64 BigNum *S1, *U1, *H, *R, *t0, *t1, *t2, *t3;
Alexandre Lisionddd731e2014-01-31 11:50:08 -050065} NistECpCurve;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050066
Alexandre Lisionddd731e2014-01-31 11:50:08 -050067/**
68 * \brief This structure contains the x, y affine coordinates and the z value if we
69 * use projective coordinates during EC point arithmetic.
70 */
71typedef struct _EcPoint {
72 BigNum *x, *y, *z;
73 BigNum tx, ty, tz;
74} EcPoint;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050075
76/**
77 * \brief Marco to initialize a EC point structure.
78 *
79 * \param P Address of the EC point structure
80 */
81#define INIT_EC_POINT(P) {EcPoint *e = P; e->x = &e->tx; e->y = &e->ty; e->z = &e->tz; bnBegin(e->x); bnBegin(e->y); bnBegin(e->z);}
82
83/**
84 * \brief Marco to free a EC point structure.
85 *
86 * \param P Address of the EC point structure
87 */
88#define FREE_EC_POINT(P) {EcPoint *e = P; bnEnd(e->x); bnEnd(e->y); bnEnd(e->z);}
89
90/**
91 * \brief Marco to set a EC point structure to the curve's base point.
92 *
93 * \param C Address of the NistECpCurve structure.
94 *
95 * \param P Address of the EC point structure.
96 */
Alexandre Lisionddd731e2014-01-31 11:50:08 -050097#define SET_EC_BASE_POINT(C, P) {EcPoint *e = P; const NistECpCurve *c = C; bnCopy(e->x, c->Gx); bnCopy(e->y, c->Gy); bnSetQ(e->z, 1);}
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050098
99/**
100 * \brief Get NIST EC curve parameters.
101 *
102 * Before reusing a EC curve structure make sure to call ecFreeCurveNistECp
103 * to return memory.
104 *
105 * \param curveId Which curve to initialize
106 *
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500107 * \param curve Pointer to a NistECpCurve structure
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500108 *
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500109 * \return 0 if successful, or a POLARSSL_ERR_EC_XXX/ POLARSSL_ERR_MPI_XXX error code.
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500110 *
111 * \note Call ecFreeCurveNistECp to return allocated memory.
112 */
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500113int ecGetCurveNistECp(NistCurves curveId, NistECpCurve *curve);
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500114
115
116/**
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500117 * \brief Free NIST EC curve parameters.
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500118 *
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500119 * \param curve Pointer to a NistECpCurve structure
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500120 *
121 * \note Curve parameters must be initialized calling ecGetCurveNistECp.
122 */
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500123void ecFreeCurveNistECp(NistECpCurve *curve);
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500124
125/**
126 * \brief Double an EC point.
127 *
128 * This function uses affine coordinates to perform the computations. For
129 * further reference see RFC 6090 or the standard work <i>Guide to Elliptic
130 * Curve Cryptography</i>.
131 *
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500132 * \param curve Address of Nist EC curve structure
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500133 * \param R Address of resulting EC point structure
134 * \param P Address of the EC point structure
135 *
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500136 * \return 0 if successful, or a POLARSSL_ERR_EC_XXX / POLARSSL_ERR_MPI_XXX error code.
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500137 */
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500138int ecDoublePoint(const NistECpCurve *curve, EcPoint *R, const EcPoint *P);
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500139
140/**
141 * \brief Add two EC points.
142 *
143 * This function uses affine coordinates to perform the computations. For
144 * further reference see RFC 6090 or the standard work <i>Guide to Elliptic
145 * Curve Cryptography</i>.
146 *
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500147 * \param curve Address of Nist EC curve structure
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500148 * \param R Address of resulting EC point structure
149 * \param P Address of the first EC point structure
150 * \param Q Address of the second EC point structure
151 *
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500152 * \return 0 if successful, or a POLARSSL_ERR_EC_XXX / POLARSSL_ERR_MPI_XXX error code.
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500153 */
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500154int ecAddPoint(const NistECpCurve *curve, EcPoint *R, const EcPoint *P, const EcPoint *Q);
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500155
156/**
157 * \brief Mulitply an EC point with a scalar value.
158 *
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500159 * \param curve Address of Nist EC curve structure
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500160 * \param R Address of resulting EC point structure
161 * \param P Address of the EC point structure
162 * \param scalar Address of the scalar multi-precision integer value
163 *
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500164 * \return 0 if successful, or a POLARSSL_ERR_EC_XXX / POLARSSL_ERR_MPI_XXX error code.
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500165 */
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500166int ecMulPointScalar(const NistECpCurve *curve, EcPoint *R, const EcPoint *P, const BigNum *scalar);
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500167
168/**
169 * \brief Convert an EC point from Jacobian projective coordinates to normal affine x/y coordinates.
170 *
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500171 * \param curve Address of Nist EC curve structure
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500172 * \param R Address of EC point structure that receives the x/y coordinates
173 * \param P Address of the EC point structure that contains the jacobian x/y/z coordinates.
174 *
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500175 * \return 0 if successful, or a POLARSSL_ERR_EC_XXX / POLARSSL_ERR_MPI_XXX error code.
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500176 */
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500177int ecGetAffine(const NistECpCurve *curve, EcPoint *R, const EcPoint *P);
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500178
179/**
180 * @brief Generate a random number.
181 *
182 * The method generates a random number and checks if it matches the curve restricitions.
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500183 * Use this number to generate a ECDH public key.
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500184 *
185 * @param curve the NIST curve to use.
186 *
187 * @param d receives the generated random number.
188 */
189int ecGenerateRandomNumber(const NistECpCurve *curve, BigNum *d);
190
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500191/*
192 * Some additional functions that are not available in bnlib
193 */
194int bnAddMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *mod);
195
196int bnAddQMod_ (struct BigNum *rslt, unsigned n1, struct BigNum *mod);
197
198int bnSubMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *mod);
199
200int bnSubQMod_ (struct BigNum *rslt, unsigned n1, struct BigNum *mod);
201
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500202int bnMulMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *n2, struct BigNum *mod);
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500203
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500204int bnMulQMod_ (struct BigNum *rslt, struct BigNum *n1, unsigned n2, struct BigNum *mod);
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500205
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500206int bnSquareMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *mod);
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500207
208#ifdef __cplusplus
209}
210#endif
211
212/**
213 * @}
214 */
215
216#endif