Writeup for crypto in RCTF 2021
Table of Contents
👴第二次打RCTF,周末又来苟了个水题,👴太极吧菜了,全靠队友带
uncommon1 #
气死了气死了,明明都已经把fastgcd修好了
拿着fastgcd日了半天uncommon2,以为没用,直接扔掉了
淦,根本没考虑过会出现同样的素数,太菜了,明明上课学过的😀😀😀
Fastgcd #
这是个什么玩意呢?
众所周知GCD可以快速的算出两个数最大公约数,但如果有$N$个数我可能要算大概$N^2$次
于是一群数学家想:能不能概一个算法吧它的复杂度降低一点?
大概流程如下
生成树这种概念已经太久远了,👴记不清了
或者长这样:
u神不知在那篇文章找到的实现流程:
文章说复杂度为$O(N(lgN)^2lg(lgN))$
和$N^2$相比就很舒服了
implement #
u神的证明:
完全没想到这一层,上学期还学过,太摆了
fastgcd实现:
你让👴实现这玩意👴肯定是会当场摆烂的,所以👴找到了现成的仓库
https://github.com/sagi/fastgcd
拖下来发现不能立马intsall,于是我们来着手修install
#!/bin/bash
__exists() {
which $1 1>/dev/null 2>&1
}
get="fetch";
! __exists fetch && get="curl -OL";
if [ ! -d gmp-5.0.5 ];
then
if [ ! -f gmp-5.0.5.tar.bz2 ];
then
$get ftp://ftp.gmplib.org/pub/gmp-5.0.5/gmp-5.0.5.tar.bz2
fi
sum=`openssl sha1 gmp-5.0.5.tar.bz2 | awk -F' ' '{print $2}'`
if [[ $sum != "12a662456033e21aed3e318aef4177f4000afe3b" ]];
then
echo ''
echo '=========================================='
echo 'ERROR: could not verify gmp-5.0.5.tar.bz2;'
echo 'Downloaded over untrusted channel (non-https)'
echo '=========================================='
exit;
fi
tar xf gmp-5.0.5.tar.bz2
fi
cd gmp-5.0.5
patch -p 1 < ../gmp-5.0.5.patch
mkdir ../gmp-patched
./configure --prefix=$PWD/../gmp-patched/
make
make install
cd ..
make
显然是$get ftp://ftp.gmplib.org/pub/gmp-5.0.5/gmp-5.0.5.tar.bz2
出了问题(反正我下载不下来)
于是上gmp官网手动下一个
修改install.sh,修改源码报错的预编译代码
fastgcd.c
#define NTHREADS 4 // Get from compile-time argument?
// #ifdef mpz_raw_64 // if patched gmp, use large format int i/o
// #define __mpz_inp_raw mpz_inp_raw_64
// #define __mpz_out_raw mpz_out_raw_64
// #else // otherwise use normal i/o...beware 2^31 byte size limit
#define __mpz_inp_raw mpz_inp_raw
#define __mpz_out_raw mpz_out_raw
// #endif
install.sh
tar xf gmp-5.0.5.tar.bz2
cd gmp-5.0.5
patch -p 1 < ../gmp-5.0.5.patch
mkdir ../gmp-patched
./configure --prefix=$PWD/../gmp-patched/
make
make install
cd ..
make
直接install编译
提取数据为input.modle的格式
from Crypto.Util.number import *
from tqdm import
size = 2**22
with open("lN.bin","rb") as f:
data = f.read()
f1 = open("data","w+")
for i in tqdm(range(size)):
tmp = hex(bytes_to_long(data[i*64:(i+1)*64]))[2:]
f1.write(tmp+'\n')
开跑~~
结果:
比u神多花了5分钟,还是机子不太行🐨🐨🐨
solve #
In [2]: s=0x7f2ec3455a5f6763645f5472333333333333338a2068398023
...:
In [3]: from Crypto.Util.number import *
In [4]: long_to_bytes(s)
Out[4]: b'\x7f.\xc3EZ_gcd_Tr3333333\x8a h9\x80#'
In [5]:
uncommon2 #
A AGCD problem,using lattice reduce is simple to solve it
AGCD #
$n_i=p*q_i+r_i$形式的AGCD问题,利用格规约是可解的
👴看到很多文章都有打法介绍,但是只有这篇介绍了格子的结构(
https://martinralbrecht.wordpress.com/2020/03/21/the-approximate-gcd-problem/
一把梭哈就能解uncommon2
solve #
#! /usr/bin/sage
from sage.all import *
from sage.groups.generic import bsgs
from Crypto.Util.number import *
from Crypto.Util.number import *
with open("lN.bin","rb") as f:
data = f.read()
f1 = open("./data","wb")
size = 128
print('size',size)
nn=[]
for i in range(size):
nn.append((bytes_to_long(data[i*64:(i+1)*64])))
B = [[0 for i in range(size)] for _ in range(size)]
x0 = nn[0]
B[0][0]=2^305
for i in range(1,size):
B[0][i]=nn[i]
# B[0][i]=i
# print(B)
# print(x0)
print('start LLL....')
for i in range(1,size):
B[i][i]=-x0
B = Matrix(B)
V = B.LLL()
q = abs(V[0][0])
q = q>>305
print(x0-q)
p = x0//q
print(long_to_bytes(p))
# flag{Simpl3_LLL_TrIck}
attachment #
refer #
https://www.usenix.org/system/files/conference/usenixsecurity12/sec12-final228.pdf