Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C ECC双精度和加法_C_Segmentation Fault_Elliptic Curve - Fatal编程技术网

C ECC双精度和加法

C ECC双精度和加法,c,segmentation-fault,elliptic-curve,C,Segmentation Fault,Elliptic Curve,我目前正在使用Double和Add算法编写椭圆曲线密码的C代码。我面临一个seg故障问题,我不明白。我希望你们中有人能有个主意 #include "lib/include/gmp.h" #include <stdio.h> #include <string.h> #include <stdlib.h> #include <openssl/sha.h> typedef struct{ mpz_t p; mpz_t a; mp

我目前正在使用Double和Add算法编写椭圆曲线密码的C代码。我面临一个seg故障问题,我不明白。我希望你们中有人能有个主意

#include "lib/include/gmp.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/sha.h>

typedef struct{
    mpz_t p;
    mpz_t a;
    mpz_t b;
    mpz_t gx;
    mpz_t gy;
} ECC;

static mpz_t *inverse_y1, *inverse_y2, *tx, *ty;
ECC secp256k1;

/*
 * Initializes the secp256k1 curve.
 */
void initSECP256K1(){
    mpz_set_str(secp256k1.p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16);
    mpz_init(secp256k1.a);
    mpz_set_str(secp256k1.b, "7", 10);
    mpz_set_str(secp256k1.gx, "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 16);
    mpz_set_str(secp256k1.gy, "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 16);
    inverse_y1 = malloc(sizeof(mpz_t));
    inverse_y2 = malloc(sizeof(mpz_t));
    mpz_set_str(*inverse_y1, "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 16);
    mpz_set_str(*inverse_y2, "b7c52588d95c3b9aa25b0403f1eef75702e84bb7597aabe663b82f6f04ef2777", 16);
}

/*
 * Calculates the s value for ecc point and doubling.
 * s = (y2 - y1) / (x2 - x1) mod p if P != Q
 * s = (3 * x1 ^ 2 + a) / (2 * y1) mod p if P = Q
 * 5 parameters. First one is mpz_t pointer to save the result.
 * The other 4 are of type pointer, representing the coordinates.
 */
void calculate_s(mpz_t *s, mpz_t *x1, mpz_t *y1, mpz_t *x2, mpz_t *y2){
    mpz_t *s1 = malloc(sizeof(mpz_t));
    mpz_init(*s1);
    //Point Addition
    if(mpz_cmp(*x1, *x2) != 0 || mpz_cmp(*y1, *y2) != 0){
        mpz_sub(*s, *y2, *y1);
        mpz_sub(*s1, *x2, *x1);
    }else{
    //Point doubling
        mpz_powm_ui(*s, *x1, 2, secp256k1.p);
        mpz_mul_si(*s, *s, 3);
        mpz_mul_si(*s1, *y1, 2);
    }
    mpz_invert(*s1, *s1, secp256k1.p);
    mpz_mul(*s, *s, *s1);
    mpz_clear(*s1);
}



/*
 * ECC - Point add and Point double
 * It takes 6 parameters, each of type mpz_t pointer.
 * The result is stored in the first two pointers.
 * The third and forth pointer represent the first coordinate.
 * The last two pointer are the second coordinate.
 * It calculates the new coordinates as follows:
 * x3 = s ^ 2 - x1 - x2 mod p
 * y3 = s * (x1 - x3) - y1 mod p
 */
int ecc_papd(mpz_t *x3, mpz_t *y3, mpz_t *x1, mpz_t *y1, mpz_t *x2, mpz_t *y2){
    mpz_t *s = malloc(sizeof(mpz_t));
    mpz_init(*s);
    //calculates s value
    calculate_s(s, x1, y1, x2, y2);
    //x3 = s^2 - x1 - x2 mpd p
    mpz_powm_ui(*x3, *s, 2, secp256k1.p);
    mpz_sub(*x3, *x3, *x1);
    mpz_sub(*x3, *x3, *x2);
    mpz_mod(*x3, *x3, secp256k1.p);
    //y3 = s * (x1 - x3) - y1 mod p
    mpz_sub(*y3, *x1, *x3);
    mpz_mul(*y3, *y3, *s);
    mpz_sub(*y3, *y3, *y1);
    mpz_mod(*y3, *y3, secp256k1.p);
    mpz_clear(*s);
    //check if the result is the infinity point
    if(mpz_cmp(*x1, *x2) == 0){
        if((mpz_cmp(*y1, *inverse_y1) == 0 && mpz_cmp(*y2, *inverse_y2) == 0) ||
               (mpz_cmp(*y2, *inverse_y1) == 0 && mpz_cmp(*y1, *inverse_y2) == 0)){
            //printf("INFINITY");
            return 1;
        }
    }
    return 0;
}


void ecc_double_add(mpz_t *rx, mpz_t *ry, mpz_t *x, mpz_t *y, mpz_t d){
    mpz_t *tx = malloc(sizeof(mpz_t));
    mpz_t *ty = malloc(sizeof(mpz_t));
    mpz_set(*tx, *x);
    mpz_set(*ty, *y);
    //returns the amount of bits the number has
    //sub 2 because it starts to count from 1 and we remove the msb, too.
    int bits = (int) mpz_sizeinbase(d, 2) - 2;
    int bit, infinity = 0;
    //check if bits is -1, (case d=1). If yes, set the base point as solution
    if(bits < 0){
        mpz_set(*rx, *x);
        mpz_set(*ry, *y);
    }
    for(; bits >= 0; bits--){
        bit = mpz_tstbit(d, bits);
        if(infinity == 0){
            infinity = ecc_papd(rx, ry, tx, ty, tx, ty);
            mpz_set(*tx, *rx);
            mpz_set(*ty, *ry);
        }
        //point addition
        if(bit == 1){
            if(infinity == 0){
                infinity = ecc_papd(rx, ry, tx, ty, x, y);
                mpz_set(*tx, *rx);
                mpz_set(*ty, *ry);
            }else{
                mpz_set(*tx, *x);
                mpz_set(*ty, *y);
                infinity = 0;
            }
        }
    }
    free(tx);
    free(ty);
}

int main(){
    initSECP256K1();
    mpz_t *rx = malloc(sizeof(mpz_t));
    mpz_t *ry = malloc(sizeof(mpz_t));
    //tx = malloc(sizeof(mpz_t));
    //ty = malloc(sizeof(mpz_t));
    mpz_t d;
    mpz_init(*rx);
    mpz_init(*ry);
    mpz_init(d);

    int i = 0;
    for(; i < 2; i++){
        gmp_printf ("d %Zd\n", d);
        ecc_double_add(rx, ry, &secp256k1.gx, &secp256k1.gy, d);
        gmp_printf ("R.x %Zx\n", rx);
        gmp_printf ("R.y %Zx\n", ry);
        printf("\n");
        mpz_add_ui(d, d, 1);
    }
    //mpz_clear(*tx);
    //mpz_clear(*ty);
    mpz_clear(*rx);
    mpz_clear(*ry);

    return 0;
}
#包括“lib/include/gmp.h”
#包括
#包括
#包括
#包括
类型定义结构{
mpz_t p;
mpz_t a;
mpz_t b;
mpz_t gx;
mpz_t gy;
}幼儿保育中心;
静态mpz_t*逆y 1,*逆y 2,*tx,*ty;
ECC-secp256k1;
/*
*初始化secp256k1曲线。
*/
void initSECP256K1(){
mpz_set_str(secp256k1.p,“fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff”,16);
mpz_init(secp256k1.a);
mpz_set_str(secp256k1.b,“7”,10);
mpz_set_str(secp256k1.gx,“79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798”,16);
mpz_set_str(secp256k1.gy,“483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8”,16);
逆_y1=malloc(sizeof(mpz_t));
逆_y2=malloc(sizeof(mpz_t));
mpz_集_str(*逆_y1,“483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8”,16);
mpz_集_str(*逆_y2,“B7C52588D95C3B9AA25B0403F1EEF70702E84BB7597AABE663B82F6F04EF2777”,16);
}
/*
*计算ecc点和倍增点的s值。
*s=(y2-y1)/(x2-x1)模p如果p!=Q
*s=(3*x1^2+a)/(2*y1)如果p=Q,则为p模
*5个参数。第一个是保存结果的mpz_t指针。
*其他4个是指针类型,表示坐标。
*/
无效计算(mpz_t*s,mpz_t*x1,mpz_t*y1,mpz_t*x2,mpz_t*y2){
mpz_t*s1=malloc(sizeof(mpz_t));
mpz_init(*s1);
//点加法
如果(mpz_cmp(*x1,*x2)!=0 | | mpz_cmp(*y1,*y2)!=0){
mpz_sub(*s,*y2,*y1);
mpz_sub(*s1,*x2,*x1);
}否则{
//倍点
mpz_powm_ui(*s,*x1,2,secp256k1.p);
mpz_mul_si(*s,*s,3);
mpz_mul_si(*s1,*y1,2);
}
mpz_逆变器(*s1,*s1,secp256k1.p);
mpz_mul(*s,*s,*s1);
mpz_清除(*s1);
}
/*
*ECC-加点和双加点
*它包含6个参数,每个参数类型为mpz_t指针。
*结果存储在前两个指针中。
*第三个和第四个指针表示第一个坐标。
*最后两个指针是第二个坐标。
*它按如下方式计算新坐标:
*x3=s^2-x1-x2模p
*y3=s*(x1-x3)-y1模数p
*/
内部ecc_papd(mpz_t*x3、mpz_t*y3、mpz_t*x1、mpz_t*y1、mpz_t*x2、mpz_t*y2){
mpz_t*s=malloc(sizeof(mpz_t));
mpz_init(*s);
//计算s值
计算_s(s,x1,y1,x2,y2);
//x3=s^2-x1-x2 mpd p
mpz_powm_ui(*x3,*s,2,secp256k1.p);
mpz_sub(*x3,*x3,*x1);
mpz_sub(*x3,*x3,*x2);
mpz_mod(*x3,*x3,secp256k1.p);
//y3=s*(x1-x3)-y1模数p
mpz_sub(*y3,*x1,*x3);
mpz_mul(*y3,*y3,*s);
mpz_sub(*y3,*y3,*y1);
mpz_mod(*y3,*y3,secp256k1.p);
mpz_清除(*s);
//检查结果是否为无穷远点
如果(mpz_cmp(*x1,*x2)==0){
if((mpz_-cmp(*y1,*逆_-y1)==0&&mpz_-cmp(*y2,*逆_-y2)==0)||
(mpz_-cmp(*y2,*逆_-y1)==0&&mpz_-cmp(*y1,*逆_-y2)==0)){
//printf(“无限”);
返回1;
}
}
返回0;
}
无效ecc_双加(mpz_t*rx、mpz_t*ry、mpz_t*x、mpz_t*y、mpz_t*d){
mpz_t*tx=malloc(sizeof(mpz_t));
mpz_t*ty=malloc(sizeof(mpz_t));
mpz_组(*tx,*x);
mpz_集(*ty,*y);
//返回数字的位数
//sub 2,因为它从1开始计数,并且我们也删除了msb。
int位=(int)mpz_sizeinbase(d,2)-2;
整数位,无穷大=0;
//检查位是否为-1(情况d=1)。如果是,将基点设置为解决方案
if(位<0){
mpz_组(*rx,*x);
mpz_集(*ry,*y);
}
对于(;位>=0;位--){
位=mpz_tstbit(d,位);
if(无穷大==0){
无穷大=ecc_papd(rx,ry,tx,ty,tx,ty);
mpz_组(*tx,*rx);
mpz_集(*ty,*ry);
}
//点加法
如果(位==1){
if(无穷大==0){
无穷大=ecc_papd(rx,ry,tx,ty,x,y);
mpz_组(*tx,*rx);
mpz_集(*ty,*ry);
}否则{
mpz_组(*tx,*x);
mpz_集(*ty,*y);
无穷大=0;
}
}
}
免费(tx);
免费(ty);
}
int main(){
initSECP256K1();
mpz_t*rx=malloc(sizeof(mpz_t));
mpz_t*ry=malloc(sizeof(mpz_t));
//tx=malloc(sizeof(mpz_t));
//ty=malloc(sizeof(mpz_t));
mpz_t d;
mpz_init(*rx);
mpz_初始值(*ry);
mpz_init(d);
int i=0;
对于(;i<2;i++){
gmp_printf(“d%Zd\n”,d);
ecc双加(rx、ry和secp256k1.gx和secp256k1.gy、d);
gmp_printf(“R.x%Zx\n”,rx);
gmp_printf(“R.y%Zx\n”,ry);
printf(“\n”);
mpz_-add_-ui(d,d,1);
}
//mpz_清除(*tx);
//mpz_清除(*ty);
mpz_清除(*rx);
mpz_清除(*ry);
返回0;
}
问题在于ecc_double_add函数中使用了mpz_t*tx和mpz_t*ty变量。当我运行代码时,我得到一个seg错误。 因此,我初始化了函数外部的变量(在主函数中注释掉)。只要我这样做,它就会起作用。我很困惑,不知道为什么我会收到seg故障。我的C语言知识不是很好,我正在努力变得更好。 我感谢任何帮助:)

*编辑:
我正在使用GNU MP库完成这项任务,它就在这里:

我一直在修修补补,我发现gmp\u printf函数导致了这个问题。一旦我从for循环中删除它,代码就开始工作了。我用printf和gmp_printf替换了它,没有参数,代码开始工作。 我不知道为什么gmp_printf会出现问题,但我发现:

我将gmp_printf替换为

printf("Result: %s\n", mpz_get_str(NULL, 16, *rx));

这不是一个好的解决方案,但用于测试就足够了。

您有
的文件吗#include“lib/include/gmp.h”
?是的,对不起