椭圆曲线离散对数

时间:2015-05-14 23:24:04

标签: c segmentation-fault elliptic-curve ecdsa

我正在尝试使用Pollard rho求解椭圆曲线离散对数(找到 k ,其中 G = kp ),所以我搜索了c中的实现,我发现了一个在main函数中添加问题特定数据segmentation fault (core dumped)

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <gmp.h>
#include <limits.h>
#include <sys/time.h>

#include <openssl/ec.h>
#include <openssl/bn.h>
#include <openssl/obj_mac.h> // for NID_secp256k1

#define POLLARD_SET_COUNT 16

#if defined(WIN32) || defined(_WIN32)
#define EXPORT __declspec(dllexport)
#else
#define EXPORT
#endif

#define MAX_RESTART 100

int ec_point_partition(const EC_GROUP *ecgrp, const EC_POINT *x) {  

    size_t len = EC_POINT_point2oct( ecgrp, x, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL );
    unsigned char ret[len]; 
    EC_POINT_point2oct( ecgrp, x, POINT_CONVERSION_UNCOMPRESSED, ret, len, NULL );

    int id = ( ret[len - 1] & 0xFF ) % POLLARD_SET_COUNT;

    return id;
}

// P generator 
// Q result*P
// order of the curve
// result
//Reference: J. Sattler and C. P. Schnorr, "Generating random walks in groups"

int elliptic_pollard_rho_dlog(const EC_GROUP *group, const EC_POINT *P, const EC_POINT *Q, const BIGNUM *order, BIGNUM *res) {

    printf("Pollard rho discrete log algorithm... \n");

    BN_CTX* ctx;
    ctx = BN_CTX_new();

    int i, j;
    int iterations = 0;

    if ( !EC_POINT_is_on_curve(group, P, ctx ) || !EC_POINT_is_on_curve(group, Q, ctx ) ) return 1;

    EC_POINT *X1 = EC_POINT_new(group);
    EC_POINT *X2 = EC_POINT_new(group);

    BIGNUM *c1 = BN_new();
    BIGNUM *d1 = BN_new();
    BIGNUM *c2 = BN_new();
    BIGNUM *d2 = BN_new();

    BIGNUM* a[POLLARD_SET_COUNT];
    BIGNUM* b[POLLARD_SET_COUNT];
    EC_POINT* R[POLLARD_SET_COUNT];

    BN_zero(c1); BN_zero(d1);
    BN_zero(c2); BN_zero(d2);


    for (i = 0; i < POLLARD_SET_COUNT; i++) {   

        a[i] = BN_new();
        b[i] = BN_new();
        R[i] = EC_POINT_new(group);

        BN_rand_range(a[i], order);     
        BN_rand_range(b[i], order);

        // R = aP + bQ

        EC_POINT_mul(group, R[i], a[i], Q, b[i], ctx);
        //ep_norm(R[i], R[i]);
    }

    BN_rand_range(c1, order);       
    BN_rand_range(d1, order);       


    // X1 = c1*P + d1*Q
    EC_POINT_mul(group, X1, c1, Q, d1,  ctx);  
    //ep_norm(X1, X1);

    BN_copy(c2, c1);
    BN_copy(d2, d1);
    EC_POINT_copy(X2, X1);


    double work_time = (double) clock();
    do {
        j = ec_point_partition(group, X1);
        EC_POINT_add(group, X1, X1, R[j], ctx);

        BN_mod_add(c1, c1, a[j], order, ctx); 

        BN_mod_add(d1, d1, b[j], order, ctx); 

        for (i = 0; i < 2; i++) {
            j = ec_point_partition(group, X2);

            EC_POINT_add(group, X2, X2, R[j], ctx);

            BN_mod_add(c2, c2, a[j], order, ctx); 

            BN_mod_add(d2, d2, b[j], order, ctx);
        }

        iterations++;
        printf("Iteration %d \r",iterations );
    } while ( EC_POINT_cmp(group, X1, X2, ctx) != 0 ) ;


    printf("\n ");

    work_time = ( (double) clock() - work_time ) / (double)CLOCKS_PER_SEC;

    printf("Number of iterations %d %f\n",iterations, work_time );

    BN_mod_sub(c1, c1, c2, order, ctx);
    BN_mod_sub(d2, d2, d1, order, ctx);

    if (BN_is_zero(d2) == 1) return 1;


    //d1 = d2^-1 mod order  
    BN_mod_inverse(d1, d2, order, ctx);

    BN_mod_mul(res, c1, d1, order, ctx);

    for (int k = 0; k < POLLARD_SET_COUNT; ++k) {
        BN_free(a[k]); 
        BN_free(b[k]);
        EC_POINT_free(R[k]);
    }
    BN_free(c1); BN_free(d1);
    BN_free(c2); BN_free(d2);
    EC_POINT_free(X1); EC_POINT_free(X2);

    BN_CTX_free(ctx);
    return 0;
}


int main(int argc, char *argv[])
{
    unsigned char *p_str="134747661567386867366256408824228742802669457";
    unsigned char *a_str="-1";
    unsigned char *b_str="0";
    BIGNUM *p = BN_bin2bn(p_str, sizeof(p_str), NULL);
    BIGNUM *a = BN_bin2bn(a_str, sizeof(a_str), NULL);
    BIGNUM *b = BN_bin2bn(b_str, sizeof(b_str), NULL);
    BN_CTX* ctx;
    ctx = BN_CTX_new();
    EC_GROUP* g = EC_GROUP_new(EC_GFp_simple_method());
    EC_GROUP_set_curve_GFp(g,p,a,b,ctx);    
    unsigned char *XP_str="18185174461194872234733581786593019886770620";
    unsigned char *YP_str="74952280828346465277451545812645059041440154";

    BN_CTX* ctx1;
    ctx1 = BN_CTX_new();
    BIGNUM *XP = BN_bin2bn(XP_str, sizeof(XP_str), NULL);
    BIGNUM *YP = BN_bin2bn(YP_str, sizeof(YP_str), NULL);
    EC_POINT* P = EC_POINT_new(g);
    EC_POINT_set_affine_coordinates_GFp(g,P,XP,YP,ctx1);

    unsigned char *XQ_str="76468233972358960368422190121977870066985660";
    unsigned char *YQ_str="33884872380845276447083435959215308764231090";
    BIGNUM* XQ = BN_bin2bn(XQ_str, sizeof(XQ_str), NULL);
    BIGNUM* YQ = BN_bin2bn(YQ_str, sizeof(YQ_str), NULL);
    EC_POINT *Q = EC_POINT_new(g);
    BN_CTX* ctx2;
    ctx2 = BN_CTX_new();
    EC_POINT_set_affine_coordinates_GFp(g,Q,XQ,YQ,ctx2);
    char * str;


    unsigned char *N_str="2902021510595963727029";
    BIGNUM *N = BN_bin2bn(N_str, sizeof(N_str), NULL);
    BIGNUM *res;
    elliptic_pollard_rho_dlog (g,P,Q,N,res);
    BN_bn2mpi(res,str); 
    printf("%s\n", str);


  return 0;
}

这是导致segmentation fault

的陈述
    BN_bn2mpi(res,str); 

0 个答案:

没有答案