blob: 172ffd8618c3e7a90ec64fa9de6fecf5c9ded35c [file] [log] [blame]
/*
* Copyright (C) 2012 Werner Dittmann
* All rights reserved. For licensing and other legal details, see the file legal.c.
*
* @author Werner Dittmann <Werner.Dittmann@t-online.de>
*
*/
#ifndef _EC_H_
#define _EC_H_
#include <bn.h>
/**
* @file ec.h
* @brief Elliptic curve functions for bnlib
* @defgroup BNLIB_EC Elliptic curve functions
* @{
*/
#ifdef __cplusplus
extern "C"
{
#endif
typedef struct BigNum BigNum;
typedef enum {
NIST192P = 1,
NIST224P = 2,
NIST256P = 3,
NIST384P = 4,
NIST521P = 5,
Curve25519 = 10,
Curve3617 = 11
} Curves;
/**
* \brief This structure contains the x, y affine coordinates and the z value if we
* use projective coordinates during EC point arithmetic.
*/
typedef struct _EcPoint {
BigNum *x, *y, *z;
BigNum tx, ty, tz;
} EcPoint;
/**
* @brief This structure contains the value of EC curves over Prime Fields.
*
* The for NIST curves the field names correspond to the variable names defined in
* NIST FIPS 186-3, E.1.2. The <b>a</b> curve parameter is the constant -3 and is
* computed during initialization of the curve structure.
*
* For other curves, for example curve3917 we have less parameters to fill in, mostly
* the prime number, the base point, etc. Refer to the curve's initialization function
* about the use of the fileds.
*/
struct EcCurve;
struct EcCurve {
Curves id;
BigNum _p;
BigNum _n;
BigNum _SEED;
BigNum _c;
BigNum _a;
BigNum _b;
BigNum _Gx;
BigNum _Gy;
/* Pointers to the BigNum structures, for better readability mainly */
BigNum *p;
BigNum *n;
BigNum *SEED;
BigNum *c;
BigNum *a;
BigNum *b;
BigNum *Gx;
BigNum *Gy;
/* some scratch pad variables, the EC algorithms use them to
avoid to much memory allocation/deallocatio0n overhead */
BigNum _S1, _U1, _H, _R, _t0, _t1, _t2, _t3;
BigNum *S1, *U1, *H, *R, *t0, *t1, *t2, *t3;
int (*affineOp)(const struct EcCurve *curve, EcPoint *R, const EcPoint *P);
int (*doubleOp)(const struct EcCurve *curve, EcPoint *R, const EcPoint *P);
int (*addOp)(const struct EcCurve *curve, EcPoint *R, const EcPoint *P, const EcPoint *Q);
int (*modOp)(BigNum *, const BigNum *, const BigNum *);
int (*checkPubOp)(const struct EcCurve *curve, const EcPoint *pub);
int (*randomOp)(const struct EcCurve *curve, BigNum *d);
int (*mulScalar)(const struct EcCurve *curve, EcPoint *R, const EcPoint *P, const BigNum *scalar);
};
typedef struct EcCurve EcCurve;
typedef EcCurve NistECpCurve;
/**
* \brief Marco to initialize a EC point structure.
*
* \param P Address of the EC point structure
*/
#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);}
/**
* \brief Marco to free a EC point structure.
*
* \param P Address of the EC point structure
*/
#define FREE_EC_POINT(P) {EcPoint *e = P; bnEnd(e->x); bnEnd(e->y); bnEnd(e->z);}
/**
* \brief Marco to set a EC point structure to the curve's base point.
*
* \param C Address of the NistECpCurve structure.
*
* \param P Address of the EC point structure.
*/
#define SET_EC_BASE_POINT(C, P) {EcPoint *e = P; const EcCurve *c = C; bnCopy(e->x, c->Gx); bnCopy(e->y, c->Gy); bnSetQ(e->z, 1);}
/*
* EC point helper functions
*/
extern void ecInitPoint(EcPoint *P);
extern void ecFreePoint(EcPoint *P);
extern void ecSetBasePoint(EcCurve *C, EcPoint *P);
/**
* \brief Get NIST EC curve parameters.
*
* Before reusing a EC curve structure make sure to call ecFreeCurveNistECp
* to return memory.
*
* \param curveId Which curve to initialize
*
* \param curve Pointer to a EcCurve structure
*
* \return 0 if successful
*
* \note Call ecFreeCurveNistECp to return allocated memory.
*/
int ecGetCurveNistECp(Curves curveId, NistECpCurve *curve);
/**
* \brief Free EC curve parameters.
*
* \param curve Pointer to a EcCurve structure
*
* \note Curve parameters must be initialized calling ecGetCurveNistECp.
*/
void ecFreeCurveNistECp(EcCurve *curve);
/**
* \brief Double an EC point.
*
* This function uses affine coordinates to perform the computations. For
* further reference see RFC 6090 or the standard work <i>Guide to Elliptic
* Curve Cryptography</i>.
*
* \param curve Address of EC curve structure
* \param R Address of resulting EC point structure
* \param P Address of the EC point structure
*
* \return 0 if successful
*/
int ecDoublePoint(const EcCurve *curve, EcPoint *R, const EcPoint *P);
/**
* \brief Add two EC points.
*
* This function uses affine coordinates to perform the computations. For
* further reference see RFC 6090 or the standard work <i>Guide to Elliptic
* Curve Cryptography</i>.
*
* \param curve Address of EC curve structure
* \param R Address of resulting EC point structure
* \param P Address of the first EC point structure
* \param Q Address of the second EC point structure
*
* \return 0 if successful
*/
int ecAddPoint(const EcCurve *curve, EcPoint *R, const EcPoint *P, const EcPoint *Q);
/**
* \brief Mulitply an EC point with a scalar value.
*
* \param curve Address of EC curve structure
* \param R Address of resulting EC point structure
* \param P Address of the EC point structure
* \param scalar Address of the scalar multi-precision integer value
*
* \return 0 if successful
*/
int ecMulPointScalar(const EcCurve *curve, EcPoint *R, const EcPoint *P, const BigNum *scalar);
/**
* \brief Convert an EC point from Jacobian projective coordinates to normal affine x/y coordinates.
*
* \param curve Address of EC curve structure
* \param R Address of EC point structure that receives the x/y coordinates
* \param P Address of the EC point structure that contains the jacobian x/y/z coordinates.
*
* \return 0 if successful
*/
int ecGetAffine(const EcCurve *curve, EcPoint *R, const EcPoint *P);
/**
* @brief Generate a random number.
*
* The method generates a random number and checks if it matches the curve restricitions.
* Use this number as ECDH private key.
*
* @param curve the NIST curve to use.
*
* @param d receives the generated random number.
*/
int ecGenerateRandomNumber(const NistECpCurve *curve, BigNum *d);
/**
* @brief Check a public key.
*
* The method checks if a public key is valid. For NIST curves it uses the
* ECC Partial Validation, NIST SP800-56A section 5.6.2.6
*
* For other curves it computes the equation and compares the left hand and
* the right handresults. If they are equal the point is on the curve.
*
* @param curve the curve to use.
*
* @param pub the public key to check.
*
* @returns true (!0) if the check was ok, false (0) otherwise.
*
* @note The function uses some scratch pad variable of the NistECpCurve structure.
*/
int ecCheckPubKey(const EcCurve *curve, const EcPoint *pub);
int ecGetCurvesCurve(Curves curveId, EcCurve *curve);
void ecFreeCurvesCurve(EcCurve *curve);
/**
* This is a special function for DJB's curve 25519. Actually it's the scalar multiplication
* mypublic = basepoint * secret
*/
int curve25519_donna(unsigned char *mypublic, const unsigned char *secret, const unsigned char *basepoint);
/*
* Some additional functions that are not available in bnlib
*/
int bnAddMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *mod);
int bnAddQMod_ (struct BigNum *rslt, unsigned n1, struct BigNum *mod);
int bnSubMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *mod);
int bnSubQMod_ (struct BigNum *rslt, unsigned n1, struct BigNum *mod);
int bnMulMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *n2, struct BigNum *mod, const EcCurve *curve);
int bnMulQMod_ (struct BigNum *rslt, struct BigNum *n1, unsigned n2, struct BigNum *mod, const EcCurve *curve);
int bnSquareMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *mod, const EcCurve *curve);
#ifdef __cplusplus
}
#endif
/**
* @}
*/
#endif