Exemplo n.º 1
0
def test_check_xor_structure():
    f = Function("f", 1)
    a = Constant("a")
    b = Constant("b")
    c = Constant("c")
    x = Variable("x")
    z = Zero()

    func = FuncTerm(f, [a])
    func1 = FuncTerm(f, [b])
    func2 = FuncTerm(f, [c])
    func3 = FuncTerm(f, [x])
    func4 = xor(func, func1)
    func5 = xor(func2, func3)

    eq1 = Equation(func, b)
    eq2 = Equation(func3, c)
    eq3 = Equation(func5, z)
    eq4 = Equation(xor(func2, func3), z)
    eq5 = Equation(xor(func4, func5), z)

    topf: Set[Equation] = {eq1, eq2, eq3, eq5}

    print("Testing pick_f with equation set: ", topf)
    print("Result pick_f: ", pick_f(topf))
    print()
Exemplo n.º 2
0
def test_pick_fail():
    c = Function("C", 3)
    f = Function("f", 1)
    a = Constant("a")
    b = Constant('1')
    e = Constant("e")
    p = Constant('p')
    q = Constant('q')
    i = Constant('i')
    j = Constant('j')
    x = Variable("x")
    z = Zero()

    func = FuncTerm(f, [a])
    func2 = FuncTerm(f, [e])

    func_pi = FuncTerm(c, [p, i, b])
    func_qj = FuncTerm(c, [q, j, b])

    eq1 = Equation(func, z)
    eq2 = Equation(func_qj, x)
    eq3 = Equation(xor(func_pi, func), z)
    eq4 = Equation(xor(xor(func_pi, func), func2), z)

    topf: Set[Equation] = {eq1, eq4}
    print("Testing pick_fail with ", topf)
    new_set = pick_fail(topf, cbc_gen)
    print("Result: ", new_set)
    print()

    topf: Set[Equation] = {eq1, eq2, eq3}
    print("Testing pick_fail with ", topf)
    new_set = pick_fail(topf, ex4_gen)
    print("Result: ", new_set)
    print()
Exemplo n.º 3
0
def ex4_gen(p, i):
    if i == 0:
        return Constant('r' + str(p))
    else:
        return xor(
            xor(FuncTerm(f, [ex4_gen(p, i - 1)]),
                FuncTerm(f, [FuncTerm(f, [ex4_gen(p, i - 1)])])),
            Variable("x" + str(p) + str(i)))
Exemplo n.º 4
0
def make_a_decision(bad_var_term_pairs, p_unif_problem):
    constraints = p_unif_problem.constraints
    disequations = p_unif_problem.disequations
    for (var, term) in bad_var_term_pairs:
        if (isinstance(term, Constant)):
            continue
        if (isinstance(term, FuncTerm) and term.function.symbol == "h"):
            continue
        if (isinstance(term, FuncTerm) and term.function.symbol == "f"):
            #fix it using the Prev rule
            term = convert_to_xorterm(term)
            for prev_term in constraints[var]:
                if (not isinstance(prev_term, Variable)):
                    candidate_equation = Equation(xor(term, prev_term), Zero())
                    if (consistent_with_diseqs(candidate_equation,
                                               disequations)):
                        return candidate_equation
        if (isinstance(term, Variable)):
            #set it to zero if consistent
            candidate_equation = Equation(term, Zero())
            if (consistent_with_diseqs(candidate_equation, disequations)):
                return candidate_equation
        if (isinstance(term, XORTerm)):
            #if it has a variable x in it, set x to some subset
            #otherwise, use the cancel rule to cancel two terms
            terms = term.arguments
            terms = simplify(terms)
            terms = list(map(convert_to_xorterm, terms))
            vars = get_vars_in_list(terms)
            if (len(vars) == 0):
                pairs = findsubsets(terms, 2)
                #print(pairs)
                for pair in pairs:
                    (left, right) = pair
                    left = convert_to_xorterm(left)
                    right = convert_to_xorterm(right)
                    candidate_equation = Equation(xor(left, right), Zero())
                    if (consistent_with_diseqs(candidate_equation,
                                               disequations)):
                        return candidate_equation
            else:
                for var in vars:
                    subsets = powerset(terms)
                    for subset in subsets:
                        xor_terms = list(set(subset) | set([var]))
                        if (len(xor_terms) == 1):
                            left_side = xor_terms[0]
                        else:
                            left_side = xor(*xor_terms)
                        candidate_equation = Equation(left_side, Zero())
                        if (consistent_with_diseqs(candidate_equation,
                                                   disequations)):
                            return candidate_equation
    return None
