Challenge:

from secret import flag

Kbits1 = 120
Kbits2 = 493

p = random_prime(2^512-1, false, 2^511)
q = random_prime(2^512-1, false, 2^511)
N = p*q
e = 0x10001

# Wait this is illegal
Pdigits = p.digits(2)
leaky_p = [0]*19 + Pdigits[19:Kbits1] + [0]*19 + Pdigits[Kbits1+19:Kbits2]

c = pow(flag, e, N)
print(f"(c, e, N) = {(c, e, N)}")
print(f"leaky = {leaky_p}")

# (c, e, N) = (26332525917536404445261335188023824835582728456010807789427648382546117992477286201354477933620634042162778383500347554403856479653121560047163571802966352911016989944196656213695292273900862199180497043773236377160608017101154863030724519304212930989627167943539496731959903689581119612196554873637719776156, 65537, 107953240319236322637058433940161528510672490103418517617520324178241611238072198345853818249768509790971608169523056348162590719063088182552103689228188347112141257514135750575118448199789749158885349374251834100136760987321248910344201579746268207678856824451563937881565576119683013793260110227648499602781)
# leaky = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]


Solve:

from tqdm import tqdm

Kbits1 = 120
Kbits2 = 493

(c, e, N) = (26332525917536404445261335188023824835582728456010807789427648382546117992477286201354477933620634042162778383500347554403856479653121560047163571802966352911016989944196656213695292273900862199180497043773236377160608017101154863030724519304212930989627167943539496731959903689581119612196554873637719776156, 65537, 107953240319236322637058433940161528510672490103418517617520324178241611238072198345853818249768509790971608169523056348162590719063088182552103689228188347112141257514135750575118448199789749158885349374251834100136760987321248910344201579746268207678856824451563937881565576119683013793260110227648499602781)
leaky = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]

leaky_p = leaky

P = PolynomialRing(Zmod(N), 3, 'xyz', order='lex')
x,y,z = P.gens()

f = x +\
 (2**19)*sum([2**i * leaky_p[19+i] for i in range(Kbits1-19)]) +\
 (2**Kbits1)*y +\
 (2**(Kbits1+19))*sum([2**i * leaky_p[19+Kbits1+i] for i in range(Kbits2-(Kbits1+19))]) + \
 (2**(Kbits2))*z

def hermann_may_main(f, bounds, m, t):
    import itertools

    N = int(f.parent().characteristic())
    
    vars = f.parent().gens()
    if f.degree() > 1:
        raise ValueError
    if f.monomial_coefficient(vars[0]) != 1:
        try:
            f = f / f.monomial_coefficient(vars[0])
        except:
            print(f"inverse error: {f.monomial_coefficient(vars[0])}")
            return None
    
    f = f.change_ring(ZZ)
    vars = f.parent().gens() # on ZZ

    polylst = []
    for k in range(m):
        for i in range(m-k + 1):
            for subvars in itertools.combinations_with_replacement(vars[1:], i):
                poly = f**k * prod(subvars) * N**(max(t - k, 0))
                polylst.append(poly)
    
    monos = (f**m).monomials()
    matele = []
    for poly in polylst:
        mateleele = []
        for mono in monos:
            mateleele.append(poly.monomial_coefficient(mono)*mono.subs({vars[i]: bounds[i] for i in range(len(vars))}))
        matele += mateleele
    mat = matrix(ZZ, len(polylst), len(monos), matele)
    red, U = mat.LLL(transformation=True)
    
    redpolys = []
    for i in range(len(vars)):
        redpolys.append(sum([U[i,j]*polylst[j] for j in range(len(polylst))]))
        redpolys[i] = redpolys[i].change_ring(QQ)

    return redpolys


for m in range(5, 5+1):
    try:
        beta = 0.5
        n = len(P.gens())
        tau = 1 - (1-beta)**(1.0/n)
        t = int(m * tau)
        result = hermann_may_main(f, [2**19, 2**19, 2**19], m, t)
    except:
        continue
    x_,y_,z_ = result[0].parent().gens()
    pol1 = result[0].resultant(result[1], x_)
    pol2 = result[0].resultant(result[2], x_)
    
    smallp = PolynomialRing(QQ, 'z__')
    z__ = smallp.gens()[0]
    
    for y__val in tqdm(range(2**19, 0, -1)):
        pol1__ = pol1.subs({x_:0, y_:y__val, z_:z__})
        pol2__ = pol2.subs({x_:0, y_:y__val, z_:z__})
        pol12__ = pol1__.gcd(pol2__)
        rt_z = pol12__.roots()
        if rt_z != []:
            soly = ZZ(y__val)
            solz = ZZ(rt_z[0][0])
            solx = ZZ(result[0].subs({x_:z__, y_:soly, z_:solz}).roots()[0][0])
            print((solx, soly, solz))
            break


#solx,soly,solz = (438971, 391065, 320914)

from Crypto.Util.number import *
p = GCD(int((f.subs({x:solx, y:soly, z:solz})).lift()), N)
q = N // p

d = pow(int(e), -1, int((p-1)*(q-1)))
print(long_to_bytes(int(pow(c, d, N))))
# ASCIS{C0nGratulation_s0_Y0u_D0_kNow_about_H3rm4nN_M4y_730EF6498A3B0441B43400367B788817413F5A65A3900E2976D071232A2FC827}