Endermanch / XPKeygen

Windows XP Keygen
GNU General Public License v3.0
889 stars 48 forks source link

Get generator order easily! #7

Closed CONIGUERO closed 1 year ago

CONIGUERO commented 1 year ago

Here's a SageMath script to get the ECDLP solver ready (not mine, all credit goes to sk00ter)

#!/usr/bin/env sage
import sys

def warnx(*args, **kwargs):
    print(*args, file=sys.stderr, **kwargs)

with open(sys.argv[1], 'rb') as f:
    bink = f.read()[4:] # skip res ID

    def btoi(bb):
        n = 0
        for b in reversed(bb): # little-endian
            n = n << 8
            n |= b
        return n

    offs = 4 * int.from_bytes(bink[0x04:0x08], 'little') # offset to curve params in words
    nb = 4 * int.from_bytes(bink[0x10:0x14], 'little') # size of curve params in words
    pkScalarBits = int.from_bytes(bink[0x18:0x1c], 'little')
    warnx("pkScalarBits = %d" % pkScalarBits)
    p = btoi(bink[offs:offs+nb])
    warnx("offs = %d, nb = %d, p = %x" % (offs, nb, p))
    F = GF(p)
    a = F(btoi(bink[offs+nb:offs+2*nb]))
    b = F(btoi(bink[offs+2*nb:offs+3*nb]))
    Bx = F(btoi(bink[offs+3*nb:offs+4*nb]))
    By = F(btoi(bink[offs+4*nb:offs+5*nb]))
    Kx = F(btoi(bink[offs+5*nb:offs+6*nb]))
    Ky = F(btoi(bink[offs+6*nb:offs+7*nb]))

E = EllipticCurve(F, [0, 0, 0, a, b])
warnx(E)
B = E(Bx, By)
K = E(Kx, Ky)

# If we get here, we know B and K are on the curve.
# Now get the order of the curve and then factorize it.

n = E.order()
warnx("n = %d, now factoring..." % n)
# Find L by just trying if any of the factors in f yield the point at infinity
factors = []
def rfactor(m):
    digits = len('%d' % (2^pkScalarBits - 1))
    ff = ecm.find_factor(m, factor_digits=digits) # Try to find a good candidate
    for f in ff:
        if f > 2 and f.is_prime() and not f * B:
            warnx("ok for %d" % f)
            return True, [f]
    else:
        warnx("bad run: %s" % ff)
        return False, ff

ok, values = rfactor(n)
while not ok:
    for value in values:
        ok, nl = rfactor(value)
        if ok:
            L = nl[0]
            break
        values.extend(nl)

factors = [n // L, L]
warnx(factors)
warnx("Reduce the result of ECDLP Solver modulo %d" % L)

warnx("\n\njob input:\n\n")
print("GF := GF(%d);" % p)
print("E := EllipticCurve([GF|%d,%d]);" % (a, b))
print("G := E![%d,%d];" % (Bx, By))
print("K := E![%d,%d];" % (Kx, Ky))
print("/*")
print("FactorCount:=%d;" % len(factors))
for f in factors:
    print("%d;" % f)
print("*/")
CONIGUERO commented 1 year ago

Nevermind. This just sets up the ECDLP solver, it doesn't output the order.

Endermanch commented 1 year ago

Useful nonetheless. Noted