Challenge Description 1 ECC + RSA = Double security! 
Attachment - ecc-rsa.py
- ecc-rsa.txt
ecc-rsa.py 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 from  fastecdsa.curve import  P521 as  Curvefrom  fastecdsa.point import  Pointfrom  Crypto.Util.number import  bytes_to_long, isPrimefrom  os import  urandomfrom  random import  getrandbitsdef  gen_rsa_primes (G ): urand = bytes_to_long(urandom(521 //8 ))  while  True :   s = getrandbits(521 ) ^ urand   Q = s*G   if  isPrime(Q.x) and  isPrime(Q.y):    print ("ECC Private key:" , hex (s))    print ("RSA primes:" , hex (Q.x), hex (Q.y))    print ("Modulo:" , hex (Q.x * Q.y))    return  (Q.x, Q.y) flag = int .from_bytes(input (), byteorder="big" ) ecc_p = Curve.p a = Curve.a b = Curve.b Gx = Curve.gx Gy = Curve.gy G = Point(Gx, Gy, curve=Curve) e = 0x10001  p, q = gen_rsa_primes(G) n = p*q file_out = open ("downloads/ecc-rsa.txt" , "w" ) file_out.write("ECC Curve Prime: "  + hex (ecc_p) + "\n" ) file_out.write("Curve a: "  + hex (a) + "\n" ) file_out.write("Curve b: "  + hex (b) + "\n" ) file_out.write("Gx: "  + hex (Gx) + "\n" ) file_out.write("Gy: "  + hex (Gy) + "\n" ) file_out.write("e: "  + hex (e) + "\n" ) file_out.write("p * q: "  + hex (n) + "\n" ) c = pow (flag, e, n) file_out.write("ciphertext: "  + hex (c) + "\n" ) 
ecc-rsa.txt 1 2 3 4 5 6 7 8 ECC Curve Prime: 0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff  Curve a: -0x3  Curve b: 0x51953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00  Gx: 0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66  Gy: 0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650  e: 0x10001  p * q: 0x1d61da34917e872315d41403c6a59911be97ba4673b0ff1e40201a7c7381845716d1e2f3906f226f649d663af7d9f68e0029629ff9bb07991db2bdff13adad242e9c4c06c6b5cf1ca5fa20eae64f1cdc2376651a4a7f7610e71257ce5da3cc8389c80797a2a9952bcd8c165d0dd5eef523ceb96748eb5aa66d0b4959dcef6a53dac5  ciphertext: 0x12fc466fa277837af8f20c59144d22e80fe4f9ab7371668487cdea44ff1677655d8628aacb688747c2bca111c3b34fa034b9915736fc614c3233bf6445d5ee90eac16a218770f296885bd997989f64a2e70324bba4171ad39759435b4f6d598952e6600eb663d5d9a210baa7134b1aa556aa56a092e7414127a1c35a3bbb1cbb455c  
Observation We can notice that the primes are generated using a custom function named gen_rsa_primes,
means: y^2 = x^3 + a*x + b =>=> q^2 = p^3 + a*p + b
Exploit Idea - Recover primes using the relation
- Decrypt the Ciphertext to get the Flag
Recovering Primes using the curve equation 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 lines = open ("downloads/ecc-rsa.txt" , "r" ).read().split("\n" ) p = ZZ(lines[0 ].split(" " )[-1 ]) a = ZZ(lines[1 ].split(" " )[-1 ]) b = ZZ(lines[2 ].split(" " )[-1 ]) e = ZZ(lines[5 ].split(" " )[-1 ]) n = ZZ(lines[6 ].split(" " )[-1 ]) c = ZZ(lines[7 ].split(" " )[-1 ]) P = GF(p) E = EllipticCurve(P, [a, b]) G = E(Gx, Gy) F. < x > = PolynomialRing(P) f = x ^ 5  + a*x ^ 3  + b*x ^ 2  - n ^ 2  p = [int (i[0 ]) for  i in  f.roots() if  int (n) % int (i[0 ]) == 0 ][0 ] q = n//q 
Decryption 1 2 3 4 5 6 phi = (p-1 )*(q-1 ) d = invert(e, phi) m = pow (c, d, n) flag = b'watevr{'  + long_to_bytes(m) + b'}'  
Exploit 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 lines = open ("downloads/ecc-rsa.txt" , "r" ).read().split("\n" ) p = ZZ(lines[0 ].split(" " )[-1 ]) a = ZZ(lines[1 ].split(" " )[-1 ]) b = ZZ(lines[2 ].split(" " )[-1 ]) e = ZZ(lines[5 ].split(" " )[-1 ]) n = ZZ(lines[6 ].split(" " )[-1 ]) c = ZZ(lines[7 ].split(" " )[-1 ]) P = GF(p) E = EllipticCurve(P, [a, b]) G = E(Gx, Gy) F. < x > = PolynomialRing(P) f = x ^ 5  + a*x ^ 3  + b*x ^ 2  - n ^ 2  p = [int (i[0 ]) for  i in  f.roots() if  int (n) % int (i[0 ]) == 0 ][0 ] q = n//q phi = (p-1 )*(q-1 ) d = invert(e, phi) m = pow (c, d, n) flag = b'watevr{'  + long_to_bytes(m) + b'}'  assert  flag == b'watevr{lol}' 
Flag 
b’watevr{lol}’