示例#1
0
 def symbolic_moo_gen(session_label, block_label):
     c = Function("C", 3)
     p = Constant(session_label)
     i = Constant(block_label)
     a = Constant("1")
     pList = [
         Variable(f"x{session_label}{block_label}"),
         Variable(f"x{session_label}{block_label}"),
         Variable(f"x{session_label}{block_label}")
     ]
     cList = [c(p, i, a), c(p, i, a), c(p, i, a)]
     return program.chaining_function(3, [0], pList, cList)
示例#2
0
def program():
    """
    Webpage that walks the user through an interaction between
    the adversary and the oracle.
    """
    if request.method != "POST":
        # If you step away from the simulation, destroy the previous session
        if 'uid' in session and session['uid'] in moo_sessions.keys():
            del moo_sessions[session['uid']]
            session.pop('uid', None)
        return render_moo_template('program_create.html')

    # If a MOOProgram is already in session....
    if 'uid' in session and session['uid'] in moo_sessions.keys():
        uid = session['uid']
        moo_session: MOOProgram = moo_sessions[uid]
        if 'next' in request.form:
            plaintext = Variable("x_" + str(moo_session.iteration))
            ciphertext = moo_session.rcv_block(plaintext)
            response = str(
                ciphertext
            ) if ciphertext is not None else "Sent " + str(plaintext)
            return render_moo_template('program.html', response=response)
        if 'end' in request.form:
            ciphertext = moo_session.rcv_stop()
            del moo_sessions[uid]
            session.pop('uid', None)
            response = str(ciphertext) if ciphertext is not None else None
            if response is None:
                return render_moo_template('program_create.html')
            return render_moo_template('program.html', response=response)

    # If we are creating a session of a MOOProgram....
    if 'chaining' in request.form and 'schedule' in request.form:
        # Create new session
        chaining_moo = request.form.get('chaining')
        schedule = request.form.get('schedule')
        moo_session = MOOProgram(chaining_moo, schedule)
        # Send an initial message
        plaintext = Variable("x_" + str(moo_session.iteration))
        ciphertext = moo_session.rcv_block(plaintext)
        # Set up a userid and save the moo_session
        session['uid'] = uuid4()
        moo_sessions[session['uid']] = moo_session
        response = str(
            ciphertext) if ciphertext is not None else "Sent " + str(plaintext)
        return render_moo_template('program.html', response=response)

    return render_moo_template('program_create.html')
示例#3
0
def _temporary_parser(moo_string: str) -> Term:
    """
    A temporary parser to parse a user
    supplied cryptographic mode of operation.
    This function is limited in what it can parse.
    """
    parser = Parser()
    parser.add(Function("f", 1))
    parser.add(xor)
    parser.add(Variable("P[i]"))
    parser.add(Variable("C[i]"))
    parser.add(Variable("C[i-1]"))
    parser.add(Constant("r"))
    parser.add(Constant("P[0]"))
    return parser.parse(moo_string)
示例#4
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()
示例#5
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()
示例#6
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)))
示例#7
0
def _satisfies_chaining(term: Term, max_history: int):
    """Checks to see if a preivous ciphertext is in the term."""
    previous_ciphertexts = [
        Variable("C[i-" + str(i + 1) + "]") for i in range(max_history)
    ]
    previous_ciphertexts_in_term = [(ci in term)
                                    for ci in previous_ciphertexts]
    return any(previous_ciphertexts_in_term)
示例#8
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)
示例#9
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
示例#10
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()
示例#11
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)
示例#12
0
def test_occurs():
    f = Function("f", 1)
    g = Function("g", 1)
    c = Function("C", 3)
    p = Constant('p')
    q = Constant('q')
    i = Constant('i')
    z = Variable("z")
    x = Variable("x")
    y = Variable("y")
    b = Variable("b")
    a = Variable("a")

    cpi = FuncTerm(c, [p, i, Constant("1")])
    fcpi = FuncTerm(f, [cpi])
    e1 = Equation(cpi, fcpi)
    e2 = Equation(x, FuncTerm(f, [g(x)]))
    e3 = Equation(x, FuncTerm(f, [b]))

    occ = {e1, e2, e3}
    print("Testing occurs check with ", occ)
    print("new set: ", occurs_check(occ))
    print()