Exemplo n.º 5
0
def cipher_block_chaining(iteration, nonces, P, C):
    """Cipher Block Chaining"""
    IV = nonces[0]
    f = Function("f", 1)
    i = iteration - 1
    if i == 0:
        return f(
            xor(P[0], IV)
        )
    return f(
        xor(P[i], C[i-1])
    )
Exemplo n.º 6
0
def abc_h_identity(iteration, nonces, P, C):
    """ABC H IDENTITY"""
    IV = nonces[0]
    i = iteration - 1
    f = Function("f", 1)
    Q = {}
    if i > 0:
        Q[i] = _calcQI(i, nonces, P, C)
        Q[i-1] = _calcQI(i - 1, nonces, P, C)
    
    keystream = f(IV)
    if i == 0:
        return IV
    return xor(f(xor(Q[i], C[i-1])),Q[i-1])
Exemplo n.º 7
0
def propogating_cbc(iteration, nonces, P, C):
    """Propogating Cipher Block Chaining"""
    IV = nonces[0]
    f = Function("f", 1)
    i = iteration - 1
    if i == 0:
        return f(
            xor(P[0], IV)
        )
    return f(
        xor(
            P[i],
            P[i - 1],
            C[i - 1]
        )
    )
Exemplo n.º 8
0
def _calcQI(i, nonces, P, C):
    h = Function("h", 1)
    if i == 0:
        return P[0]
    return xor(
        P[i],
        h(_calcQI(i - 1, nonces, P, C))
    )    
Exemplo n.º 9
0
def convert_to_xorterm(t):
    # convert all the sub-XORTerms to xor terms
    if (isinstance(t, Constant)):
        return t
    if (isinstance(t, Variable)):
        return t
    if (is_xor_term(t)):
        new_arguments = list(map(convert_to_xorterm, t.arguments))
        return xor(*new_arguments)
    if (isinstance(t, FuncTerm) and not is_xor_term(t)):
        new_arguments = list(map(convert_to_xorterm, t.arguments))
        return FuncTerm(t.function, new_arguments)
    if (isinstance(t, XORTerm)):
        new_arguments = list(map(convert_to_xorterm, t.arguments))
        if (len(new_arguments) == 1):
            return new_arguments[0]
        else:
            return xor(*new_arguments)
Exemplo n.º 10
0
def symbolic_cbc_gen(session_label, block_label):

    a = Constant("1")
    p = Constant(session_label)
    i = Constant(block_label)

    cInner = FuncTerm(c, [p, i, a])
    x = Variable("xpi")
    return xor(FuncTerm(f, [cInner]), x)
Exemplo n.º 11
0
def output_feedback(iteration, nonces, P, _):
    """Output Feedback"""
    IV = nonces[0]
    i = iteration - 1
    f = Function("f", 1)
    keystream = f(IV)
    for _ in range(i):
        keystream = f(keystream)
    return xor(P[i], keystream)
Exemplo n.º 12
0
def hash_cbc(iteration, nonces, P, C):
    """Hash Cipher Block Chaining"""
    IV = nonces[0]
    f = Function("f", 1)
    h = Function("h", 1)
    i = iteration - 1
    if i == 0:
        return f(
            xor(
                h(IV),
                P[0]
            )
        )
    return f(
        xor(
            h(C[i - 1]),
            P[i]
        )
    )
