首页 > 其他分享 >长城杯2022 known_phi

长城杯2022 known_phi

时间:2022-08-28 00:45:30浏览次数:52  
标签:prime phi factors bytes long 2022 known import

Involved Knowledge

  • 已知phi,n 分解n

  • DSA K共享攻击

Description

from Crypto.Util.number import getPrime, bytes_to_long, inverse, long_to_bytes
from Crypto.PublicKey import DSA
from hashlib import sha256
import random
from secret import flag

def gen(a):
    p = getPrime(a) 
    q = getPrime(a)
    r = getPrime(a)
    x = getPrime(a)
    n = p*q*r*x
    phi = (p-1)*(q-1)*(r-1)*(x-1)

    return n, phi, [p, q, r, x]

def sign(m, k, x, p, q, g):
    hm = bytes_to_long(sha256(m).digest())
    r = pow(g, k, p) % q
    s = (hm + x*r) * inverse(k, q) % q

    return r,s

e = 65537
a = 256
x = bytes_to_long(flag)
# print(x)

n, phi, n_factors = gen(a)
n_factors = sorted(n_factors)
print(f'n = {n}')
print(f'phi = {phi}')
m1 = long_to_bytes(n_factors[0] + n_factors[3]) #p x
m2 = long_to_bytes(n_factors[1] + n_factors[2]) #q r
# print(f'm1 = {m1}')
# print(f'm2 = {m2}')

# DSA 共享K攻击
key = DSA.generate(int(2048)) #签名
q = key.q
p = key.p
g = key.g
assert q > x 
k = random.randint(1, q-1)      #1<k<q-1
r1, s1 = sign(m1, k, x, p, q, g)
r2, s2 = sign(m2, k, x, p, q, g)
# print(f'k = {k}')
print(f'q = {q}')
# print(f's1 = {s1}')
print(f'r1 = {r1}')
print(f's1 = {s1}')
print(f'r2 = {r2}')
print(f's2 = {s2}')

'''
n = 104228256293611313959676852310116852553951496121352860038971098657350022997841589403091722735802150153734050783858816709247647536393314564077002364012463220999962114186339228164032217361145009468516448617173972835797623658266515762201804936729547278758839604969469770650218191574897316410254695420895895051693
phi = 104228256293611313959676852310116852553951496121352860038971098657350022997837434645707418205268240995284026522165519145773852565112344453740579163420312890001524537570675468046604347184376661743552799809753709321949095844960227307733389258381950812717245522599433727311919405966404418872873961877021696812800
q = 24513014442114004234202354110477737650785387286781126308169912007819
s1 = 764450933738974696530033347966845551587903750431946039815672438603
r1 = 8881880595434882344509893789458546908449907797285477983407324325035
s1 = 764450933738974696530033347966845551587903750431946039815672438603
r2 = 8881880595434882344509893789458546908449907797285477983407324325035
s2 = 22099482232399385060035569388467035727015978742301259782677969649659
'''

Analyze

已知phi , n 将n分解,脚本如下