示例#13
0
def _changeVars(overlaping_vars: List[Variable], term: Term, hypothesis: Term,
                conclusion: Term):
    """Change variable names in hypothesis & conclusion to not overlap with overlapping_vars"""
    hypothesis = deepcopy(hypothesis)
    conclusion = deepcopy(conclusion)
    all_vars = get_vars(term, unique=True) | \
        get_vars(hypothesis, unique=True) | \
        get_vars(conclusion, unique=True)
    new_vars: List[Variable] = []
    # Go through all the variables that share the same symbol between the term and rewrite rule
    # and change the variables in the rewrite rule
    for v in overlaping_vars:
        new_var = v
        # Keep renaming variable in rewrite rule until it is not an already existing variable
        while new_var in all_vars:
            new_var = Variable(new_var.symbol + "_1", new_var.sort)
        new_vars.append(new_var)
    # Create substitution between the old and new variable names and apply them
    s = SubstituteTerm()
    for old_v, new_v in zip(overlaping_vars, new_vars):
        s.add(old_v, new_v)
    return hypothesis * s, conclusion * s
示例#14
0
def InvertMOO(term: Term, plaintext: str, nonces: list, nonceone: Constant,
              knowsiv: bool):
    """
    NOT COMPLETE
    Implementation of Lemma 10 from the Indocrypt paper

    Parameters
    ==========
    Term:
        The first recursive case
    str:
        The plaintext to check for
    bool:
        Is the IV known

    Examples
    ========
    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)
    """
    if nonceone in get_constants(term, unique=True):
        if knowsiv == False:
            return False
    #Make sure C_0 is only IV
    if len(nonces) == 1:
        plaintext = Variable(plaintext)
        # Make sure C_i contains p_i but only once
        if count_occurence(plaintext, term) == 1:
            return True

    # Passes all the criteria
    return False
示例#15
0
    def rcv_block(self, message: Term) -> Optional[MOOFrame]:
        """
        The adversary gives a plaintext block to the oracle to encrypt.
        Depending on the schedule, the oracle might return back a MOOFrame.
        """
        if self.stopped:
            raise ValueError("Session already stopped.")
        self.iteration += 1
        self.plain_texts.append(message)

        # Create new cipher text variable and map it to the MOO Term
        new_cipher_var = Variable(f"y_{self.iteration}")
        encrypted_block = self.chaining_function(self.iteration, self.nonces,
                                                 self.plain_texts,
                                                 self.cipher_texts)
        self.substitutions.add(new_cipher_var, encrypted_block)
        self.cipher_texts.append(new_cipher_var)

        # If the schedule allows, return a MOO Frame
        if self.schedule(self.iteration):
            return MOOFrame(deepcopy(new_cipher_var),
                            deepcopy(self.substitutions))
        return None
示例#16
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)
示例#17
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()
示例#18
0
def name_xor_terms(t, eqs):
    # Purify arguments
    # Name top-level xor-subterms
    # Return (renamed_term, a set of equations)
    if is_zero(t):
        return (t, eqs)
    elif (isinstance(t, Constant)):
        return (t, eqs)
    elif (isinstance(t, Variable)):
        return (t, eqs)
    elif (is_xor_term(t)):
        (term1, eqs) = purify_a_term(t.arguments[0], eqs)
        #eqs = eqs + equation1
        (term2, eqs) = purify_a_term(t.arguments[1], eqs)
        #eqs = eqs + equation2
        #equations = equation1 + equation2

        name = look_up_a_name(xor(term1, term2), eqs)
        if (name != None):
            return (name, eqs)
        else:
            global variable_counter
            variable_counter += 1
            new_variable = Variable("N" + str(variable_counter))
            eqs.append(Equation(new_variable, xor(term1, term2)))
            return (new_variable, eqs)
    elif (isinstance(t, FuncTerm)):
        terms = []
        for arg in t.arguments:
            (term, eqs) = name_xor_terms(arg, eqs)
            #eqs = eqs + equations
            terms.append(term)
        return (FuncTerm(t.function, terms), eqs)
    else:
        print("error")
        return None
#!/usr/bin/env python3
from symcollab.algebra import Function, Variable, Constant, Equation
from symcollab.Unification.unif import unif

# Setting up terms
f = Function("f", 2)
g = Function("g", 1)
x = Variable("x")
y = Variable("y")
z = Variable("z")
a = Constant("a")
b = Constant("b")

