写在前言:持续更新中...

光滑数

定义

对于一个数 \(n\),如果它能够被唯一分解为 \(n = p_{1}^{\alpha_1}p_{2}^{\alpha_2} \dots p_{s}^{\alpha_s}(p_1 < p_2 < ... < p_s)\),如果对于所有的 \(p_i(1 \le i \le s)\) 均有 \(p_i \le B\),那么我们称这个数为 \(B - \text{光滑}\) 的。

很多算法是基于 \(B\) 较小的情况来进行解决,我们可以看下面的例题来学习,以下 \(B - \text{光滑}\) 的数若 \(B\) 较小,简称光滑数。

p - 1 光滑

Pollard's 算法

若 \(p\) 是 \(n\) 的因数,并且 \(p − 1\) 是光滑数,可以考虑使用 Pollard's 算法来分解 \(n\)。

Wiki 上的算法流程如下:

由于 \(p - 1\) 是光滑的,选取一个 \(B\) 使得 \((p - 1) \mid B!\)。

根据费马小定理,我们有:

\[a^{p-1} \equiv 1 (\bmod ~ p)
\]

那么可以推出 \(a^{K(p-1)} \equiv 1 \pmod p\)。

由于 \(B! = K(p-1)\),所以 \(a^{B!} \equiv 1 \pmod p\)

因此 \(a^{B!} - 1 = k_{1}p\)。

同时,让 \(a^{B!}\) 模 \(n\) 有 \(a^{B!} \equiv A \pmod n\)

因此 \(a^{B!} - A = k_{2}n\)。

上述两式相减可得 \(A - 1 = k_{2}n - k_{1}p\)。

不难发现 \(p = \gcd{(A - 1, ~ n)}\)。

注意:选取恰当的 \(B\) 是必要的,如果 \(n = pq\) 中 \(p, ~ q\) 两个因子均是光滑的,且 \((p - 1) \mid B!\) 与 \((q - 1) \mid B!\) 同时成立,那么此时 \(a^{(p - 1)(q - 1)} \equiv 1 \pmod {pq}\) 此时计算 \(\gcd{(A - 1, ~ n)}\) 得到的结果为 \(n\),同理,\(B\) 较小会导致 \(\gcd{(A - 1, ~ n)} = 1\)。

由于计算阶乘的算法效率低下所以对于非光滑数这个算法没有意义

下面我们来看一个例题。

SHCTF 2024 魔鬼的步伐

from Crypto.Util.number import *
from random import choice
from enc import flag m = bytes_to_long(flag)
def get_primes(limit):
primes = []
is_prime = [True] * (limit + 1)
for num in range(2, limit + 1):
if is_prime[num]:
primes.append(num)
for multiple in range(num * num, limit + 1, num):
is_prime[multiple] = False
return primes def get_Prime(bits):
while True:
n = 2
while n.bit_length() < bits:
n *= choice(primes)
if isPrime(n + 1):
return n + 1 e = 65537
primes = get_primes(e)
p = get_Prime(512)
q = get_Prime(512)
n = p*q
c = pow(m,e,n)
print(f"n = {n}")
print(f"e = {e}")
print(f"c = {c}")
'''
n = 391005776046755596699618659246340733279513517050143630792209612493300221058346162409182143062864675702996104615097739220521431717966140002923091879824285706802681307073746160973177190517416980825268203022023401016332004335037582180267013391314432153625679364386326204808730143431891425324668120649464691460108081
e = 65537
c = 143234875923924414196836790485715958182553144290862550786433431528452602241496206240152356816911891891888596692519884126258641274109685025389569676536718006741800941833337629087306702531952775237637889020188884538158307245138965948781078007989600030230701865185135035643226997549934727114764825219500382771617775
'''

通过代码可以发现 \(p, q\) 一定是 \(e - \text{光滑}\) 的,尝试将 \(B\) 取 \(e\) 进行运算发现结果为 \(n\),因此我们在 \((1, ~ e)\) 中进行二分求得一个恰当的 \(B\),时间复杂度是 \(O(e\log{e})\) 的,所以我们可以很快求出答案。

脚本如下:

from Crypto.Util.number import *
from gmpy2 import *
from math import factorial
n = 391005776046755596699618659246340733279513517050143630792209612493300221058346162409182143062864675702996104615097739220521431717966140002923091879824285706802681307073746160973177190517416980825268203022023401016332004335037582180267013391314432153625679364386326204808730143431891425324668120649464691460108081
e = 65537
c = 143234875923924414196836790485715958182553144290862550786433431528452602241496206240152356816911891891888596692519884126258641274109685025389569676536718006741800941833337629087306702531952775237637889020188884538158307245138965948781078007989600030230701865185135035643226997549934727114764825219500382771617775 l = 1
r = e
while (l < r):
mid = l + r >> 1
a = pow(2, math.factorial(mid), n)
p = gmpy2.gcd(a - 1, n)
if p == 1:
l = mid + 1
continue
if p == n:
r = mid - 1
continue
q = n // p
d = gmpy2.invert(e, (p - 1) * (q - 1))
m = pow(c, d, n)
print(long_to_bytes(m))
break

