超大整数运算算法——为RSA加密算法提供运算工具
/* program: Large integer operations
* Made by: Daiyyr
* date: 2013/07/09
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*/
//开源代码,引用请务必遵守GNU规则
//未完待续,尚缺 乘方、除法、取模运算
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
//#define DEBUG
#ifdef DEBUG
#define LOG(format, args...) do { printf(format, ## args); \
printf("\n");}\
while(0)
#define DBG() printk("[%s]:%d => \n",__FUNCTION__,__LINE__)
#else
#define LOG(format, args...);
#define DBG()
#endif
#define LOGE(format, args...) do { printf(format, ## args); \
printf("\n");}\
while(0)
#define LENGTH 1000 //max digit of this long number
struct charnumber{
char sign; //0 for positive, 1 for negative
int length;
unsigned char* array;//low index of this array is for high digit of the number
unsigned char* pointerforfree;
};
int char2interger(unsigned char onebyte){
if (onebyte < 10)
return onebyte;
else
return ((onebyte>>4)*10)+(onebyte&15);
}
struct charnumber* interger2charnumber(signed long int number){
unsigned char charnumber[LENGTH/2];
int i=0;
struct charnumber *target;
LOG("num: %ld", number);
target = malloc(sizeof(struct charnumber));
if (number<0){
target->sign=1;
number = -number;
LOG("num:%ld", number);
}
else{
target->sign=0;
}
while(number!=0){
charnumber[i]=number%10;
LOG("i:%d, num:%ld, char:%d", i, number, charnumber[i]);
number/=10;
charnumber[i]|=number%10<<4;
LOG("i:%d, num:%ld, char:%d", i, number, charnumber[i]);
number/=10;
i++;
}
target->length=i;
target->array = malloc(target->length);
target->pointerforfree = target->array;
for(i--;i>(target->length-1)/2;i--){ //Reverse
LOG("length=%d, i=%d, left=%d, right=%d", target->length, i, charnumber[target->length-i-1], charnumber[i]);
charnumber[i] = charnumber[i] + charnumber[target->length-i-1];
charnumber[target->length-i-1] = charnumber[i] - charnumber[target->length-i-1];
charnumber[i] = charnumber[i] - charnumber[target->length-i-1];
}
memcpy(target->array, charnumber, target->length);
for(i=0;i<target->length;i++)
LOG("i:%d:%d", i, char2interger(target->array[i]));
LOG("~~length:%d", target->length, target->length);
return target;
}
char* charnumber2string(struct charnumber* charnumber){
int length = 2*charnumber->length+1;
char* showchar = malloc(length);
int i;
LOG("string signed:%d", charnumber->sign);
if(charnumber->sign!=0)
showchar[0]='-';
else
showchar[0]='+';
for(i=0; i<charnumber->length; i++){
showchar[2*i+1]='0'+(charnumber->array[i]>>4);
showchar[2*i+2]='0'+(charnumber->array[i]&15);
LOG("%d: %x, %c%c",i, charnumber->array[i], showchar[2*i+1],showchar[2*i+2]);
}
showchar[length]='\0';
if (!strcmp(showchar, "+"))
strcpy(showchar, "+0");
else if(showchar[1]=='0')
showchar++, showchar[0]=charnumber->sign ? '-' : '+';
return showchar;
}
struct charnumber* string2charnumber(char* string){
if(!(string[0]=='-' || string[0]=='+' || (string[0]>='0' && string[0]<='9'))){
printf("error: in string2charnumber, invalid input number!\n");
return NULL;
}
struct charnumber *number;
char* temp = malloc(strlen(string));
int i, odd;
strcpy(temp, string);
number = malloc(sizeof(struct charnumber));
if(temp[0]=='-'){
number->sign = 1;
temp++;
}
else{
number->sign = 0;
}
odd = strlen(temp)%2;
LOG("strlen(temp): %d, odd=%d\n", strlen(temp), odd);
number->length = strlen(temp)/2 + odd;
number->array = malloc(number->length);
number->pointerforfree = number->array;
for(i=number->length-1; i>=0; i--){
if(i){
if(temp[i*2+1-odd] > '9' || temp[i*2+1-odd] < '0' || temp[i*2-odd] > '9' || temp[i*2-odd] < '0'){
printf("error! in string2charnumber, invalid input number!\n");
LOG("temp[%d]=%x, temp[%d]=%x",i*2+1-odd, temp[i*2+1-odd], i*2-odd, temp[i*2-odd]);
return NULL;
}
number->array[i]=(temp[i*2+1-odd] - '0') + ((temp[i*2-odd] - '0') << 4);
LOG("number->array[%d]=%x", i, number->array[i]);
}
else{
number->array[0]=odd ? temp[0] - '0' : (temp[1] - '0') + ((temp[0] - '0') << 4);
LOG("temp[1]:%d, temp[0]:%d, '0':%d, number->array[%d]=%x",temp[1],temp[0], '0', i, number->array[i]);
}
}
return number;
}
struct charnumber* minusCharNumber(struct charnumber* charnumber1, struct charnumber* charnumber2);
struct charnumber* plusCharNumber(struct charnumber* charnumber1, struct charnumber* charnumber2){
struct charnumber *temp1, *temp2, *sum;
if(!!charnumber1->sign != !!charnumber2->sign){
temp1 = malloc(sizeof(struct charnumber));
temp2 = malloc(sizeof(struct charnumber));
memcpy(temp1, charnumber1, sizeof(struct charnumber));
memcpy(temp2, charnumber2, sizeof(struct charnumber));
temp2->sign = !temp2->sign;
sum = minusCharNumber(temp1, temp2);
free(temp1->pointerforfree), free(temp2->pointerforfree), free(temp1), free(temp2);
return sum;
}
int i, carry = 0;
if(charnumber1->length >= charnumber2->length){
temp1 = charnumber1;
temp2 = charnumber2;
}
else{
temp1 = charnumber2;
temp2 = charnumber1;
}
sum = malloc(sizeof(struct charnumber));
sum->sign = temp1->sign;
LOG("signed:%d", sum->sign);
sum->array = malloc(temp1->length+1);
sum->pointerforfree = sum->array;
for(i=temp1->length; i>temp1->length-temp2->length; i--){ //遍历较小数的位数
sum->array[i]=(carry + temp1->array[i-1]&15) + (temp2->array[i-(temp1->length+1-temp2->length)]&15);
carry = 0;
if(sum->array[i]>9){
sum->array[i] = 6 + sum->array[i];
}
sum->array[i]=sum->array[i] + (temp1->array[i-1]>>4<<4) + (temp2->array[i-(temp1->length+1-temp2->length)]>>4<<4);
if(sum->array[i]>159)
sum->array[i] -= 160, carry = 1;
LOG("i: %d, 0x%x, 1:0x%x, 2:0x%x", i, sum->array[i], temp1->array[i-1], temp2->array[i-(temp1->length+1-temp2->length)]);
}
while(carry && i>=1){ //在遍历完较小数的位数后,处理可能的进位
sum->array[i] = temp1->array[i-1] + 1;
if((sum->array[i]&15) == 10){
LOG("carry1.0, %x", sum->array[i]);
sum->array[i]=(sum->array[i]&240) + 16;
LOG("carry1.1, %x", sum->array[i]);
if(sum->array[i] == 160){
sum->array[i]=0;
carry=1;
LOG("carry2");
}
else
carry=0;
}
else
carry=0;
i--;
}
if(carry){
sum->array[0]=1;
sum->length = temp1->length+1;
}
else{
sum->array++;
memcpy(sum->array, temp1->array, i);
sum->length = temp1->length;
}
return sum;
}
struct charnumber* multiplyCharNumberAndInt(struct charnumber* charnumber, int n){
long i;
struct charnumber *result, *temp;
result = interger2charnumber(0);
for(i=0; i<n; i++){
temp = result;
result = plusCharNumber(result, charnumber);
free(temp->pointerforfree);
free(temp);
}
if(charnumber->sign ^ (n<0) )
result->sign = 1;
else
result->sign = 0;
return result;
}
int mypow(int x, int y){
int i, sum=1;
for(i=0; i<y; i++){
sum=sum*x;
}
return sum;
}
struct charnumber* multiplyCharNumber(struct charnumber* charnumber1, struct charnumber* charnumber2){
int i, orisign1, orisign2;
struct charnumber* result, *temp1, *temp2, *tempforfree1, *tempforfree2, *tempforfree3;
orisign1 = charnumber1->sign;
orisign2 = charnumber2->sign;
charnumber1->sign = 0;
charnumber2->sign = 0;
if(charnumber1->length >= charnumber2->length){
temp1 = charnumber1;
temp2 = charnumber2;
}
else{
temp1 = charnumber2;
temp2 = charnumber1;
}
result = interger2charnumber(0);
LOG("t1length:%d, t2length:%d", temp1->length, temp2->length);
for(i=0; i<temp2->length; i++){
tempforfree1 = multiplyCharNumberAndInt(temp1, temp2->array[i]&15);
tempforfree2 = multiplyCharNumberAndInt(tempforfree1, mypow(10, (temp2->length-i)*2-2));
tempforfree3 = result;
result = plusCharNumber(tempforfree3, tempforfree2);
free(tempforfree1->pointerforfree), free(tempforfree2->pointerforfree), free(tempforfree3->pointerforfree), free(tempforfree1), free(tempforfree2), free(tempforfree3);
LOG("multip1 i=%d, t1=0x%x, t2=0x%x, t3=0x%x, res=0x%x", i, tempforfree1->array[i], tempforfree2->array[i], tempforfree3->array[i], result->array[i]);
tempforfree1 = multiplyCharNumberAndInt(temp1, temp2->array[i]>>4);
tempforfree2 = multiplyCharNumberAndInt(tempforfree1, mypow(10, (temp2->length-i)*2-1));
LOG("tempforfree1:%s, tempforfree2:%s",charnumber2string(tempforfree1), charnumber2string(tempforfree2));
tempforfree3 = result;
result = plusCharNumber(tempforfree3, tempforfree2);
free(tempforfree1->pointerforfree), free(tempforfree2->pointerforfree), free(tempforfree3->pointerforfree), free(tempforfree1), free(tempforfree2), free(tempforfree3);
}
charnumber1->sign = orisign1;
charnumber2->sign = orisign2;
if(charnumber1->sign ^ charnumber2->sign ){
result->sign = 1;
}
else
result->sign = 0;
return result;
}
struct charnumber* minusCharNumber(struct charnumber* charnumber1, struct charnumber* charnumber2){
struct charnumber *temp1, *temp2, *difference;
if(!!charnumber1->sign != !!charnumber2->sign){
temp1 = malloc(sizeof(struct charnumber));
temp2 = malloc(sizeof(struct charnumber));
memcpy(temp1, charnumber1, sizeof(struct charnumber));
memcpy(temp2, charnumber2, sizeof(struct charnumber));
temp2->sign = !temp2->sign;
difference = plusCharNumber(temp1, temp2);
free(temp1->pointerforfree), free(temp2->pointerforfree), free(temp1), free(temp2);
return difference;
}
int i, borrow = 0;
difference = malloc(sizeof(struct charnumber));
if(charnumber1->length > charnumber2->length){
temp1 = charnumber1;
temp2 = charnumber2;
difference->sign = temp1->sign;
}
else if(charnumber1->length < charnumber2->length){
temp1 = charnumber2;
temp2 = charnumber1;
difference->sign = -temp1->sign;
}
else{
for(i=0; i<charnumber1->length; i++){
if(charnumber1->array[i] > charnumber2->array[i]){
temp1 = charnumber1;
temp2 = charnumber2;
difference->sign = temp1->sign;
break;
}
else if(charnumber1->array[i] < charnumber2->array[i]){
temp1 = charnumber2;
temp2 = charnumber1;
difference->sign = -temp1->sign;
break;
}
}
if(i == charnumber1->length)
return interger2charnumber(0);
}
difference->array = malloc(temp1->length);
difference->pointerforfree = difference->array;
for(i=temp1->length-1; i>=temp1->length-temp2->length; i--){ //遍历较小数的位数
difference->array[i]=(borrow + temp1->array[i]&15) - (temp2->array[i-(temp1->length-temp2->length)]&15);
if(difference->array[i]>10){
difference->array[i] = difference->array[i]-6;
}
LOG("minus:i: %d, 0x%x, 1:0x%x, 2:0x%x", i, difference->array[i], temp1->array[i], temp2->array[i-(temp1->length-temp2->length)]);
borrow = 0;
difference->array[i]=difference->array[i] + (temp1->array[i]>>4<<4) - (temp2->array[i-(temp1->length-temp2->length)]>>4<<4);
if(difference->array[i]>160)
difference->array[i] += 160, borrow = -1;
LOG("minus:i: %d, 0x%x, 1:0x%x, 2:0x%x", i, difference->array[i], temp1->array[i], temp2->array[i-(temp1->length-temp2->length)]);
}
if(!borrow && temp1->length - temp2->length == 1)
memcpy(difference->array, temp1->array, i+1);
while(borrow && i>=0){ //在遍历完较小数的位数后,处理可能的借位
difference->array[i] = temp1->array[i] - 1;
if((difference->array[i]&15) == 15){
LOG("carry1.0, %x", difference->array[i]);
difference->array[i]=(difference->array[i]&240) - 7;
LOG("carry1.1, %x", difference->array[i]);
if(difference->array[i] == 249){//0xf9
difference->array[i]=153;//0x99
borrow=-1;
LOG("carry2");
}
else
borrow=0;
}
else
borrow=0;
i--;
}
LOG("BEFORE WHILE, i=%d", i);
if(i>0){
LOG("memcpy");
memcpy(difference->array, temp1->array, i+1);
difference->length = temp1->length;
}
else{
i=0;
while(difference->array[0]==0){
difference->array++;
i++;
}
difference->length = temp1->length-i;
}
return difference;
}
//struct charnumber* powerCharNumber(struct charnumber* charnumber1, struct charnumber* pow){
// struct charnumber* char1, sum=1;
// int i;
// char1 = malloc(struct charnumber);
// char1->length = charnumber1->length;
// char1->sign = charnumber1->sign;
// char1->array = malloc(char1->length);
// char1->pointerforfree = char1->array;
// memcpy(char1->array, charnumber1->array, char1->length);
// while(char1->length != 0){
// if(char1->array[char1->length-1]&15 == 0){
// if(char1->array[char1->length-1] == 0){
// char1->array[char1->length-2]
// }
// }
// sum=multiplyCharNumber(sum, charnumber1);
// char1->length--;
// }
// return sum;
//}
超大整数运算算法——为RSA加密算法提供运算工具的更多相关文章
- 数据加密--详解 RSA加密算法 原理与实现
RSA算法简介 RSA是最流行的非对称加密算法之一.也被称为公钥加密.它是由罗纳德·李维斯特(Ron Rivest).阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adlema ...
- RSA加密算法的加密与解密
转发原文链接:RSA加密算法加密与解密过程解析 1.加密算法概述 加密算法根据内容是否可以还原分为可逆加密和非可逆加密. 可逆加密根据其加密解密是否使用的同一个密钥而可以分为对称加密和非对称加密. 所 ...
- RSA加密算法 C++实现
上信息安全课,老师布置了几个大作业,其中一个为RSA加密算法的实现,不能用Java写.出于兴趣,决定尝试.完成之后,为了便于查找,于是写下这篇文章,以备后续查看.也供大家一起学习,一起进步. 1.预备 ...
- 用实例讲解RSA加密算法(精)
RSA是第一个比较完善的公开密钥算法,它既能用于加密,也能用于数字签名.RSA以它的三个发明者Ron Rivest, Adi Shamir, Leonard Adleman的名字首字母命名,这个算法经 ...
- 轻松学习RSA加密算法原理
转自:http://blog.csdn.net/sunmenggmail/article/details/11994013 http://blog.csdn.net/q376420785/articl ...
- RSA加密算法原理及RES签名算法简介
第一部分:RSA算法原理与加密解密 一.RSA加密过程简述 A和B进行加密通信时,B首先要生成一对密钥.一个是公钥,给A,B自己持有私钥.A使用B的公钥加密要加密发送的内容,然后B在通过自己的私钥解密 ...
- 轻松学习RSA加密算法原理 (转)
轻松学习RSA加密算法原理 (转) http://blog.csdn.net/q376420785/article/details/8557266 http://www.ruanyifeng.com/ ...
- [转] 用实例给新手讲解RSA加密算法
http://www.cfca.com.cn/zhishi/wz-012.htm PS: 通常公钥对数据加密,私钥对数据解密:私钥对数据签名,公钥对数据签名进行认证 RSA加密算法是最常用的非对称加密 ...
- 用实例给新手讲解RSA加密算法
图为 RSA公开密钥算法的发明人,从左到右Ron Rivest, Adi Shamir, Leonard Adleman. 照片摄于1978年 RSA加密算法是最常用的非对称加密算法,CFCA在证书服 ...
随机推荐
- 网络服务器带宽Mbps、Mb/s、MB/s有什么区别?10M、100M到底是什么概念?
网络服务器带宽Mbps.Mb/s.MB/s有什么区别?我们经常听到IDC提供的服务器接入带宽是10M独享,或者100M独享,100M共享之类的数据.这的10M.100M到底是什么概念呢? 工具/原料 ...
- 项目开发-->一键登录功能汇总
开发网站经常会提供一些一键登录功能,如:QQ.新浪微博.淘宝账号.开心网账号.人人网账号等进行快捷登录,下面记录几个常用的开放平台地址,方便以后开发需要. 1.QQ互联 2.新浪微博 网站接入QQ互联 ...
- 我是IT小小鸟,老师我之前上传了!!!!老是请您看到我
我是IT小小鸟读后感 世界上没有一蹴而就的成功者,只有头悬梁锥刺股的奋斗者.蜉蝣向往大鹏的辉煌,却不曾知大鹏以往的汗水.蜉蝣之所以为蜉蝣,是因为它犹如井底之蛙,目光短浅,之盲目地羡慕成功者,而大鹏之所 ...
- 避免JS全局变量冲突
一.原则1.1 用匿名函数将脚本包起来1.2 使用命名空间(多级) 二.改进过程 2.1 原始数据(a.js和b.js都有全局变量window.a,导致冲突,全局变量属于window) //a.js& ...
- Matlab动态数组实现
clear all; clc; a = []; %不是null,也不能什么都不是 for i=1:10 a = [a i]; end
- c++ 遍历ini
inline void CDLG_SET1::EnumIniFile(LPCTSTR pFilePath, CString strKey) { TCHAR strAppNameTemp[];//所有A ...
- FullPage.js全屏滚动插件学习总结
如今我们经常能见到全屏网站,尤其是国外网站.这些网站用几幅很大的图片或色块做背景,再添加一些简单的内容,显得格外的高端大气上档次.比如 iPhone 5C 的介绍页面(查看),QQ浏览器的官网站.如果 ...
- 1051: [HAOI2006]受欢迎的牛
1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2276 Solved: 1190[Submit][Sta ...
- java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed
org.springframework.dao.TransientDataAccessResourceException: ### Error updating database. Cause: ja ...
- 使用Rails 4.2+ 测试异步邮件系统
[导读]异步测试总是一个很大的问题,邮件发送测试更是让很多开发同学不知道从哪里入手.在新版的Rails里,这类测试在很大程度上被简化了. 以下为译文 在编写需要发送邮件的应用时,控制器是绝不能被阻塞的 ...