Skip to content

Instantly share code, notes, and snippets.

@AhnMo
Created April 11, 2016 11:39
Show Gist options
  • Save AhnMo/0c9e3403a1cab9be0eb4d396cade0750 to your computer and use it in GitHub Desktop.
Save AhnMo/0c9e3403a1cab9be0eb4d396cade0750 to your computer and use it in GitHub Desktop.
elliptic curve cryptography with openssl library
// ECDH.c
// $ gcc -o ECDH -lcrypto -lssl ECDH.c
#include <stdio.h>
#include <stdlib.h>
#include <openssl/ec.h>
#include <openssl/ecdh.h>
#include <openssl/obj_mac.h>
typedef struct _KEYPAIR {
BIGNUM *x, *y;
BIGNUM *d;
EC_POINT *pub_key;
EC_KEY *key;
} KEYPAIR;
void generate_ec_key(KEYPAIR *current, EC_GROUP *ec_group) {
current->key = EC_KEY_new();
EC_KEY_set_group(current->key, ec_group);
EC_KEY_generate_key(current->key);
current->d = EC_KEY_get0_private_key(current->key);
printf("d: (%s)\n", BN_bn2hex(current->d));
current->pub_key = EC_KEY_get0_public_key(current->key);
current->x = BN_new();
current->y = BN_new();
if (EC_POINT_get_affine_coordinates_GFp(ec_group, current->pub_key, current->x, current->y, NULL)) {
printf("Q(x, y): (%s, %s)\n", BN_bn2hex(current->x), BN_bn2hex(current->y));
}
}
void generate_shared_key(KEYPAIR *user1, KEYPAIR *user2) {
unsigned char *secret;
int field_size;
size_t secret_len;
int i;
field_size = EC_GROUP_get_degree(EC_KEY_get0_group(user1->key));
secret_len = (field_size + 7) / 8;
secret = OPENSSL_malloc(secret_len);
secret_len = ECDH_compute_key(secret, secret_len, user2->pub_key, user1->key, NULL);
for (i = 0; i < secret_len; i++)
printf("%02X", secret[i]);
OPENSSL_free(secret);
puts("");
}
int main(int argc, char **argv) {
EC_GROUP *ec_group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
KEYPAIR *alice, *bob;
puts("ALICE PART:");
alice = (KEYPAIR *)malloc(sizeof(KEYPAIR));
generate_ec_key(alice, ec_group);
puts("");
puts("BOB PART:");
bob = (KEYPAIR *)malloc(sizeof(KEYPAIR));
generate_ec_key(bob, ec_group);
puts("");
puts("ALICE MAKE SHARED KEY: ");
generate_shared_key(alice, bob);
puts("");
puts("BOB MAKE SHARED KEY: ");
generate_shared_key(bob, alice);
puts("");
free(alice);
free(bob);
return 0;
}
// ECDSA.c
// $ gcc -o ECDSA -lcrypto -lssl ECDSA.c
#include <stdio.h>
#include <string.h>
#include <openssl/ec.h>
#include <openssl/ecdsa.h>
#include <openssl/obj_mac.h>
int create_signature(unsigned char* hash) {
int ret;
ECDSA_SIG *sig;
EC_KEY *eckey;
EC_GROUP *ec_group;
EC_POINT *pub_key = NULL;
BIGNUM *x, *y;
BIGNUM *d;
int hash_length = strlen((char *)hash);
eckey = EC_KEY_new();
ec_group = EC_GROUP_new_by_curve_name(NID_secp192k1);
if (eckey == NULL) {
// ERROR
}
EC_KEY_set_group(eckey, ec_group);
if (!EC_KEY_generate_key(eckey)) {
// ERROR
}
d = EC_KEY_get0_private_key(eckey);
printf("d: (%s)\n", BN_bn2hex(d));
pub_key = EC_KEY_get0_public_key(eckey);
x = BN_new();
y = BN_new();
if (EC_POINT_get_affine_coordinates_GFp(ec_group, pub_key, x, y, NULL)) {
printf("Q(x, y): (%s, %s)\n", BN_bn2hex(x), BN_bn2hex(y));
}
sig = ECDSA_do_sign(hash, hash_length, eckey);
if (sig == NULL) {
// ERROR
}
printf("(sig->r, sig->s): (%s, %s)\n", BN_bn2hex(sig->r), BN_bn2hex(sig->s));
ret = ECDSA_do_verify(hash, hash_length, sig, eckey);
if (ret == -1) {
// EROR
} else if(ret == 0) {
// Incorrect signature
} else {
// Signature ok
}
return ret;
}
int main(int argc, char **argv) {
unsigned char hash[] = "c7fbca202a95a570285e3d700eb04ca2";
int status = create_signature(hash);
printf("%d\n", status);
return 0;
}
@rezamahdi
Copy link

Very nice 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment