C/C++教程

椭圆曲线加密算法——求某一个点的所有倍数点(c/c++实现)

本文主要是介绍椭圆曲线加密算法——求某一个点的所有倍数点(c/c++实现),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

求解某点的数乘点

最近被密码学折磨的不轻,手算椭圆曲线上的点经常算错,简直生草。

因次就有了以下下代码~~

#include <iostream>
#include <cassert>
#include <map>
#include <cmath>
using namespace std;

int inverse(int x, int mod){
    // 计算x模mod的逆 要求模数为素数 使用费马小定理
    if(x>mod)
        x %= mod;
    int i(1),j(0);
    map<int,int> temp;
    while(i!=mod-2){
        temp[i+j] = (int)pow(x,i+j);
        temp[i+j]%= mod;
        
        i += j;

        if(2*i > mod-2){
            for(j=1;j<=i;j*=2)
                if(i+j > mod-2){
                    j /= 2;
                    break;
                }
        }
        else{
            i *= 2; j = 0;
        }
    }
    if(temp[mod-2]<0)
        temp[mod-2]+=mod;
    return temp[mod-2];
}

int gcd(int x, int y){
    if(x<=0 || y<=0)
        return -1;
    
    while(x!=y){
        if(x > y)
            x -= y;
        else
            y -= x;
    }
    return y;
}

int lamda(int x1,int y1,int x2,int y2,int a,int mod){
    if(x1<0 && x2<0)
        return -1;
    int re;
    if(x1==x2 && y1 == y2){
        // 同一个点不为无穷 计算lamda
        // lamda = 3x^{2}+a / 2y;
        int x = 3*x1*x1+a;
        int y = 2*y1;
        int gcd_xy = gcd(x,y);
        x/=gcd_xy; y/=gcd_xy;
        if(y == 1)
            re = x;
        else{
        re = x * inverse(y,mod);
        re %= mod;
        }
    }
    else{
        // 不同计算斜率
        int x = x1-x2;
        x = (x<0)?-x:x;
        int y = y1-y2;
        y = (y<0)?-y:y;
        int gcd_xy = gcd(x,y);
        x/=gcd_xy; y/=gcd_xy;
        if(y==1)
            re = x;
        else{
            re =  y * inverse(x,mod);
            re %= mod;
        }
    }
    return re;
}

int re_x(int x1,int x2,int lamda){
    lamda *= lamda;

    return lamda - x1 -x2;
}

int re_y(int x1, int x3, int y1, int lamda){
    lamda *= x1 - x3;

    return lamda - y1;
}

int main (){
    int x,y,a,mod;
    ios::sync_with_stdio(0);
    cout << "输入初始点的横纵坐标,a,及模数"<< endl;
    cin >> x >> y >> a >> mod;
    if(x<0 || y<0)
        assert(0);
    bool flag = false;  // 不是无穷的标志 因为 0*P=无穷
    int i=1,x1=x,y1=y;
    printf("0`th: NAN NAN\n");


    // 循环次数的确定实在是没时间想了,以后有时间再说~~~
    while(i<19){    
        printf("%d`th: %d %d\n",i,x1,y1);
        int k = lamda(x1,y1,x,y,a,mod);
        int t_x = re_x(x1,x,k);
        y1 = re_y(x1,t_x,y1,k);
        x1 = t_x;
        x1 %= mod; y1 %= mod;
        if(x1<0)
            x1 += mod;
        if(y1<0)
            y1 += mod;
        i++;
    }

    return 0;
}
这篇关于椭圆曲线加密算法——求某一个点的所有倍数点(c/c++实现)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!