示例#1
0
文件: solve.py 项目: unjambonakap/ctf
def analyse(base):

    n = 128
    data = base + [random.randint(0, 2 * n - 1) for i in range(n)]

    data = {i: data[i] for i in range(len(data))}
    idata = {v: k for k, v in data.items()}
    cnt = 0
    tot = DictWithDefault(0)
    seen = {}
    for i in range(n):
        lst, typ = get_cycle(data, i, n)
        if typ == 0:
            if not lst[-2] in seen:
                seen[lst[-2]] = 1
                tot[lst[-1]] += 1
            cnt += 1
            print(len(lst))
    tb = []
    print('####')
    for i in range(n, 2 * n):
        print(tot[i])
        if tot[i] == 0:
            tb.append(i)
    print(tb, len(tb))
    print(cnt)
示例#2
0
 def on_error_rendering(self, request, f):
     frames = f.stack[-5:] + f.frames
     traceback = []
     
     for fn, filename, line_no, loc, glob in frames:
         traceback.append({
             "fn" : fn,
             "filename" : filename,
             "line_no" : line_no,
             "preview" : get_code_preview(filename, line_no)
         })
         
     ctx = {
         "failure" : f,
         "traceback" : traceback,
         "error" : "%s.%s : %s" % (f.type.__module__, f.type.__name__, f.value)
     }
     
     t = yield plugin.run_hook("on_render_jinja2_template", request,
                            "gyro.development/500.html", ctx)
     
     if not t:
         #Our 500 page didn't get rendered
         log.msg("Error rendering 500 template")
         t = "<html><body><pre>%s</pre></body></html>" % (f.getTraceback(), )
         
     request.set_response_code(500)
     request.set_header("content-type", "text/html")
     request.write(t.encode("utf-8"))
     request.finish()
     defer.returnValue(request)
示例#3
0
 def handler(a, b):
     tb = []
     while b is not None:
         tb.append('%d %s %d' %
                   (b.f_lineno, b.f_code.co_filename, os.getpid()))
         b = b.f_back
     raise LongJump('\n'.join(tb))
示例#4
0
 def handler(a, b):
     tb = []
     while b is not None:
         tb.append('%d %s %d' % (b.f_lineno, b.f_code.co_filename,
             os.getpid()))
         b = b.f_back
     raise LongJump('\n'.join(tb))
