#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#include <openssl/e_os.h>
#include <openssl/opensslconf.h> /* for OPENSSL_NO_ECDH */
#include <openssl/crypto.h>
#include <openssl/bio.h>
#include <openssl/bn.h>
#include <openssl/objects.h>
#include <openssl/rand.h>
#include <openssl/sha.h>
#include <openssl/err.h>
#include <openssl/applink.c>
#include <io.h>
#define children 0
#define BUG 0
#ifdef OPENSSL_NO_ECDH
int main(int argc, char *argv[]) {
printf("No ECDH support\n");
return(0);
}
#endif
#include <openssl/ec.h>
#include <openssl/ecdh.h>
static const char rnd_seed[] = "21o4h32rfon4d3ornou53gnwqpegbnng";
static int test_ec_ElGamal(int nid, const char *text, BN_CTX *ctx, BIO
*out) {
//定义并初始化
EC_KEY *b=NULL;
EC_KEY *c=NULL;
BIGNUM *x_a=NULL, *y_a=NULL,
*x_b=NULL, *y_b=NULL;
BIGNUM *k=NULL,*order=NULL;
int ret=0;
const EC_GROUP *group;
EC_POINT *M = NULL, *P = NULL, *Pm=NULL,*R = NULL, *Q = NULL, *A = NULL, *B =
NULL, *tmp_point = NULL;
const EC_POINT *G = NULL;
/** Creates a new EC_KEY object using a named curve as underlying
* EC_GROUP object.
* \param nid NID of the named curve.
* \return EC_KEY object or NULL if an error occurred.
* \EC_KEY *EC_KEY_new_by_curve_name(int nid);
*/
b = EC_KEY_new_by_curve_name(nid);
c = EC_KEY_new_by_curve_name(nid);
if ( b == NULL||c==NULL)
goto err;
if ((x_a=BN_new()) == NULL) goto err;
if ((y_a=BN_new()) == NULL) goto err;
if ((x_b=BN_new()) == NULL) goto err;
if ((y_b=BN_new()) == NULL) goto err;
if((k=BN_new()) ==NULL) goto err;
if ((order = BN_new())==NULL) goto err;
BIO_puts(out, "\n\n\nTesting key generation with ");
BIO_puts(out, text);
BIO_puts(out, "\n");
/** Creates a new ec private (and optional a new public) key.
* \param key EC_KEY object
* \return 1 on success and 0 if an error occurred.
* \int EC_KEY_generate_key(EC_KEY *key)
*/
//生成密钥
if (!EC_KEY_generate_key(b)) goto err;
if (!EC_KEY_generate_key(c)) goto err; //c的公钥对应曲线的点充当明文
/** Returns the EC_GROUP object of a EC_KEY object
* \param key EC_KEY object
* \return the EC_GROUP object (possibly NULL).
* \const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key);
*/
group = EC_KEY_get0_group(b);
/** Creates a new EC_POINT object for the specified EC_GROUP
* \param group EC_GROUP the underlying EC_GROUP object
* \return newly created EC_POINT object or NULL if an error occurred
* \EC_POINT *EC_POINT_new(const EC_GROUP *group);
*/
P = EC_POINT_new(group);
Pm= EC_POINT_new(group);
Q = EC_POINT_new(group);
R = EC_POINT_new(group);
A = EC_POINT_new(group);
B = EC_POINT_new(group);
M = EC_POINT_new(group);
tmp_point = EC_POINT_new(group);
/** Copies EC_POINT object
* \param dst destination EC_POINT object
* \param src source EC_POINT object
* \return 1 on success and 0 if an error occured
* \int EC_POINT_copy(EC_POINT *dst, const EC_POINT *src);
*/
EC_POINT_copy(Pm,
/** Returns the public key of a EC_KEY object.
* \param key the EC_KEY object
* \return a EC_POINT object with the public key (possibly NULL)
* \const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key);
*/
EC_KEY_get0_public_key(c));
/** Gets the order of a EC_GROUP
* \param group EC_GROUP object
* \param order BIGNUM to which the order is copied
* \param ctx BN_CTX object (optional)
* \return 1 on success and 0 if an error occured
* \int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx);
*/
if (!EC_GROUP_get_order(group, order, ctx))
{
goto err;
}
/* get random k */
do
if (!BN_rand_range(k, order))
{
goto err;
}while (BN_is_zero(k));
/*output privatekey*/
BIO_printf(out, "\n\nPrivateKey: ");
BN_print(out,
/** Returns the private key of a EC_KEY object.
* \param key EC_KEY object
* \return a BIGNUM with the private key (possibly NULL).
* \const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key);
*/
EC_KEY_get0_private_key(b));
BIO_printf(out, "\n\n\n");
/*output publickey*/
/** Returns the field type of the EC_METHOD.
* \param meth EC_METHOD object
* \return NID of the underlying field type OID.
* \int EC_METHOD_get_field_type(const EC_METHOD *meth);
*
* Returns the EC_METHOD of the EC_GROUP object.
* \param group EC_GROUP object
* \return EC_METHOD used in this EC_GROUP object.
* \const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group);
*/
if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
{
/** Gets the affine coordinates of a EC_POINT over GFp
* \param group underlying EC_GROUP object
* \param p EC_POINT object
* \param x BIGNUM for the x-coordinate
* \param y BIGNUM for the y-coordinate
* \param ctx BN_CTX object (optional)
* \return 1 on success and 0 if an error occured
* \int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,const EC_POINT *p, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
*/
if (!EC_POINT_get_affine_coordinates_GFp(group, EC_KEY_get0_public_key(b), x_a, y_a, ctx))
goto err;
}
/** Gets the affine coordinates of a EC_POINT over GF2m
* \param group underlying EC_GROUP object
* \param p EC_POINT object
* \param x BIGNUM for the x-coordinate
* \param y BIGNUM for the y-coordinate
* \param ctx BN_CTX object (optional)
* \return 1 on success and 0 if an error occured
* \int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group,const EC_POINT *p, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
*/
else {
if (!EC_POINT_get_affine_coordinates_GF2m(group, EC_KEY_get0_public_key(b), x_a, y_a, ctx))
goto err;
}
BIO_printf(out, "PublicKey: ");
BN_print(out, x_a);
BIO_printf(out, " ,");
BN_print(out, y_a);
BIO_printf(out, "\n\n\n");
/** Returns the generator of a EC_GROUP object.
* \param group EC_GROUP object
* \return the currently used generator (possibly NULL).
* \const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group);
*/
G = EC_GROUP_get0_generator(group);
/*
* Encrypting message P because message must be in E
*/
/*
* R = k * G
*/
/** Computes r = generator * n + q * m
* \param group underlying EC_GROUP object
* \param r EC_POINT object for the result
* \param n BIGNUM with the multiplier for the group generator (optional)
* \param q EC_POINT object with the first factor of the second summand
* \param m BIGNUM with the second factor of the second summand
* \param ctx BN_CTX object (optional)
* \return 1 on success and 0 if an error occured
* \int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx);
*/
if (!EC_POINT_mul(group, R, k, NULL, NULL, ctx))
{
goto err;
}
/*
* B = k * public_key(b)
*/
EC_POINT_mul(group, B, NULL, EC_KEY_get0_public_key(b),k , ctx);
/*
* B = Pm + k * public_key(b)
*/
/** Computes the sum of two EC_POINT
* \param group underlying EC_GROUP object
* \param r EC_POINT object for the result (r = a + b)
* \param a EC_POINT object with the first summand
* \param b EC_POINT object with the second summand
* \param ctx BN_CTX object (optional)
* \return 1 on success and 0 if an error occured
* \int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_
评论1