def factorize_multi_prime(N, phi):
    """
    Recovers the prime factors from a modulus if Euler's totient is known.
    This method works for a modulus consisting of any number of primes, but is considerably be slower than factorize.
    More information: Hinek M. J., Low M. K., Teske E., "On Some Attacks on Multi-prime RSA" (Section 3)
    :param N: the modulus
    :param phi: Euler's totient, the order of the multiplicative group modulo N
    :return: a tuple containing the prime factors
    """
    prime_factors = set()
    factors = [N]
    while len(factors) > 0:
        # Element to factorize.
        N = factors[0]

        w = randrange(2, N - 1)
        i = 1
        while phi % (2 ** i) == 0:
            sqrt_1 = pow(w, phi // (2 ** i), N)
            if sqrt_1 > 1 and sqrt_1 != N - 1:
                # We can remove the element to factorize now, because we have a factorization.
                factors = factors[1:]

                p = gcd(N, sqrt_1 + 1)
                q = N // p

                if isPrime(p):
                    prime_factors.add(p)
                elif p > 1:
                    factors.append(p)

                if isPrime(q):
                    prime_factors.add(q)
                elif q > 1:
                    factors.append(q)

                # Continue in the outer loop
                break

            i += 1

    return tuple(prime_factors)

接着是DSA的K共享攻击

我们具体的一个求解步骤

具体原理参见ctfwiki

Exp

from Crypto.Util.number import *
import libnum
import gmpy2
import sympy
from z3 import *
import random
from math import gcd
from gmpy2 import isqrt
from random import randrange
from hashlib import *

e = 65537
n = 104228256293611313959676852310116852553951496121352860038971098657350022997841589403091722735802150153734050783858816709247647536393314564077002364012463220999962114186339228164032217361145009468516448617173972835797623658266515762201804936729547278758839604969469770650218191574897316410254695420895895051693
phi = 104228256293611313959676852310116852553951496121352860038971098657350022997837434645707418205268240995284026522165519145773852565112344453740579163420312890001524537570675468046604347184376661743552799809753709321949095844960227307733389258381950812717245522599433727311919405966404418872873961877021696812800
q = 24513014442114004234202354110477737650785387286781126308169912007819
s1 = 764450933738974696530033347966845551587903750431946039815672438603
r1 = 8881880595434882344509893789458546908449907797285477983407324325035
r2 = 8881880595434882344509893789458546908449907797285477983407324325035
s2 = 22099482232399385060035569388467035727015978742301259782677969649659

def factorize_multi_prime(N, phi):
    """
    Recovers the prime factors from a modulus if Euler's totient is known.
    This method works for a modulus consisting of any number of primes, but is considerably be slower than factorize.
    More information: Hinek M. J., Low M. K., Teske E., "On Some Attacks on Multi-prime RSA" (Section 3)
    :param N: the modulus
    :param phi: Euler's totient, the order of the multiplicative group modulo N
    :return: a tuple containing the prime factors
    """
    prime_factors = set()
    factors = [N]
    while len(factors) > 0:
        # Element to factorize.
        N = factors[0]

        w = randrange(2, N - 1)
        i = 1
        while phi % (2 ** i) == 0:
            sqrt_1 = pow(w, phi // (2 ** i), N)
            if sqrt_1 > 1 and sqrt_1 != N - 1:
                # We can remove the element to factorize now, because we have a factorization.
                factors = factors[1:]

                p = gcd(N, sqrt_1 + 1)
                q = N // p

                if isPrime(p):
                    prime_factors.add(p)
                elif p > 1:
                    factors.append(p)

                if isPrime(q):
                    prime_factors.add(q)
                elif q > 1:
                    factors.append(q)

                # Continue in the outer loop
                break

            i += 1

    return tuple(prime_factors)
n_factors = factorize_multi_prime(n , phi)
n_factors = sorted(n_factors)
m1 = long_to_bytes(n_factors[0] + n_factors[3]) # p x
m2 = long_to_bytes(n_factors[1] + n_factors[2]) # q r

hm1 = bytes_to_long(sha256(m1).digest())
hm2 = bytes_to_long(sha256(m2).digest())
# k , x -> flag
k = gmpy2.invert((s1 - s2) , q) * (hm1 - hm2) % q
x = (s1 * k - hm1) * gmpy2.invert(r1 , q) % q
flag = libnum.n2s(int(x))   
print(flag)

标签:prime,phi,factors,bytes,long,2022,known,import
From: https://www.cnblogs.com/m1nus/p/16631869.html

相关文章

  • Cannot resolve org.springframework.cloud:spring-cloud-starter-netflix-eureka-ser
    Cannotresolveorg.springframework.cloud:spring-cloud-starter-netflix-eureka-server:unknown前言:启动eureka项目,发现右侧maven中的项目dependencies报红,reimport也......
  • 2022-08-27 第四小组 王星苹 学习心得
    学习心得今天主要学习了在html里面用Vue库,也是一个js文件,这个也是相当于写好的东西可以直接用。Vue.js的核心是一个采用简洁的模板语法来声明式地将数据渲染进DOM的系统。......
  • NOI2022 VP寄
    Day-?由于我特别菜,去年NOIP寄成了158,今年省选遇上疫情,分数线提到了210,所以省选寄了,NOI2022D类梦也寄了。8月26日晚上拿到了两天的pdf和day1的数据,准备VP......
  • 2022百度之星 初赛1 A-B
    A:洞穴不是很懂,但是跑了一遍kruskal就过了//-------------------------代码----------------------------//#defineintllconstintN=200;intn,m;intdist[N]......
  • 2022-08-27 卢睿 学习心得
    目录1.VueVue的创建事件面试题属性的绑定遍历双向绑定注意事项1.Vuevue是JavaScript的一个框架——【JavaScript的库】Vue的创建<divid="app"><!--插值表达......
  • 2022-08-26 第二小组 张鑫 学习笔记
    实训四十八天JS库学习内容JS库别人写好的JS文件,我们拿来直接用开发中,会引入很多的.js文件JQuery.js------濒临淘汰,经典10%以下css库,bootstrap,layui,easyuiReact.j......
  • NOI2022 退役记
    在更。8.13因为突然要提前7天去比赛城市,所以买了今天的下午三点的高铁。上午还有模拟赛,和上一届一起考过的200+,其他人100-,体验非常痛苦。t1神秘期望,题解说是F......
  • NOI2022 退役记
    8.13因为突然要提前7天去比赛城市,所以买了今天的下午三点的高铁。上午还有模拟赛,和上一届一起考过的200+,其他人100-,体验非常痛苦。t1神秘期望,题解说是FWT套FFT......
  • visual studio 2022离线安装包制作教程
    1、在线下载VisualStudi安装包https://aka.ms/vs/17/release/vs_enterprise.exe  2、在线安装visualsudio22布局 2.1.NETWeb和.NET桌面开发,运行(不选en-US......
  • 戒烟第一天(20220807)
    记录下戒烟第一天的感受:白天的时候,烟瘾来的感觉并不强烈,好像烟对我来说是可有可无的。到下午4点的时候有一点点想抽,有出现习惯性摸烟的动作。4点半我出去游泳了。到了晚上......