def convert_to_Term(t): #t is a BTerm type = t.get_type() if (type == "Zero_BTerm"): return Constant("0") if(type == "Var_BTerm"): return Variable(t.name) if (type == "Constant_BTerm"): return Constant(t.name) elif (type == "BFuncTerm"): args = t.arguments func = Function(t.function.symbol, t.function.arity) new_args = list(map(convert_to_Term, args)) return FuncTerm(func, new_args) elif (type == "Variable_BTerm"): return Variable(t.name) elif (type == "Mul_BTerm"): func = Function("Mul", 2) return func( convert_to_Term(t.left), convert_to_Term(t.right) ) elif (type == "Xor_BTerm"): args = t.arguments #xor = XorFunction() new_args = list(map(convert_to_Term, args)) #return xor(*[Constant("a"), Constant("b")]) if(len(new_args) == 1): return new_args[0] else: return xor(*new_args) else: print("type error in convert_to_Term.") return t
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()
class Group(TheorySystem): """ A group is a set G with an operation op that contain the closure and associative properties, as well as contains an identity and inverse element. """ identity = Constant("e") op = Function("op", 2) inverse = Function("inv", 1)
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")
class Field(TheorySystem): """ A field is a ring with every nonzero element having a multiplicative inverse. """ add = Function("add", 2) mul = Function("mul", 2) negate = Function("neg", 1) inverse = Function("inv", 1) zero = Constant("0") unity = Constant("1")
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()
def _f_depth(term: Term) -> int: """Returns the maximum depth of nested f terms.""" if isinstance(term, FuncTerm) and term.function.arity > 0: if term.function == Function("f", 1): return 1 + _f_depth(term.arguments[0]) return max((_f_depth(t) for t in term.arguments)) return 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)) )
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)
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] ) )
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] )
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)
def __init__(self, max_history: int = 2, max_f_depth: int = 3): self.max_history = max_history self.max_f_depth = max_f_depth self.f = Function("f", 1) self.r = Constant("r") # Only one nonce currently self.tree: List[List[Term]] = [[ self.f(MOOGenerator._P(0)), xor(self.r, MOOGenerator._P(0)) ]] self.branch_iter: Iterator[Term] = iter( self.tree[0]) # Where we are at the branch
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]) )
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()
def _valid_moo_unif_pair(moo: Term, unif_choice) -> bool: """ Responds true if the unification algorithm chosen and the chaining method chosen are compatible. """ if unif_choice != p_unif and unif_choice != XOR_rooted_security: return True if not isinstance(moo, FuncTerm) or moo.function.arity < 1: return False if unif_choice == p_unif: return moo.function == Function("f", 1) # XOR_rooted_security return moo.function == xor
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])
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()
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)
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)
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] ) )
def wrap(cls): cls.sort = Sort(cls.__name__) cls.rules = deepcopy(cls.rules) cls.definitions = deepcopy(cls.definitions) for name, term in cls.__dict__.items(): # Ignore private, already defined, and custom methods if '_' in name \ or name in TheorySystem.__dict__ \ or (callable(term) and not isinstance(term, Function)): continue if isinstance(term, Constant): if term.sort is not None and term.sort != cls.sort: raise ValueError( f"Constant {term} is of sort '{term.sort}' \ which is not the class name '{class_sort}'.") setattr(cls, name, Constant(term.symbol, sort=cls.sort)) elif isinstance(term, Function): if term.domain_sort is not None and term.domain_sort != cls.sort: raise ValueError(f"Function {term} has the domain sort \ set to '{term.domain_sort}' \ which is not the class name '{class_sort}'.") range_sort = cls.sort if term.range_sort is None else term.range_sort setattr( cls, name, Function(term.symbol, term.arity, domain_sort=cls.sort, range_sort=range_sort)) else: raise ValueError(f"Variable '{name}' is of invalid type \ '{type(term)}' inside an inductive class. (Constant, Function)" ) _system_sort_map[cls.sort] = cls return cls
class Nat(TheorySystem): zero = Constant("0") S = Function("S", 1) @classmethod def from_int(cls, x: int) -> Term: """Converts an integer to a nat.""" result = deepcopy(Nat.zero) for _ in range(x): result = Nat.S(result) return result @classmethod def to_int(cls, x: Term) -> int: """Converts a nat to an int.""" if not isinstance(x, FuncTerm) or x.sort != Nat.sort: raise ValueError("to_int function expects a nat.") if x == Nat.zero: return 0 if isinstance(x, FuncTerm) and x.function == Nat.S: return 1 + cls.to_int(x.arguments[0]) raise ValueError("to_int: Only accepts signature {0, S}")
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()
#!/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])
#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))
#!/usr/bin/env python3 from symcollab.algebra import Constant, Function, Variable from symcollab.rewrite import RewriteRule, RewriteSystem, narrow, is_finite, Variants f = Function("f", 2) x = Variable("x") a = Constant("a") b = Constant("b") r = RewriteRule(f(x, x), x) r2 = RewriteRule(f(a, x), b) print("Rewrite Rule 1:", r) print("Rewrite Rule 2:", r2) term = f(a, f(b, b)) rs = RewriteSystem({r, r2}) vt = Variants(term, rs) print("Variants of", term, ":", list(vt)) print("Variants Finite?", is_finite(vt, -1)) print("Rewrite rule from", term, "to", f(a, b), narrow(term, f(a,b), rs, -1))
#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)
""" 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), })) Implies = Function("implies", 2, domain_sort=Prop.sort, range_sort=Prop.sort) Prop.define(Implies, RewriteSystem({RewriteRule(Implies(A, B), Or(Not(A), B))}))
#!/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))))})