超大整数运算算法——为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在证书服 ...
随机推荐
- Python编码设置
系统编码顺序: 1, a.encode(sys.stdout.encoding) 2, a.encode(default_string) sys.stdout.encoding里的值可以用环境变量PY ...
- Android入门视频推荐
marschen老师的Android入门视频推荐网址: 1.Android应用程序开发视频教程(重制版)第一季 2.Android应用开发视频教程(重制版)第二季 2.marschen老师的个人微 ...
- 机器学习&&数据挖掘之一:决策树基础认识
决策树入门篇 前言:分类是数据挖掘中的主要分析手段,其任务就是对数据集进行学习并构造一个拥有预测功能的分类模型,用于预测未知样本的类标号,把类标号未知的样本按照某一规则映射到预先给定的类标号中. 分类 ...
- IE 选择文字后 显示小箭头 加速按钮
IE - 工具 - Internet选项 - 高级 - 不选择<在选择是显示加速按钮>选项就可以了.
- Sqlite基础及其与SQLServer语法差异
1 TOP 这是一个大家经常问到的问题,例如在SQLSERVER中可以使用如下语句来取得记录集中的前十条记录: SELECT TOP 10 * FROM [index] ORDER BY indexi ...
- [转载]为什么我希望用C而不是C++来实现ZeroMQ
来源: http://blog.jobbole.com/19647/ 开始前我要先做个澄清:这篇文章同Linus Torvalds这种死忠C程序员吐槽C++的观点是不同的.在我的整个职业生涯里我都在使 ...
- JavaScript事件委托的技术原理
如今的JavaScript技术界里最火热的一项技术应该是‘事件委托(event delegation)’了.使用事件委托技术能让你避免对特定的每个节点添加事件监听器:相反,事件监听器是被添加到它们的父 ...
- sshd_config配置 详解
原文:http://blog.licess.org/sshd_config/ # 1. 关于 SSH Server 的整体设定,包含使用的 port 啦,以及使用的密码演算方式 Port 22 # S ...
- POJ 1939
#include<iostream> #include<iomanip> #define MAXN 10000 using namespace std; ]; int main ...
- mvc5 _ViewStart.cshtml 模板页如何定义
1._Viewstart.cshtml是一个在呈现View文件的时候的启动文件,会在所有View(.cshtml)被执行之前执行,主要用于一些不方便或不能在母版(_Layout.cshtml)中进行的 ...