Skip to content

Instantly share code, notes, and snippets.

@Silur
Last active July 13, 2018 11:19
Show Gist options
  • Save Silur/c70f4633cc7fd033780cb6bbeb9131c5 to your computer and use it in GitHub Desktop.
Save Silur/c70f4633cc7fd033780cb6bbeb9131c5 to your computer and use it in GitHub Desktop.
cli curve25519 keygen
// gcc -o keygen keygen.c -lcrypto
#include <stdio.h>
#include <string.h>
#include <openssl/ec.h>
#include <openssl/err.h>
unsigned long
main(int argc, char **argv)
{
if (argc < 2)
{
fprintf(stderr, "usage: %s \n", argv[0]);
return 1;
}
BIGNUM *a = BN_new();
BIGNUM *b = BN_new();
BIGNUM *p = BN_new();
BIGNUM *gx = BN_new();
BIGNUM *gy = BN_new();
BIGNUM *order = BN_new();
BIGNUM *cofactor = BN_new();
EC_GROUP *ed25519 = EC_GROUP_new(EC_GFp_simple_method());
if(!ed25519) goto ed_err;
EC_POINT *g = EC_POINT_new(ed25519);
if(!g) goto g_err;
BN_hex2bn(&p, "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed");
BN_hex2bn(&a, "2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa984914a144");
BN_hex2bn(&b, "7b425ed097b425ed097b425ed097b425ed097b425ed097b4260b5e9c7710c864");
BN_hex2bn(&gx, "2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaad245a");
BN_hex2bn(&gy, "20ae19a1b8a086b4e01edd2c7748d14c923d4d7e6d7c61b229e9c5a27eced3d9");
BN_hex2bn(&order, "1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed");
BN_set_word(cofactor, 8);
EC_GROUP_set_curve_GFp(ed25519, p, a, b, 0);
EC_POINT_set_affine_coordinates_GFp(ed25519, g, gx, gy, 0);
EC_GROUP_set_generator(ed25519, g, order, cofactor);
BIGNUM *privkey = BN_new(); if(!privkey) goto bn_op_err;
EC_POINT *pubkey = EC_POINT_new(ed25519);
if(!pubkey) goto pub_err;
if(!BN_rand_range(privkey, order)) goto rand_err;
if(!EC_POINT_mul(ed25519, pubkey, 0, g, privkey, 0));
FILE *fd = fopen(argv[1], "w");
unsigned char *privbuf = malloc(BN_num_bytes(privkey));
if(!privbuf || !fd) goto conv_err;
BN_bn2bin(privkey, privbuf);
if(fwrite(privbuf, BN_num_bytes(privkey), 1, fd) < 0) goto conv_err;
fclose(fd);
char *pubname = malloc(strlen(argv[1]) + 5); // .pub
if(!pubname) goto conv_err;
strcpy(pubname, argv[1]);
strcat(pubname, ".pub");
fd = fopen(pubname, "w");
unsigned char *pubbuf;
size_t pubsize = EC_POINT_point2buf(ed25519, pubkey, POINT_CONVERSION_UNCOMPRESSED, &pubbuf, 0);
if(fwrite(pubbuf, pubsize, 1, fd) < 0) goto conv_err;
fclose(fd);
conv_err:
free(privbuf);
OPENSSL_free(pubbuf);
rand_err:
EC_POINT_free(pubkey);
pub_err:
BN_free(privkey);
bn_op_err:
EC_POINT_free(g);
g_err:
EC_GROUP_free(ed25519);
ed_err:
BN_free(cofactor);
BN_free(a);
a_err:
BN_free(b);
BN_free(p);
BN_free(gx);
BN_free(gy);
BN_free(order);
return ERR_get_error();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment