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")
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)
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")
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)