其他分享
首页 > 其他分享> > RSA的连分数攻击C语言实现

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