# applying unification
#example 1: unifiable
unif({Equation(f(x, y), f(a, b))})

#example 2: simple function clash
unif({Equation(f(x, y), g(z))})

#example 3: function clash
unif({Equation(f(x, x), f(g(y), a))})

#example 4: occurs check
unif({Equation(f(x, y), f(g(x), a))})

#example 5: unifiable
unif({Equation(f(z, z), f(g(f(x, y)), g(f(a, b))))})
示例#20
0
#!/usr/bin/env python3
from symcollab.algebra import Constant, Function, Variable
from symcollab.rewrite import RewriteRule

a = Constant("a")
b = Constant("b")
c = Constant("c")
x = Variable("x")
y = Variable("y")
f = Function("f", 2)
g = Function("g", 2)

r = RewriteRule(f(y, g(x, a)), g(y, a))

term = f(b, g(c, a))
print("Applying " + str(r) + " to " + str(term))
print("Result:", r.apply(term))

print("Now to show what happens when you can't apply a term...")
term = f(a, b)
print("Applying " + str(r) + " to " + str(term))
print("Result:", r.apply(term))

print("Applying f(x, x) -> x to f(f(x, x), f(x, x))")
term = f(f(x, x), f(x, x))
r = RewriteRule(f(x, x), x)
print("Result:", r.apply(term))

