反素数,英文称作emirp(prime(素数)的左右颠倒拼写),是素数的一种,把一个素数的阿拉伯字数字序列(十进制)变成由低位向高位反写出来,得到的另一个数还是素数,例如素数<font style="color:rgb(32, 33, 34);">13</font>
,反写就是<font style="color:rgb(32, 33, 34);">31</font>
,它是另一个素数,所以<font style="color:rgb(32, 33, 34);">13</font>
是一个反素数;(这个定义排除了相关的回文素数,因为回文素数反写不是另一个数而是它本身)
最小的几个反素数为:13, 17, 31, 37, 71, 73, 79, 97, 107, 113, 149, 157, 167, 179, 199, ...
所有非纯位数的可交换素数都是反素数
反素数-WiKi
题目:
from Crypto.Util.number import getPrime, isPrime, bytes_to_long
from secret import flagdef emirp(x):y = 0while x !=0:y = y*2 + x%2x = x//2return ywhile True:p = getPrime(512)q = emirp(p)if isPrime(q):breakn = p*q
e = 65537
m = bytes_to_long(flag)
c = pow(m,e,n)
print(f"{n = }")
print(f"{c = }")
'''
n = 141326884939079067429645084585831428717383389026212274986490638181168709713585245213459139281395768330637635670530286514361666351728405851224861268366256203851725349214834643460959210675733248662738509224865058748116797242931605149244469367508052164539306170883496415576116236739853057847265650027628600443901
c = 47886145637416465474967586561554275347396273686722042112754589742652411190694422563845157055397690806283389102421131949492150512820301748529122456307491407924640312270962219946993529007414812671985960186335307490596107298906467618684990500775058344576523751336171093010950665199612378376864378029545530793597
'''
解题思路:
- 已知
q=reverse_x(p)
,x
为进制数 - 爆破思路类似RSA parity oracle(RSA奇偶校验预言机)
p
,q
是bit
翻转关系,已知p
最低的k
位,则已知q
最高的k
位 - 假设已知
k
位的p
,q
,记为ph
,qh
,利用不等式
- 逐位向低地址爆破,不断收缩不等式的范围,最终可求得
n
值
解答:
from Crypto.Util.number import *
from gmpy2 import *
n = 141326884939079067429645084585831428717383389026212274986490638181168709713585245213459139281395768330637635670530286514361666351728405851224861268366256203851725349214834643460959210675733248662738509224865058748116797242931605149244469367508052164539306170883496415576116236739853057847265650027628600443901
c = 47886145637416465474967586561554275347396273686722042112754589742652411190694422563845157055397690806283389102421131949492150512820301748529122456307491407924640312270962219946993529007414812671985960186335307490596107298906467618684990500775058344576523751336171093010950665199612378376864378029545530793597
e=65537x=2 # q相对p是几进制下的反转
'''
from gmpy2 import isqrt
n = 141326884939079067429645084585831428717383389026212274986490638181168709713585245213459139281395768330637635670530286514361666351728405851224861268366256203851725349214834643460959210675733248662738509224865058748116797242931605149244469367508052164539306170883496415576116236739853057847265650027628600443901
sqrt_number = isqrt(n)
bit_length = sqrt_number.bit_length()
print("Square root in binary has", bit_length, "bits.")
'''
#Square root in binary has 512 bits.
leak_bits = 512 # sqrt(n)的二进制位数
def t(p,q,k):if k==leak_bits//2:if p*q==n:print(p,q)#12119998731259483292178496920109290754181396164390285597126378297678818779092115139911720576157973310671490865211601201831597946479039132512609504866583931#11660635291534613230423193509391946961264539191735481147071890944740311229658362673314192872117237108949853531941630122241060679012089130178372253390640871print(long_to_bytes(pow(c,invert(e,(p-1)*(q-1)),n)))exit()returnfor i in range(x):for j in range(x):p1=p+i*(x**k)+j*(x**(leak_bits-1-k))q1=q+j*(x**k)+i*(x**(leak_bits-1-k))if p1*q1>n:continueif (p1+(x**(leak_bits-1-k)))*(q1+(x**(leak_bits-1-k)))<n:continueif ((p1*q1)%(x**(k+1)))!=(n%(x**(k+1))):continuet(p1,q1,k+1)for i in range(x):t(i*(x**(leak_bits//2)),i*(x**(leak_bits//2)),0)
#moectf{WA!y0u@er***g00((d))}
题目:
while True:p = random_prime(2**512)q = ZZ(int(hex(p)[::-1], 16))if q.is_prime():break# hex(p*q)
# '7ef80c5df74e6fecf7031e1f00fbbb74c16dfebe9f6ecd29091d51cac41e30465777f5e3f1f291ea82256a72276db682b539e463a6d9111cf6e2f61e50a9280ca506a0803d2a911914a385ac6079b7c6ec58d6c19248c894e67faddf96a8b88b365f16e7cc4bc6e2b4389fa7555706ab4119199ec20e9928f75393c5dc386c65'
# hex(ciphertext)
# '3ea5b2827eaabaec8e6e1d62c6bb3338f537e36d5fd94e5258577e3a729e071aa745195c9c3e88cb8b46d29614cb83414ac7bf59574e55c280276ba1645fdcabb7839cdac4d352c5d2637d3a46b5ee3c0dec7d0402404aa13525719292f65a451452328ccbd8a0b3412ab738191c1f3118206b36692b980abe092486edc38488'
解题思路:
- 与上面那个题只隔个进制位数
- 改下脚本就行
解答:
from Crypto.Util.number import *
from gmpy2 import *
n = 0x7ef80c5df74e6fecf7031e1f00fbbb74c16dfebe9f6ecd29091d51cac41e30465777f5e3f1f291ea82256a72276db682b539e463a6d9111cf6e2f61e50a9280ca506a0803d2a911914a385ac6079b7c6ec58d6c19248c894e67faddf96a8b88b365f16e7cc4bc6e2b4389fa7555706ab4119199ec20e9928f75393c5dc386c65
c = 0x3ea5b2827eaabaec8e6e1d62c6bb3338f537e36d5fd94e5258577e3a729e071aa745195c9c3e88cb8b46d29614cb83414ac7bf59574e55c280276ba1645fdcabb7839cdac4d352c5d2637d3a46b5ee3c0dec7d0402404aa13525719292f65a451452328ccbd8a0b3412ab738191c1f3118206b36692b980abe092486edc38488
e = 65537x=16 # q相对p是几进制下的反转
'''
from gmpy2 import isqrt
hex_number = "0x7ef80c5df74e6fecf7031e1f00fbbb74c16dfebe9f6ecd29091d51cac41e30465777f5e3f1f291ea82256a72276db682b539e463a6d9111cf6e2f61e50a9280ca506a0803d2a911914a385ac6079b7c6ec58d6c19248c894e67faddf96a8b88b365f16e7cc4bc6e2b4389fa7555706ab4119199ec20e9928f75393c5dc386c65"
number = int(hex_number, 16)
sqrt_number = isqrt(number)
hex_sqrt = hex(sqrt_number)
hex_length = len(hex_sqrt) - 2
print("Number of hexadecimal digits:", hex_length)
'''
#Number of hexadecimal digits: 128
leak_bits = 128 # sqrt(n)的十六进制位数
def t(p,q,k):if k==leak_bits//2:if p*q==n:print(p,q)#10940426841622676366921134263606230797852377049845508023073731851498778062165943872403574214831422325352658084111135335937429027508321743816310547640134073#8149647373983803351750886568540598477647671089400013740300059155182763355863916783703939054112148224308893530604866892896459967322672335047042674959531533print(long_to_bytes(pow(c,invert(e,(p-1)*(q-1)),n)))exit()returnfor i in range(x):for j in range(x):p1=p+i*(x**k)+j*(x**(leak_bits-1-k))q1=q+j*(x**k)+i*(x**(leak_bits-1-k))if p1*q1>n:continueif (p1+(x**(leak_bits-1-k)))*(q1+(x**(leak_bits-1-k)))<n:continueif ((p1*q1)%(x**(k+1)))!=(n%(x**(k+1))):continuet(p1,q1,k+1)for i in range(x):t(i*(x**(leak_bits//2)),i*(x**(leak_bits//2)),0)
#midnight{d1vid3_and_c0nqu3r}x/\xda\xc9\xc4y\xb4\xc5!\x14\xc4p\xfal<a\x00\xd9m\xae\xb0k\xf8\xe0\xb31\xd9\xe6J\xcd\xaf|\x0b\xde6\xe2\xe8|>\xb8\xa2\x03\xa6\x92\xf6\xf3i\x10\xbb\x04\xc4Ha\x83d\x9d}6S\x88K\xba\tp\xed\xa3\xe2\xaf3\xc9\xae\xa9\xafF\xe5\x0c?\xae\x99\xae\x12\xb1\x9fO\xd2\xbc\x86\xedi\xab\xfc\xe7I\x82\xba\xfee\xba\xf0\xed