mp_mul_d(&temp2, 27, &temp4); mp_add(&temp3, &temp4, &temp5); mp_mod(&temp5,p,&temp);
if(mp_cmp(&temp, &compare)!=0 ) { } }
//y2=x3+ax+b,随机产生X坐标,根据X坐标计算Y坐标 GetPrime(x1,30);// 随机产生30比特长的X坐标 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);//得到Y坐标
break; //满足条件跳出循环
……..
私钥的确定:随机选取1到P-1之间的素数作为私钥d. 公钥的确定:由d乘我们所确定的基点得到公钥K,即K=dG。
四、 椭圆曲线的点加和纯量乘法
对于一般的椭圆曲线方程y^2+a1xy+a3y=x^3+a2x^2+a4x+a6, 设点P(x1,y1),Q(x2,y2)的和R(x3,y3)的坐标。R(x3,y3)的计算公式如下:
x3=k^2+ka1+a2+x1+x2; y3=k(x1-x4)-y1-a1x4-a3; 其中k= (y1-y2)/(x1-x2)
当P≠Q时
k=(3x2+2a2x+a4 -a1y) /(2y+a1x+a3)
当P=Q时,对于椭圆曲线方程Y^2=X^3+aX+b,上述的公式变为: x3=θ2- x1-x2;
y3=θ(x1-x3)-y1
其中θ=(y1-y2)/(x1-x2) 当P≠Q时; θ=(3x1^2-a)/2y1 当P=Q时
由上述运算公式,可以得出点积mP的运算,即mP=P+P+…+P,共m个P相加,这里m∈N.
具体算法为:设m的二进制表示为
m=(m_n-1m_n-2…m1m0),其中m_n-1=1,Q=P,从左到右依次计算: for(I=n-2 to 0) { Q=2Q;
if(mi ==1) Q=Q+P; } 则Q=mP. Return ;
函数原形为:
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) 成功返回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) 成功返回1。
五、加密文件的读入与输出
mp_digit只用28比特,因此一个单元最多可存放三个半字节。为充分利用存取空间,采用 一个单元放三个半字节。 1.
函数putin()实现将明文的二进制比特串赋给mp_int数a:
主要循环部分及说明如下:
//chlong为要存入的字符数组长
for(j=0;j<<=\存入字符 255); 左移8位 存入高8位并向左移8位,以便放入下一个字符 temp跳过前一个单元,先存入后一单元 *++temp 每次跳七个字符 i+=\的两个单元中 以7个字符为单元循环,把七个字符放入的mp_int 7;j++){>> 4); //存放被切分的字符的高四位,temp跳回前一个单元 //存入第一单元
*temp |= (mp_digit)(ch[i-4] & yy); //存放被
切分的字符的低四位,yy=(mp_digit)15
*temp <<= (mp_digit)CHAR_BIT; //向左移8位,以便放入下一个字符
*temp |= (mp_digit)(ch[i-5] & 255); //存入字符
*temp <<= (mp_digit)CHAR_BIT; //左移8位
*temp |= (mp_digit)(ch[i-6] & 255); //存入字符
*temp <<= (mp_digit)CHAR_BIT; //左移8位
*temp++ |= (mp_digit)(ch[i-7] & 255); //存放被切分的字符的低四位,temp跳到后一个单元
temp++; //再向后跳一单元,这样和下次的
++temp实现每次循环跳两个单元