RSA的连分数攻击C语言实现
作者:互联网
RSA的连分数攻击C语言实现
R S A RSA RSA公钥加密所基于的困难问题是大整数的质因数分解,在本文中我基于连分数分解合数的思想,对RSA的连分数攻击进行了基本的C语言模拟,我尝试利用连分数对一个小合数进行质因数分解,下方给出了我实现的C代码,并添加了必要的注释.
// 合数的连分数求解.cpp: 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include"conio.h"
#include"math.h"
#include"malloc.h"
#include"string.h"
#include"stdlib.h"
long long GCD(long long a, long long b)//计算最大公因数
{
long long tmp, r;
a < 0 ? a = -a : a = a;
b < 0 ? b = -b : b = b;
a > b ? (a = a, b = b) : (tmp = a, a = b, b = tmp);
r = a % b;
while (r != 0)
{
a = b;
b = r;
r = a % b;
}
return b;
}
typedef double quotient;
typedef long long AP;
typedef struct ContinuedFraction
{
union
{
quotient data;
long long RN;
};
long long length;
struct ContinuedFraction* next;
} CF;
typedef struct ApproximativeContinuedFraction//渐进连分数
{
union
{
AP P;
long long length;
};
AP Q;
struct ApproximativeContinuedFraction* next;
} ACF;
static CF* ApplyNode(quotient x)//申请连分数的新节点
{
CF* s = (CF*)malloc(sizeof(CF));
if (s == NULL)
return NULL;
s->data = x;
s->length = 0;
s->next = NULL;
return s;
}
static ACF* ApplyNode(quotient x, quotient y )//申请连分数的新节点
{
ACF* s = (ACF*)malloc(sizeof(ACF));
if (s == NULL)
return NULL;
s->P = x;
s->Q = y;
s->next = NULL;
return s;
}
void CFInitiate(CF* head)//连分数头结点初始化
{
if (head == NULL)
exit(0);
head->next = NULL;
head->length = 0;
}
void ACFInitiate(ACF* head,long long x)//渐进连分数头结点初始化
{
if (head == NULL)
exit(0);
head->next = NULL;
head->length = x;
}
bool CFInsert(CF* p, quotient x)//连分数节点连接
{
if (p == NULL)
return false;
p->next = ApplyNode(x);
return true;
}
bool ACFInsert(ACF* p, quotient x,quotient y)//渐进连分数节点连接
{
if (p == NULL)
return false;
p->next = ApplyNode(x, y);
return true;
}
CF* SCF(double y)//求解连分数
{
CF* head = (CF*)malloc(sizeof(CF));
CFInitiate(head);
head->RN = y;
double x = sqrt(y);
double A = floor(x);
double X = x - A;
CFInsert(head, A);
head->length = 1;
CF*p = head->next;
while (X > 0.001)
{
A = floor(1 / X);
X = 1 / X - A;
CFInsert(p, A);
p = p->next;
head->length += 1;
}
return head;
}
ACF* SACF(CF * SCF ,long long x)//求解渐进连分数
{
CF* p = SCF;
ACF* head = (ACF*)malloc(sizeof(ACF));
ACFInitiate(head, SCF->length);
ACF* q = head;
long long p1 = 0, p2 = 1, p3, tmp1;
long long q1 = 1, q2 = 0, q3, tmp2;
for(long long i=0;i<SCF->length;i++)
{
p3 = p2 * (p->next->data) + p1;
q3 = q2 * (p->next->data) + q1;
abs(p3%x) < abs((p3%x) - x) ? tmp1 = p3 % x : tmp1 = (p3%x) - x;
abs(q3%x) < abs((q3%x) - x) ? tmp2 = q3 % x : tmp2 = (q3%x) - x;
ACFInsert(q, tmp1, tmp2);
q = q->next;
p = p->next;
p1 = p2;
p2 = p3;
q1 = tmp1;
q2 = tmp2;
}
return head;
}
//质因数分解
long long * PF(ACF*head,long long X)
{
double tmp;
long long tmp1, tmp2, x, y;
long long * s = (long long *)malloc(2 * sizeof(long long));
ACF* p = head->next;
for (long long i = 0; i < head->length; i++)
{
ACF* q = p->next;
for (long long j = 0; j < head->length - i; j++)
{
if (p == NULL)
break;
if (q == NULL)
break;
tmp = sqrt((((p->P)*(p->P)) % X)*(((q->P)*(q->P)) % X));
if ((long long)tmp == tmp)
{
x = p->P*q->P;
y = (long long)tmp;
s[0] = GCD(x - y, X);
s[1] = GCD(x + y, X);
printf("%lld,%lld", s[0], s[1]);
return s;
}
q = q->next;
}
p = p->next;
}
}
void ShowCF(CF* head)//展示连分数
{
CF* p = head->next;
while (p != NULL)
{
printf("%lf;\n", p->data);
p = p->next;
}
}
void ShowACF(ACF* head)//展示渐进连分数
{
ACF* p = head->next;
while (p != NULL)
{
printf("%lld; %lld \n", p->P, p->Q);
p = p->next;
}
}
int main()
{
double X = 37909;
long long Y = 37909;
ACF * p = SACF(SCF(X), Y);
long long *s = PF(p, X);
free(s);
free(p);
_getch();
return 0;
}
我尝试对
37909
37909
37909进行分解:
通过程序的运行,我们得到:
37909
=
227
∗
167
37909=227*167
37909=227∗167
由于计算机的计算精度原因,无法对实数进行精确的连分数分解,这就导致了我的程序不够稳定,并不能对任意的大合数进行精确质因数分解,我会在后续工作中进一步改进我的代码,也欢迎您给予我可贵的指点。
标签:head,ACF,连分数,RSA,long,next,CF,C语言 来源: https://blog.csdn.net/qq_43100483/article/details/110699499