mirror of https://github.com/UMSKT/DB.git
132 lines
3.6 KiB
Python
132 lines
3.6 KiB
Python
try:
|
|
from sage.all import *
|
|
except ImportError:
|
|
print("Unable to load SageMath")
|
|
|
|
# def warnx(*args, **kwargs):
|
|
# print(*args, file=sys.stderr, **kwargs)
|
|
|
|
|
|
# def tee(*output, file=None, **kwargs):
|
|
# print(*output, file=sys.stdout, **kwargs)
|
|
# if file is not None:
|
|
# print(*output, file=file, **kwargs)
|
|
|
|
|
|
def btoi(bb):
|
|
return int.from_bytes(bb, byteorder='little')
|
|
|
|
|
|
def rfactor(m, keysize, B):
|
|
digits = len('%d' % (2 ^ keysize - 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
|
|
|
|
|
|
def parse_bink_data_with_sage(bink):
|
|
curve = bink['curve']
|
|
bink_header = bink['header']
|
|
F = GF(curve['p'])
|
|
# warnx("offs = %d, nb = %d, p = %x" % (offs, nb, p))
|
|
a = F(curve['a'])
|
|
b = F(curve['b'])
|
|
bx = F(curve['g']['x'])
|
|
by = F(curve['g']['y'])
|
|
Kx = F(curve['pub']['x'])
|
|
Ky = F(curve['pub']['y'])
|
|
|
|
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 = []
|
|
|
|
ok, values = rfactor(n, bink_header['hashlen'], B)
|
|
while not ok:
|
|
for value in values:
|
|
ok, nl = rfactor(value, bink_header['keysize'], B)
|
|
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")
|
|
|
|
bink['curve']['n'] = L
|
|
|
|
solver_input = ''
|
|
solver_input += 'GF := GF(%d);\n' % curve['p']
|
|
solver_input += 'E := EllipticCurve([GF|%d,%d]);\n' % (curve['a'], curve['b'])
|
|
solver_input += 'G := E![%d,%d];\n' % (curve['g']['x'], curve['g']['y'])
|
|
solver_input += 'K := E![%d,%d];\n' % (curve['pub']['x'], curve['pub']['y'])
|
|
solver_input += '/*\n'
|
|
solver_input += 'FactorCount:=%d;\n' % len(factors)
|
|
for f in factors:
|
|
solver_input += '%d;\n' % f
|
|
solver_input += '*/'
|
|
|
|
bink['solver_input'] = solver_input
|
|
|
|
return bink
|
|
|
|
|
|
def parse(bink):
|
|
bink_id_int = btoi(bink[0x00:0x04])
|
|
bink_id = "%08x" % bink_id_int
|
|
|
|
bink_header = {
|
|
'identifier': btoi(bink[0x00:0x04]),
|
|
'sizeof': btoi(bink[0x04:0x08]),
|
|
'countof': btoi(bink[0x08:0x0C]),
|
|
'checksum': btoi(bink[0x0C:0x10]),
|
|
'version': btoi(bink[0x10:0x14]),
|
|
'keysize': btoi(bink[0x14:0x18]),
|
|
'hashlen': btoi(bink[0x18:0x1C]),
|
|
'siglen': btoi(bink[0x1C:0x20]),
|
|
}
|
|
|
|
bink_values = bink[0x20:]
|
|
if bink_header["version"] > 20020420:
|
|
bink_values = bink[0x28:]
|
|
bink_header['authlen'] = btoi(bink[0x20:0x24])
|
|
bink_header['pidlen'] = btoi(bink[0x24:0x28])
|
|
|
|
offs = bink_header["keysize"] * 4
|
|
|
|
curve = {
|
|
'p': btoi(bink_values[:offs]),
|
|
'a': btoi(bink_values[offs:offs * 2]),
|
|
'b': btoi(bink_values[offs * 2:offs * 3]),
|
|
'g': {'x': btoi(bink_values[offs * 3:offs * 4]), 'y': btoi(bink_values[offs * 4:offs * 5])},
|
|
'pub': {'x': btoi(bink_values[offs * 5:offs * 6]), 'y': btoi(bink_values[offs * 6:offs * 7])},
|
|
'n': '',
|
|
'priv': ''
|
|
}
|
|
|
|
output = {
|
|
'bink_name': bink_id,
|
|
'header': bink_header,
|
|
'curve': curve,
|
|
}
|
|
|
|
output = parse_bink_data_with_sage(output)
|
|
|
|
return output
|