椭圆曲线上的加密算法——MV(Menezes-Vanstone)算法的具体实现

椭圆曲线上的加密算法——MV算法的具体实现

密码学实验课老师要求我们使用大数运算库实现椭圆曲线上的MV算法。最开始老师要求很笼统,什么多余的要求也没说,之前我们做过一个小数MV算法的实现,直观感觉就是把程序中的数据类型改一改,调一调就行了…越往后做才发现大模数下的椭圆曲线算法没有想象的那么简单

1.椭圆曲线概述

这部分先鸽了

推荐大家阅读椭圆曲线密码学原理分析这篇博客,写的非常详尽,里面也有椭圆曲线在密码学的应用

2.MV算法流程

MV算法全称是Menezes-Vanstone公钥密码体制,顾名思义,是由Menezes和Vanstone两人提出的应该没有人关心吧

MV算法是ElGamal公钥加密算法的变种,大概就是ElGamal在椭圆曲线上的一种表现形式,两者的核心是一样的。

密码学MV

我们学校使用的这本密码学课本对MV的具体实现做作了详细的描述具体的算法实现因为临近期末,鸽了。。

3.miracl库下的椭圆曲线方程常用函数

此处参考了博客miracl库下椭圆曲线方程常用函数使用入门

1)椭圆曲线方程初始化
void ecurve_init(big A,big B,big p,type);

其中A,B,P为椭圆曲线 y 2 = x 3 + a x + b y^2=x^3+ax+b y2=x3+ax+b​​(其中 4 a 2 + 27 b ≠ 0 4a^2+27b\neq0 4a2+27b=0​​)

2)初始化点
epoint* epoint_init()

当定义 e p o i n t epoint epoint​后​需要使用这个函数初始化

3)点乘
void ecurve_mult(big k,epoint* G,epoint *P)

返回值为 P = k G P=kG P=kG​( P , G 为 椭 圆 曲 线 上 的 点 P,G为椭圆曲线上的点 P,G线​)​

4)点的加法
void ecurve_add(epoint* P,epoint* Q)

返回值为 Q = P + Q ( 椭 圆 曲 线 上 的 加 法 运 算 ) Q=P+Q(椭圆曲线上的加法运算) Q=P+Q线

5)点的减法
void ecurve_sub(epoint *P,epoint *Q)

返回值为 Q = Q − P ( 椭 圆 曲 线 上 的 运 算 ) Q=Q-P(椭圆曲线上的运算) Q=QP(线)

6)比较椭圆曲线上两点是否相同
bool epoint_comp(epoint *P,epoint *Q)

比较 P P P​和 Q Q Q​是否相同,相同返回 t r u e true true​,否则为 f a l s e false false

7)释放点内存
void epoint_free(epoint *p)
8)设置点坐标,若属于当前方程则返回True,不满足当前方程返回False
bool epoint_set(big x,big y,lsb,epoint *p)

l s b lsb lsb作为 y y y的最低有效位我也不知道是啥,我填0

9)从 e p o i n t epoint epoint结构体中取出点坐标赋给给x、y
int epoint_get(epoint *p,big x,big y)
10)是否为无穷远点
bool point_at_infinity(epoint *p)

4.MV算法实现具体代码

推荐使用Visual Studio并且安装miracl大数运算库执行以下代码
具体安装方法请参考其它博客其实是懒得写了

extern "C" {
#include <miracl.h>
#include <mirdef.h>
#include <stdio.h>
}
#include<stdlib.h>
#include "miracl.h"
#include<iostream>
using namespace std;