print("Applying f(x, x) -> x to f(f(x, x), f(x,x)) at position 2")
print("Result:", r.apply(term, '2'))
示例#21
0
def Launcher():
    window = make_window()
    window.finalize()
    filename = "moo_output.txt"
    f_writetype = "w+"
    fileinfo = ""
    moo_session = None
    window_size = window.Size
    # event loop
    while True:
        event, values = window.read()  # type: str, dict
        # if the window is closed leave loop immediately
        if event == sg.WIN_CLOSED:
            break
        #print(event, values)

        start, stop = 1, 6
        result = []
        popup = True
        goodInput = True
        function = ''
        '''Commenting this out because not sure if it is
        desired or not
        if event == 'Submit settings':
            filename = str(values[22]) + ".txt"
            if values[23] == 'Append':
                f_writetype = "a+"'''

        # all tool tab events
        if event == 'Execute!':
            # check all input
            start, stop = 1, 6
            function = 'tool'
            for i in range(start, stop + 1):
                result.append(values[i])

        sim_next = False
        # all simulation tab events
        if event == 'Execute!0' or event == 'Next>>':
            if event == 'Next>>':
                sim_next = True
            # check all input
            start, stop = 7, 8
            function = 'simulation'
            for i in range(start, stop):
                result.append(values[i])
            result.append(values[stop])

        # all custom tab events
        if event == 'Execute!1':
            # check all input
            start, stop = 9, 14
            function = 'custom'
            for i in range(start, stop + 1):
                result.append(values[i])

        # all random tab events
        if event == 'Execute!2':
            #check all input
            start, stop = 15, 24
            function = 'random'
            for i in range(start, stop + 1):
                result.append(values[i])

        # check if any of the inputs are blank
        if all(result) is not True:
            sg.Popup('Input left blank, please enter a value.', title='ERROR')
            popup = False
            goodInput = False

        if function == 'tool' and goodInput:
            if valid_moo_unif_pair(result[0], result[1]) == False:
                goodInput = False
                sg.Popup(
                    'Invalid unfication algorithm and chaining function combination, see Help -> Tool for more information',
                    title='ERROR')

        # if none of the input is blank / combinations are good
        #then perform tool functions and output results to window
        if goodInput:
            if function == 'tool':
                fileinfo += "#######################################################################################################\n"
                fileinfo += "Tool inputs: " + str(result) + "\n"
                unif = unif_dict[result[0]]
                chaining = cf_dict[result[1]]
                sched = scd_dict[result[2]]
                length_bound = restrict_to_range(int(result[3]), 0, 100)
                knows_iv = yn_tf(result[4])
                invert_check = yn_tf(result[5])
                # check for security and catch exceptions
                try:
                    result = moo_check(chaining, sched, unif, length_bound,
                                       knows_iv, invert_check)
                except ValueError as v_err:
                    message = 'ValueError: ' + str(v_err)
                    sg.Popup(message, title='VALUE ERROR')
                    window.close()
                except:
                    print("Unexpected error:", sys.exc_info()[0])
                    window.close()
                response = get_response(result)
                fileinfo += "tool output:\n" + response + "\n"
                window['-O1-'].update(response)
            if function == 'simulation':
                fileinfo += "#######################################################################################################\n"
                fileinfo += "Simulation inputs: " + str(result) + "\n"
                chaining = cf_dict[result[0]]
                sched = scd_dict[result[1]]
                if sim_next:  # continuing session
                    if moo_session is None:
                        window['-O2-'].update("Begin session first!")
                    else:
                        plaintext = Variable("x_" + str(moo_session.iteration))
                        ciphertext = moo_session.rcv_block(plaintext)
                        response = str(
                            ciphertext
                        ) if ciphertext is not None else "Sent " + str(
                            plaintext)
                        fileinfo += "Next: " + response + "\n"
                        window['-O2-'].update(response)
                else:  # creating the session
                    moo_session = MOOProgram(chaining, sched)
                    plaintext = Variable("x_" + str(moo_session.iteration))
                    ciphertext = moo_session.rcv_block(plaintext)
                    response = str(
                        ciphertext
                    ) if ciphertext is not None else "Sent " + str(plaintext)
                    fileinfo += "Simulation begin:\n" + response + "\n"
                    window['-O2-'].update(response)
            if function == 'custom':
                fileinfo += "#######################################################################################################\n"
                fileinfo += "Custom inputs: " + str(result) + "\n"
                chaining = CustomMOO(_temporary_parser(result[0])).name
                unif = unif_dict[result[1]]
                sched = scd_dict[result[2]]
                length_bound = restrict_to_range(int(result[3]), 0, 100)
                knows_iv = yn_tf(result[4])
                invert_check = yn_tf(result[5])
                try:
                    result = moo_check(chaining, sched, unif, length_bound,
                                       knows_iv, invert_check)
                except ValueError as v_err:
                    message = 'ValueError: ' + str(v_err)
                    sg.Popup(message, title='VALUE ERROR')
                    window.close()
                except:
                    print("Unexpected error:", sys.exc_info()[0])
                    window.close()
                response = get_response(result)
                fileinfo += "Custom output:\n" + response + "\n"
                window['-O3-'].update(response)
            if function == 'random':
                fileinfo += "#######################################################################################################\n"
                fileinfo += "Random inputs: " + str(result) + "\n"
                unif = unif_dict[result[0]]
                sched = scd_dict[result[1]]
                length_bound = restrict_to_range(int(result[2]), 0, 100)
                f_bound = int(result[3])
                moo_bound = restrict_to_range(int(result[4]), 1, 100)
                c_req = yn_tf(result[5])
                iv_req = yn_tf(result[6])
                sec_req = yn_tf(result[7])
                knows_iv = yn_tf(result[8])
                invert_check = yn_tf(result[9])
                # generate random moos
                filtered_gen = FilteredMOOGenerator(1, f_bound, iv_req, c_req)
                moo_list = (next(filtered_gen) for i in range(moo_bound))
                response = ""
                # Check security of the modes of operation
                moo_safe_list: List[Term] = list()
                for random_moo_term in moo_list:
                    response += str(random_moo_term) + "\n"
                    cm = CustomMOO(random_moo_term)
                    moo_result = moo_check(cm.name, sched, unif, length_bound,
                                           knows_iv, invert_check)
                    if moo_result.secure:
                        moo_safe_list.append(random_moo_term)

                fileinfo += "Random output:\n" + response + "\n"
                window['-O4-'].update(response)

        # menu button events create popups
        # my intent with these is for this to be a place to give users more information
        # about how to use each part of the tool, but any of this can be removed as desired
        if event == 'Tool':
            sg.Popup('Valid unification algorithm and chaining function pairs:\n\n'
                     'Syntactic: Cipher Block Chaining, Propogating Cipher Block Chaining,' \
                     ' Hash Cipher Block Chaining, Cipher Feedback, Output Feedback\n'
                     'F-Rooted P-XOR: Cipher Block Chaining, Propogating Cipher Block Chaining, Hash Cipher Block Chaining\n'
                     'XOR-Rooted P-XOR: Cipher Feedback, Output Feedback', title='Tool usage', line_width=200)
        if event == 'Simulation':
            sg.Popup('This is a blurb about how to use the simulation page',
                     title='Simulation usage')
        if event == 'Custom':
            sg.Popup('This is a blurb about how to use the custom page',
                     title='Custom usage')
        if event == 'Random':
            sg.Popup('This is a blurb about how to use the random page',
                     title='Random usage')

    f = open(filename, f_writetype)
    f.write(fileinfo)
    f.close()
    window.close()
