complex rsa

复数rsa,没遇到过这种类型的题,可以记录一下相关知识

先来看一段

from gmpy2 import invert,lcm,is_prime
import sys
sys.setrecursionlimit(2047)f = (378122348642214690905411683807377396279362526734068034297186493255873563264253248095197659138069664908850853277799239471404715546747080714581633876343291058815268009173602365587463522797812239900814474973941995698621021680129530453282192603316731832323767320307650941745085796583822798379896337325L, 205549984221850341303682190742446959375043769671555741781145106776498798455293849755553794941345135675348633855787880355726112506553703853175271830126908219803257875131387292937296039523359975622001865593227631119497003599166091642640101746534401068507972834895023584843991641629874709898672559632L)
e = 59107
p = 228517792080140341
q = 1675909164550923263854591345270445396052847869117231939809062226222204253885693425526434134321712288675268468398852452684029376569327518089966506865838909486699078280423099271324646863671350838232140981094611254627738568184261530942469845202934677427234062382272736609418198352717n = p*qdef cadd(a,b,n):return (a[0]+b[0]%n,a[1]+b[1]%n)def cmul(a,b,n):return ((a[0]*b[0]-a[1]*b[1])%n,(a[0]*b[1]+a[1]*b[0])%n)def cpow(a,k,n):if(k==0):return (1,0)if(k==1):return aif(k%2==0):a=cmul(a,a,n)return cpow(a,k/2,n)else:return cmul(a,cpow(cmul(a,a,n),(k-1)/2,n),n)o=lcm((p*p-1),(q*q-1))
fm=cpow(f,invert(e,o),n)
print(fm)

来源:https://github.com/Ariana1729/CTF-Writeups/blob/master/2019/CryptoCTF/Complex%20RSA/README.md

