Question

(Just abit of context:) I'm a novice to Cryptography, but for a school project I wanted to create a proof of concept 64-bit ECC curve. (Yes I do know 64-bit keys are not very secure!) However afaik there is no SEC standard parameters for 64-bit, only 160-512bit.

So I had to go about generating my own parameters, which is the bit i'm (quite) unsure on. I followed a quick guide, and came out with these parameters for my curve:

p = 10997031918897188677

a = 3628449283386729367

b = 4889270915382004880

x = 3124469192170877657

y = 4370601445727723733

n = 10997031916045924769 (order)

h = 1 (co-factor)

Could someone give me some advice as to if this curve will generate valid private/public key pairs? How could I check this?

Any help (/confirmation) would be greatly appreicated, thanks!

Was it helpful?

Solution

You can use OpenSSL's EC_GROUP_check() function to make sure it's a valid group. In the following program I did two things:

  • Generate an EC_GROUP with the provided parameters, and check if it's valid
  • Generate an EC_KEY using the generated EC_group, and check if it's valid

Note that it is the EC group you want to check if it can be used to generate valid EC keys, not EC curve.

Please read the comments for details:)

// gcc 22270485.c -lcrypto -o 22270485
#include <openssl/ec.h>
#include <stdio.h>

int main(){
    BN_CTX *ctx = NULL;
    BIGNUM *p, *a, *b, *x, *y, *order;
    EC_GROUP *group;
    EC_POINT *G;
    int ok = 1;

    ctx = BN_CTX_new();
    p = BN_new();
    a = BN_new();
    b = BN_new();
    x = BN_new();
    y = BN_new();
    order = BN_new();

    /* Set EC_GROUP */
    group = EC_GROUP_new(EC_GFp_mont_method());
    BN_dec2bn(&p, "10997031918897188677");
    BN_dec2bn(&a, "3628449283386729367");
    BN_dec2bn(&b, "4889270915382004880");
    EC_GROUP_set_curve_GFp(group, p, a, b, ctx);

    /* Set generator G=(x,y) and its cofactor */
    G = EC_POINT_new(group);
    BN_dec2bn(&x, "3124469192170877657");
    BN_dec2bn(&y, "4370601445727723733");
    BN_dec2bn(&order, "10997031916045924769");
    EC_POINT_set_affine_coordinates_GFp(group,G,x,y,ctx);
    EC_GROUP_set_generator(group,G,order,BN_value_one());

    /* Checks whether the parameter in the EC_GROUP define a valid ec group */
    if(!EC_GROUP_check(group,ctx)) {
        fprintf(stdout, "EC_GROUP_check() failed\n");
        ok = 0;
    }

    if (ok) {
        fprintf(stdout, "It is a valid EC group\n");
    }


    /* Generate a private/public key pair with above EC_GROUP */
    if (ok) {
        BIGNUM *private_key, *pub_x, *pub_y;
        EC_POINT *public_key;
        EC_KEY *eckey;

        pub_x = BN_new(); pub_y = BN_new();
        eckey = EC_KEY_new();

        /* create key on group */
        EC_KEY_set_group(eckey,group);
        EC_KEY_generate_key(eckey);

        /* Verifies that a private and/or public key is valid */
        if (!EC_KEY_check_key(eckey)) {
            fprintf(stdout, "EC_KEY_check_key() failed\n");
            ok = 0;
        }

        if (ok) {
            fprintf(stdout, "It is a valid EC key, where\n");

            private_key = EC_KEY_get0_private_key(eckey);
            fprintf(stdout, "\tprivate key = %s",BN_bn2dec(private_key));

            public_key = EC_KEY_get0_public_key(eckey);
            EC_POINT_get_affine_coordinates_GFp(group,public_key,pub_x,pub_y,ctx);
            fprintf(stdout, "\n\tpublic key = ( %s , %s )\n",
                BN_bn2dec(pub_x),BN_bn2dec(pub_y));
        }

        BN_free(pub_x); BN_free(pub_y);
        EC_KEY_free(eckey);
    }


    if (ctx)
        BN_CTX_free(ctx);
    BN_free(p); BN_free(a); BN_free(b);
    EC_GROUP_free(group);
    EC_POINT_free(G);
    BN_free(x); BN_free(y); BN_free(order);

    return 0;
}

Compile and run with this command:

$ gcc 22270485.c -lcrypto -o 22270485
$ ./22270485

The stdout should print

It is a valid EC group
It is a valid EC key, where
private key = 1524190197747279622
public key = ( 3228020167903858345 , 9344375093791763077 )

The private/public key pair will change every time, since EC_KEY_generate_key(eckey) randomly chooses a private key and compute the corresponding public key for every run.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top