Exemple #1
0
 def __call__(self, iteration: int, nonces: List[Constant], P: List[Term],
              C: List[Term]):
     IV = nonces[0]
     i = iteration - 1
     # Create substitution between symbolic plain and cipher texts
     # and the symbolic instantiations of them in MOOProgram
     sigma = SubstituteTerm()
     subterms = get_vars(self.term)
     for subterm in subterms:
         if subterm.symbol[0] == "P":
             if '-' not in subterm.symbol:
                 # Assume we mean current plaintext
                 sigma.add(subterm, P[-1])
             else:
                 j = int(subterm.symbol[4:-1])
                 if j > i:
                     # If we request for a cipher block that doesn't exist yet
                     # due to the current session length
                     # then map the subterm to a different nounce
                     #sigma.add(subterm, Constant(IV.symbol + f"_{j}"))
                     sigma.add(subterm, Constant(IV.symbol))
                 else:
                     sigma.add(subterm, P[-j])
         elif subterm.symbol[0] == "C":
             j = int(subterm.symbol[4:-1])
             if j > i:
                 # If we request for a cipher block that doesn't exist yet
                 # due to the current session length
                 # then map the subterm to a different nounce
                 #sigma.add(subterm, Constant(IV.symbol + f"_{j}"))
                 sigma.add(subterm, Constant(IV.symbol))
             else:
                 sigma.add(subterm, C[-j])
     return self.term * sigma
Exemple #2
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()
Exemple #3
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)
Exemple #4
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")
Exemple #5
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)
Exemple #6
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)
class Boolean(TheorySystem):
    trueb = Constant("true")
    falseb = Constant("false")

    @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
Exemple #8
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)
Exemple #9
0
def freeze(term):
    """
    Converts all the variables inside a term into constants.

    Parameters
    ----------
    term : Term
      The term in which to turn the variables into constants.

    Examples
    --------
    >>> from symcollab.algebra import Function, Variable
    >>> from symcollab.rewrite import freeze
    >>> f = Function("f", 1)
    >>> x = Variable("x")
    >>> freeze(f(x))
    f(x)
    """
    if isinstance(term, Variable):
        return Constant(term.symbol, term.sort)
    elif isinstance(term, FuncTerm):
        arguments = list(term.arguments)
        for i, t in enumerate(arguments):
            arguments[i] = freeze(t)
        term.arguments = arguments
    return term
Exemple #10
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)))
Exemple #11
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()
Exemple #12
0
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)
Exemple #13
0
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")
Exemple #14
0
    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
Exemple #15
0
    def _conditions_met(self, term: Term) -> bool:
        """Given a term, state whether the conditions are met."""
        if _f_depth(term) > self.max_f_depth:
            return False

        if self.requires_chaining and not _satisfies_chaining(
                term, self.max_history):
            return False

        if self.requires_iv and Constant("r") not in term:
            return False

        # Passes all conditions
        return True
Exemple #16
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()
Exemple #17
0
    def __init__(self, moo_name: str, schedule_name: str = 'every'):
        chaining_function = MOO.find(moo_name)
        if chaining_function is None:
            raise ValueError(f"Mode of operation {moo_name} is not found.")
        self.chaining_function: Callable = chaining_function

        schedule = MOO_Schedule.find(schedule_name)
        if schedule is None:
            raise ValueError(f"Schedule of name {schedule_name} is not found.")
        self.schedule: Callable = schedule

        self.substitutions: SubstituteTerm = SubstituteTerm()
        self.iteration: int = 0
        # TODO: Maybe consider generating a uuid for the IV, so that
        # it is different across sessions?
        self.nonces: List[Constant] = [Constant("r")]
        self.plain_texts: List[Term] = list()
        self.cipher_texts: List[Term] = list()
        self.stopped = False
Exemple #18
0
def deducible(term: Term, known_constants: Set[Constant]):
    """
    Implementation of Lemma 9 from the Indocrypt paper 

    Parameters
    ==========
    term:
        Term we want to deduce from
    known_constants:
        Constants known by a valid decryptor

    Examples
    ========
    >>> from symcollab.algebra import *
    >>> from symcollab.moe.invertibility import deducible
    >>> x = Constant("x")
    >>> p = Constant("p_i")
    >>> f = Function("f", 2)
    >>> deducible(f(x, p), {x})
    True
    >>> deducible(f(x, p), {})
    False
    """
    # First check if term is ground
    if len(get_vars(term)) > 0:
        return False

    # Get constants from term without p_i
    p_i = Constant("p_i")
    constants_from_term = get_constants(term, unique=True)
    constants_from_term.difference_update({p_i})

    # Check that all constants other than p_i are known
    if len(constants_from_term.difference(known_constants)) > 0:
        return False

    # Make sure p_i only appears once
    if count_occurence(p_i, term) != 1:
        return False

    # Passes all the criteria
    return True
    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
Exemple #20
0
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}")
Exemple #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()
Exemple #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)
Exemple #23
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()
Exemple #24
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])
#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))
Exemple #26
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)))
Exemple #27
0
#!/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))
Exemple #28
0
 def convertToConstant(self):
     s = self.symbol
     newSymbol = s[0].lower() + s[1:]
     return Constant(newSymbol)
Exemple #29
0
#!/usr/bin/env python3
from symcollab.algebra import Constant, Function, Parser, Variable

f = Function("f", 2)
a = Constant("a")
x = Variable("x")
p = Parser()
p.add(f)
p.add(x)
p.add(a)
print("Parsing f(x,a) is successful?", p.parse("f(x,a)") == f(x,a))
print("Parsing f(f(x,a),f(x,a)) is successful?", p.parse("f(f(x,a),f(x,a))") == f(f(x,a), f(x,a)))
#!/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])