椭圆曲线加密算法
- 格式:pdf
- 大小:718.23 KB
- 文档页数:10
ecc加密中,椭圆曲线点加法
椭圆曲线点加法是指在椭圆曲线上进行点的加法运算。
在ECC(椭圆曲线加密)算法中,点加法是指将两个点P和Q相加得到一个新的点R。
具体的点加法运算步骤如下:
1. 假设椭圆曲线方程为y^2 = x^3 + ax + b,其中a、b为常数,P、Q、R为曲线上的点。
2. 如果P和Q是同一个点,那么点加法的结果是将点P进行倍乘,即将点P与自身相加。
3. 如果P和Q不是同一个点,那么点加法的结果是找到曲线上与直线PQ相交的第三个点R,将点R的坐标作为点加法的结果。
4. 要计算R的坐标,首先需要求得直线PQ的斜率,然后使用该斜率与曲线方程联立求解求得R的坐标。
通过多次重复执行点加法运算,可以实现对消息进行加密和解密。
椭圆曲线点加法的特点是运算复杂度高,但安全性较高,适用于加密通信和数字签名等应用场景。
rsa算法和椭圆曲线
RSA算法和椭圆曲线,是现代密码学中两种非常重要的加密算法。
这两种算法的设计目的很简单,就是希望能够在确保数据传输过程中的安全性的同时,又能够保证数据的快速传输,尽可能的减少数据传输过程中可能出现的误解、操作。
RSA算法是由Ron Rivest、Adi Shamir和Leonard Adleman于1977年发明的公钥加密算法。
这种算法的原理很简单,就是将一个十分庞大的数字分解成两个相对较小的素数,然后再利用这两个素数来进行加密和解密。
由于能够进行大数分解的算法非常复杂,使用RSA 算法进行加密的数据可以得到很好的保护。
椭圆曲线密码学是一种基于有限域上的向量加法和乘法运算的密码学算法。
在这种算法中,使用椭圆曲线来代表加密密钥以及进行运算,从而达到加密和解密的目的。
椭圆曲线算法比RSA算法更加快速和高效,还可以进行更高级别的安全性保护。
在实际的应用中,RSA算法和椭圆曲线算法都得到了广泛的应用。
例如,在银行和交易市场中,通常会采用RSA算法来对交易信息进行加密和解密,以确保交易信息的安全性和准确性。
而在电子邮件和电子商务中,通常会采用椭圆曲线密码学来对邮件和交易信息进行加密和
解密,以保证信息的安全性。
总的来说,RSA算法和椭圆曲线算法是现代密码学中两种非常重要的加密算法。
虽然这两种算法的应用领域不同,但它们都可以提供高强度的加密保护,并能够满足不同应用场景的需求。
随着科技的不断发展,这些加密算法也在不断优化和改进,为保障信息传输的安全性和快速性提供了可靠的保障。
椭圆曲线加密算法(⼀)椭圆曲线加密和签名算法简述椭圆曲线密码学,简称ECC。
是⼀种建⽴公开加密的算法,也就是⾮对称加密。
和RSA类似。
被公认在给定密钥长度下最安全的加密算法。
应⽤范围很⼴,主要的三个技术TLS、PGP、SSH都在使⽤它,特别是以BTC为代表的数字货币。
椭圆曲线椭圆曲线并不是我们⾼中时学习的椭圆形状,其名字的由来是应为椭圆曲线的描述⽅程,类似于计算⼀个椭圆周长的⽅程。
这⾥⽤来加密的椭圆曲线的定义是⼀个特殊情况。
椭圆曲线暂时可以简单的理解为:其中:a和b决定了曲线在坐标系的不同形状。
举个例⼦:当b=1,a的取值从2到-3时,曲线的形状如下:特殊曲线:当a=b=0时(左),或a=-3,b=2时(右),这两条都不是符合标准的曲线。
阿贝尔群数学上,群是指定义了⼆元操作运算并且⽤符号“+”表⽰的⼀个集合。
则必须满⾜以下要求:封闭性:如果a和b都是群成员,那么a+b也是群成员。
组合性:(a+b)+c=a+(b+c)单位元:存在确切的⼀个值可以保证 a+0=0+a=a成⽴,我们称之为单位元逆元:每个成员都有⼀个相反数:对于任意值a必定存在b使得a+b=0这样的群我们称之为阿贝尔群。
另外阿贝尔群还应该满⾜交换律a+b=b+a我们所熟知的在整数范围内的加法运算(Z,+)就是阿贝尔群封闭性:a、b属于整数,a+b也属于整数组合性:(a+b)+c=a+(b+c)单位元:0值就是单位元逆元:a的逆元就是-a所以(Z,+)是⼀个阿贝尔群。
椭圆曲线的加法假设我们有这样⼀条椭圆曲线y2=x3-x,曲线上有两点P、Q,过P和Q做⼀条直线,交椭圆曲线于R'点,再过R'点做垂直于X轴的直线,交椭圆曲线于另⼀点R,我们定义P+Q=R。
当P=Q时候,则是过P点的切线交于椭圆曲线于R',此时R=2P,如图所⽰:当有k个相同的点P相加时,记做kP,如:P+P+P=2P+P=3P,如图:椭圆曲线密码利⽤上述“运算”中的“椭圆曲线上的离散多数问题”,就像RSA利⽤“⼤数质因数分解”⼀样。
(完整版)椭圆曲线知识点总结(经典版)
1. 椭圆曲线简介
椭圆曲线是一种特殊类型的曲线,可以用于加密和签名算法中。
它的数学性质使得椭圆曲线加密成为一种强大且安全的加密方法。
2. 关键概念
2.1 椭圆曲线方程
椭圆曲线的方程一般形式为:y^2 = x^3 + ax + b,其中a和b
是方程中的常数。
2.2 基点
基点是椭圆曲线上的一个固定点,用于构建密码算法中的公钥
和私钥。
2.3 椭圆曲线运算
椭圆曲线运算包括点的加法和乘法操作。
点的加法操作用于构
建公钥,点的乘法操作用于构建私钥。
3. 椭圆曲线加密算法
3.1 密钥生成
在椭圆曲线加密算法中,首先需要生成公钥和私钥。
公钥是基
点经过多次乘法运算得到的点,私钥是一个随机生成的整数。
3.2 加密和解密
加密过程中,需要选择一个随机数作为加密的短期私钥,并使
用公钥进行点乘操作。
解密过程中,需要使用私钥进行点乘操作以
还原加密文本。
4. 安全性和优势
椭圆曲线加密算法相较于其他加密算法具有更高的安全性和更
小的密钥长度要求。
其安全性取决于基点的选择和曲线参数的选取。
5. 应用领域
椭圆曲线加密算法广泛应用于网络通信、数字签名、支付系统
等安全领域。
6. 总结
椭圆曲线是一种数学上的强大工具,其在加密和签名领域有着广泛的应用。
了解椭圆曲线的基本概念和运算规则,可以帮助我们更好地理解和应用椭圆曲线加密算法。
nist p-256椭圆曲线算法NIST P-256是一种基于椭圆曲线算法的公钥加密算法。
它被广泛用于各种应用,包括数字签名、密钥交换和加密算法。
椭圆曲线密码学是一种现代的公钥密码学方法,与传统的RSA算法相比,具有更高的效率和更短的密钥长度。
NIST P-256就是其中一种应用广泛的椭圆曲线算法。
P-256使用的是一条特定的椭圆曲线,即NIST定义的曲线。
其数学方程为:y^2 = x^3 - 3x + b mod p其中,p是一个大的素数,通常是2^256-2^224+2^192+2^96-1;b 是一个常数,具体的值通过NIST标准规定。
椭圆曲线密码学的安全性基于解决椭圆曲线离散对数问题的困难性。
在P-256中,曲线上的点对应于公钥,而私钥是一个随机数。
私钥可以用于生成公钥,而公钥则可以用于加密或进行数字签名验证。
在P-256中,公钥由曲线上的一个点表示,该点的坐标为(x,y)。
这个点还可以表示为一个无限远点,用O表示。
加密时使用公钥对数据进行加密,而解密则需要使用相应的私钥。
P-256还可以用于密钥交换。
当两个用户要进行密钥交换时,他们可以分别生成自己的私钥和公钥,并将公钥交换给对方。
然后,他们可以使用对方的公钥和自己的私钥来计算一个共享的密钥,该密钥只有他们两个人知道。
P-256还可以用于数字签名算法。
当一个用户要对一份文件进行数字签名时,他可以使用自己的私钥对文件进行签名,并将签名与文件一起发送给接收方。
接收方可以使用发送方的公钥来验证签名的有效性。
总之,NIST P-256是一种基于椭圆曲线的公钥加密算法,具有高效和安全的特点。
它可以用于各种应用,包括加密、密钥交换和数字签名。
在实际应用中,我们可以利用P-256来保护我们的数据安全。
椭圆曲线加密的算法是一种基于椭圆曲线数学理论的公钥加密技术。
椭圆曲线加密的算法主要依赖于椭圆曲线离散对数问题的困难性。
其加密过程主要包括以下几个步骤:
1.选择一条椭圆曲线E和椭圆曲线上的一个点P,以及一
个整数n,n大于1且n是椭圆曲线E上的阶(即E上的点的个数)。
2.选择一个随机数d,d在1到n-1之间,d作为私钥。
3.计算椭圆曲线E上的点Q=dP,Q作为公钥。
4.发送方将明文编码到椭圆曲线E上的点M上,然后选
择一个随机数k,计算椭圆曲线E上的点C1=kM和C2=kP。
5.发送方将C1和C2发送给接收方。
6.接收方收到C1和C2后,使用自己的公钥Q和接收到
的C1计算椭圆曲线E上的点S=QC1。
7.接收方再使用自己的私钥d和计算得到的点S计算椭圆
曲线E上的点M'=dS。
8.接收方将M'解码为明文,得到发送方发送的原始信息。
椭圆曲线密码算法(ECC)是一种非对称加密算法,它通过椭圆曲线上的点来实现密钥的生成与交换。
ECC的安全性与RSA等传统非对称加密算法相当,但它所需的密钥长度较短,使得它在移动设备等资源受限环境下具有明显的优势。
而椭圆曲线密钥生成算法就是ECC中用来生成密钥对的重要算法之一。
椭圆曲线密码算法的安全性建立在椭圆曲线离散对数问题的困难性上。
也就是说,在已知一个点P和整数kP的情况下,要很难计算出整数k。
这一性质使得椭圆曲线密码算法成为一种非常有前景的加密算法,因为相较于RSA等算法,可以用更短的密钥长度实现同等级的安全性。
椭圆曲线密钥生成算法的过程可以分为如下几个步骤:1. 选择椭圆曲线参数首先需要选择一个合适的椭圆曲线来作为公开参数。
这个椭圆曲线的选择直接影响到了密钥对的生成过程以及算法的安全性。
一般来说,椭圆曲线的安全性和性能是一对矛盾体,需要在其中寻找一个平衡点。
2. 生成私钥选择一个随机数作为私钥,私钥的大小通常是根据椭圆曲线的位数来确定的。
在ECC中,私钥通常是一个整数,它是生成公钥的重要参数。
3. 计算公钥利用椭圆曲线参数和私钥,可以通过一系列计算得到对应的公钥。
公钥通常是一个椭圆曲线上的点,它将被用于加密和数字签名等操作中。
4. 密钥对生成完成私钥和公钥组成了一个完整的密钥对,可以用于加密通信和身份认证等操作。
椭圆曲线密钥生成算法的实现涉及到大量数论和代数运算,其中包括模运算、点乘、椭圆曲线点加等复杂运算。
如何高效地实现这些运算对于算法的性能和安全性都有很大的影响。
椭圆曲线密钥生成算法是一种重要的非对称加密算法,它在移动设备、物联网设备等资源受限环境下具有明显的优势。
加之它在相同安全级别下所需的密钥长度较短,因此在当前信息安全领域有着广泛的应用前景。
椭圆曲线密钥生成算法(ECC)是当今信息安全领域中备受瞩目的一种加密算法。
其独特的数学原理和高效的计算性能使得它成为了许多安全通信协议和应用中不可或缺的一部分。
密钥算法】 1 椭圆曲线算法ECC椭圆曲线指的是由韦尔斯特拉斯(Weierstrass)方程y2+a1xy+a3y=x3+a2x2+a4x+a6所确定的平面曲线。
若F是一个域,ai∈F,i=1,2,…,6。
满足式1的数偶(x,y)称为F域上的椭圆曲线E的点。
F域可以式有理数域,还可以式有限域GF(Pr)。
椭圆曲线通常用E表示。
除了曲线E的所有点外,尚需加上一个叫做无穷远点的特殊O。
在椭圆曲线加密(ECC)中,利用了某种特殊形式的椭圆曲线,即定义在有限域上的椭圆曲线。
其方程如下:y2=x3+ax+b(mod p)这里p是素数,a和b为两个小于p的非负整数,它们满足:4a3+27b2(mod p)≠0其中,x,y,a,b∈Fp,则满足式(2)的点(x,y)和一个无穷点O就组成了椭圆曲线E。
椭圆曲线离散对数问题ECDLP定义如下:给定素数p和椭圆曲线E,对Q=kP,在已知P,Q的情况下求出小于p的正整数k。
可以证明,已知k和P计算Q比较容易,而由Q和P计算k则比较困难,至今没有有效的方法来解决这个问题,这就是椭圆曲线加密算法原理之所在。
椭圆曲线算法与RSA算法的比较椭圆曲线公钥系统是代替RSA的强有力的竞争者。
椭圆曲线加密方法与RSA方法相比,有以下的优点:(1)安全性能更高如160位ECC与1024位RSA、DSA有相同的安全强度。
(2)计算量小,处理速度快在私钥的处理速度上(解密和签名),ECC远比RSA、DSA快得多。
(3)存储空间占用小ECC的密钥尺寸和系统参数与RSA、DSA相比要小得多,所以占用的存储空间小得多。
(4)带宽要求低使得ECC具有广泛得应用前景。
ECC的这些特点使它必将取代RSA,成为通用的公钥加密算法。
比如SET协议的制定者已把它作为下一代SET协议中缺省的公钥密码算法。
椭圆曲线ECC加密算法入门介绍(作者:ZMWorm[CCG]来源:)前言同RSA(Ron Rivest,Adi Shamir,Len Adleman三位天才的名字)一样,ECC(Elliptic Curves Cryptography,椭圆曲线密码编码学)也属于公开密钥算法。
椭圆曲线加密算法(ECC)原理和C++实现源码(摘录)/* 1、⽤户A选定⼀条适合加密的椭圆曲线Ep(a,b)(如:y2=x3+ax+b),并取椭圆曲线上⼀点,作为基点G。
2、⽤户A选择⼀个私有密钥k,并⽣成公开密钥K=kG。
3、⽤户A将Ep(a,b)和点K,G传给⽤户B。
4、⽤户B接到信息后,将待传输的明⽂编码到Ep(a,b)上⼀点M,并产⽣⼀个随机整数r(r<n)。
5、⽤户B计算点C1=M+rK;C2=rG。
6、⽤户B将C1、C2传给⽤户A。
7、⽤户A接到信息后,计算C1-kC2,结果就是点M。
因为C1-kC2=M+rK-k(rG)=M+rK-r(kG)=M 再对点M进⾏解码就可以得到明⽂。
密码学中,描述⼀条Fp上的椭圆曲线,常⽤到六个参量:T=(p,a,b,G,n,h)。
(p 、a 、b ⽤来确定⼀条椭圆曲线,G为基点,n为点G的阶,h 是椭圆曲线上所有点的个数m与n相除的整数部分) 这⼏个参量取值的选择,直接影响了加密的安全性。
参量值⼀般要求满⾜以下⼏个条件: 1、p 当然越⼤越安全,但越⼤,计算速度会变慢,200位左右可以满⾜⼀般安全要求; 2、p≠n×h; 3、pt≠1 (mod n),1≤t<20; 4、4a3+27b2≠0 (mod p); 5、n 为素数; 6、h≤4。
*/#include <stdio.h>#include <string.h>#include <stdlib.h>#include <iostream.h>#include "tommath.h"#include <time.h>#define BIT_LEN 800#define KEY_LONG 128 //私钥⽐特长#define P_LONG 200 //有限域P⽐特长#define EN_LONG 40 //⼀次取明⽂字节数(x,20)(y,20)//得到lon⽐特长素数int GetPrime(mp_int *m,int lon);//得到B和G点X坐标G点Y坐标void Get_B_X_Y(mp_int *x1,mp_int *y1,mp_int *b, mp_int *a, mp_int *p);//点乘bool Ecc_points_mul(mp_int *qx,mp_int *qy, mp_int *px, mp_int *py,mp_int *d,mp_int *a,mp_int *p);//点加int Two_points_add(mp_int *x1,mp_int *y1,mp_int *x2,mp_int *y2,mp_int *x3,mp_int *y3,mp_int *a,bool zero,mp_int *p);//⼆进制存储密⽂int chmistore(mp_int *a,FILE *fp);//把读取的字符存⼊mp_int型数int putin(mp_int *a,char *ch,int chlong);//ECC加密void Ecc_encipher(mp_int *qx,mp_int *qy, mp_int *px, mp_int *py,mp_int *a,mp_int *p);//ECC解密void Ecc_decipher(mp_int *k, mp_int *a,mp_int *p);//实现将mp_int数a中的⽐特串还原为字符串并赋给字符串ch:int chdraw(mp_int *a,char *ch);//取密⽂int miwendraw(mp_int *a,char *ch,int chlong);int myrng(unsigned char *dst, int len, void *dat){int x;for (x = 0; x < len; x++) dst[x] = rand() & 0xFF;return len;}void main(){cout<<"\n 本程序实现椭圆曲线的加密解密"<<endl;cout<<"\n------------------------------------------------------------------------\n"<<endl;mp_int GX;mp_int GY;mp_int K;//私有密钥mp_int A;mp_int QX;mp_int QY;mp_int P;//Fp中的p(有限域P)mp_init(&GX);mp_init(&GY);mp_init(&K);mp_init(&A);mp_init(&B);mp_init(&QX);mp_init(&QY);mp_init(&P);time_t t;srand( (unsigned) time( &t ) );printf("椭圆曲线的参数如下(以⼗进制显⽰):\n");GetPrime(&P,P_LONG);printf("有限域 P 是:\n");char temp[800]={0};mp_toradix(&P,temp,10);printf("%s\n",temp);GetPrime(&A,30);char tempA[800]={0};printf("曲线参数 A 是:\n");mp_toradix(&A,tempA,10);printf("%s\n",tempA);Get_B_X_Y(&GX,&GY,&B,&A,&P);char tempB[800]={0};printf("曲线参数 B 是:\n");mp_toradix(&B,tempB,10);printf("%s\n",tempB);char tempGX[800]={0};printf("曲线G点X坐标是:\n");mp_toradix(&GX,tempGX,10);printf("%s\n",tempGX);char tempGY[800]={0};printf("曲线G点Y坐标是:\n");mp_toradix(&GY,tempGY,10);printf("%s\n",tempGY);//------------------------------------------------------------------GetPrime(&K,KEY_LONG);char tempK[800]={0};printf("私钥 K 是:\n");mp_toradix(&K,tempK,10);printf("%s\n",tempK);Ecc_points_mul(&QX,&QY,&GX,&GY,&K,&A,&P);char tempQX[800]={0};printf("公钥X坐标是:\n");mp_toradix(&QX,tempQX,10);printf("%s\n",tempQX);char tempQY[800]={0};printf("公钥Y坐标是:\n");mp_toradix(&QY,tempQY,10);printf("%s\n",tempQY);printf("\n------------------------------------------------------------------------\n"); Ecc_encipher(&QX,&QY,&GX,&GY,&A,&P);//加密printf("\n------------------------------------------------------------------------\n"); Ecc_decipher(&K,&A,&P);//解密printf("\n------------------------------------------------------------------------\n"); char cc;cout<<"\n\n请击⼀键退出!\n";mp_clear(&GX);mp_clear(&GY);mp_clear(&K);//私有密钥mp_clear(&A);mp_clear(&B);mp_clear(&QX);mp_clear(&QY);mp_clear(&P);//Fp中的p(有限域P)}int GetPrime(mp_int *m,int lon){mp_prime_random_ex(m, 10, lon,(rand()&1)?LTM_PRIME_2MSB_OFF:LTM_PRIME_2MSB_ON, myrng, NULL); return MP_OKAY;}void Get_B_X_Y(mp_int *x1,mp_int *y1,mp_int *b, mp_int *a, mp_int *p){mp_int tempx,tempy;mp_int temp;mp_int compare;mp_int temp1;mp_int temp2;mp_int temp3;mp_int temp4;mp_int temp5;mp_int temp6;mp_int temp7;mp_int temp8;mp_init_set_int (&compare, 0);mp_init(&tempx);mp_init(&tempy);mp_init(&temp);mp_init(&temp1);mp_init(&temp2);mp_init(&temp3);mp_init(&temp4);mp_init(&temp5);mp_init(&temp6);mp_init(&temp7);mp_init(&temp8);while(1){//4a3+27b2≠0 (mod p)GetPrime(b,40);mp_expt_d(a, 3, &temp1);mp_sqr(b, &temp2);mp_mul_d(&temp1, 4, &temp3);mp_mul_d(&temp2, 27, &temp4);mp_add(&temp3, &temp4, &temp5);mp_mod(&temp5,p,&temp);if(mp_cmp(&temp, &compare)!=0 ){break;}}//y2=x3+ax+b,随机产⽣X坐标,根据X坐标计算Y坐标GetPrime(x1,30);mp_expt_d(x1, 3, &temp6);mp_mul(a, x1, &temp7);mp_add(&temp6, &temp7, &temp8);mp_add(&temp8, b, &tempx);mp_sqrt(&tempx, y1);mp_clear(&tempx);mp_clear(&tempy);mp_clear(&temp);mp_clear(&temp1);mp_clear(&temp2);mp_clear(&temp3);mp_clear(&temp4);mp_clear(&temp5);mp_clear(&temp8);}bool Ecc_points_mul(mp_int *qx,mp_int *qy, mp_int *px, mp_int *py,mp_int *d,mp_int *a,mp_int *p){mp_int X1, Y1;mp_int X2, Y2;mp_int X3, Y3;mp_int XX1, YY1;mp_int A,P;int i;bool zero=false;char Bt_array[800]={0};char cm='1';mp_toradix(d,Bt_array,2);mp_init_set_int(&X3, 0);mp_init_set_int(&Y3, 0);mp_init_copy(&X1, px);mp_init_copy(&X2, px);mp_init_copy(&XX1, px);mp_init_copy(&Y1, py);mp_init_copy(&Y2, py);mp_init_copy(&YY1, py);mp_init_copy(&A, a);mp_init_copy(&P, p);for(i=1;i<=KEY_LONG-1;i++){mp_copy(&X2, &X1);mp_copy(&Y2, &Y1);Two_points_add(&X1,&Y1,&X2,&Y2,&X3,&Y3,&A,zero,&P);mp_copy(&X3, &X2);mp_copy(&Y3, &Y2);if(Bt_array[i]==cm){mp_copy(&XX1, &X1);mp_copy(&YY1, &Y1);Two_points_add(&X1,&Y1,&X2,&Y2,&X3,&Y3,&A,zero,&P);mp_copy(&X3, &X2);mp_copy(&Y3, &Y2);}}if(zero){cout<<"It is Zero_Unit!";return false;//如果Q为零从新产⽣D}mp_copy(&X3, qx);mp_copy(&Y3, qy);mp_clear(&X1);mp_clear(&Y1);mp_clear(&X2);mp_clear(&Y2);mp_clear(&X3);mp_clear(&Y3);mp_clear(&XX1);mp_clear(&YY1);mp_clear(&A);mp_clear(&P);return true;}//两点加int Two_points_add(mp_int *x1,mp_int *y1,mp_int *x2,mp_int *y2,mp_int *x3,mp_int *y3,mp_int *a,bool zero,mp_int *p) {mp_int x2x1;mp_int y2y1;mp_int tempk;mp_int tempy;mp_int temp1;mp_int temp2;mp_int temp3;mp_int temp4;mp_int temp5;mp_int temp6;mp_int temp7;mp_int temp8;mp_int temp9;mp_int temp10;mp_init(&x2x1);mp_init(&y2y1);mp_init(&tempk);mp_init(&tempy);mp_init(&tempzero);mp_init(&k);mp_init(&temp1);mp_init(&temp2);mp_init_set(&temp3,2);mp_init(&temp4);mp_init(&temp5);mp_init(&temp6);mp_init(&temp7);mp_init(&temp8);mp_init(&temp9);mp_init(&temp10);if(zero){mp_copy(x1, x3);mp_copy(y1, y3);zero=false;goto L;}mp_zero(&tempzero);mp_sub(x2, x1, &x2x1);if(mp_cmp(&x2x1,&tempzero)==-1){mp_add(&x2x1, p, &temp1);mp_zero(&x2x1);mp_copy(&temp1, &x2x1);}mp_sub(y2, y1, &y2y1);if(mp_cmp(&y2y1,&tempzero)==-1){mp_add(&y2y1, p, &temp2);mp_zero(&y2y1);mp_copy(&temp2, &y2y1);}if(mp_cmp(&x2x1, &tempzero)!=0){mp_invmod(&x2x1,p,&tempk);mp_mulmod(&y2y1, &tempk, p, &k);}else{if(mp_cmp(&y2y1, &tempzero)==0){mp_mulmod(&temp3,y1,p,&tempy); mp_invmod(&tempy,p,&tempk);mp_sqr(x1, &temp4);mp_mul_d(&temp4, 3, &temp5);mp_add(&temp5, a, &temp6);mp_mulmod(&temp6, &tempk, p, &k); }else{zero=true;goto L;}}mp_sqr(&k, &temp7);mp_sub(x1, x3, &temp9);mp_mul(&temp9, &k, &temp10);mp_submod(&temp10, y1, p, y3);L:mp_clear(&x2x1);mp_clear(&y2y1);mp_clear(&tempk);mp_clear(&tempy);mp_clear(&tempzero);mp_clear(&k);mp_clear(&temp1);mp_clear(&temp2);mp_clear(&temp3);mp_clear(&temp4);mp_clear(&temp5);mp_clear(&temp6);mp_clear(&temp7);mp_clear(&temp8);mp_clear(&temp9);mp_clear(&temp10);return1;}//⼆进制存储密⽂int chmistore(mp_int *a,FILE *fp){int i,j;char ch;char chtem[4];mp_digit yy=(mp_digit)255;for (i=0; i <= a->used - 1; i++) {chtem[3]=(char)(a->dp[i] & yy);chtem[2]=(char)((a->dp[i] >> (mp_digit)8) & yy); chtem[1]=(char)((a->dp[i] >> (mp_digit)16) & yy); chtem[0]=(char)((a->dp[i] >> (mp_digit)24) & yy);for(j=0;j<4;j++){fprintf(fp,"%c",chtem[j]);}}ch=char(255);fprintf(fp, "%c", ch);return MP_OKAY;}//把读取的字符存⼊mp_int型数int putin(mp_int *a,char *ch,int chlong){mp_digit *temp,yy;int i,j,res;if(a->alloc<chlong*2/7+2){if((res=mp_grow(a,chlong*2/7+2))!=MP_OKAY)return res;}a->sign=0;mp_zero(a);temp=a->dp;i=0;yy=(mp_digit)15;if(chlong<4){for(j=chlong-1;j>=0;j--){*temp |= (mp_digit)(ch[j] & 255);*temp <<= (mp_digit)CHAR_BIT;}return MP_OKAY;}if(chlong<7){i+=4;*++temp |= (mp_digit)(ch[i-1] & yy);*temp <<= (mp_digit)CHAR_BIT;*temp |= (mp_digit)(ch[i-2] & 255);*temp <<= (mp_digit)CHAR_BIT;*temp |= (mp_digit)(ch[i-3] & 255);*temp <<= (mp_digit)CHAR_BIT;*temp-- |= (mp_digit)(ch[i-4] & 255); //存放被切分的字符的低四位for(j=chlong-1;j>=i;j--){*temp |= (mp_digit)(ch[j] & 255);*temp <<= (mp_digit)CHAR_BIT;}*temp >>= (mp_digit)4;*temp |= (mp_digit)((ch[i-1] & 255) >> 4); //存放被切分的字符的⾼四位 a->used=2;return MP_OKAY;}//以7个字符为单元循环,把七个字符放⼊的mp_int 的两个单元中for(j=0;j<chlong/7;j++){i+=7;*++temp |= (mp_digit)(ch[i-1] & 255);*temp <<= (mp_digit)CHAR_BIT;*temp |= (mp_digit)(ch[i-2] & 255);*temp <<= (mp_digit)CHAR_BIT;*temp |= (mp_digit)(ch[i-3] & 255);*temp <<= (mp_digit)4;*temp-- |= (mp_digit)((ch[i-4] & 255) >> 4); //存放被切分的字符的⾼四位 *temp |= (mp_digit)(ch[i-4] & yy); //存放被切分的字符的低四位*temp <<= (mp_digit)CHAR_BIT;*temp |= (mp_digit)(ch[i-5] & 255);*temp <<= (mp_digit)CHAR_BIT;*temp |= (mp_digit)(ch[i-6] & 255);*temp <<= (mp_digit)CHAR_BIT;*temp++ |= (mp_digit)(ch[i-7] & 255);temp++;}if((chlong>=7)&&(chlong%7!=0)) //剩余字符的存放{if(chlong%7 < 4) //剩余字符少余4个时,只需⼀个mp_digit单元存放 {for(j=chlong-1;j>=i;j--){*temp |= (mp_digit)(ch[j] & 255);*temp <<= (mp_digit)CHAR_BIT;}*temp >>= (mp_digit)8;a->used=chlong*2/7+1;}else{ //剩余字符不⼩于4个时,需两个mp_digit单元存放i+=4;*temp |= (mp_digit)(ch[i-1] & yy);*temp <<= (mp_digit)CHAR_BIT;*temp |= (mp_digit)(ch[i-2] & 255);*temp <<= (mp_digit)CHAR_BIT;*temp |= (mp_digit)(ch[i-3] & 255);*temp <<= (mp_digit)CHAR_BIT;*temp++ |= (mp_digit)(ch[i-4] & 255); //存放被切分的字符的低四位for(j=chlong-1;j>=i;j--){*temp |= (mp_digit)(ch[j] & 255);*temp <<= (mp_digit)CHAR_BIT;}*temp >>= (mp_digit)4;*temp |= (mp_digit)((ch[i-1] & 255) >> 4); //存放被切分的字符的⾼四位}}else{a->used=chlong*2/7;}return MP_OKAY;}void Ecc_encipher(mp_int *qx,mp_int *qy, mp_int *px, mp_int *py,mp_int *a,mp_int *p){ //公钥X、Y坐标,曲线G点X、Y坐标,曲线参数A,有限域P mp_int mx, my;mp_int c1x, c1y;mp_int c2x, c2y;mp_int r;mp_int tempx, tempy;bool zero=false;FILE *fp,*fq;int i;char miwenx[280]={0};char miweny[280]={0};char stemp[650]={0};mp_init(&mx);mp_init(&my);mp_init(&c1x);mp_init(&c1y);mp_init(&c2x);mp_init(&c2y);mp_init(&r);mp_init(&tempx);mp_init(&tempy);GetPrime(&r, 100);char filehead[60],filefoot[20],filename[85]={0};cout<<"请输⼊您要加密⽂件的存放路径和⽂件名(如: c:\\000\\⼤整数运算 ):"<<endl;cin>>filehead;cout<<"请输⼊您要加密⽂件的扩展名(如: .doc ):"<<endl;cin>>filefoot;strcpy(filename,filehead);strcat(filename,filefoot);//打开要加密⽂件if((fp=fopen(filename,"rb"))==NULL){printf("can not open the file!");exit(1);}unsigned int FileLong=0;//⽂件字符长度char ChTem;//临时字符变int Frequency=0;int Residue=0;while( !feof(fp) )//找⽂件字符长度{ChTem = fgetc( fp );FileLong++;}--FileLong;Frequency = FileLong/EN_LONG;Residue = FileLong%EN_LONG;int enlongtemp=EN_LONG/2;//printf("%d\n",Frequency);//printf("%d\n",Residue);char filemi[85];strcpy(filemi,filehead);strcat(filemi,"密⽂");strcat(filemi,filefoot);//打开保存密⽂⽂件if((fq=fopen(filemi,"wb"))==NULL)exit(1);}printf("\n开始加密...\n");rewind(fp);for(i=0; i<Frequency; i++){fread(miwenx,1,enlongtemp,fp);//读⼊字符串miwenx[enlongtemp]=char(255);fread(miweny,1,enlongtemp,fp);//读⼊字符串miweny[enlongtemp]=char(255);putin(&mx, miwenx,enlongtemp+1);//⽂件存⼊putin(&my, miweny,enlongtemp+1);//⽂件存⼊Ecc_points_mul(&c2x,&c2y,px,py,&r,a,p);//加密Ecc_points_mul(&tempx,&tempy,qx,qy,&r,a,p);Two_points_add(&mx,&my,&tempx,&tempy,&c1x,&c1y,a,zero,p);//保存密⽂chmistore(&c1x,fq);chmistore(&c1y,fq);chmistore(&c2x,fq);chmistore(&c2y,fq);}//剩余字符处理if ( Residue > 0){if (Residue <= enlongtemp ){fread(miwenx,1,Residue,fp);//读⼊字符串miwenx[Residue]=char(255);putin(&mx, miwenx,Residue+1);//⽂件存⼊mp_zero(&my);}else{fread(miwenx,1,enlongtemp,fp);//读⼊字符串miwenx[enlongtemp]=char(255);fread(miweny,1,Residue-enlongtemp,fp);//读⼊字符串miweny[Residue-enlongtemp]=char(255);putin(&mx, miwenx,enlongtemp+1);//⽂件存⼊putin(&my, miweny,Residue-enlongtemp+1);//⽂件存⼊}Ecc_points_mul(&c2x,&c2y,px,py,&r,a,p);//加密Ecc_points_mul(&tempx,&tempy,qx,qy,&r,a,p);Two_points_add(&mx,&my,&tempx,&tempy,&c1x,&c1y,a,zero,p);//保存密⽂chmistore(&c1x,fq);chmistore(&c1y,fq);chmistore(&c2x,fq);chmistore(&c2y,fq);}cout<<"\nok!加密完毕!"<<endl;cout<<"密⽂以⼆进制保存"<<endl;cout<<"密⽂存放路径为 "<<filemi<<endl ;mp_clear(&mx);mp_clear(&my);mp_clear(&c1x);mp_clear(&c1y);mp_clear(&c2x);mp_clear(&c2y);mp_clear(&r);mp_clear(&tempx);mp_clear(&tempy);}//取密⽂int miwendraw(mp_int *a,char *ch,int chlong){mp_digit *temp;int i,j,res;if(a->alloc<chlong/4){if((res=mp_grow(a,chlong/4))!=MP_OKAY)return res;}a->alloc=chlong/4;a->sign=0;mp_zero(a);temp=a->dp;i=0;for(j=0;j<chlong/4;j++){i+=4;*temp |= (mp_digit)(ch[i-4] & 255);*temp <<= (mp_digit)CHAR_BIT;*temp |= (mp_digit)(ch[i-3] & 255);*temp <<= (mp_digit)CHAR_BIT;*temp |= (mp_digit)(ch[i-2] & 255);*temp <<= (mp_digit)CHAR_BIT;*temp++ |= (mp_digit)(ch[i-1] & 255);}a->used=chlong/4;return MP_OKAY;}//实现将mp_int数a中的⽐特串还原为字符串并赋给字符串ch:int chdraw(mp_int *a,char *ch){int i,j;mp_digit *temp,xx,yy;temp=a->dp;i=0;yy=(mp_digit)255; //⽤于位与运算,取⼋位⽐特串xx=(mp_digit)15; //⽤于位与运算,取四位⽐特串for(j=0;j<a->used/2;j++) //以两个单元为循环,把两个单元的⽐特串赋给7个字符 {i+=7;ch[i-4]=(char)(*++temp & xx);ch[i-3]=(char)((*temp >> (mp_digit)4) & yy);ch[i-2]=(char)((*temp >> (mp_digit)12) & yy);ch[i-1]=(char)((*temp-- >> (mp_digit)20) & yy);ch[i-7]=(char)(*temp & yy);ch[i-6]=(char)((*temp >> (mp_digit)8) & yy);ch[i-5]=(char)((*temp >> (mp_digit)16) & yy);ch[i-4] <<= 4;ch[i-4]+=(char)((*temp++ >> (mp_digit)24) & xx);temp++;}if(a->used%2!=0) //剩于⼀个单元的处理{ch[i++] = (char)(*temp & yy);ch[i++] = (char)((*temp >> (mp_digit)8) & yy);ch[i++] = (char)((*temp >> (mp_digit)16) & yy);}--i;while(int(ch[i]&0xFF) != 255 && i>0) i--;return i;void Ecc_decipher(mp_int *k, mp_int *a,mp_int *p){mp_int c1x, c1y;mp_int c2x, c2y;mp_int tempx, tempy;mp_int mx, my;mp_int temp;mp_init(&temp);mp_init(&c1x);mp_init(&c1y);mp_init(&c2x);mp_init(&c2y);mp_init(&tempx);mp_init(&tempy);mp_init(&mx);mp_init(&my);mp_int tempzero;mp_init(&tempzero);int i;char stemp[700]={0};FILE *fp,*fq;bool zero=false;char filehead[60],filefoot[20],filename[85]={0};cout<<"请输⼊您要解密的⽂件的存放路径和⽂件名(如: c:\\000\\⼤整数运算 ):"<<endl; cin>>filehead;cout<<"请输⼊您要解密的⽂件的扩展名(如: .doc ):"<<endl;cin>>filefoot;strcpy(filename,filehead);strcat(filename,filefoot);printf("\n开始解密\n");if((fp=fopen(filename,"rb"))==NULL){printf("can not open the file!");exit(1);}//打开保存解密结果⽂件char filemi[80];strcpy(filemi, filehead);strcat(filemi, "解密");strcat(filemi, filefoot);if((fq=fopen(filemi,"wb"))==NULL){printf("can not open the file!");exit(1);}rewind(fp);while(!feof(fp)){i=0;while(1){stemp[i]=fgetc(fp);if(i%4==0){if(int(stemp[i]&0xFF) == 255 ) goto L1;}i++;}L1: miwendraw(&c1x, stemp, i);i=0;while(1){stemp[i]=fgetc(fp);if(i%4==0){if(int(stemp[i]&0xFF) == 255 ) goto L2;}i++;}L2: miwendraw(&c1y, stemp, i);i=0;while(1){stemp[i]=fgetc(fp);if(i%4==0){if(int(stemp[i]&0xFF) == 255 ) goto L3;}i++;}L3: miwendraw(&c2x, stemp, i);i=0;while(1){stemp[i]=fgetc(fp);if(i%4==0){if(int(stemp[i]&0xFF) == 255 ) goto L4;}i++;}L4: miwendraw(&c2y, stemp, i);mp_zero(&tempzero);if(mp_cmp(&c1x, &tempzero)==0) break;Ecc_points_mul(&tempx, &tempy, &c2x, &c2y, k, a, p);mp_neg(&tempy, &temp);Two_points_add(&c1x,&c1y,&tempx,&temp,&mx,&my,a,zero,p);int chtem;chtem=chdraw(&mx,stemp);//从ming中取出字符串//保存解密结果for(int kk=0;kk<chtem;kk++){fprintf(fq,"%c",stemp[kk]);}chtem=chdraw(&my,stemp);//从ming中取出字符串//保存解密结果for(kk=0;kk<chtem;kk++){fprintf(fq,"%c",stemp[kk]);}}cout<<"\nok!解密完毕!"<<endl;cout<<"解密后的⽂字存放路径为 "<<filemi<<endl;fclose(fq);fclose(fp);mp_clear(&c1x);mp_clear(&c1y);mp_clear(&c2x);mp_clear(&c2y);mp_clear(&tempx);mp_clear(&tempy);mp_clear(&mx);mp_clear(&my);mp_clear(&temp);}。
ECC加密算法入门介绍ECC(Elliptic Curve Cryptography)椭圆曲线密码学是一种公钥密码体系,是基于椭圆曲线数学问题的一种加密算法。
相较于传统的RSA算法,ECC在相同的安全强度下使用更短的密钥长度,因此具有更高的效率和更低的资源消耗。
本文将介绍ECC加密算法的基本原理、优势与应用场景。
1.ECC加密算法原理:ECC加密算法利用椭圆曲线在群上的离散对数难题,来实现安全的加密和解密过程。
该算法的基本原理是选取一个椭圆曲线和点作为公开参数,然后选择一个合适的私钥生成公钥,通过私钥和公钥进行加密和解密。
具体流程如下:-选择一个合适的椭圆曲线E和点G作为公开参数。
-私钥选择一个随机数k。
-通过椭圆曲线计算公钥Q=kG。
-要加密的明文经过哈希函数得到一个点P。
-选择一个随机数r,计算点S=rG。
-计算点P+rQ,得到加密后的密文C=P+rQ。
-解密时使用私钥k计算点P'=C-kS,然后通过哈希函数应用反过程得到明文。
2.ECC加密算法的优势:-安全性强:ECC利用椭圆曲线的离散对数难题,在相同的安全强度下所需要的密钥长度要短于传统的RSA算法。
这使得ECC在保证安全性的同时,降低了资源的消耗。
-效率高:相较于RSA算法,ECC在相同的安全强度下使用更短的密钥长度,从而提高了加密和解密的效率。
这对于处理大量数据的场景,尤其是在移动设备上使用时非常有用。
-存储空间小:ECC生成的密钥长度较短,这意味着所需的存储空间更小。
这对于物联网设备等资源受限的环境非常重要。
3.ECC加密算法的应用场景:-加密通信:ECC可用于保护网络通信中的数据安全。
通过使用ECC算法生成的公钥对数据进行加密,保证数据的机密性。
-数字签名:ECC可用于生成数字签名以验证消息的完整性和身份认证。
通过私钥对消息进行签名,然后使用相应的公钥进行验证。
-移动设备安全:由于ECC在资源受限的移动设备上具有更高的效率和更小的存储需求,因此适用于移动设备的安全通信和数据保护。
ECC椭圆曲线加密算法—加解密(SageMath实现)简介ECC椭圆曲线加密,它的安全性基于椭圆曲线上的离散对数问题。
⽐特币和⽬前的⼆代居民⾝份证都采⽤了ECC作为加密算法。
ECC椭圆曲线函数为:y2=x3+ax+b (mod p)ECC算法如下:椭圆曲线Ep(a,b)(p为模数),基点(⽣成元)G(x,y),G点的阶数n,私钥k,公钥K(x,y),随机整数r,明⽂为⼀点m(x,y),密⽂为两点c1(x,y)和c2(x,y)(其中基点G,明⽂m,公钥K,密⽂c1、c2都是椭圆曲线E上的点)选择私钥k(k<n)得到公钥K = k*G选择随机整数r(r<n)加密:c1 = m+r*Kc2 = r*G解密:m = c1-k*c2(= c1-r*K)SageMath可以直接计算椭圆曲线加法和椭圆曲线乘法。
椭圆曲线运算(SageMath):点u(x,y),整数a,点v(x,y),点w(x,y)a_inv = inverse_mod(a,p) #a_inv是a关于模p的乘法逆元a_invv = a*uu = v*a_invw = u+v加解密脚本SageMath加密脚本:'''加密椭圆曲线选取时,模数p应是⼀个⼤质数常⽤的有⼏个公开的椭圆曲线,如Secp256k1、Secp256r1等'''p = 115792089210356248762697446949407573530086143415290314195533631308867097853951a = 115792089210356248762697446949407573530086143415290314195533631308867097853948b = 41058363725152142129326129780047268409114441015993725554835256314039467401291E = EllipticCurve(GF(p),[a,b]) #建⽴椭圆曲线EG = E(101981543389703054444906888236965100227902100585263327233246492901054535785571,105947302391877180514060433855403037184838385483621546199124860815209826713886) #选择⼀点作为⽣成元n = G.order() #G的阶数k = 78772200542717449282831156601030024198219944170436309154595818823706214492400K = k*Gr = 3546765m = E(80764032034929976879602863302323059647882062252124869895215418422992624743795,4964654783828069942602279691168356721024126126864424301508238062949726916347) #取E上⼀点m作为明⽂c1 = m+r*Kc2 = r*Gprint(c1)print(c2)SageMath解密脚本:'''解密'''p = 115792089210356248762697446949407573530086143415290314195533631308867097853951a = 115792089210356248762697446949407573530086143415290314195533631308867097853948b = 41058363725152142129326129780047268409114441015993725554835256314039467401291k = 78772200542717449282831156601030024198219944170436309154595818823706214492400E = EllipticCurve(GF(p),[a,b]) #建⽴椭圆曲线Ec1 = E(55527726590533087179712343802771216661752045890626636388680526348340802301667,99976146729305231192119179111453136971828647307627310904093286590128902629941)c2 = E(85460365972589567444123006081329559170090723413178386022601904195400422637884,58249081362527056631776731740177334121295518073095154119886890634279528757192)m = c1-k*c2print(m)其他使⽤Crypto.PublicKey.ECC⽣成ECC密钥:from Crypto.PublicKey import ECC#⽣成ECC密钥key = ECC.generate(curve='NIST P-256') #使⽤椭圆曲线NIST P-256#输出密钥(包括私钥k,基点G)print(key)#公钥(point_x,point_y是基点G的坐标)print(key.public_key())#椭圆曲线print(key.curve)#私钥kprint(key.d)#导出为pem密钥⽂件print(key.export_key(format='PEM'))#导⼊密钥⽂件key = ECC.import_key(f.read())通过fastecdsa.Curve可以查到公开椭圆曲线的参数import fastecdsa.curve as curve#P-384的acurve.P384.a#P-384的bcurve.P384.bProcessing math: 100%#P-384的pcurve.P384.p⼏种公开椭圆曲线参数:#NIST P-256(Secp256r1)#p = 2^224(2^32 − 1) + 2^192 + 2^96 − 1p = 115792089210356248762697446949407573530086143415290314195533631308867097853951a = 115792089210356248762697446949407573530086143415290314195533631308867097853948b = 41058363725152142129326129780047268409114441015993725554835256314039467401291#Secp256k1(⽐特币使⽤)#p = 2^256 − 2^32 − 2^9 − 2^8 − 2^7 − 2^6 − 2^4 − 1 = 2^256 – 2^32 – 977p = 115792089237316195423570985008687907853269984665640564039457584007908834671663a = 0b = 7#NIST P-384#p = 2^384 – 2^128 – 2^96 + 2^32 – 1p = 39402006196394479212279040100143613805079739270465446667948293404245721771496870329047266088258938001861606973112319a = -3b = 27580193559959705877849011840389048093056905856361568521428707301988689241309860865136260764883745107765439761230575#NIST P-521p = 6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151a = -3b = 1093849038073734274511112390766805569936207598951683748994586394495953116150735016013708737573759623248592132296706313309438452531591012912142327488478985984 SageMath取椭圆曲线上随机⼀点:E = EllipticCurve(GF(p),[a,b])E.random_point() #取椭圆曲线E上随机⼀点sagemath计算椭圆曲线上的离散对数问题(数据量不能太⼤)a = 1234577b = 3213242p = 7654319E = EllipticCurve(GF(p),[a,b])G = E(5234568, 2287747) #⽣成元#k = 1584718K = E(2366653, 1424308) #公钥#求解私钥,⾃动选择bsgs或Pohlig Hellman算法discrete_log(K,G,operation='+')#求解私钥,Pollard rho算法discrete_log_rho(K,G,operation='+')#求解私钥,Pollard Lambda算法,能够确定所求值在某⼀⼩范围时效率较⾼discrete_log_lambda(K,G,(1500000,2000000),operation='+')使⽤openssl查看ECC的pem密钥⽂件信息#查看ECC私钥信息openssl ec -in p384-key.pem -text -noout#查看ECC公钥信息openssl ec -pubin -in public.pem -text -noout。
ECC加密算法入门介绍ECC(Elliptic Curve Cryptography)是一种基于椭圆曲线的公钥密码算法,与RSA和DSA等传统的公钥密码算法相比,具有更小的密钥尺寸和更高的安全性。
本文将介绍ECC加密算法的基本原理、优势以及应用领域。
一、ECC加密算法的基本原理ECC是基于椭圆曲线数学理论设计的加密算法。
其基本原理是利用离散对数问题的难解性来保护数据的安全性。
在ECC中,将椭圆曲线上的点作为密钥,利用椭圆曲线的加法等运算规则来实现加密和解密的过程。
1.椭圆曲线的定义椭圆曲线是一个由满足特定方程的点构成的集合,具有非常特殊的性质。
在ECC中,使用的椭圆曲线的方程一般为y^2 = x^3 + ax + b,其中a和b为曲线参数。
2.点的加法和乘法运算在椭圆曲线上,定义了点的加法和乘法运算。
点的加法运算可以简单理解为将两个点在曲线上进行连线,与曲线的其他点交点即为相加的结果。
点的乘法运算是将一个点通过多次相加的方式得到另一个点。
3.离散对数问题椭圆曲线加密算法的安全性基于离散对数问题的难解性。
在ECC中,给定椭圆曲线上的两个点P和Q,求解使得nP=Q成立的整数n所具有很高的复杂度,即离散对数问题。
二、ECC加密算法的优势相比传统的公钥密码算法,ECC具有以下优势:1.更小的密钥尺寸ECC相较于RSA和DSA等算法,使用更小的密钥尺寸即可达到相同的安全性。
例如,128位的ECC密钥与3072位的RSA密钥具有相当的安全强度,但ECC密钥的尺寸仅为RSA密钥的1/32.更高的加密效率由于使用更小的密钥尺寸,ECC在加密和解密的速度上比传统算法更快,尤其适合于移动设备等资源受限的环境。
3.更好的安全性ECC的安全性基于离散对数问题的难解性,且具有较高的抗量子计算攻击能力。
即使量子计算机出现,ECC仍然可以提供更好的保护。
三、ECC加密算法的应用领域ECC广泛应用于各种领域,特别适用于对计算资源要求高、带宽受限的环境:1.移动通信领域由于ECC具有更小的密钥尺寸和更高的加密效率,因此在移动通信领域广泛应用。
椭圆加密算法椭圆加密算法(ECC)是一种公钥加密体制,最初由Koblitz和Miller两人于1985年提出,其数学基础是利用椭圆曲线上的有理点构成Abel加法群上椭圆离散对数的计算困难性。
优点与经典的RSA,DSA等公钥密码体制相比,椭圆密码体制有以下优点:1、安全性高有研究表示160位的椭圆密钥与1024位的RSA密钥安全性相同。
处理速度快2、在私钥的加密解密速度上,ecc算法比RSA、DSA速度更快。
存储空间占用小。
带宽要求低.原理椭圆曲线密码体制来源于对椭圆曲线的研究,所谓椭圆曲线指的是由韦尔斯特拉斯(Weierstrass)方程:y2+a1xy+a3y=x3+a2x2+a4x+a6 (1)所确定的平面曲线。
其中系数ai(I=1,2,…,6)定义在某个域上,可以是有理数域、实数域、复数域,还可以是有限域GF(pr),椭圆曲线密码体制中用到的椭圆曲线都是定义在有限域上的。
椭圆曲线上所有的点外加一个叫做无穷远点的特殊点构成的集合连同一个定义的加法运算构成一个Abel群。
在等式mP=P+P+…+P=Q (2)中,已知m和点P求点Q比较容易,反之已知点Q和点P求m却是相当困难的,这个问题称为椭圆曲线上点群的离散对数问题。
椭圆曲线密码体制正是利用这个困难问题设计而来。
椭圆曲线应用到密码学上最早是由Neal Koblitz和Victor Miller在1985年分别独立提出的。
椭圆曲线密码体制是目前已知的公钥体制中,对每比特所提供加密强度最高的一种体制。
解椭圆曲线上的离散对数问题的最好算法是Pollard rho方法,其时间复杂度为,是完全指数阶的。
其中n为等式(2)中m的二进制表示的位数。
当n=234, 约为2117,需要1.6x1023 MIPS 年的时间。
而我们熟知的RSA所利用的是大整数分解的困难问题,目前对于一般情况下的因数分解的最好算法的时间复杂度是子指数阶的,当n=2048时,需要2x1020MIPS年的时间。
椭圆曲率密码算法
椭圆曲线密码算法(Elliptic Curve Cryptography,ECC)是一种非对称加密算法,与RSA、D-H等加密算法相比,它需要的密钥短得多,同时安全性更高。
ECC最早由Koblitz和Miller独立发明,又因为它用到了椭圆曲线而得名。
椭圆曲线是在x和y坐标中定义的一类特殊的曲线,其数学定义形式为y²=x³+ax+b,其中a和b是曲线中特定的常数。
图像上看,这一曲线形状像一个传统的“椭圆”,但实际上它无论是长轴还是短轴,都是由某一个常数a和b所决定的。
而密钥生成的过程,可以如下所述:
1. 随机选择一条椭圆曲线E: y²=x³+ax+b
2. 随机选择一个基点G(记为P)作为公钥,其纵标在曲线上
3. 选择一个私钥d,计算Q=dP
4. 将P和Q作为公钥和私钥
在此基础上,可以执行加密和解密操作
加密:将明文m转换为一点P(x,y),随机选择一个数k,计算C1=kP,C2=kQ+P,加密结果为(C1,C2)
解密:首先计算kP,然后计算C2-k(dC1),得到明文m。
而安全性取决于曲线的选择和私钥的长度,在相同的密钥长度条件下,ECC的安全性比RSA高得多。
具体来说,当需要相同的密钥长度时,ECC提供了比RSA更高的安全性,并且它使用的密钥长度要短得多。
总的来说,ECC不仅适用于移动设备、物联网等对计算资源有限的场景,而且也是一种在普遍应用中的加密技术。
当前,它已被大量应用于银行、电子商务和安全应用领域。
因此,对椭圆曲线加密算法有更深的了解,对我们理解加密算法和信息安全有重要的意义。
椭圆曲线加密算法椭圆曲线密码学(英语:Elliptic curve cryptography,缩写为 ECC),一种建立公开密钥加密的算法,基于椭圆曲线数学。
椭圆曲线在密码学中的使用是在1985年由Neal Koblitz和Victor Miller分别独立提出的。
ECC的主要优势是在某些情况下它比其他的方法使用更小的密钥——比如RSA 加密算法——提供相当的或更高等级的安全。
ECC的另一个优势是可以定义群之间的双线性映射,基于Weil对或是Tate对;双线性映射已经在密码学中发现了大量的应用,例如基于身份的加密。
不过一个缺点是加密和解密操作的实现比其他机制花费的时间长1.椭圆曲线在数学上,椭圆曲线(英语:Elliptic curve,缩写为EC)为一代数曲线,被下列式子所定义y2=x3+ax+b其是无奇点的;亦即,其图形没有尖点或自相交。
满足此条件的a b满足:4a3+27b2≠0图1在基础上需要定义一个无穷远的点,将此点作为零点:此时椭圆曲线定义为:{(x,y)∈ℝ2|y2=x3+ax+b,4a3+27b2≠0}∪{0}在椭圆曲线中的群的运算律:1. 所有的点都在椭圆曲线上2. 0点作为群上的单元点即P+0=P3. P点关于X轴的对称点为P点的逆即P+(−P)=04.对于位于同一条直线上的三个点P,Q,R.则有P+Q+R=0图2P+Q+R=0(无限远点P Q R三个点的位置是任意的,他们满足加法的结合律,因为这个群是一个阿贝尔群。
2.椭圆曲线加法当P和Q不相等时(x P≠x Q)由于是在阿贝尔群上可以将P+Q+R=0改写为P+Q=−R所以在椭圆曲线上的加法定义为P Q 两点加法为P,Q两点连线与曲线的交点R的关于X轴对称点−R图2-3P+Q=-RP Q两点的直线的斜率为:m=y P−y Q x P−x Q这条线与曲线的交点为:R=(x R,y R)x R=m2−x P−x Qy R=y P+m(x R−x P)因此(x P,y P)+(x Q,y Q)=(x R,−y R)如果在图上表示即为上述的P+Q=−R当P 和Q 不相等时(x P =x Q )( y P =−y q )因为p +(−p )=0图 3 P Q 两点相同时直线的斜率为m =3x P 2+a 2y P 经计算的m =3x P 2+a 2y P x R =m 2−x P −x Q y R =y P +m(x R −x P )图 43.椭圆曲线标量乘法通过上面的加法运算我们可以得出其标量乘法运算可以得出nP=P+P+⋯+P⏟n times从上式可以看出当我们计算nP的时候需要做n次加法,如果n有k位那么的计算时间复杂度变为O(2k),这显然不是快捷的方式。
其中一种加快计算的方式是将这些加法运算的次数减少,我们将n写成2进制形式,然后我们按每位计算,每次复用上一次的结果如当n=151时,其二进制位100101112所以151=1⋅27+0⋅26+0⋅25+1⋅24+0⋅23+1⋅22+1⋅21+1⋅20 =27+24+22+21+20所以如果运用在上面的标量乘法时,其运算可以简化为:151⋅P=27P+24P+22P+21P+20P4.离散空间椭圆曲线我们将曲线上的点全部局限于F p上此时离散形式的椭圆曲线变为:{(x,y)∈(F p)2 | y2≡x3+ax+b(modp),4a3+27b2≢0(modp)}∪{0}0仍然为无穷远点,a,b 为整数Array图5y2≡x3−7x+10(modp)p=19,97,127,487的图示在离散椭圆图上的加法和曲线上的加法的定义类似,在离散的椭圆曲线中,直线的方程变为ax+by+c≡0(modp),点P,Q两点的加法的操作也是基于这个定义上下图展示了y2≡x3−x+3(mod127)曲线上P=(16,20)和Q= (41,120)两点之间的加法直线y≡4x+83(mod127)在此空间上是一组距离相等的平行线图65.离散椭圆曲线代数加法对照曲线上的加法,离散空间椭圆曲线加法公式可以写作x R=(m2−x P−x Q)modpy R=[y P+m(x R−x P)]modp=[y Q+m(x R−x Q)]modp如果P≠Q,此时的m的值的形式为m=(y P−y Q)(x P−x Q)−1modp如果P=Q时:m=(3x P2+a)(2y P)−1modp在离散型的椭圆空间里面我们知道点的数目是有限的,而这些点的个数我们称为椭圆曲线群的阶数同样的在离散空间,对于曲线上的点同样满足标量加法的法则nP=P+P+⋯+P⏟n times但是在离散空间椭圆曲线加法会有一个有趣的现象,对一个点进行有限次的加法,存在一个是n使得nP=P例如在曲线y2≡x3+2x+3(mod97)的一点P=(3,6),计算其的标量乘法,计算结果如下:图7可以看出P=(3,6)经过6次加法后又回到本身,也即是5P=0所以对于P的加法可以写作kP=(k mod 5)P可以证明的是一个点的加法所构成的子集是一个循环的子集首先一个点的加法所得到的点一定是有限的,因为加法所获得的点全部都在父集上的,父集的大小是有限的,所以经过有限次的加法后所获得的结果必定会重复,那么结果就会重复下去。
只需证明第一个重复的值是P即可。
假设第一个重复的值不是P,而是kP,那么后面的结果也必然是kP的倍数,假设重复的次数为n,如果gcd(n,k)不为1,那么存在使得km mod n=0即kmP=0即(km+1)P=P与假设矛盾如果gcd(n,k)=1那么kmP=(m mod n) kP那么存在一个数使得mk mod n=1即mkP=(mk mod n)P=P与假设矛盾。
在一个循环子集中将P称之为生成点或者基点,其子集的点的大小n称之为子集的阶即nP=0由拉格朗日定理可知子群的阶n是全集阶N的因子例如y2=x3−x+3在F37上N=42它的子集大小只能n=1,2,3,6,7,14,21,42为基点P=(2,3),因为P≠0,2P≠0…7P=0所以构成的子集的大小为7如果在F29上,其阶为N=37 所以其子集大小只能为n=1或者 37对于ECC(椭圆加密算法),需要找到一个具有高阶子集,一般情况下选择一个椭圆曲线并计算他的阶,然后找到一个数字大的因子n作为子集的阶,如果这个子集的基点为P则nP=Np=0给定n和P,那么需要计算n次计算出Q=nP,如果只给出P,Q如何计算出n这就是所谓的对数问题。
这个问题也就是椭圆曲线的离散对数问题而求解这个对数问题是非常困难的,而正是由于这种困难使得我们使用椭圆加密算法变得更加可靠与其他类似的加密算法相比,破解椭圆加密算法更加困难,这也意味着更少位数的秘钥k可以达到同类算法同样的安全强度6.椭圆加密算法ECDH 和ECSDA椭圆加密算法是基于有限域的离散型的椭圆曲线的循环子集上,定义一个这样的子集需要以下参数,●有限域的大小素数P●椭圆曲线方程a和b●用于生成子集的基点G●子集的阶n●子集的辅因子 h总的来说一个椭圆加密算法基于(p,a,b,G,n,ℎ)参数上(1)ECDH同其他非对称加密算法一样,需要计算私钥和公钥,在ECC中私钥是一个随机数d来自于{1,…,n−1}(n是子集的阶)公钥是曲线上的一个点H=dG(G是子集的基点)如果我们知道d和G,找到公钥H是很容易的,但是如果只知道H和G找到私钥d是及其困难的,这等同有在做离散对数问题,上文有提到这个问题在现在来说还没有有效的算法,所以是很困难的。
ECDH是迪夫赫尔曼算法的一个变种,它实际上是一个秘钥共识协议,ECDH协议定义了秘钥的如何产生以及如何交换秘钥。
如果Alice和Bob需要交换秘钥,中间人Hack可以在两者之间监听1.Alice和Bob使用同样参数的椭圆曲线,并且随机产生各自的秘钥d A和d B,并且计算出各自的公钥H A=d A G和H B=d B G,2.他们彼此交换各自的公钥H A和H B,而中间人也将他们的公钥截获,但是他们都不能从这些信息中计算出他们的私钥3.Alice计算出S=d A H B,Bob计算出S=d A H B,明显的是他们各自计算出的结果是一致的。
S=d A H B=d A(d B G)=d B(d A G)=d B H A而中间人不能从公钥中计算出S,所以Alice和Bob共享了密码S,这也正是迪夫赫尔曼所要解决的问题。
当Alice和Bob获得了共同的秘钥S,他们就可以使用对称加密算法如AES,3DES来加密他们的信息了。
(2)ECSDA签名算法在比特币的交易中,一笔交易会在整个区块链网络中传播,每个节点需要验证一笔交易的有效性,通过交易中解锁脚本去验证交易中的输入是否是有效的。
这其中正是使用了ECDSA算法来验证。
假如Alice需要对一个信息进行签名,Bob需要使用Alice的公钥来验证这个信息。
Alice和Bob都使用的是同一个参数相同的椭圆曲线函数。
ECDSA作用在的是信息的hash值上的,且这个值是被截取后的使得其大小与这个曲线的子集的阶一致。
将这个截取后的hash值定义为 z图8算法的流程是1.Alice随机选择一个随机数k (k<n),作为本次加密的临时私钥,并对需要签名的信息作hash处理得到z。
计算P=kG并将r=x P modn作为临时公钥,若r=0则重新选择。
2.计算s=k−1(z+rd A)modn,d A是Alice使用的私钥,k−1是k关于n的模逆,如果s为0则重新选择k再次计算。
将(r,s)作为签名信息3.Bob此时有了Alice的公钥H A和签名信息(r,s),首先计算u1=s−1zmodnu2=s−1rmodn4.然后在计算P=u1G+u2H A如果r=x P modn,则可以判定这个信息是来自于Alice的(3)算法的正确性证明从验证的步骤往前回溯有P=u1G+u2H A=u1G+u2d A G=(u1+u2d A)G将u1和u2的等式带入得到P=(u1+u2d A)G=(s−1z+s−1rd A)G=s−1(z+rd A)G因为对于基点G来说它的阶为n,因此为了简洁,可以省去mod n由模逆运算的性质可以将s=k−1(z+rd A)modn改写为k=s−1(z+rd A)modn 于是有P=s−1(z+rd A)G=kG可以看出此式正是通过随机数k生成点P的运算,回溯到了最开始的计算,可以验证算法的正确性(4)算法的漏洞在Console Hacking 2010大会上,黑客披露了一个Sony PS3的关于ECSDA的一个破解方式。
造成这个漏洞的原因在于PS3 在ECSDA算法中未随机的选择数字k用来生成点P,从而造成私钥泄露。
在此处键入公式。