#!/usr/bin/env python3from Crypto.Util.number import getRandomRange, isPrimefrom secret import FLAG, zdefnextPrime(a): b = a |1whilenotisPrime(b)or a == b: b +=2return bdefgetPrime(z):whileTrue: a =nextPrime(getRandomRange(z //2, z -1)) b =nextPrime(getRandomRange(z //2, z -1)) p = a *pow(z, 2)+ bifisPrime(p):return pm =int.from_bytes(FLAG, "big")e =65537p =getPrime(z)q =getPrime(z)n = p * qc =pow(m, e, n)print(f"{z = }")print(f"{e = }")print(f"{n = }")print(f"{c = }")
We know that the factor of n (p and q) calculated from linear operation which is a * pow(z, 2) + b. In this case we know z and n. If we convert n to equation that contains z it should be like this
z^4*a1a2 + z^2*a1b2 + z^2*b1a2 + b1b2
Since it is z^4 also a and b value lower than z we can get value of a1a2 by dividing it with z^4 then subtract by one. After getting a1a2 value, we can get the value of (a1b2 + a2b1) through equation below
Repeating the same way, we can get a1b2 + a2b1 by dividing it with z^2. After that we can get b1b2 since we know the rest value. Since we have a1b2 + a2b1 we can square it to get (a1b2)^2 + 2(a2b1a1b2) + (a2b1)^2 then since we know a2b1a1b2 we can substract those equation with 4(a2b1a1b2) and then we have equation in format a2 - 2ab + b2 which has root a-b or in this case a1b2 - a2b1. After that just eliminate 1 value then substitute it to get a1,a2,b1,and b2. After that we can reconstruct the p and q then decrypt the flag. Here is the implementation in python