示例#5
0
 def disp_cols_helper(self):
     n = 1
     tb = []
     while n < self.maxl:
         sx = ' ' * self.left_margin
         for j in range(self.maxl // n):
             sx += '{val:<{width}d}'.format(width=n, val=j % 10)
         tb.append(sx)
         n *= 10
     print('\n'.join(reversed(tb)))
示例#6
0
def fail_imports(module, needs_certifi=True):
    errors = []
    traceback = []
    if not HAS_REDIS_PACKAGE:
        errors.append(missing_required_lib('redis'))
        traceback.append(REDIS_IMP_ERR)
    if not HAS_CERTIFI_PACKAGE and needs_certifi:
        errors.append(missing_required_lib('certifi'))
        traceback.append(CERTIFI_IMPORT_ERROR)
    if errors:
        module.fail_json(errors=errors, traceback='\n'.join(traceback))
示例#7
0
 def get_target_path(self):
     if not self.target_path:
         n = len(self.stack_path) - 1
         tb = []
         cur = self.path
         for x in range(n):
             cur, tmp = os.path.split(cur)
             tb.append(tmp)
         tb.reverse()
         self.target_path = self.PATH_SEPARATOR.join(tb)
     return self.target_path
示例#8
0
  def extract_seccomp_filters(self, addr):
    l = self.mem.get_u16(addr)
    # only works for x86 atm (alignment)
    ptr = self.mem.get_ptr(addr + 4)
    tb = []

    sz = SeccompFilters.SIZE
    mem = x.get_memory(ptr, sz * l)
    for i in range(l):
      tb.append(SeccompFilters(mem[i * sz:i * sz + sz]))
    return tb
示例#9
0
def check1(b):

    tb = []
    for i in range(len(b) // 8):
        tb.append(int(b[i * 8:i * 8 + 8], 16))
    x = 0
    for e in tb:
        print(hex(e))
        x ^= e
    x = enc_w1(x)
    print(hex(x), hex(W1_CMP))
    assert x == W1_CMP
示例#10
0
def go(*argv):
    x = GdbDebugger()
    elf = x.get_elf()
    x.add_entry_bpt()

    #x.do_execute('set confirm off')
    #end_bpt = x.set_bpt(elf.get_symbol('test_end'), cb=lambda *args: print('kappa'))
    #start_bpt = x.set_bpt(elf.get_symbol('test_wrap'))
    #iter_bpt = x.set_bpt(0x08049559)

    #buf_pos = elf.get_symbol('g_buf')
    #len_pos = elf.get_symbol('g_len')

    print(x.do_execute('b main'))
    print(x.do_execute('info breakpoints'))
    print('laaa')
    x.run(silent=0)
    print(x.do_execute('info breakpoints'))
    print('STOP')
    cur_str = bytearray(b'\x00')
    x.resume()

    tb = []
    cnt = 0
    while True:
        x.show_context()
        if x.is_bpt_active(end_bpt):
            res = x.mem.read_u32(x.reg.esp + 4)
            if res == 1:
                print('FOUND SOL ', cur_str)
                break
            tb.append(cnt)
            cur_str[-1] += 1
            cnt = 0

        elif x.is_bpt_active(start_bpt):
            if cur_str[-1] == 128:
                bst = np.argmax(tb)
                cur_str[-1] = bst
                print('ON >> ', cur_str)
                cur_str.append(0)
                x.mem.write_u32(len_pos, len(cur_str))

            x.mem.write(buf_pos, cur_str)

        elif x.is_bpt_active(iter_bpt):
            cnt += 1

        else:
            assert 0
        x.resume()
    print('DONE HERE KAPPA')
示例#11
0
    def create_trace(self):
        traceback = []
        for tb in self.traceback.stack:
            traceback.append(StackLine(tb, variables=tb.locals))

        if hasattr(self.e, 'from_obj'):
            frame_summary = [
                inspect.getsourcefile(self.e.from_obj),
                inspect.getsourcelines(self.e.from_obj)[1], '', 'null'
            ]
            traceback.append(StackLine(frame_summary, variables={}))

        return traceback
示例#12
0
    def guess_best(self):
        for i in range(self.maxl):
            sx = bytearray()
            for x in self.data:
                if len(x) <= i:
                    continue
                sx.append(x[i])

            tb = []
            for k in range(256):
                tmp = xor(sx, k)
                tb.append((self.scoring.compute_score(tmp), k))
            tb.sort(key=lambda x: x[0].score)
            self.pad[i] = tb[0][1]
示例#13
0
def test_perm(ctx):
    lines = open('./test.in').readlines()
    tb = []
    for line in lines:
        x = defaultdict(list)
        line.strip()
        for i, c in enumerate(line):
            x[c].append(i)
        print(len(line))
        tb.append(x)
    n = len(lines[0]) - 1
    can = defaultdict(lambda: set(range(n)))
    for i in range(len(lines) - 1):
        for j in range(n):
            can[j].intersection_update(tb[i + 1][lines[i][j]])
        break
    for i in range(n):
        print(i, can[i])
    print(lines)
示例#14
0
def hack_client(ctx):

    local_pk = load(open(f'./public-data/bob.key', 'rb'))
    remote_pk = load(open(f'./public-data/alice.key', 'rb'))
    lsig = SignatureScheme(None, local_pk)
    rsig = SignatureScheme(None, remote_pk)

    r = make_ratchet(lsig, rsig)

    import glob
    msgs = glob.glob('./public-data/messages/b2a*')
    msgs.sort()
    data = {}

    tb = []
    for msg_id, msg_fname in enumerate(msgs):
        content = open(msg_fname, 'rb').read()
        signed_data, signature = content.rsplit(b"|", 1)

        h = lsig.hash2(signed_data, msg_id + 1)
        data[msg_id + 1] = [h, signed_data, protocol.decode_int(signature)]
        tb.append([h, protocol.decode_int(signature)])
        print(tb[-1])
        print()
        #signature_valid = lsig.verify(data, protocol.decode_int(signature))
        #assert signature_valid

    N = local_pk.n
    hl = 256
    fk = local_sig(ctx)
    last_sig = tb[-1][1]

    def inv(x):
        ix = gmpy2.invert(x, N)
        assert x * ix % N == 1
        return ix

    for i in range(1, len(tb)):
        tb[-i][1] = tb[-i][1] * inv(tb[-i - 1][1]) % N

    last = tb[-1]
    tb = tb[:-1]
    n = len(tb)
    tmp = []

    for i in range(n):
        x = inv(pow(tb[i][1], 2**(hl * (n - i)), N)) * last[1] % N
        hdiff = last[0] - tb[i][0]
        tmp.append([x, hdiff])

    sel1 = tmp[-1]
    sel2 = None
    for cnd in tmp:
        if gmpy2.gcd(tmp[-1][1], cnd[1]) == 1:
            sel2 = cnd
            break
    else:
        assert 0

    d, u, v = gmpy2.gcdext(sel1[1], sel2[1])
    if u < 0:
        sel1[0] = inv(sel1[0])
        u = -u
    if v < 0:
        sel2[0] = inv(sel2[0])
        v = -v
    spw = pow(sel1[0], u, N) * pow(sel2[0], v, N) % N
    expected = pow(fk.sk.s, 2**(hl * n), N)

    rpw = last[1] * gmpy2.powmod(spw, -last[0], N) % N

    r.remote_public_element = 1
    public_element, iv, ciphertext = r._encrypt_message(REQ_FLAG)
    public_element = 1
    signed_data = protocol.encode_int(
        public_element, 256) + b"|" + protocol.encode_int(
            iv, 16) + b"|" + protocol.encode_bytes(ciphertext)

    nmsg_id = n + 2

    nh = lsig.hash2(signed_data, nmsg_id)
    print(nh, nmsg_id, signed_data)
    forged_sig = last_sig * pow(rpw * pow(spw, nh, N), 2**hl, N) % N
    print(forged_sig)

    data = signed_data + b"|" + protocol.encode_int(forged_sig, 256)

    with Connection(ctx.host, ctx.port) as conn:

        conn.send(data + b'\x00')
        res = conn.recv_until(b'\x00')[:-1]
        r.public_element = 1
        flagans = r.on_recv_message(res, hack=True)
        print(flagans)
示例#15
0
def html(context=5, i18n=None):
    _ = get_translator(i18n)
    etype, evalue = sys.exc_info()[0], sys.exc_info()[1]
    if type(etype) is type:
        etype = etype.__name__
    pyver = 'Python ' + sys.version.split()[0] + '<br>' + sys.executable
    head = pydoc.html.heading(
        _('<font size=+1><strong>%(exc_type)s</strong>: %(exc_value)s</font>')
        % {
            'exc_type': etype,
            'exc_value': evalue
        }, '#ffffff', '#777777', pyver)

    head = head + (_('<p>A problem occurred while running a Python script. '
                     'Here is the sequence of function calls leading up to '
                     'the error, with the most recent (innermost) call first. '
                     'The exception attributes are:'))

    indent = '<tt><small>%s</small>&nbsp;</tt>' % ('&nbsp;' * 5)
    traceback = []
    for frame, file, lnum, func, lines, index in inspect.trace(context):
        if file is None:
            link = _("&lt;file is None - probably inside <tt>eval</tt> "
                     "or <tt>exec</tt>&gt;")
        else:
            file = os.path.abspath(file)
            link = '<a href="file:%s">%s</a>' % (file, pydoc.html.escape(file))
        args, varargs, varkw, locals = inspect.getargvalues(frame)
        if func == '?':
            call = ''
        else:
            call = _(
                'in <strong>%s</strong>') % func + inspect.formatargvalues(
                    args,
                    varargs,
                    varkw,
                    locals,
                    formatvalue=lambda value: '=' + pydoc.html.repr(value))

        level = '''
<table width="100%%" bgcolor="#dddddd" cellspacing=0 cellpadding=2 border=0>
<tr><td>%s %s</td></tr></table>''' % (link, call)

        if index is None or file is None:
            traceback.append('<p>' + level)
            continue

        # do a file inspection
        names = []

        def tokeneater(type, token, start, end, line, names=names):
            if type == tokenize.NAME and token not in keyword.kwlist:
                if token not in names:
                    names.append(token)
            if type == tokenize.NEWLINE: raise IndexError

        def linereader(file=file, lnum=[lnum]):
            line = s2b(linecache.getline(file, lnum[0]))
            lnum[0] = lnum[0] + 1
            return line

        # The interface that is tokenize.tokenize in Python 3 is
        # called tokenize.generate_tokens in Python 2.  However,
        # Python 2 has tokenize.tokenize with a different interface,
        # and Python 3 has an undocumented generate_tokens function,
        # also with a different interface, so a version check is
        # needed instead of checking for which functions exist.
        if sys.version_info[0] > 2:
            tokenize_fn = tokenize.tokenize
        else:
            tokenize_fn = tokenize.generate_tokens
        try:
            for t in tokenize_fn(linereader):
                tokeneater(*t)
        except IndexError:
            pass
        lvals = []
        for name in names:
            if name in frame.f_code.co_varnames:
                if name in locals:
                    value = pydoc.html.repr(locals[name])
                else:
                    value = _('<em>undefined</em>')
                name = '<strong>%s</strong>' % name
            else:
                if name in frame.f_globals:
                    value = pydoc.html.repr(frame.f_globals[name])
                else:
                    value = _('<em>undefined</em>')
                name = '<em>global</em> <strong>%s</strong>' % name
            lvals.append('%s&nbsp;= %s' % (name, value))
        if lvals:
            lvals = ', '.join(lvals)
            lvals = indent + '<small><font color="#909090">%s'\
                '</font></small><br>'%lvals
        else:
            lvals = ''

        excerpt = []
        i = lnum - index
        for line in lines:
            number = '&nbsp;' * (5 - len(str(i))) + str(i)
            number = '<small><font color="#909090">%s</font></small>' % number
            line = '<tt>%s&nbsp;%s</tt>' % (number, pydoc.html.preformat(line))
            if i == lnum:
                line = '''
<table width="100%%" bgcolor="white" cellspacing=0 cellpadding=0 border=0>
<tr><td>%s</td></tr></table>''' % line
            excerpt.append('\n' + line)
            if i == lnum:
                excerpt.append(lvals)
            i = i + 1
        traceback.append('<p>' + level + '\n'.join(excerpt))

    traceback.reverse()

    exception = '<p><strong>%s</strong>: %s' % (str(etype), str(evalue))
    attribs = []
    for name in dir(evalue):
        value = pydoc.html.repr(getattr(evalue, name))
        attribs.append('<br>%s%s&nbsp;= %s' % (indent, name, value))

    return head + ' '.join(attribs) + ' '.join(traceback) + '<p>&nbsp;</p>'
示例#16
0
    def __init__(self):
        mu = Uc(UC_ARCH_X86, UC_MODE_64)
        elf = load_elf(mu, flags.file)
        kern = Kernel(mu, None)

        perms = []
        base = 0x7ffff7dc70ac
        for i in range(4):
            tb = []
            for j in range(0x20):
                x = kern.mem.get_u8(base)
                tb.append(x)
                base += 1
            perms.append(tb)
        self.op_params = []
        self.op_params.append(
            Attributize(xorv=0x20bfdf15,
                        addv=0x762defc2,
                        shiftv=0x7,
                        perm=perms[0],
                        add0=0x19bf70ca))
        self.op_params.append(
            Attributize(xorv=0x83e2c81b,
                        addv=0x4525e7b8,
                        shiftv=0xd,
                        perm=perms[1],
                        add0=0xabb456d0))
        self.op_params.append(
            Attributize(xorv=0xd4d084ba,
                        addv=0x3f5be319,
                        shiftv=0x11,
                        perm=perms[2],
                        add0=0xdd1d76ca))
        self.op_params.append(
            Attributize(xorv=0xa6872cbd,
                        addv=0xf59e62f,
                        shiftv=0x19,
                        perm=perms[3],
                        add0=0x17d7d01d))

        in_test = [
            0x368f38be,
            0xabb456d1,
            0xdd1d76ca,
            0x17d7d01d,
        ]
        out_test = [0x16aacfd6, 0x2fc42297, 0xf045384d, 0x2722cb0f]
        assert out_test == self.full(in_test)
        assert in_test == self.ifull(out_test)
        test_full = [0x1ccfc7f4, 1, 0, 0]
        res = self.tsf(test_full)
        assert test_full == self.itsf(res)

        self.ans = [0xdd78363f, 0x2f19e578, 0x3ad92c4f, 0x2b6917a5]
        res = self.itsf(self.ans)

        res[3] = self.find_s3(res)
        assert self.checksum(res) == W1_CMP
        res = ['{:08x}'.format(x) for x in res]
        print(res)
        print(''.join(res))

        buf = '1ccfc7f400000001' + ('0' * 16)
        buf = flags.buf
        if buf:
            lst = list(struct.unpack('>4I', binascii.unhexlify(buf)))
            print([hex(x) for x in lst])
            print([hex(x) for x in self.tsf(lst)])
            print([hex(x) for x in self.tsf(lst, 0)])
            print([hex(x) for x in self.tsf(lst, 1)])
示例#17
0
    def create_trace(self):
        traceback = []
        for tb in self.traceback.stack:
            traceback.append(SimpleStackLine(tb, variables=tb.locals))

        return traceback
示例#18
0
def compare_graph(obj1, obj2, traceback=None, visited=None):
    """ Compares two objects and shows traceback to first found difference

    :param obj1 (Job/Path): Object1 to compare
    :param obj2 (Job/Path): Object2 which is compared to Object1
    :param traceback: Used for recursion, leave blank
    :param visited: Used for recursion, leave blank
    :return: traceback
    """

    visited = set() if visited is None else visited

    traceback = [] if traceback is None else traceback
    traceback.append((obj1, obj2))

    sis_hash = gs.SIS_HASH(obj1)
    skip = sis_hash in visited
    if not skip:
        visited.add(gs.SIS_HASH(obj1))

    if skip:
        pass
    elif type(obj1) != type(obj2):
        yield traceback + [(type(obj1), type(obj2))]
    elif isinstance(obj1, Job):
        if obj1._sis_id() != obj2._sis_id():
            yield from compare_graph(obj1._sis_kwargs, obj2._sis_kwargs,
                                     traceback[:], visited)
    elif isinstance(obj1, Path):
        if obj1.path != obj2.path:
            yield traceback + [(obj1.path, obj2.path)]
        else:
            yield from compare_graph(obj1.creator, obj2.creator, traceback[:],
                                     visited)
    elif isinstance(obj1, (list, tuple, set)):
        if len(obj1) != len(obj2):
            yield traceback + [len(obj1), len(obj2)]
        else:
            if isinstance(obj1, set):
                obj1 = sorted(list(obj1))
                obj2 = sorted(list(obj2))
            for a, b in zip(obj1, obj2):
                yield from compare_graph(a, b, traceback[:], visited)
    elif isinstance(obj1, dict):
        for k, v1 in obj1.items():
            try:
                v2 = obj2[k]
            except KeyError:
                yield traceback + [(k, None)]
            else:
                yield from compare_graph(v1, v2, traceback[:], visited)

        for k, v2 in obj2.items():
            if k not in obj1:
                yield traceback + [(None, k)]
    elif hasattr(obj1, '__dict__'):
        yield from compare_graph(obj1.__dict__, obj2.__dict__, traceback[:],
                                 visited)
    elif hasattr(obj1, '__slots__'):
        for k in obj1.__slots__:
            if hasattr(obj1, k):
                if hasattr(obj2, k):
                    v1 = getattr(obj1, k)
                    v2 = getattr(obj2, k)
                    yield from compare_graph(v1, v2, traceback[:], visited)
                else:
                    yield traceback + [(k, None)]
            else:
                if hasattr(obj2, k):
                    yield traceback + [(None, k)]
    else:
        if obj1 != obj2:
            yield traceback[:]
示例#19
0
def html(context=5, i18n=None):
    _ = get_translator(i18n)
    etype, evalue = sys.exc_info()[0], sys.exc_info()[1]
    if type(etype) is type:
        etype = etype.__name__
    pyver = 'Python ' + string.split(sys.version)[0] + '<br>' + sys.executable
    head = pydoc.html.heading(
        _('<font size=+1><strong>%(exc_type)s</strong>: %(exc_value)s</font>')
        % {'exc_type': etype, 'exc_value': evalue},
        '#ffffff', '#777777', pyver)

    head = head + (_('<p>A problem occurred while running a Python script. '
                   'Here is the sequence of function calls leading up to '
                   'the error, with the most recent (innermost) call first. '
                   'The exception attributes are:'))

    indent = '<tt><small>%s</small>&nbsp;</tt>' % ('&nbsp;' * 5)
    traceback = []
    for frame, file, lnum, func, lines, index in inspect.trace(context):
        if file is None:
            link = _("&lt;file is None - probably inside <tt>eval</tt> "
                "or <tt>exec</tt>&gt;")
        else:
            file = os.path.abspath(file)
            link = '<a href="file:%s">%s</a>' % (file, pydoc.html.escape(file))
        args, varargs, varkw, locals = inspect.getargvalues(frame)
        if func == '?':
            call = ''
        else:
            call = _('in <strong>%s</strong>') % func + inspect.formatargvalues(
                    args, varargs, varkw, locals,
                    formatvalue=lambda value: '=' + pydoc.html.repr(value))

        level = '''
<table width="100%%" bgcolor="#dddddd" cellspacing=0 cellpadding=2 border=0>
<tr><td>%s %s</td></tr></table>''' % (link, call)

        if index is None or file is None:
            traceback.append('<p>' + level)
            continue

        # do a file inspection
        names = []
        def tokeneater(type, token, start, end, line, names=names):
            if type == tokenize.NAME and token not in keyword.kwlist:
                if token not in names:
                    names.append(token)
            if type == tokenize.NEWLINE: raise IndexError
        def linereader(file=file, lnum=[lnum]):
            line = linecache.getline(file, lnum[0])
            lnum[0] = lnum[0] + 1
            return line

        try:
            tokenize.tokenize(linereader, tokeneater)
        except IndexError:
            pass
        lvals = []
        for name in names:
            if name in frame.f_code.co_varnames:
                if name in locals:
                    value = pydoc.html.repr(locals[name])
                else:
                    value = _('<em>undefined</em>')
                name = '<strong>%s</strong>' % name
            else:
                if name in frame.f_globals:
                    value = pydoc.html.repr(frame.f_globals[name])
                else:
                    value = _('<em>undefined</em>')
                name = '<em>global</em> <strong>%s</strong>' % name
            lvals.append('%s&nbsp;= %s'%(name, value))
        if lvals:
            lvals = string.join(lvals, ', ')
            lvals = indent + '<small><font color="#909090">%s'\
                '</font></small><br>'%lvals
        else:
            lvals = ''

        excerpt = []
        i = lnum - index
        for line in lines:
            number = '&nbsp;' * (5-len(str(i))) + str(i)
            number = '<small><font color="#909090">%s</font></small>' % number
            line = '<tt>%s&nbsp;%s</tt>' % (number, pydoc.html.preformat(line))
            if i == lnum:
                line = '''
<table width="100%%" bgcolor="white" cellspacing=0 cellpadding=0 border=0>
<tr><td>%s</td></tr></table>''' % line
            excerpt.append('\n' + line)
            if i == lnum:
                excerpt.append(lvals)
            i = i + 1
        traceback.append('<p>' + level + string.join(excerpt, '\n'))

    traceback.reverse()

    exception = '<p><strong>%s</strong>: %s' % (str(etype), str(evalue))
    attribs = []
    if type(evalue) is types.InstanceType:
        for name in dir(evalue):
            value = pydoc.html.repr(getattr(evalue, name))
            attribs.append('<br>%s%s&nbsp;= %s' % (indent, name, value))

    return head + string.join(attribs) + string.join(traceback) + '<p>&nbsp;</p>'
示例#20
0
def hack_client(ctx):

    local_pk = load(open(f'./public-data/bob.key', 'rb'))
    remote_pk = load(open(f'./public-data/alice.key', 'rb'))
    lsig = SignatureScheme(None, local_pk)
    rsig = SignatureScheme(None, remote_pk)

    ratchet = make_ratchet(lsig, rsig)

    import glob
    msgs = glob.glob('./public-data/messages/b2a*')
    msgs.sort()
    data = {}

    tb = []
    hl = 256
    for msg_id, msg_fname in enumerate(msgs):
        content = open(msg_fname, 'rb').read()
        signed_data, signature = content.rsplit(b"|", 1)

        h = lsig.hash2(signed_data, msg_id + 1)
        data[msg_id + 1] = [h, signed_data, protocol.decode_int(signature)]

        tb.append(
            [np.array(h, dtype='object'),
             protocol.decode_int(signature)])
        #signature_valid = lsig.verify(data, protocol.decode_int(signature))
        #assert signature_valid

    N = local_pk.n
    fk = local_sig(ctx)
    last_sig = tb[-1][1]

    def inv(x):
        ix = gmpy2.invert(x, N)
        assert x * ix % N == 1
        return ix

    for i in range(1, len(tb)):
        tb[-i][1] = tb[-i][1] * inv(tb[-i - 1][1]) % N

    for i, (h, x) in enumerate(tb):
        v = fk.sk.r
        for j in range(hl):
            if h[j] == 1: v = v * fk.sk.s[j] % N
        v = pow(v, 2**i, N)
        assert v == x, i

    mat = []

    last = tb[-1]
    tb = tb[:-1]
    n = len(tb)
    tmp = []

    hlist = []
    for i in range(n):
        x = inv(pow(tb[i][1], 2**(n - i), N)) * last[1] % N
        hdiff = last[0] - tb[i][0]
        tmp.append([x, hdiff])
        hlist.append(list(hdiff))
        #print(list(hdiff)) for dumping to sage
    json.dump(hlist, open('./mat.data', 'w'))
    if 0: return

    data = Attributize(json.load(open('./tsf.data', 'r')))
    print(data.base)
    slast = 1
    for i, (u, v) in enumerate(data.make_unimodular):
        slast = gmpy2.powmod(slast, u, N) * gmpy2.powmod(
            tmp[data.base[i]][0], v, N) % N

    scoeffs = [1] * hl
    scoeffs[0] = slast

    for i in range(1, hl):
        scoeffs[i] = tmp[data.mat_id[i - 1]][0]

    if 0:
        for have, hdiff in tmp:
            x = 1
            for j, v in enumerate(hdiff):
                x = x * gmpy2.powmod(fk.sk.s[j], (2**(n)) * v, N) % N
            assert x == have

    sexpr = [0] * hl

    if 1:
        for i in range(hl):
            print('processing ', i)
            cur = 1
            for j in range(hl):
                cur = cur * gmpy2.powmod(scoeffs[j], data.imat[i][j], N) % N

            sexpr[i] = cur
            assert cur == (gmpy2.powmod(fk.sk.s[i], 2**n, N))
    else:
        for i in range(hl):
            sexpr[i] = pow(fk.sk.s[i], 2**(n), N)
        r = pow(fk.sk.r, 2**(n), N)

    r = last[1]
    for i in range(hl):
        if last[0][i]:
            r = r * inv(sexpr[i]) % N

    ratchet.remote_public_element = 1
    public_element, iv, ciphertext = ratchet._encrypt_message(REQ_FLAG)
    public_element = 1
    signed_data = protocol.encode_int(
        public_element, 256) + b"|" + protocol.encode_int(
            iv, 16) + b"|" + protocol.encode_bytes(ciphertext)

    nmsg_id = n + 2
    nh = lsig.hash2(signed_data, nmsg_id)
    print(nh)

    forged_sig = r
    for i, v in enumerate(nh):
        if v: forged_sig = forged_sig * sexpr[i]
    forged_sig = forged_sig * forged_sig * last_sig % N

    data = signed_data + b"|" + protocol.encode_int(forged_sig, 256)

    with Connection(ctx.host, ctx.port) as conn:

        conn.send(data + b'\x00')
        res = conn.recv_until(b'\x00')[:-1]
        ratchet.public_element = 1
        flagans = ratchet.on_recv_message(res, hack=True)
        print(flagans)