示例#22
0
def instantiate_a_constraint(constraint, sigma):
    #Instantiate a constraint using sigma
    #For example, if constraint is {x1: [a, b], x2: [f(x1)]}, and sigma is {x1 |-> a}
    #then the result is {x1: [a, b], x2: [f(a)]}
    new_constraints = {}
    for key in constraint.keys():
        old_constraint = constraint[key]
        new_constraint = []
        for o in old_constraint:
            new_constraint.append(
                ConstrainedTerm(o.term * sigma, SubstituteTerm()))
        new_constraints.update({key: new_constraint})
    return new_constraints


x1 = Variable("x1")
x2 = Variable("x2")
x3 = Variable("x3")
x4 = Variable("x4")

a = Constant("a")
b = Constant("b")
c = Constant("c")
d = Constant("d")
f = Function("f", 1)

t0 = a
t1 = xor(a, b)
t2 = xor(b, c)
t3 = f(xor(x1, c))
t4 = f(x2)
示例#23
0
"""Definition and properties for two-arity tuple."""
from symcollab.algebra import Function, Variable
from symcollab.rewrite import RewriteRule, RewriteSystem
from .inductive import TheorySystem, Inductive


@Inductive
class Pair(TheorySystem):
    pair = Function("pair", 2)


# Fix domain of pair to take anything
Pair.pair.domain_sort = None

# Variables for later rules
_a = Variable("a", sort=Pair.sort)
_b = Variable("b", sort=Pair.sort)

fst = Function("fst", 1, domain_sort=Pair.sort)
Pair.define(fst, RewriteSystem({
    RewriteRule(fst(Pair.pair(_a, _b)), _a),
}))

lst = Function("lst", 1, domain_sort=Pair.sort)
Pair.define(lst, RewriteSystem({
    RewriteRule(lst(Pair.pair(_a, _b)), _b),
}))
示例#24
0
    @classmethod
    def from_bool(cls, x: bool) -> Term:
        """Converts a bool to a Boolean."""
        return deepcopy(Boolean.trueb if x else Boolean.falseb)

    @classmethod
    def to_bool(cls, x: Term) -> bool:
        """Converts a Boolean to an bool."""
        if not isinstance(x, FuncTerm) or x != Boolean.trueb or x != Boolean.falseb:
            raise ValueError("to_bool function expects a simplified Boolean.")
        return x == Boolean.trueb


# Variables for later rules
_n = Variable("n", sort=Boolean.sort)
_m = Variable("m", sort=Boolean.sort)

# Negation
neg = Function("neg", 1, domain_sort=Boolean.sort, range_sort=Boolean.sort)
Boolean.define(
    neg,
    RewriteSystem({
        RewriteRule(neg(Boolean.trueb), Boolean.falseb),
        RewriteRule(neg(Boolean.falseb), Boolean.trueb)
    })
)

# Boolean And
andb = Function("andb", 2, domain_sort=Boolean.sort, range_sort=Boolean.sort)
Boolean.define(
示例#25
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))
示例#26
0
it does not simplify to a normal form of a term.

