Как лучше всего проверить правильность этих параметров эллиптической кривой?

(Немного контекста :) Я новичок в криптографии, но для школьного проекта я хотел создать экспериментальную 64-битную кривую ECC. (Да, я знаю, что 64-битные ключи не очень безопасны!) Однако, на самом деле, нет стандартных параметров SEC для 64-битных, только 160-512 бит.

Поэтому мне пришлось генерировать свои собственные параметры, в чем я (совершенно) не уверен. Я следовал краткому руководству и получил следующие параметры для моей кривой:

p = 10997031918897188677

a = 3628449283386729367

b = 4889270915382004880

x = 3124469192170877657

y = 4370601445727723733

п = 10997031916045924769 (порядок)

h = 1 (кофактор)

Может ли кто-нибудь дать мне несколько советов относительно того, будет ли эта кривая генерировать действительные пары закрытый/открытый ключ? Как я мог это проверить?

Любая помощь (/подтверждение) будет очень признательна, спасибо!


person James Andrew    schedule 08.03.2014    source источник


Ответы (1)


Вы можете использовать функцию OpenSSL EC_GROUP_check(), чтобы убедиться, что это допустимая группа. В следующей программе я сделал две вещи:

  • Создайте EC_GROUP с предоставленными параметрами и проверьте, действительно ли это
  • Сгенерируйте EC_KEY, используя сгенерированную EC_group, и проверьте, действительна ли она.

Обратите внимание, что вы хотите проверить, можно ли использовать группу EC для создания действительных ключей EC, а не кривую EC.

Подробности читайте в комментариях :)

// 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;
}

Скомпилируйте и запустите с помощью этой команды:

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

Стандартный вывод должен печатать

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

Пара закрытый/открытый ключ будет меняться каждый раз, так как EC_KEY_generate_key(eckey) случайным образом выбирает закрытый ключ и вычисляет соответствующий открытый ключ для каждого запуска.

person Chiara Hsieh    schedule 10.03.2014
comment
Спасибо, вау, это круто. Я использую Python, но я уверен, что смогу получить jist. Быстрый вопрос, почему вы вместо этого распечатываете координаты открытого ключа, а не только ключа? (как вы сделали с закрытым ключом) - person James Andrew; 11.03.2014
comment
Я полагаю, вы уже это знаете: закрытый ключ d — это bignum; открытый ключ P является точкой EC. Пусть генератор будет G, G=(x,y), затем P=d*G, где P=(pub_x,pub_y). Как вы хотите, чтобы открытый ключ был похож? Открытый ключ в алгоритмах ECC (таких как ECDSA) фактически является точкой EC на кривой и является элементом группы EC. Вы также можете распечатать сжатые координаты этой точки, это будет выглядеть как бигнум, но все же это точка ;) - person Chiara Hsieh; 11.03.2014