GGH非对称密码体制破解方法

GGH密码体制,基于格的CVP(最近接向量问题)设计的非对称密码算法

E n c r y p t i o n Encryption Encryption

  • 生成密钥:

选择幺模矩阵 U U U作为私钥

  • 公钥: B ′ = U ⋅ B B'=U\cdot B B=UB;其中 B B B是格 L L L中的基

  • 加密公式: c = m ⋅ B ′ + e c=m\cdot B'+e c=mB+e

其中

  • m : m: m: 由明文构成的一个1×n向量

类似于这样的向量:m = [ 1 2 3 4 5 6 7 8 9 10]

  • B ′ : B': B: n×n矩阵,相当于公钥

  • e : e: e: 1×n向量,属于干扰向量;有的GGH加密 e e e每项都是 3 3 3或者 − 3 -3 3,有的GGH加密的 e e e所包含的数值不只是 3 3 3或者 − 3 -3 3

  • c : c: c: 密文向量,也就是1×n

D e c r y p t i o n Decryption Decryption

c ⋅ B − 1 = ( m ⋅ B ′ + e ) B − 1 = m ⋅ U + e ⋅ B − 1 c\cdot B^{-1}=(m\cdot B'+e)B^{-1}=m\cdot U+e\cdot B^{-1} cB1=(mB+e)B1=mU+eB1

利用Babai rounding technique去除 e ⋅ B − 1 e\cdot B^{-1} eB1CVP - CTF Wiki (ctf-wiki.org)

(由于官方解密不是重点,就尽快带过)

最后 m = m ⋅ U ⋅ U − 1 m=m\cdot U\cdot U^{-1} m=mUU1

A t t a c k Attack Attack

  • N g u y e n ′ s   A t t a c k Nguyen's~Attack Nguyens Attack

Nguyen's Attack进行的前提条件是 e e e必须是由 3 3 3 − 3 -3 3构成

s = ( 3 , 3 , . . . , 3 ) ∈ Z n s=(3,3,...,3)\in \mathbb{Z}^{n} s=(3,3,...,3)Zn

在加密等式两边同时加上 s s s,得到

c + s = m ⋅ B + ( e + s ) c+s=m\cdot B+(e+s) c+s=mB+(e+s)

等式两边同取模 6 6 6,这样 ( e + s ) (e+s) (e+s)会等于 0 0 0,得到

c 6 ≡ m 6 ⋅ B 6 ( m o d 6 ) c_6\equiv m_6\cdot B_6\pmod 6 c6m6B6(mod6)

得到明文取模 6 6 6后的结果,也就是说,得到的是部分明文内容

  • e m b e d d e d   t e c h n i q u e embedded~technique embedded technique

embedded technique简单来说,就是把 c c c作为一组向量嵌入 B ′ B' B中去,进而转换为SVP问题,直接使用封装函数求解SVP问题,得到的结果映射到原来的维度中就等于干扰向量 e e e,在 c c c中直接减去得到的干扰向量结果再乘以 B ′ B' B的逆即可

原来的公钥向量 B ′ B' Bn×n向量,这时把 c c c作为行向量嵌套进去并且加入一个 ( 0 , 0 , . . . , 0 , 1 ) (0,0,...,0,1) (0,0,...,0,1)的列向量,得到一个(n+1)×(n+1)的向量

temp = B.stack(c).augment(vector([0]*B.ncols()+[1]))

得到的 t e m p temp temp向量是 n + 1 n+1 n+1维度的,该向量作为 n + 1 n+1 n+1维的格的基,求解这个晶格的最小向量(SVP问题),而得到的最小向量投影在 n n n维上的向量(也就是直接去掉向量中 n + 1 n+1 n+1处的值)等于干扰向量 e e e

from sage.modules.free_module_integer import IntegerLattice
e = IntegerLattice(temp).shortest_vector()[:-1]

得到结果

m = B.solve_left(c - e)

完整代码(来自于hxp | VolgaCTF 2016 Quals: crypto300 “XXY” writeup

from sage.modules.free_module_integer import IntegerLattice

B = 
c = 

B = matrix(B)
c = matrix(c)
temp = B.stack(c).augment(vector([0]*B.ncols()+[1]))
e = IntegerLattice(B).shortest_vector()[:-1]
m = B.solve_left(c - matrix(e))

E x a m p l e Example Example

  • 陇原战"疫"2021网络安全大赛_easytask
def get_random_U(n):
    def get_U1():
        A = Matrix(ZZ, n, n)
        for i in range(0,n):
            for j in range(0,n):
                if i<j:
                    A[i,j] = random.randint(1,1000)
                if i==j:
                    A[i,j] = 1
        return A
    def get_U2():
        A = Matrix(ZZ, n, n)
        for i in range(0,n):
            for j in range(0,n):
                if i>j:
                    A[i,j] = random.randint(1,1000)
                if i==j:
                    A[i,j] = 1
        return A
    return get_U1()*get_U2()
def get_public_key():
    U = get_random_U(9)
    V = matrix(V)
    W = V*U
    return W
def get_random_r():
    n = 9
    delta = 4
    r = random_vector(ZZ, n, x=-delta+1, y=delta)
    r = matrix(r)
    return r
def encrypt():
    M = [getPrime(10)for i in range(9)]
    m = matrix(M)
    W = get_public_key()
    r = get_random_r()
    e = m*W+r
    print("e =",e)
    print("W =",W)
    return M
def new_encrypt():
    M = encrypt()
    key = hashlib.sha256(str(M).encode()).digest()
    cipher = AES.new(key, AES.MODE_ECB)
    c = cipher.encrypt(flag).hex()
    print("c =",c)
new_encrypt()

该题目给出的 e e e W W W相当于GGH加密体制中的 c c c B ′ B' B,下面就按照GGH加密体制的习惯来进行解密

已知 c , B c,B c,B,在GGH中求得的 m m m作为 A E S AES AES k e y key key来解密

按照embedded technique的方式来求解GGH中的 m m m

# sagemath
from sage.modules.free_module_integer import IntegerLattice
c = e = [151991736758354,115130361237591,58905390613532,130965235357066,74614897867998,48099459442369,45894485782943,7933340009592,25794185638]
B = W = [[-10150241248,-11679953514,-8802490385,-12260198788,-10290571893,-334269043,-11669932300,-2158827458,-7021995],
[52255960212,48054224859,28230779201,43264260760,20836572799,8191198018,14000400181,4370731005,14251110],
[2274129180,-1678741826,-1009050115,1858488045,978763435,4717368685,-561197285,-1999440633,-6540190],
[45454841384,34351838833,19058600591,39744104894,21481706222,14785555279,13193105539,2306952916,7501297],
[-16804706629,-13041485360,-8292982763,-16801260566,-9211427035,-4808377155,-6530124040,-2572433293,-8393737],
[28223439540,19293284310,5217202426,27179839904,23182044384,10788207024,18495479452,4007452688,13046387],
[968256091,-1507028552,1677187853,8685590653,9696793863,2942265602,10534454095,2668834317,8694828],
[33556338459,26577210571,16558795385,28327066095,10684900266,9113388576,2446282316,-173705548,-577070],
[35404775180,32321129676,15071970630,24947264815,14402999486,5857384379,10620159241,2408185012,7841686]]

c = matrix(c)
B = matrix(B)
temp = B.stack(c).augment(vector([0]*B.ncols()+[1]))
e = IntegerLattice(temp).shortest_vector()[:-1]
m = B.solve_left(c - matrix(e))
print(m)

得到的 m m m代入 A E S AES AES作为 k e y key key解密即可

from Crypto.Util.number import *
from Crypto.Cipher import AES
import hashlib
c = 0x1070260d8986d5e3c4b7e672a6f1ef2c185c7fff682f99cc4a8e49cfce168aa0
m = [877,619,919,977,541,941,947,1031,821]
key = hashlib.sha256(str(m).encode()).digest()
aes = AES.new(key,AES.MODE_ECB)
flag = aes.decrypt(long_to_bytes(c))
print(flag)

P e r f e r e n c e Perference Perference

hxp | VolgaCTF 2016 Quals: crypto300 “XXY” writeup

Intended Solution to GGH in GYCTF 2020 | Soreat_u’s Blog (soreatu.com)

GGH | 4XWi11的博客

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

M3ng@L

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值