Created
June 2, 2020 06:50
-
-
Save ruan777/37b85db2c38f41a081c98f9bfbb742bd to your computer and use it in GitHub Desktop.
RCTF2020 Crypto solution
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "cells": [ | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "from Crypto.Util.number import getStrongPrime, bytes_to_long, long_to_bytes\n", | |
| "from hashlib import sha256" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 2, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "#flag=b\"flag{Copper5mith_M3thod_f0r_ECC}\"\n", | |
| "flag = open(\"flag.txt\",\"rb\").read()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 3, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "p=q=1\n", | |
| "while p % 3 == 1 or q % 3 == 1:\n", | |
| " p=getStrongPrime(512)\n", | |
| " q=getStrongPrime(512)\n", | |
| "R=Zmod(p*q)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 4, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "Mx=R.random_element()\n", | |
| "My=R.random_element()\n", | |
| "b=My^2-Mx^3\n", | |
| "\n", | |
| "E=EllipticCurve(R, [0,b])\n", | |
| "Ep=EllipticCurve(GF(p), [0,b])\n", | |
| "Eq=EllipticCurve(GF(q), [0,b])\n", | |
| "Ecard=Ep.cardinality()*Eq.cardinality()\n", | |
| "\n", | |
| "r=random_prime((p^^q)>>100)\n", | |
| "s=inverse_mod(r, Ecard)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 5, | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "(75955160398499284582365252139080970001650760916103485139764772804872919753584583266880450168691594499273667135971973410322196200867273228602818191337500001985277231136312528247776522365265305999130251922539242906774436240079513662278472385074144007520670892131774622475195904194782409160126720307889422458493, 77177027104677568205407604834674529531364563093957497500999166982602504419069856531944277180657371948259751584070052558297024329254421478902909314105677601829946763003101714995414429721253749752004489966994416785386578232345759601687283799109121167811119474655723555777958644927956223836954912245628550110978)\n", | |
| "(4711224273331373977910490238834352060115767875175802159547226065477305442089160927662447689173899921650511329325780640723114337409594286878782729078200642107740290701060578228869140368026890517666438024038857959369890859620213582632492536372064331054738057670135220299550225569372043397171859053270019068355 : 115211308552251170712289808928148740860983837650102588683377623008544267391191924126068218015231728978324393682388525139729336358075647796250226401077991544249724163243218998831603715346875233148667954133219290967210863389487046525121955885958355116923414097756577255364622079931898528134115452256600708038726 : 1)\n", | |
| "(62241391058840568910776980601486746103312381301373763888005396103132307981408297903504158004027159105570481208389946426882339887604238467177668004592692619137112167401951410360701661999103688500118599007972700256808636078714986354753253210433854996992178601473176978091605053110132146252044190523249304613683 : 13793163824370740918757250634119183853694404762927846616819837629056037858973994028329934876698304788763251957232693510519616156534548152844103039796946124038883381327999652864009559777925995016374384309773683277835618673551989983219612427436029030053080913000651662100624554430136504060233058702814784921823 : 1)\n", | |
| "1682763377329999876088266320718040612037901309690939971774155809417306970613019643384970947520167566392039523522115794946769307950140283710314194591002069\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "print((s,b))\n", | |
| "print(s*E(Mx,My))\n", | |
| "print(randint(0,Ecard)*E(Mx,My))\n", | |
| "print(r^^(bytes_to_long(sha256(long_to_bytes(Mx)).digest())^^bytes_to_long(flag))<<256)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 6, | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "7\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "e=s\n", | |
| "b=b\n", | |
| "Cx,Cy,_=s*E(Mx,My)\n", | |
| "Tx,Ty,_=randint(0,Ecard)*E(Mx,My)\n", | |
| "secret=r^^(bytes_to_long(sha256(long_to_bytes(Mx)).digest())^^bytes_to_long(flag))<<256\n", | |
| "d0=secret%2^256\n", | |
| "N=gcd(int(Cy)^2-int(Cx)^3-int(b),int(Ty)^2-int(Tx)^3-int(b))\n", | |
| "print(N/p/q)\n", | |
| "from sage.rings.factorint import factor_trial_division\n", | |
| "N=factor_trial_division(N, 1000)[-1][0]\n", | |
| "assert N == p*q" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 7, | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "77 415\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "ab=412\n", | |
| "beta=256\n", | |
| "R=e*d0-1\n", | |
| "\n", | |
| "m=4\n", | |
| "t=1\n", | |
| "X=2^(ab-beta)+1\n", | |
| "while gcd(R,X) != 1:\n", | |
| " X+=2\n", | |
| "Y=2^ab+1\n", | |
| "while gcd(R,Y) != 1:\n", | |
| " Y+=2\n", | |
| "Z=2^512+1\n", | |
| "while gcd(R,Z) != 1:\n", | |
| " Z+=2\n", | |
| "W=(2^1024+1)*Y\n", | |
| "n=(X*Y)^m*Z^(m+t)*W\n", | |
| "\n", | |
| "P.<x,y,z>=PolynomialRing(ZZ)\n", | |
| "PP.<xx,yy,zz>=PolynomialRing(Zmod(n))\n", | |
| "PR.<qr>=PolynomialRing(ZZ)\n", | |
| "\n", | |
| "detB=0\n", | |
| "w=0\n", | |
| "for i in range(m+1):\n", | |
| " for j in range(m-i+1):\n", | |
| " for k in range(j+t+1):\n", | |
| " detB += x*m+y*m+z*(m+t)\n", | |
| " w+=1\n", | |
| "for i in range(m+2):\n", | |
| " j=m+1-i\n", | |
| " for k in range(j+t+1):\n", | |
| " detB += x*(m+i)+y*(m+j)+z*(m+t+k)+1024+y\n", | |
| " w+=1\n", | |
| "detB -= (x*m+y*m+z*(m+t)+1024+y)*w\n", | |
| "print(w, int(PolynomialRing(RR, 'rx')(detB(qr-beta,qr,512)).roots()[0][0]))\n", | |
| "assert ab <= PolynomialRing(RR, 'rx')(detB(qr-beta,qr,512)).roots()[0][0]\n", | |
| "\n", | |
| "\n", | |
| "M=e*2^beta\n", | |
| "R=e*d0-1\n", | |
| "A=int((N+1)/2)\n", | |
| "pol=M*x-A*y-y*z+R\n", | |
| "#assert pol(d//2^beta,2*int((e*d-1)/((p+1)*(q+1))),(p+q)/2) == 0\n", | |
| "pol=P(PP(pol)/R)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 8, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "gg=[]\n", | |
| "monomials = []\n", | |
| "for i in range(m+1):\n", | |
| " for j in range(m-i+1):\n", | |
| " for k in range(j+t+1):\n", | |
| " xshift = x^i*y^j*z^k*pol*X^(m-i)*Y^(m-j)*Z^(m+t-k)\n", | |
| " gg.append(xshift)\n", | |
| "gg.sort()\n", | |
| "\n", | |
| "for i in range(m+2):\n", | |
| " j=m+1-i\n", | |
| " for k in range(j+t+1):\n", | |
| " yshift = n*x^i*y^j*z^k\n", | |
| " gg.append(yshift)\n", | |
| " monomials.append(x^i*y^j*z^k)\n", | |
| "\n", | |
| "for polynomial in gg:\n", | |
| " for monomial in polynomial.monomials():\n", | |
| " if monomial not in monomials:\n", | |
| " monomials.append(monomial)\n", | |
| "monomials.sort()\n", | |
| "\n", | |
| "nn = len(monomials)\n", | |
| "BB = Matrix(ZZ, nn)\n", | |
| "for ii in range(nn):\n", | |
| " BB[ii, 0] = gg[ii](0, 0, 0)\n", | |
| " for jj in range(1, nn):\n", | |
| " if monomials[jj] in gg[ii].monomials():\n", | |
| " BB[ii, jj] = gg[ii].monomial_coefficient(monomials[jj]) * monomials[jj](X,Y,Z)\n", | |
| "\n", | |
| "#assert abs(BB.det()) < n^(nn)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 9, | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "CPU times: user 2min 55s, sys: 250 ms, total: 2min 55s\n", | |
| "Wall time: 2min 55s\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "%time BB=BB.LLL()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 10, | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "found them, using vectors 0 and 1\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "pol=M*x-A*y-y*z+R\n", | |
| "found_polynomials = False\n", | |
| "for pol1_idx in range(nn - 1):\n", | |
| " pol1 = 0\n", | |
| " for jj in range(nn):\n", | |
| " pol1 += P(monomials[jj] * BB[pol1_idx, jj] / monomials[jj](X,Y,Z))\n", | |
| " r1=pol.resultant(pol1,y)\n", | |
| " if r1.is_zero() or r1.monomials() == [1]:\n", | |
| " continue\n", | |
| " for pol2_idx in range(pol1_idx + 1, nn):\n", | |
| " pol2 = 0\n", | |
| " for jj in range(nn):\n", | |
| " pol2 += P(monomials[jj] * BB[pol2_idx, jj] / monomials[jj](X,Y,Z))\n", | |
| " r2=pol.resultant(pol2,y)\n", | |
| " if r2.is_zero() or r2.monomials() == [1]:\n", | |
| " continue\n", | |
| " else:\n", | |
| " print(\"found them, using vectors\", pol1_idx, \"and\", pol2_idx)\n", | |
| " found_polynomials = True\n", | |
| " break\n", | |
| " if found_polynomials:\n", | |
| " break\n", | |
| "if not found_polynomials:\n", | |
| " print(\"no independant vectors could be found. This should very rarely happen...\")" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 11, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "rr=r1.resultant(r2)\n", | |
| "rr=rr(qr,qr,qr)\n", | |
| "pq=rr.roots()[0][0]*2\n", | |
| "assert pq != -(N+1)\n", | |
| "(pp,_),(qq,_)=(qr^2-pq*qr+N).roots()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 12, | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "b'flag{Copper5mith_M3thod_f0r_ECC}'\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "EE=EllipticCurve(Zmod(N),[0,Cy^2-Cx^3])\n", | |
| "dd=inverse_mod(e,(pp+1)*(qq+1))\n", | |
| "M=dd*EE(Cx,Cy)\n", | |
| "print(long_to_bytes((bytes_to_long(sha256(long_to_bytes(M[0])).digest())<<256^^secret^^dd)>>256))" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [] | |
| } | |
| ], | |
| "metadata": { | |
| "kernelspec": { | |
| "display_name": "SageMath 9.0", | |
| "language": "sage", | |
| "name": "sagemath" | |
| }, | |
| "language_info": { | |
| "codemirror_mode": { | |
| "name": "ipython", | |
| "version": 3 | |
| }, | |
| "file_extension": ".py", | |
| "mimetype": "text/x-python", | |
| "name": "python", | |
| "nbconvert_exporter": "python", | |
| "pygments_lexer": "ipython3", | |
| "version": "3.7.3" | |
| } | |
| }, | |
| "nbformat": 4, | |
| "nbformat_minor": 2 | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment