It’s my first time to participate CCTF. Finally I got 1218 points and rank 30. During CCTF, I learned some tricks and gained many new view.
I will choose to record some meaningful challenges which I have solved or are still puzzling
BTW , it’s my first time to write solution in English , it can be lame. But it did a opportunity to know terminology.
SOTS
A classical math problem. Maybe called Sum of Gauss squares. I always use it during the math competition to prove some proposition. But I haven’t thought how to find it. I just search some algorithm named Fermat reduced order method and achieve it.
import gmpy2 defrecover2(t,w): cofs=[] PR.<x>=PolynomialRing(Zmod(2)) f=x^2-t root=f.roots()[0][0] cofs.append(int(root)) tmp=int(root) cofs.append(1) tmp+=2 for i inrange(4,w+1): cof=((t-tmp^2)*gmpy2.invert(tmp,2^i)%2^i)//2^(i-1) cofs.append(cof) tmp+=cof*2^(i-2) cofs.append(1) re=0 for i inrange(w): re+=cofs[i]*2^i return re
defrecover(t,p,w,i): cofs=[] PR.<x>=PolynomialRing(Zmod(p)) f=x^2-t root=f.roots()[i][0] cofs.append(int(root)) tmp=int(root) for i inrange(2,w+1): cof=((t-tmp^2)*gmpy2.invert(2*tmp,p^i)%p^i)//p^(i-1) cofs.append(cof) tmp+=cof*p^(i-1) re=0 for i inrange(w): re+=cofs[i]*p^i return re
xx = 10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046477020617917601884853827611232355455223966039590143622792803800879186033924150173912925208583 a = 31337 b = 66826418568487077181425396984743905464189470072466833884636947306507380342362386488703702812673327367379386970252278963682939080502468506452884260534949120967338532068983307061363686987539408216644249718950365322078643067666802845720939111758309026343239779555536517718292754561631504560989926785152983649035 p1=2 p2=690712633549859897233 p3= 651132262883189171676209466993073 n=117224988229627436482659673624324558461989737163733991529810987781450160688540001366778824245275287757373389887319739241684244545745583212512813949172078079042775825145312900017512660931667853567060810331541927568102860039898116182248597291899498790518105909390331098630690977858767670061026931938152924839936 t=(xx^3+a*xx+b)%n y1=recover2(t,63) y2=recover(t,p2,6,1) y3=recover(t,p3,5,1) m=crt([y1,y2,y3],[p1^63,p2^6,p3^5]) print(bytes.fromhex(hex(m)[2:]))
another way is to use p-adic. It’s easy beacause sage have some module. But I don’t know much about it.
I didn’t finish it on time because lack the proper Smooth number. However I find this problem can be solved by reduce the smooth level.(Cyclic groups have higher orders)
from Crypto.Util.number import * defgen_primes(nbit, imbalance): p = 2 FACTORS = [p] while p.bit_length() < nbit - 2 * imbalance: factor = getPrime(imbalance) FACTORS.append(factor) p *= factor rbit = (nbit - p.bit_length()) // 2
whileTrue: r, s = [getPrime(rbit) for _ in'01'] _p = p * r * s if _p.bit_length() < nbit: rbit += 1 if _p.bit_length() > nbit: rbit -= 1 if isPrime(_p + 1): FACTORS.extend((r, s)) p = _p + 1 break
I did’t finish it. I see someone do it by recursion. It’s perfect but a little hard. Rencently, I see some new solution- and it’s fast.
1 2 3 4 5 6 7 8 9 10
from z3 import * n=40 V=[z3.BitVec("V{}".format(i),42) for i inrange(n)] con1=[z3.And(1<=V[i],V[i]<=n) for i inrange(n)] con2=[z3.Distinct(V)] con3=[sum(V[i]*(-2)**i for i inrange(n))==0] sol=Solver() sol.add(con1+con2+con3) print(sol.check()) print(sol.model())
Side step
All it takes is a simple idea, use to check s bit by bit
function pow_d’s process will calculate pow(g,bin(s)[:i],p) for any i. So we can use g=pow(2,-bin(s)[:i],p) to check whether the bit of s is equal to 1.
The script may needs to be run multiple times to make sure s is 1023 bits
defts(m, p): m = m % p returnpow(m, (p - 1) // 2, p) == 1
defsearch(): global s io.sendlineafter('[Q]uit\n','t') e=int(s,2) d=gmpy2.invert(e,(p-1)//2) g=pow(2,d,p) io.sendline(str(g)) io.recvuntil('t, r = (') sign=int(io.recvuntil(',')[:-1]) if sign==0: s+='1' else: s+='0' for i in tqdm(range(1022)): search() print(s) s=int(s,2) dd=inverse(s,(p-1)//2) m=pow(4,dd,p) io.sendlineafter('[Q]uit\n','t') sleep(0.01) io.sendline(str(m)) io.interactive()
Post title:Writeup in 2022CryptoCTF
Post author:hash_hash
Create time:2022-07-20 21:00:40
Post link:https://hash-hash.github.io/2022/07/20/Writeup-in-2022CryptoCTF/
Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.