Exemplo n.º 13
0
def invert_simple(term):
    """
    Algorithm to get the plaintext P_{i} out of a MOO.

    Works by moving up in the DAG from the plaintext variable
    Applying the reverse transformation as it moves along
    f -> f^{-1}
    xor(P, x) -> xor(P, xor(x, x)) -> P

    Assumptions:
      - Previous plaintexts aren't in the term
      - The plaintext is only in one position
    """
    inverse_term = Variable("x")
    transforms = []

    # Create a TermDAG and check to see
    # that the plaintext is only in one position.
    d = TermDAG(term)
    assert Counter(d.leaves())[_P] == 1

    # Move up the DAG starting from the plaintext
    # leaf and add inverse operations to the
    # transforms list.
    current_term = deepcopy(_P)
    parent_term = list(d.parents(current_term))
    while parent_term != []:
        parent_term = parent_term[0]

        if parent_term.function == _f:
            transforms.append((_finv, ))

        elif parent_term.function == xor:
            # Cancel out the xor by xoring with
            # the other argument again.
            if parent_term.arguments[0] == current_term:
                transforms.append((xor, parent_term.arguments[1]))
            else:
                transforms.append((xor, parent_term.arguments[0]))

        else:
            raise ValueError("A function other than f or xor detected")

        current_term = deepcopy(parent_term)
        parent_term = list(d.parents(parent_term))

    # Construct inverse term
    for transform in reversed(transforms):
        if transform[0] == _finv:
            inverse_term = _finv(inverse_term)
        else:  # Assume xor
            inverse_term = xor(inverse_term, transform[1])

    return inverse_term
Exemplo n.º 14
0
def cipher_feedback(iteration, nonces, P, C):
    """Cipher Feedback"""
    IV = nonces[0]
    i = iteration - 1
    f = Function("f", 1)
    if i == 0:
        return f(IV)
    return xor(
        f(C[i-1]),
        P[i]
    )
Exemplo n.º 15
0
def symbolic_ex4_gen(session_label, block_label):

    a = Constant("1")
    p = Constant(session_label)
    i = Constant(block_label)

    cInner = FuncTerm(c, [p, i, a])
    x = Variable("xpi")

    fSummandOne = FuncTerm(f, [cInner])

    fSummandTwo = FuncTerm(f, [FuncTerm(f, [cInner])])

    return xor(fSummandOne, fSummandTwo, x)
Exemplo n.º 16
0
def convertToConstantTerm(t):
    if (isinstance(t, IndexedVariable)):
        return t.convertToConstant()
    if (isinstance(t, Constant) or isinstance(t, Variable)):
        return t
    if (isinstance(t, FuncTerm) and t.function.symbol == "xor"):
        new_arguments = list(map(convertToConstantTerm, t.arguments))
        return xor(*new_arguments)
    if (isinstance(t, FuncTerm) and t.function.symbol != "xor"):
        new_arguments = list(map(convertToConstantTerm, t.arguments))
        return FuncTerm(t.function, new_arguments)
    else:
        print("error in convertToConstantTerm")
        return None
Exemplo n.º 17
0
def split(state):
    #Try applying the "split" rule
    #This rule applied if an equation is of the form: s_1 xor e(...) = t_1 xor e(...)
    #or s_1 xor d(...) = t_1 xor d(...)
    #If successful, returns "True" and the new state
    #Otherwise, returns "False" and the original state
    #Example: s_1 xor e(...) = t_1 xor e(...); id ==> s_1 = t_1, e(...) xor e(...); id
    #Example: s_1 = t_1; id (not applicable)
    eqs = state.equations
    subst = state.substitution

    first = eqs[0]
    remaining_eqs = eqs[1:]

    lhs = first.left_side
    rhs = first.right_side
    lhs_summands = summands(lhs)
    rhs_summands = summands(rhs)
    applicable = containsDorE(lhs_summands)

    if (applicable):
        (e_term1, others1) = split_terms(lhs_summands)
        (e_term2, others2) = split_terms_wrt_term(rhs_summands, e_term1)

        eq1 = Equation(e_term1, e_term2)
        if (len(others1) == 1):
            eq2 = Equation(*others1, *others2)
        else:
            eq2 = Equation(xor(*others1), xor(*others2))

        remaining_eqs.append(eq1)
        remaining_eqs.append(eq2)

        return (applicable, Unification_state(remaining_eqs, subst))
    else:
        return (applicable, state)