We first consider the order of C/pC* where p is a prime. The real and imaginary parts ranges from 0 to p-1, so a valid assumption is that the order is a multiple of p*p-1(since 0,0 can't be in the group). The order is exactly p*p-1 for p=3 mod 4 since it cannot be expressed as the sum of 2 squares, but for p=1 mod 4 it is less, and it is a multiple of p*p-1. Thus if we want to find g given g^e=a mod p, we simply invert e under p*p-1. For n=pq, the order is a multiple of lcm(p*p-1,q*q-1), then it's trivial For factoring n we simply use yafu

函数cadd:实现两个复数的加法。
函数cmul:实现两个复数的乘法
函数cpow:实现复数的幂运算,其中k为指数,n为模数

该段实现了一个复数域上的rsa解题过程

复数中欧拉函数:
p h i ( p ) = p 2 − 1 p h i ( q ) = q 2 − 1 p h i ( n ) = ( p 2 − 1 ) ∗ ( q 2 − 1 ) phi(p) = p^2 - 1\\phi(q) = q^2 - 1\\phi(n) = (p^2 - 1)*(q^2 - 1) phi(p)=p21phi(q)=q21phi(n)=(p21)(q21)

题1

[GeekChallenge-2023] EzComplex
题目描述:

from Crypto.Util.number import *
flag = b'FAKE{Do_You_know_Complex_numbers}'
p = random_prime(1 << 384)
q = random_prime(1 << 384)
n = p * q
e = 0x10001
N = pow(p, 2) + pow(q, 2)
m = bytes_to_long(flag)
c = pow(m,e,n)print(c)
print(N)'''
122977267154486898127643454001467185956864368276013342450998567212966113302012584153291519651365278888605594000436279106907163024162771486315220072170917153855370362692990814276908399943293854077912175867886513964032241638851526276
973990451943921675425625260267293227445098713194663380695161260771362036776671793195525239267004528550439258233703798932349677698127549891815995206853756301593324349871567926792912475619794804691721625860861059975526781239293017498
'''

题目分析:
N = p 2 + q 2 = ( p + q ∗ i ) ∗ ( p − q ∗ i ) N = p^2 + q^2 = (p + q*i)*(p - q*i) N=p2+q2=(p+qi)(pqi)
遍历所有因子得到p,q,之后常规rsa解密

from Crypto.Util.number import *c = 122977267154486898127643454001467185956864368276013342450998567212966113302012584153291519651365278888605594000436279106907163024162771486315220072170917153855370362692990814276908399943293854077912175867886513964032241638851526276
N = 973990451943921675425625260267293227445098713194663380695161260771362036776671793195525239267004528550439258233703798932349677698127549891815995206853756301593324349871567926792912475619794804691721625860861059975526781239293017498
e = 65537zn = ZZ[i](N)
for d in divisors(zn):p = int(d[0])q = int(d[1])if isPrime(p) and isPrime(q) and p.bit_length() > 380:        breakphi = (p-1)*(q-1)
n  = p*q
d = inverse(e,phi)
print(long_to_bytes(int(pow(c,d,n))))
# SYC{D0_you_like_r41n?_i_pref3r_R1_ng}

ZZ(i)[N]:创建了一个整数高斯环。这个环的元素由整数和虚数部分组成,且整数和虚数部分都是整数。其中N是一个整数,表示高斯环的模,元素中整数和虚数部分的取值范围是[-N/2, N/2]

假设复数: a + b ∗ i a + b * i a+bi,那么 a,b ∈[-N/2, N/2]
其中有一种特殊情况:a = N,b = 0

题2

题目描述:

import os
import hashlib
from Crypto.Util.number import *
from secret import flag, totient
# where totient is a function used to calculate phiclass Complex:def __init__(self, re, im):self.re = reself.im = imdef __mul__(self, c):re_ = self.re * c.re - self.im * c.imim_ = self.re * c.im + self.im * c.rereturn Complex(re_, im_)def show(self):print([self.re, self.im])def complex_pow(c, exp, n):result = Complex(1, 0)while exp > 0:if exp & 1:result = result * cresult.re = result.re % nresult.im = result.im % nc = c * cc.re = c.re % nc.im = c.im % nexp >>= 1return resultdef pad(msg, length):pad_length = length - len(msg) - 1pad_data = os.urandom(pad_length)return msg + b'\x00' + pad_datadef unpad(msg):return msg.split(b"\x00")[0]bits = 512
p = getPrime(bits)
q = getPrime(bits)
n = p * qsha_flag = hashlib.sha256(flag).digest()m1 = Complex(int.from_bytes(sha_flag[:len(sha_flag)//2], "big"),int.from_bytes(sha_flag[len(sha_flag)//2:], "big"),)m2 = Complex(int.from_bytes(pad(flag[:len(flag)//2], bits//4-1), "big"),int.from_bytes(pad(flag[len(flag)//2:], bits//4-1), "big"),)phi = totient(p, q)
e = q * inverse(p, phi)
c1 = complex_pow(m1, e, n)
c2 = complex_pow(m2, e, n)c1.show()
c2.show()
print(f'n = {n}')"""
[90554536599623574119664951128649936419332926063696768860765928746438458550068553748440108394673303800443215316190882880737918820592384729010491685487061658710808286341751196450604089438847354206384322610922839055308138101241906861635339635907663440043442187064090630207952625897567214431195621589834131462698, 9144096375153318849308858335764188418198064372272913164911615933938183103747900881824918069830188301084043148828961577193063557255905230182831945580084452509300200269659063051152684191139872067872645370760797859584822240361290678189844670289832298393156571913616456958845361092243648857334156534377833472900]
[62925714576233017213228404230949787334346543378320798964656732359587152905032848271156799538355748406136742979043729040728123730886381468564779041856310262770766050213464073568850702827835472680885186487027698395099598698463717279017013124488699475168052581476224742146967412904416266652605031934025266540003, 62818668456104375760667670741457826560706388018921820295286033114468271151921637926389738844622672202424650967678199715932465104135980734708459543588178208672956785650944371545080965650112025782049517299538052360417245732776384089052839997333049599655001615752078742624898059780909287845495731050387891926520]
n = 94040393367054633265453751757391098049234338193258976478647369399924701067077628840760704857546243644552533845934146003988635403227234096447871132283820920489003286967145732739404245319615714787916756200564828237043658350145929927911058782352154997346295194977765305107634012698472977467843980475009837261877
"""

题目分析:
可以看出是一道基于复数的rsa,re实部,im虚部
complex_pow(m,e,n)函数计算的是 m e m o d n m^e \mod n memodn
其中phi = totient(p,q)e = q * inverse(p,phi)
里面提示totient is a function used to calculate phi,而此题又是基于复数域上的,那么可以猜测 p h i = t o t i e n t ( p , q ) = ( p 2 − 1 ) ∗ ( q 2 − 1 ) phi = totient(p,q) = (p^2-1)*(q^2-1) phi=totient(p,q)=(p21)(q21)

从加密流程可以看出:
c1的实部是sha_flag前半部分,虚部是sha_flag后半部分
c2的实部是flag前半部分,虚部是flag后半部分

e ≡ q ∗ p − 1 m o d p h i e ∗ p ≡ q m o d p h i e ∗ n ≡ q 2 m o d p h i c 1 n ≡ m 1 e ∗ n ≡ m 1 q 2 m o d n c 1 n ≡ m 1 q 2 ≡ m 1 m o d q ( 回到上面 p h i ( q ) = q 2 − 1 ) e \equiv q * p^{-1} \mod phi\\ e*p \equiv q \mod phi\\ e * n \equiv q^2 \mod phi\\ c_1^n \equiv m_1^{e*n} \equiv m_1^{q^2} \mod n\\ c_1^n \equiv m_1^{q^2} \equiv m_1\mod q\\ (回到上面phi(q) = q^2 - 1)\\ eqp1modphiepqmodphienq2modphic1nm1enm1q2modnc1nm1q2m1modq(回到上面phi(q)=q21)
c 1 n − m 1 = k ∗ q c_1^n - m_1 = k * q c1nm1=kq
m 1 m_1 m1只有128比特,比q的一半位数还小的多,完全可以copper求出 m 1 m_1 m1
之后gcd(k*q,n)得到q,那么p,q就都出了
然后常规rsa解题思路得到flag

注意,这里实现pow用它定义的complex_pow()

from Crypto.Util.number import *
from gmpy2 import *class Complex:def __init__(self, re, im):self.re = reself.im = imdef __mul__(self, c):re_ = self.re * c.re - self.im * c.imim_ = self.re * c.im + self.im * c.rereturn Complex(re_, im_)def show(self):print([self.re, self.im])def get_value(self):return self.re,self.imdef complex_pow(c, exp, n):result = Complex(1, 0)while exp > 0:if exp & 1:result = result * cresult.re = result.re % nresult.im = result.im % nc = c * cc.re = c.re % nc.im = c.im % nexp >>= 1return resultc1 = [90554536599623574119664951128649936419332926063696768860765928746438458550068553748440108394673303800443215316190882880737918820592384729010491685487061658710808286341751196450604089438847354206384322610922839055308138101241906861635339635907663440043442187064090630207952625897567214431195621589834131462698, 9144096375153318849308858335764188418198064372272913164911615933938183103747900881824918069830188301084043148828961577193063557255905230182831945580084452509300200269659063051152684191139872067872645370760797859584822240361290678189844670289832298393156571913616456958845361092243648857334156534377833472900]
c2 = [62925714576233017213228404230949787334346543378320798964656732359587152905032848271156799538355748406136742979043729040728123730886381468564779041856310262770766050213464073568850702827835472680885186487027698395099598698463717279017013124488699475168052581476224742146967412904416266652605031934025266540003, 62818668456104375760667670741457826560706388018921820295286033114468271151921637926389738844622672202424650967678199715932465104135980734708459543588178208672956785650944371545080965650112025782049517299538052360417245732776384089052839997333049599655001615752078742624898059780909287845495731050387891926520]
n = 94040393367054633265453751757391098049234338193258976478647369399924701067077628840760704857546243644552533845934146003988635403227234096447871132283820920489003286967145732739404245319615714787916756200564828237043658350145929927911058782352154997346295194977765305107634012698472977467843980475009837261877
c1 = Complex(c1[0],c1[1])
c2 = Complex(c2[0],c2[1])
cc1 = complex_pow(c1,n,n).get_value()P.<m> = Zmod(n)[]
f = cc1[0] - m
f = f.monic()
m1 = f.small_roots(2^128,0.4)[0]q = gcd(cc1[0]-int(m1),n)
p = n // q
phi = (p^2 - 1) * (q ^ 2 - 1)
e = q * inverse(p, phi)
d = inverse(e,phi)
m2 = complex_pow(c2,d,n).get_value()
print(long_to_bytes(int(m2[0])))
print(long_to_bytes(int(m2[1])))
# flag{3ef6db06-b837-11ed-9825-00155dfcdef9}

感觉这道题真的很有意思

浅记一下:
关键词:复数欧拉,ZZ(i)[N],coppersmith

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/190889.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IDEA常用快捷键

快捷键功能tab接受选择–选择的名称将覆盖带插入符号右侧的其它名称–而如果按shift或者enter&#xff0c;光标右边的内容会保留Ctrlshift空格智能匹配–查找当前上下文的方法和变量Ctrld对比文件–选中需要对比的文件shift滚动水平滚动Ctrlaltl格式化Ctrlk提交Ctrlaltz回滚类C…

Linux基础项目开发1:量产工具——UI系统(五)

前言&#xff1a; 前面我们已经把显示系统、输入系统、文字系统搭建好了&#xff0c;现在我们就要给它实现按钮操作了&#xff0c;也就是搭建UI系统&#xff0c;下面让我们一起实现UI系统的搭建吧 目录 一、按钮数据结构抽象 ui.h 二、按键编程 1.button.c 2.disp_manager…

YUM 问题解决步骤

YUM 问题解决步骤 当使用 yum 进行安装软件包或者更新时&#xff0c;如果遇到卡在加载插件阶段或其他相关问题&#xff0c;如下 [rootVM-12-2-centos ~]# sudo yum update Loaded plugins: fastestmirror, langpacks Repository epel is listed more than once in the config…

linux shell编程

Linux shell编程 一、常用功能1. 比较图片差异2. 截屏2.1 起X情况下&#xff08;X window起桌面&#xff09;2.2 没有起X或没有X系统环境下 3. 自动输入密码 一、常用功能 1. 比较图片差异 if compare -metric AE p1.png p2.png null: 2>&1 | grep -v "0$";…

查找算法及哈希表

1 二分查找 1.1 重要概念 拟解决的问题&#xff1a;判断某个区间是否包含某个元素&#xff0c;无法确定区间中包含重复元素的具体位置&#xff1b;使用条件&#xff1a;查找的区间必须符合单调性&#xff1b;本质&#xff1a;采用分治思想&#xff0c;将某个单调区间一分为二…

12.2_黑马Redis实战篇附近商铺用户签到UV统计

实战篇11 实战篇12 要先用test的方式把商铺的数据导入到idea当中&#xff0c;才可以进行查询噢。 代码&#xff1a; 实战篇13 thinking&#xff1a;插件mavenhelper&#xff1f; 方便处理pom文件。 实战篇15 实战篇16 thinking&#xff1a;XX.format(DateTimeFormatter.ofP…

【网络安全技术】实体认证技术Kerberos

一、什么是Kerberos Kerberos解决的是客户端与服务器通信场景中&#xff0c;确保客户端服务器双方的身份可信&#xff0c;并提供对称密钥的分发来加密传输。是一个应用层的协议。 二、一个简单的模型 1.看这个基础的模型&#xff0c;客户端要和服务器通信&#xff0c;他先将自…

《堆》的模拟实现

目录 前言&#xff1a; 模拟实现《堆》&#xff1a; 1.自定义数据类型 2.初始化“堆” 3.销毁“堆” 4.进“堆” 关于AdjustUp() 5.删除堆顶元素 关于AdjustDown() 6.判断“堆”是否为空 7.求“堆”中的数据个数 8.求“堆”顶元素 总结&#xff1a; 前言&#xf…

「LeetCode Hot 100 题」详解

前言 前言&#xff1a;LeetCode Hot 100 题详解 文章目录 前言1. 两数之和2. 字母异位词分组3. 最长连续序列4. 移动零 1. 两数之和 原题链接&#xff1a;两数之和 知识点&#xff1a;哈希表 题解 class Solution {public int[] twoSum(int[] nums, int target) {Map<Inte…

mysql原理--重新认识MySQL

1.MySQL请求处理 1.1.查询缓存 MySQL 服务器程序处理查询请求时&#xff0c;会把刚刚处理过的查询请求和结果缓存起来&#xff0c;如果下一次有一模一样的请求过来&#xff0c;直接从缓存中查找结果就好了&#xff0c;就不用再傻呵呵的去底层的表中查找了。这个查询缓存可以在不…

DOM 事件的传播机制

前端面试大全DOM 事件的传播机制 &#x1f31f;经典真题 &#x1f31f;事件与事件流 事件流 事件冒泡流 事件捕获流 标准 DOM 事件流 &#x1f31f;事件委托 &#x1f31f;真题解答 &#x1f31f;总结 &#x1f31f;经典真题 谈一谈事件委托以及冒泡原理 &#x1f3…

SmartSoftHelp8数据库连接字符串强优化,高并发配置

1.设置数据库是否异步连接 2.数据库连接是否复用 3.最大链接数 4.最小连接数 5.等待时间 6.生命周期 下载地址&#xff1a; 百度网盘 请输入提取码

24、蜂鸣器

蜂鸣器介绍 蜂鸣器是一种将电信号转换为声音信号的器件&#xff0c;常用来产生设备的按键音、报警音等提示信号 蜂鸣器按驱动方式可分为有源蜂鸣器和无源蜂鸣器 有源蜂鸣器&#xff1a;内部自带振荡源&#xff0c;将正负极接上直流电压即可持续发声&#xff0c;频率固定 无源蜂…

【linux】信号——信号保存+信号处理

信号保存信号处理 1.信号保存1.1信号其他相关概念1.2信号在内核中的表示 2.信号处理2.1信号的捕捉流程2.2sigset_t2.3信号集操作函数2.4实操2.5捕捉信号的方法 3.可重入函数4.volatile5.SIGCHLD信号 自我名言&#xff1a;只有努力&#xff0c;才能追逐梦想&#xff0c;只有努力…

Vue2中响应式的原理

Vue2中实现响应式的原理 vue2实现原理Vue2响应式存在的问题 vue2实现原理 使用Object.defineProperty()的get()与set()来实现响应式 <script>let p {}let person {name: "张三",sex:"男",hobby: ["吃饭","睡觉"]}Object.def…

C++:模板进阶

目录 1.非类型模板参数 2. 模板的特化 2.1 概念 2.2 函数模板的特化 2.3 类模板的特化 2.3.1 全特化 2.3.2 偏特化 3. 模板的分离编译 3.1 什么是分离编译 3.2 模板的分离编译 3.3 解决方法 4. 模板总结 1.非类型模板参数 模板参数分类&#xff1a;类型形参与非类…

计算机毕业设计 基于SpringBoot的敬老院管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

数据结构与算法-静态查找表

&#x1f31e; “清醒 自律 知进退&#xff01;” 查找 &#x1f388;1.查找的相关概念&#x1f388;2.静态查找表&#x1f52d;2.1静态查找表的类定义&#x1f52d;2.2顺序查找&#x1f52d;2.3二分查找&#x1f50e;二分查找例题 &#x1f52d;2.4分块查找&#x1f52d;2.5三…

理解BatchNormalization层的作用

深度学习 文章目录 深度学习前言一、“Internal Covariate Shift”问题二、BatchNorm的本质思想三、训练阶段如何做BatchNorm四、BatchNorm的推理(Inference)过程五、BatchNorm的好处六、机器学习中mini-batch和batch有什么区别 前言 Batch Normalization作为最近一年来DL的重…

react 字轮播滚动

一、用计时器来实现 React 字符串滚动轮播&#xff0c;可以使用 setInterval 函数和 React 的生命周期方法来实现。以下是一个简单的示例&#xff1a; import React from "react";export default class TextScroll extends React.Component {constructor(props) {s…