int main() {
    big a, b, p, Gx, Gy,n;
    FILE* fp;
    epoint* G = NULL;
    miracl* mip = mirsys(1000, 16);
    a = mirvar(0);//a,b为椭圆曲线的两个参数
    b = mirvar(0);
    p = mirvar(0); //p为 256 bits的大素数
    Gx = mirvar(0);//Gx,Gy为生成元的坐标
    Gy = mirvar(0);
    n = mirvar(0);
    fp = fopen("abp.txt", "r+");  //fp指向同目录下存放的SM2算法中推荐的参数
    if (fp == 0)
    {
        printf("文件打开失败!");
        exit(1);
    }
    mip->IOBASE = 16;
    cinnum(p, fp);
    cinnum(a, fp);
    cinnum(b, fp);
    cinnum(n, fp);
    cinnum(Gx, fp);
    cinnum(Gy, fp);
    fclose(fp);

    char s1[1000], s2[1000];//s1,s2为明文16进制字符串
    cout << "请输入明文m1:";cin >> s1;
    cout << "请输入明文m2:"; cin >> s2;
    big m1 = mirvar(0);//m1,m2为明文
    big m2 = mirvar(0);
    cinstr(m1, s1);//转化字符串为大数类型
    cinstr(m2, s2);

    ecurve_init(a, b, p, MR_PROJECTIVE);//建立椭圆曲线y^2=x^3+ax+b;
    G = epoint_init();
    epoint_set(Gx, Gy, 0, G);//G是生成元,Gx,Gy为SM2算法中推荐的参数

    big d = mirvar(0);//d随机生成的,是私钥
    copy(p, d);
    divide(d, mirvar(2), d);
    bigrand(d, d);
    add(d, mirvar(2), d);
    cout << "私钥d为:"; cotnum(d, stdout);

    big k = mirvar(0);//k是MV算法的过程量,是随机生成的
    bigrand(d, k);
    add(k, mirvar(2), k);
    //cout << "k="; cotnum(k, stdout);

    epoint *bei ;//bei是公开加密密钥
    bei = epoint_init();
    ecurve_mult(d, G, bei);//bei = d*G

    epoint* c0;//c0是密文
    c0 = epoint_init();//椭圆曲线上点c0的初始化
    ecurve_mult(k, G, c0);//c0 = k*G

    epoint* k0;//k0是MV加密算法的过程量
    k0 = epoint_init();
    ecurve_mult(k, bei, k0);//k0 = k*bei
    big k1 = mirvar(0);
    big k2 = mirvar(0);
    epoint_get(k0, k1, k2);//k1 = k0.x  k2 = k0.y

    big c1 = mirvar(0);//c1,c2都是密文
    big c2 = mirvar(0);
    multiply(k1, m1, c1); // c1 = k1*m1(mod p)
    multiply(k2, m2, c2);// c2 = k2*m2(mod p)
    divide(c1, p, p);
    divide(c2, p, p);
    
    big aa = mirvar(0), bb = mirvar(0);
    epoint_get(c0, aa, bb);
    cout << "密文c0的x坐标为:"; cotnum(aa, stdout);
    cout << "密文c0的y坐标为:"; cotnum(bb, stdout);
    cout << "密文c1为:"; cotnum(c1, stdout);
    cout << "密文c2为:"; cotnum(c2, stdout);

    epoint* k00;//k1是MV解密算法的过程量
    k00 = epoint_init();
    ecurve_mult(d, c0, k00);
    epoint_get(k00, k1, k2);

    big m11 = mirvar(0);//m11,m22为解密后的值
    big m22 = mirvar(0);
    xgcd(k1, p, k1, k1, k1);
    xgcd(k2, p, k2, k2, k2);
    multiply(c1, k1, m11);
    multiply(c2, k2, m22);
    divide(m11, p, p);
    divide(m22, p, p);
    cout << "解密后的值m1`为:"; cotnum(m11, stdout);
    cout << "解密后的值m2`为:"; cotnum(m22, stdout);

    if (!mr_compare(m1, m11) && !mr_compare(m2, m22)) {
        cout << "MV算法运行成功!" << endl;
    }
    else {
        cout << "MV算法运行失败。。。" << endl;
    }

    mirkill(k2);
    mirkill(k1);
    mirkill(m1);
    mirkill(m2);
    mirkill(m11);
    mirkill(m22);
    mirkill(k);
    mirkill(d);
    mirkill(a);
    mirkill(b);
    mirkill(p);
    mirkill(Gx);
    mirkill(Gy);
    epoint_free(bei);
    epoint_free(G);
    mirexit();
    return 0;
}
  • 5
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值