Exemplo n.º 18
0
def test_elimc():
    c = Function("C", 3)
    p = Constant('p')
    q = Constant('q')
    i = Constant('i')
    j = Constant('j')
    a = Constant('1')
    x = Variable("x")
    z = Zero()

    func_pi = FuncTerm(c, [p, i, a])
    func_qj = FuncTerm(c, [q, j, a])

    eq1 = Equation(xor(func_pi, func_qj), z)
    eq2 = Equation(xor(func_qj, func_pi), z)
    eq3 = Equation(func_pi, x)

    topf: Set[Equation] = {eq1, eq2, eq3}
    print("Testing elim_c with ", topf)
    new_set = elim_c(topf)
    print("Result: ", new_set)
    print()

    b = Constant('2')

    func_pi = FuncTerm(c, [p, i, a])
    func_qj = FuncTerm(c, [q, j, b])

    eq1 = Equation(xor(func_pi, func_qj), z)
    eq2 = Equation(xor(func_qj, func_pi), z)

    topf: Set[Equation] = {eq1, eq2}
    print("Testing elim_c with ", topf)
    new_set = elim_c(topf)
    print("Result: ", new_set)
    print()
Exemplo n.º 19
0
def elim_tk(state):
    #Try applying the "elim_tk" rule

    #This rule applied if an equation is of the form: s_1 xor ... xor s_m = t_1 xor ... xor t_n,
    #where no s_i or t_j is d-rooted or e-rooted, and some s_i is a indexed variable Tk.
    #Tk = tk; id (applicable)
    #Tk xor e(Tk, C1) = tk xor e(tk, c1); id (not applicable)

    #If successful, returns "True" and the new state
    #Otherwise, returns "False" and the original state

    #Example: Tk = tk; id ==> true, ; {Tk |-> tk}
    #Example: Tk xor e(Tk, C1) = tk xor e(tk, c1); id ==> false, Tk xor e(Tk, C1) = tk xor e(tk, c1); id
    eqs = state.equations
    subst = state.substitution

    first = eqs[0]
    remaining_eqs = eqs[1:]

    lhs = first.left_side
    rhs = first.right_side
    lhs_summands = summands(lhs)
    rhs_summands = summands(rhs)
    applicable = (not containsDorE(lhs_summands)) and containsT(lhs_summands)
    new_subst = SubstituteTerm()
    remaining_terms = []
    results = []

    if (applicable):
        (var, remaining_terms) = pickT(lhs_summands)
        remaining_terms += rhs_summands
        if (len(remaining_terms) == 1):
            new_subst.add(var, remaining_terms[0])
        else:
            new_subst.add(var, xor(*remaining_terms))
        for t in remaining_eqs:
            results.append(
                Equation(t.left_side * new_subst, t.right_side * new_subst))

    return (applicable, Unification_state(results, subst * new_subst))
Exemplo n.º 20
0
def moo_invert(K: Set[Term], nonces: Set[Constant], S: int,
               P: Set[Term]) -> bool:
    """
    Given a set K of MOO interactions and max bound for the depth of a term,
    state whether or not a MOO term is invertible.
    Note, this is intentionally more general than is needed for the
    strict invert problem for MOO programs and plaintext/var/con.
    It can also consider terms and some constructed terms.
    """
    # Compute K*
    k_star = K | nonces
    # From K* construct C*
    c_star = deepcopy(k_star)
    current_length = 0
    while len(c_star) != current_length:
        current_length = len(c_star)
        temp = set()
        for t_1 in c_star:
            # Definition 11 (2a)
            if isinstance(t_1, FuncTerm) and str(t_1.function) == 'f':
                # Apply f inverse
                temp.update({t_1.arguments[0]})
            # Definition 11 (2b)
            for t_2 in c_star:
                new_term_b = xor(t_1, t_2)
                if depth(new_term_b) <= S:
                    temp.add(new_term_b)
            # Definition 11 (2c)
            new_term_c = _f(t_1)
            if depth(new_term_c) <= S:
                temp.add(new_term_c)
        c_star.update(temp)
    # Check to see if the plaintext block is in any of the ground terms in c_star
    # xor library automatically maps terms to their ground terms
    #return _P in c_star
    print(c_star)
    if P.issubset(c_star):
        return True
    else:
        return False
Exemplo n.º 21
0
def test_elimf():
    f = Function("f", 1)
    xo = Function("f", 2)
    z = Zero()
    c = Constant("c")
    x = Variable("x")
    b = Variable("b")

    func = FuncTerm(f, [x])
    func2 = FuncTerm(f, [z])
    func3 = FuncTerm(xo, [c, b])

    eq1 = Equation(func, c)
    eq2 = Equation(xor(func, func3), z)
    eq3 = Equation(b, func)
    eq4 = Equation(func2, z)

    topf: Set[Equation] = {eq1, eq2, eq3, eq4}
    print("Testing elim_f with ", topf)
    new_set = elim_f(topf)
    print("Result ", new_set)
    print()
