ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2022-05-04 12:35:40  阅读:173  来源: 互联网

标签:x1 一个点 temp int c++ else include 加密算法 mod


求解某点的数乘点

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

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

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

标签:x1,一个点,temp,int,c++,else,include,加密算法,mod
来源: https://www.cnblogs.com/ymj68520/p/16220781.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有