Inspired by "Implementing a Propositional Logic Theorem Prover in Haskell"
by Laurence Edward Day
"""
from symcollab.algebra import Function, Variable
from symcollab.rewrite import RewriteRule, RewriteSystem
from .inductive import Inductive, TheorySystem


@Inductive
class Prop(TheorySystem):
    pass


A = Variable("A", sort=Prop.sort)
B = Variable("B", sort=Prop.sort)
C = Variable("C", sort=Prop.sort)

Not = Function("not", 1, domain_sort=Prop.sort, range_sort=Prop.sort)
Prop.define(Not, RewriteSystem({RewriteRule(Not(Not(A)), A)}))

And = Function("and", 2, domain_sort=Prop.sort, range_sort=Prop.sort)
Prop.define(And, RewriteSystem({
    RewriteRule(And(A, A), A),
}))

Or = Function("or", 2, domain_sort=Prop.sort, range_sort=Prop.sort)
Prop.define(Or, RewriteSystem({
    RewriteRule(Or(A, A), A),
}))
示例#27
0
#eac_unif_ex.py
from symcollab.algebra import Function, Equation, Variable
from symcollab.Unification.eac_unif import eac_unif

exp = Function("exp", 2)
x = Variable("x")
y = Variable("y")
w = Variable("w")
t = exp(x, y)
t2 = exp(x, w)
e1 = Equation(t, t2)
U = set()
U.add(e1)
z = Variable("z")
g = Function("g", 2)
t3 = g(z, z)
t4 = g(w, w)
e2 = Equation(t3, t4)
U.add(e2)
eac_unif(U)

u = Variable("u")
v = Variable("v")
t3 = exp(v, w)
t4 = g(x, y)
e3 = Equation(u, t3)
e4 = Equation(u, t4)
U = set()
U.add(e3)
U.add(e4)
eac_unif(U)
示例#28
0
# TODO: Capture the commutative property of addition

@Inductive
class Ring(TheorySystem):
    """
    A ring is an abelian group with another binary
    operation that is associative, distributive over the
    abelian operation, and has an ientity element.
    """
    add = Function("add", 2)
    mul = Function("mul", 2)
    negate = Function("neg", 1)
    zero = Constant("0")

_x = Variable("x", sort=Group.sort)
_y = Variable("y", sort=Group.sort)
_z = Variable("z", sort=Group.sort)
# TODO: Make Group.rules.rules match what the function symbols are
Ring.rules = RewriteSystem(Group.rules.rules | {
    ## Associativity Rules
    # (x * y) * z → x * (y * z)
    RewriteRule(Ring.mul(Ring.mul(_x, _y), _z), Ring.mul(_x, Ring.mul(_y, _z))),
    ## Zero rules
    # 0 * x → 0
    RewriteRule(Ring.mul(Ring.zero, _x), Ring.zero),
    # x * 0 → 0
    RewriteRule(Ring.mul(_x, Ring.zero), Ring.zero),
    ## Distributivity rules
    # x * (y + z) → (x * y) + (x * z)
    RewriteRule(Ring.mul(_x, Ring.add(_y, _z)), Ring.add(Ring.mul(_x, _y), Ring.mul(_x, _z))),
示例#29
0
#!/usr/bin/env python3
from symcollab.algebra import Function, Variable, Constant
from symcollab.xor.xorhelper import *
from symcollab.xor.structure import *

f = Function("f", 1)
x = Variable("x")
y = Variable("y")
z = Variable("z")
x1 = Variable("x1")
x2 = Variable("x2")
x3 = Variable("x3")
a = Constant("a")
b = Constant("b")
c = Constant("c")
d = Constant("d")
ze = Zero()

t1 = xor(x, f(y), f(x1))
t2 = xor(y, f(z), f(x2))
t3 = xor(z, f(x), f(x3))

eq1 = Equation(ze, t1)
eq2 = Equation(ze, t2)
eq3 = Equation(ze, t3)
equations = Equations([eq1, eq2, eq3])

#t1 = f(xor(x, y))
#t2 = x
#eq1 = Equation(t1, t2)
#equations = Equations([eq1])
#!/usr/bin/env python3
from symcollab.algebra import Constant, Function, Variable, Equation
from symcollab.Unification.syntactic_ac_unification import *

#Setup the variables and AC function
f = Function("f", 2)
x = Variable("x")
y = Variable("y")
z = Variable("z")
a = Constant("a")
b = Constant("b")
x1 = Variable("x1")
y1 = Variable("y1")
z1 = Variable("z1")

#Example 1
e = Equation(f(x, y), f(x1, y1))
U = {e}
sol = synt_ac_unif(U)  #For a single solution
# also sol = synt_ac)unif(U, True)
sol = synt_ac_unif(U, False)  # For all solutions

#Example 2
e = Equation(f(x, x), f(y, y))
U = {e}
sol = synt_ac_unif(U)

#Example 3
e2 = Equation(f(x, x), f(f(y, y), f(z, z)))
U1 = {e2}
sol = synt_ac_unif(U1)