示例#1
0
def __identify(app, in_name):
    # TODO: identify number of independant inputs
    NL = app.nl().vector()
    M = app.matrix()
    nbits_in = M.ncols()
    nbits_out = M.nlines()
    if nbits_in != nbits_out:
        raise ValueError("do not yet support application with a different\
                number of input and output bits!")
    mba = MBA(nbits_in)
    var_in = mba.var(in_name)

    if NL != Vector(len(NL)):
        return _identify_nonaffine(app, var_in)
    C = EX.ExprCst(mba.from_vec(app.cst()).to_cst(), nbits_out)
    if M == Matrix(nbits_out, nbits_in):
        # This is just a constant
        return C

    ret = EX.ExprBV(var_in)
    matrix_empty = 0
    # Find empty columns in the matrix.
    for j in range(nbits_in):
        is_zero = reduce(operator.and_, (M.at(i, j) == imm(0)
                                         for i in range(nbits_out)), True)
        if is_zero:
            matrix_empty |= 1 << j
    matrix_and_mask = (~matrix_empty) % (2**nbits_out)
    if matrix_empty != 0:
        ret = EX.ExprAnd(ret, EX.ExprCst(matrix_and_mask, nbits_out))
    if mba.from_vec(M * var_in.vec) ^ (var_in & matrix_empty) == var_in:
        # This is a XOR
        return EX.ExprXor(ret, C)
    raise ValueError("unable to identify an expression")
示例#2
0
def eval_expr(e, use_esf=False):
    ectx = init_ctxes(e)

    ret = Vector(e.nbits)
    for i in range(e.nbits):
        ret[i] = ectx.eval(ret, i, use_esf)
    mba = MBA(len(ret))
    return mba.from_vec(ret)
示例#3
0
    return [a[i] ^ b[i] for i in range(16)]


def even_mansour(block, key):
    block = xor(block, key[:16])
    block = f(block)
    block = xor(block, key[16:])
    return block


block = [mba8.var('b%d' % i) for i in range(16)]
key_zero = [mba8.from_cst(0)] * 32
cipher = even_mansour(block, key_zero)
cipher = flatten_vec(cipher)

CZ = mba128.from_vec(cipher).vectorial_decomp(block)
Minv = CZ.matrix().inverse()


def recover(plaintext, cipher_plaintext, cipher_unk):
    plaintext = mba128.from_bytes(plaintext)
    cipher_plaintext = mba128.from_bytes(cipher_plaintext)
    cipher_unk = mba128.from_bytes(cipher_unk)

    tmp = mba128.from_vec(
        simplify(Minv * ((cipher_plaintext ^ cipher_unk).vec)))
    return (plaintext ^ tmp).to_bytes()


def recover_ascii(*args, **kwargs):
    return recover(*args, **kwargs).decode("ascii")
示例#4
0
from arybo.lib import MBA, simplify, simplify_inplace
from arybo.tools import app_inverse

mba = MBA(32)

S, X = mba.permut2expr(S)
S = S.vectorial_decomp([X])


def compute_arybo(Z):
    C = mba.from_cst(0xFFFFFFFF)
    A = 0

    for N in range(0, 4):
        C_ = (C >> (A * 8)) & 0xFF
        Z_ = (Z >> (N * 8)) & 0xFF
        t = Z_ ^ C_
        T_ = mba.from_vec(simplify(S(t.vec)))
        B = C >> 8
        C = B ^ T_

    C = (~C)
    return simplify_inplace(C)


E = compute_arybo(X)
A = E.vectorial_decomp([X])
Ainv = app_inverse(A)
sol = mba.from_vec(simplify(Ainv(mba.from_cst(3298472535).vec))).to_cst()
print(sol)