RSA 数论技巧的更多相关文章

  1. 【数论+技巧】神奇的Noip模拟试题第二试 T1 素数统计

    1.      素数统计 (pcount.pas/.c/.cpp) [问题描述] 小tan的老师揣谙戈给同学们布置了一道题,要求统计给定区间内素数的个数.“这不是很简单吗?”小tan忍不住说.揣谙戈冷 ...

  2. RSA学习档案

    RSA 学习档案 基本原理 随机选择两个质数p,q模数n=p*qφ(n)=(p−1)(q−1)选择加密指数e: 1 < e < φ(n)计算机密指数d: e*d % φ(n) = 1c = ...

  3. Luogu P5285 [十二省联考2019]骗分过样例

    Preface ZJOI一轮被麻将劝退的老年选手看到这题就两眼放光,省选也有乱搞题? 然后狂肝了3~4天终于打完了,期间还补了一堆姿势 由于我压缩技术比较菜,所以用的都是非打表算法,所以一共写了5K- ...

  4. 题解 loj3050 「十二省联考 2019」骗分过样例

    CASE \(1\sim 3\) \(n\)组测试数据,每次输入一个数\(x\),求\(19^x\). 测试点\(1\),\(x=0,1,\dots n-1\),可以直接递推. 测试点\(2\)要开l ...

  5. RSA算法原理——(2)RSA简介及基础数论知识

    上期为大家介绍了目前常见加密算法,相信阅读过的同学们对目前的加密算法也算是有了一个大概的了解.如果你对这些解密算法概念及特点还不是很清晰的话,昌昌非常推荐大家可以看看HTTPS的加密通信原理,因为HT ...

  6. RSA简介(一)——数论原理

    RSA是最常用的非对称加密算法. 所谓非对称加密,就是说有两个密钥,一个密钥加密只可以用另外一个密钥解密,一般一个作为公钥,公开给所有人用来加密用,而另一个用来解密其他拥有公钥的加密结果,叫做私钥.另 ...

  7. python技巧总结之set、日志、rsa加密

    一.日志模块logging模块调用 1.日志模块使用原理 #!/usr/bin/python # -*- coding:utf-8 -*- import logging # 方式一: "&q ...

  8. 项目开发中的一些注意事项以及技巧总结 基于Repository模式设计项目架构—你可以参考的项目架构设计 Asp.Net Core中使用RSA加密 EF Core中的多对多映射如何实现? asp.net core下的如何给网站做安全设置 获取服务端https证书 Js异常捕获

    项目开发中的一些注意事项以及技巧总结   1.jquery采用ajax向后端请求时,MVC框架并不能返回View的数据,也就是一般我们使用View().PartialView()等,只能返回json以 ...

  9. UVA11752 The Super Powers —— 数论、枚举技巧

    题目链接:https://vjudge.net/problem/UVA-11752 题意: 一个超级数是能够至少能表示为两个数的幂,求1~2^64-1内的超级数. 题解: 1.可知对于 n = a^b ...

  10. 公钥密码RSA算法记录

    介绍: RSA算法是1978年由 R.Rivest.A.Shamir.L.Adleman提出的一种用数论构造的.也是迄今为止理论上最为成熟.完善的公钥密码体,该体制已得到广泛的应用. 算法描述: 1. ...

随机推荐

  1. WiFi基础(二):最新WiFi信道、无线OSI模型与802.11b/g/n

    liwen01 2024.09.01 前言 最近十几年,通信技术发展迅猛,通信标准更新频繁,有的设备还在使用 802.11/b/g/n 协议,有的已支持到 WiFi6.WiFi7. 而国内有关无线 W ...

  2. SpringMVC的视图

    目录 ThymeleafView 转发视图 重定向视图 视图控制器view-controller SpringMVC中的视图是View接口,视图的作用渲染数据,将模型Model中的数据展示给用户Spr ...

  3. MyBatis日志工厂

    目录 日志工厂 标准日志实现 Log4j 使用步骤: 日志工厂 我们在测试SQL的时候,要是能够在控制台输出 SQL 的话,是不是就能够有更快的排错效率? 如果一个 数据库相关的操作出现了问题,我们可 ...

  4. 使用 nuxi info 查看 Nuxt 项目详细信息

    title: 使用 nuxi info 查看 Nuxt 项目详细信息 date: 2024/9/5 updated: 2024/9/5 author: cmdragon excerpt: 摘要:文章介 ...

  5. JWT单点登录

    单点登录 概念:登录某集团的某一产品之后,访问其他产品的网站时就会是登录状态,比如登录QQ之后,进入QQ游戏的时候就是登录过的状态,具体实现方法有以下: Redis+token实现单点登录: 生成一个 ...

  6. eclipse安装及配置jdk、tomcat

    一.安装eclipse: (安装之前一定要确认jdk是否安装,没安装的一定要安装) 官网下载:Eclipse Downloads | The Eclipse Foundation 下载好如图安装程序: ...

  7. [OI] 指针与迭代器

    取地址与解引用 一般来说,我们有一个取地址符 & 可以返回该变量的地址. int main(){ int a; cout<<&a; } 0x6ffe1c 如果我们现在有一个 ...

  8. 【赵渝强老师】史上最详细的PostgreSQL体系架构介绍

    PostgreSQL是最像Oracle的开源数据库,我们可以拿Oracle来比较学习它的体系结构,比较容易理解.PostgreSQL的主要结构如下: 一.存储结构 PG数据存储结构分为:逻辑存储结构和 ...

  9. vue前端开发仿钉图系列(7)底部数据列表的开发详解

    底部数据列表主要是记录图层下面对应的点线面数据,点击单元行或者查看或者编辑,弹出右侧编辑页面,点击单元行地图定位到相应的绘图位置.里面的难点1是动态绑定字段管理编辑的字段以及对应的value值,2是点 ...

  10. html5新标签 画布 canvas 替代了 flash

    绘制矩形边框,和填充不同的是绘制使用的是strokeRect, 和strokeStyle实现的 绘制路径 绘制路径的作用是为了设置一个不规则的多边形状态 路径都是闭合的,使用路径进行绘制的时候需要既定 ...