2023-浙江省决赛-Crypto

R_r

paillier同态加密
大致介绍:
https://zhuanlan.zhihu.com/p/557034854

例题:

from Crypto.Util.number import *
import random
from gmpy2 import *
from secret import flag1,flag2

flag = flag1 + flag2

p = getPrime(256)
q = getPrime(256)
n= p*q
hint1 = p^2*q
hint2 = p*q^2

while True:
    g1 = random.randint(1, n*n)
    if gcd((g1-1)//n, n) == 1:
        break

g2=n+1

m1 = bytes_to_long(flag1)
m2 = bytes_to_long(flag2)

while True:
    r1 = random.randint(1, n-1)
    if(gcd(r1,n) == 1):
        break

r2=random.randint(1,n)

c1 = (pow(g1, m1, n*n) * pow(r1, n, n*n))% (n*n)
c2 = (pow(g2 ,m2, n*n) * pow(r2, n, n*n))% (n*n)

print(c1)
print(c2)

n = 6401013954612445818165507289870580041358569258817613282142852881965884799988941535910939664068503367303343695466899335792545332690862283029809823423608093
c1 = 22910385210568304958107161962017571071703393748261640924342214385124480716797688566364653958202687496536914575643833029904856616616361552065618233346044007555777302010059956180989299881167620123404157184856914845192870935052388587836639109148835943673531131160427033530692003589837535181715398419950146539295
c2 = 1575524821989347564982343787894614774971961408914047143111430998332905514952763763178813184329394269351923009990561408822591722869938177600916108444223304303415189694914099273457779531528733347451404048342144363056595763890310306908442288806184110971228621297398433865511027539993213883705000977616240346813
g1 = 17972230632127848019159546735961788940716048105141697301143941156703842346042203282817931551107307709193702947228391512160043387022559315244264272847054598619204201233617960636207483484678274743413667794843966312743641773413722257484289905138257413051485362435527999048370294082815591234891288108779292951281
hint1 = 6401013954612445818165507289870580041358569258817613282142852881965884799988781523237008972618187818067224685481215653712129336192028926158248667825733199
hint2 = 6401013954612445818165507289870580041358569258817613282142852881965884799988781523237008972618187818067224685481215653712129336192028926158248667825732455

from Crypto.Util.number import *
from primefac import *
from gmpy2 import gcd,next_prime,lcm


n = 6401013954612445818165507289870580041358569258817613282142852881965884799988941535910939664068503367303343695466899335792545332690862283029809823423608093
c1 = 22910385210568304958107161962017571071703393748261640924342214385124480716797688566364653958202687496536914575643833029904856616616361552065618233346044007555777302010059956180989299881167620123404157184856914845192870935052388587836639109148835943673531131160427033530692003589837535181715398419950146539295
c2 = 1575524821989347564982343787894614774971961408914047143111430998332905514952763763178813184329394269351923009990561408822591722869938177600916108444223304303415189694914099273457779531528733347451404048342144363056595763890310306908442288806184110971228621297398433865511027539993213883705000977616240346813
g1 = 17972230632127848019159546735961788940716048105141697301143941156703842346042203282817931551107307709193702947228391512160043387022559315244264272847054598619204201233617960636207483484678274743413667794843966312743641773413722257484289905138257413051485362435527999048370294082815591234891288108779292951281
g2 = n+1
hint1 = 6401013954612445818165507289870580041358569258817613282142852881965884799988781523237008972618187818067224685481215653712129336192028926158248667825733199
hint2 = 6401013954612445818165507289870580041358569258817613282142852881965884799988781523237008972618187818067224685481215653712129336192028926158248667825732455

q = gcd(n,hint1)
p = n//q


def Pailler(p,q,n,g,c):
    def L(x):
        return (x-1)//n
    λ = lcm(p-1,q-1)
    μ = modinv(L(pow(g,λ,n*n)),n)
    m = (L(pow(c,λ,n*n))*μ)%n
    return m

flag1 = Pailler(p,q,n,g1,c1)
flag2 = Pailler(p,q,n,g2,c2)
print(long_to_bytes(flag1)+long_to_bytes(flag2))
# DASCTF{a59055ff-0a22-641d-2bf2-7b0b69c2244b}

0_1_Game

from Crypto.Util.number import *
from secret import flag

p = getPrime(512)
q = getPrime(512)
n = p * (q**2)

s = 65537

hint1 = pow((p+q), s, n)
hint2 = pow((p-q), s, n)



while True:
    z = getRandomRange(1, n - 1)
    if pow(z, (p-1)//2, p) == p-1 and pow(z, (q-1)//2, q) == q-1:
        break


def secert_0_1_encrypt(m, n, z):
    secret = getRandomRange(1, n - 1)
    c = pow(secret, 2, n) * pow(z, m, n) % n
    return c

m = bytes_to_long(flag)
plaintext = int(bin(int(m))[2:])
ciphertext = [0] * len(str(plaintext))
for i in range(len(str(plaintext))):
    ciphertext[i] = secert_0_1_encrypt(plaintext % 10, n, z)
    plaintext = plaintext // 10


print("n=", n)
print("hint1", hint1)
print("hint2", hint2)
print("z=", z)
print("ciphertext", ciphertext)

题目给了pow(p+q,65537,n) pow(p-q,65537,n)
二项式展开 两式相加 => 2p ^ 65537 % n
这样(hin1+hint2,n) = p 即可分解得到p,q
然后利用二次剩余的欧拉判别法即可还原flag(这里没数据 可能不用分解n 用kronecker也行? 反正遇到二次剩余的都试试 对n p q jaccobi kronecker Euler...)

old_fractor

from Crypto.Util.number import *
from flag import flag
import random

m = bytes_to_long(flag)
assert size(m)<360

while True:
    p = getPrime(512)
    q = getPrime(512)
    r = getPrime(512)
    s = getPrime(512)
    t = getPrime(512)
    real_p = p * q * r * s * t
    real_q = p + q + r + s + t
    if isPrime(real_q) == True:
        n = real_p * real_q
        break

e=65537
c=pow(m,e,n)

print('real_p=',real_p)
print('real_q=',real_q)

print('c=',c)

'''
real_p= 55062197317446999463174096263876498316593115551165463378239159905809676640454208209918217385995561457672251651152473557992138742135601815169185076218362135899344751677854110957095631491941800392408438811446405332089775007801060526398896827361974179433880944797942088556569121442758603066960469154848058525555919633585074687002653178371734389317920858433073228324119903275748010661381766238387457768079481851583182446632335485869275973875534654769410510717692168386489418039967948185844825093846853624216235947670855966394462382073931422900372413115651622846475697848013017412006570314438593706146398436291246626158990758006393615755523796444561949003170112244508437710660501492796759763772367048031312446027160494843576151592257914618405347047042441934740949960412334441
real_q= 45155472176560032394858410670734933043941707240560969397865820853107208563396632699891831616425752109128199454680206954866754585433276759685964959793491769
c= 29523353286662420447288429739820034783180593797609319451802397100630230980492429018460170953928563500202582346942199142197785013588760361998950680313834852877108490792872966526015601050884302042018430083206594510237759312983601611859463798190030017950871533501858080631812335748118077560727632343411246129300608114305005550505334558174100631528820258311294104339625598892394650057151595693208992748213949675232397315855876112627150056755058037371576593415880216272977089381300018893299243081150404742921857440064511032025713772327330252031889227225225823090259315491541462395033093742723528280894218885823268632726414223235862198062147879817814619506196476372010238569022037192794906574876350397747710442236263832960264742898816690984736558117232240584876068441918457179310704845718452829124188403042383896118962087518608022867798693371250897927956711708162621772577123078819978462483151316840145260542738057960771219011604
'''

呃呃呃 由于m<360bit 所以可以直接转到real_q的模数下求解

from Crypto.Util.number import *

real_p= 55062197317446999463174096263876498316593115551165463378239159905809676640454208209918217385995561457672251651152473557992138742135601815169185076218362135899344751677854110957095631491941800392408438811446405332089775007801060526398896827361974179433880944797942088556569121442758603066960469154848058525555919633585074687002653178371734389317920858433073228324119903275748010661381766238387457768079481851583182446632335485869275973875534654769410510717692168386489418039967948185844825093846853624216235947670855966394462382073931422900372413115651622846475697848013017412006570314438593706146398436291246626158990758006393615755523796444561949003170112244508437710660501492796759763772367048031312446027160494843576151592257914618405347047042441934740949960412334441
real_q= 45155472176560032394858410670734933043941707240560969397865820853107208563396632699891831616425752109128199454680206954866754585433276759685964959793491769
c= 29523353286662420447288429739820034783180593797609319451802397100630230980492429018460170953928563500202582346942199142197785013588760361998950680313834852877108490792872966526015601050884302042018430083206594510237759312983601611859463798190030017950871533501858080631812335748118077560727632343411246129300608114305005550505334558174100631528820258311294104339625598892394650057151595693208992748213949675232397315855876112627150056755058037371576593415880216272977089381300018893299243081150404742921857440064511032025713772327330252031889227225225823090259315491541462395033093742723528280894218885823268632726414223235862198062147879817814619506196476372010238569022037192794906574876350397747710442236263832960264742898816690984736558117232240584876068441918457179310704845718452829124188403042383896118962087518608022867798693371250897927956711708162621772577123078819978462483151316840145260542738057960771219011604
e = 65537

d = inverse(e,real_q-1)
print(long_to_bytes(pow(c,d,real_q)))

# DASCTF{b4920de4-9b76-9222-1bc4-ae05a6714ce6}
posted @ 2023-11-21 16:14  N0zoM1z0  阅读(72)  评论(0编辑  收藏  举报