Exemplo n.º 22
0
def test_pick_c():
    c = Function("C", 3)
    f = Function("f", 1)
    a = Constant("a")
    b = Constant('1')
    p = Constant('p')
    q = Constant('q')
    i = Constant('i')
    j = Constant('j')
    x = Variable("x")
    z = Zero()

    func = FuncTerm(f, [a])

    func_pi = FuncTerm(c, [p, i, b])
    func_qj = FuncTerm(c, [q, j, b])

    eq1 = Equation(func, z)
    eq2 = Equation(func_qj, x)
    eq3 = Equation(xor(func_pi, func), 0)

    topf: Set[Equation] = {eq1, eq2, eq3}
    print("Testing pick_c with ", topf)
Exemplo n.º 23
0
#Example of using the deducible function
from symcollab.algebra import Function, Variable, Constant
from symcollab.moe.invertibility import deducible
x = Constant("x")
f = Function("f", 2)
p = Constant("p_i")
deducible(f(x, p), {x})
deducible(f(x, p), {})

#example of using invertibility with MOO security check
from symcollab.algebra import Constant, Variable
from symcollab.moe.program import MOOProgram
from symcollab.moe.check import moo_check
from symcollab.Unification.constrained.xor_rooted_unif import XOR_rooted_security
from symcollab.Unification.constrained.p_unif import p_unif

result = moo_check('cipher_block_chaining', "every", p_unif, 2, True, True)
print(result.invert_result)

#example of using invertibility by itself, not how it's intended to be used
#but can be done for testing
from symcollab.moe.invertibility import InvertMOO
from symcollab.xor import xor
f = Function("f", 1)
x = Variable("x")

IV = Constant("IV")
C1 = xor(x, IV)

print("MOO Invertible?", InvertMOO(C1, "x", [IV], IV, True))
Exemplo n.º 24
0
from symcollab.moe.syntactic_check import moo_depth_random_check, \
     moo_has_random, moo_f_depth

f = Function("f", 1)
r = Constant("r")
x = Variable("x")
x2 = Variable("x2")
zero = Zero()

print("Example 1.")
t1 = moo_f_depth(f(f(r)))
print(f"f_depth(f(f(r))) = {t1}")
print("")

print("Example 2.")
t2 = moo_f_depth(xor(f(f(r)), f(r)))
print(f"f_depth(f(f(r)) ⊕ f(r)) = {t2}")
print("")

print("Example 3.")
possible_subs1 = dict()
possible_subs1[x] = [r, f(r)]
t3 = moo_f_depth(xor(f(r), x), possible_subs1)
print(f"If {x} maps to {r} or {f(r)}...")
print(f"f_depth(f(r) ⊕ x) = {t3}")
print("")

print("Example 4.")
possible_subs2 = dict()
possible_subs2[x] = [r, zero]
t4 = moo_f_depth(xor(f(r), x), possible_subs2)
Exemplo n.º 25
0
def cbc_gen(p, i):
    if i == 0:
        return Constant('r' + str(p))
    else:
        return xor(FuncTerm(Function("f", 1), [cbc_gen(p, i - 1)]),
                   Variable("x" + str(p) + str(i)))
Exemplo n.º 26
0
#!/usr/bin/env python3
"""
A thought experiment on how to define
recursive MOOs.
"""
from symcollab.algebra import Constant, Function, Variable
from symcollab.rewrite import RewriteRule, RewriteSystem, normal
from symcollab.xor import xor
from symcollab.theories.nat import Nat

C = Function("C", 1, domain_sort=Nat.sort)
P = Function("P", 1, domain_sort=Nat.sort)
f = Function("f", 1)
IV = Constant("IV")
n = Variable("n", sort=Nat.sort)

r0 = RewriteRule(C(Nat.zero), IV)
rn = RewriteRule(C(Nat.S(n)), f(xor(P(Nat.S(n)), C(n))))
moo_system = RewriteSystem({r0, rn})
print("Cipher Block Chaining:", moo_system)

three = Nat.from_int(3)
print("Simplified form of the 3rd ciphertext:", normal(C(three), moo_system)[0])