diff --git a/bsp_MIA.py b/bsp_MIA.py
new file mode 100644
index 0000000000000000000000000000000000000000..ae6eed20dd1e172d17273392bb158c350b649da1
--- /dev/null
+++ b/bsp_MIA.py
@@ -0,0 +1,54 @@
+#!/usr/bin/sage
+# -*- coding: utf-8 -*-
+
+from __future__ import absolute_import, division, print_function
+from sage.all import *
+
+from classes.MatsumotoImaiAExample import MatsumotoImaiAExample
+
+# Endlicher Körper mit 5 Elementen:
+finite_field = GF(2**2, 'a')
+(a,) = finite_field.gens()
+
+n = 3  # Drei Variablen
+
+"""TEST MIA"""
+
+# MIA mit den Schlüsseln initialisieren
+# MatsumotoImaiAExample setzt die sonst zufälligen Werte
+# wie in den Beispielen und printed mehr
+MIA = MatsumotoImaiAExample(finite_field, n)
+
+
+# Schlüssel im sage CLI nutzbar machen
+private_key = MIA.private_key
+public_key = MIA.public_key
+
+# Schlüssel ausgeben
+print("Privater Schlüssel:")
+print("S:\n{}x + {}".format(private_key.S.M, private_key.S.y))
+print("Pr:\n{}".format(private_key.Pr))
+print("S:\n{}x + {}".format(private_key.T.M, private_key.T.y))
+
+print("\nÖffentlicher Schlüssel:")
+print("P:\n{}".format(public_key.P))
+
+# Die Nachricht soll (1, a, a^2) sein
+msg = vector(finite_field, [1, a, a**2])
+print("\n\nmsg =", msg)
+
+# Nachricht verschlüsseln
+enc = public_key.encrypt(msg)
+print("public_key.encrypt(msg): enc =", enc)
+
+# Verifizieren, dass enc auch entschlüsselt wird
+print("MIA.decryt(enc):", MIA.decrypt(enc))
+
+# Signatur erstellen
+msg = vector(finite_field, [a, 1, 1])
+print("\nmsg =", msg)
+sig = MIA.sign(msg)
+print("sig =", sig)
+
+# Signatur verifizieren
+print("public_key.verify(msg, sig):", public_key.verify(msg, sig))
diff --git a/bsp_UOV.py b/bsp_UOV.py
index 4d9b5d28f5825fc24704c4cbc964cd299068f7f8..cd28c51416f44c67643317d840188579a52450fb 100644
--- a/bsp_UOV.py
+++ b/bsp_UOV.py
@@ -4,9 +4,7 @@
 from __future__ import absolute_import, division, print_function
 from sage.all import *
 
-from classes.helpers.PublicKey import PublicKey
-from classes.helpers.PrivateKey import PrivateKey
-from classes.UnbalancedOilAndVinegar import UnbalancedOilAndVinegar
+from classes.UnbalancedOilAndVinegarExample import *
 
 # Endlicher Körper mit 5 Elementen:
 finite_field = GF(5, 'a')
@@ -16,18 +14,32 @@ n = 3  # Drei Variablen
 
 """TEST UOV"""
 
-# Initialize simple UOV
-UOV = UnbalancedOilAndVinegar(finite_field, n, m, keyfile="./keys/bsp_uov2.priv")
+# UOV mit den Schlüsseln initialisieren
+# UnbalancedOilAndVinegarExample setzt die sonst zufälligen Werte
+# wie in den Beispielen und printed mehr
+UOV = UnbalancedOilAndVinegarExample(
+    finite_field, n, m, keyfile="./keys/bsp_uov.priv")
+
+# Schlüssel im sage CLI nutzbar machen
 private_key = UOV.private_key
 public_key = UOV.public_key
 
-# use a random vector
+# Schlüssel ausgeben
+print("Privater Schlüssel:")
+print("S:\n{}x + {}".format(private_key.S.M, private_key.S.y))
+print("Pr:\n{}".format(private_key.Pr))
+print("S:\n{}x + {}".format(private_key.T.M, private_key.T.y))
+
+print("\nÖffentlicher Schlüssel:")
+print("P:\n{}".format(public_key.P))
+
+# Die Nachricht soll (1, 4) sein
 msg = vector(finite_field, [1, 4])
+print("\n\nmsg =", msg)
 
-# generate Signature
+# Signatur erstellen
 sig = UOV.sign(msg)
-
-# verify signature is valid
-print("msg =", msg)
 print("sig =", sig)
-print("UOV.verify(msg, sig):", UOV.verify(msg, sig))
+
+# Signatur verifizieren
+print("public_key.verify(msg, sig):", public_key.verify(msg, sig))
diff --git a/classes/AffineTransformation.py b/classes/AffineTransformation.py
new file mode 100644
index 0000000000000000000000000000000000000000..ca63c101b7e306bd3d8d90fa89773d87e2b1d5f9
--- /dev/null
+++ b/classes/AffineTransformation.py
@@ -0,0 +1,35 @@
+from __future__ import absolute_import, division, print_function
+from sage.all import *
+
+
+class AffineTransformation():
+    def __init__(self, M, y):
+        """
+        Eine affine Transformation wird mit einer invertierbaren
+        Matrix und einem beliebigen Vektor initialisiert
+        """
+
+        # Abbruchbedingung für nicht invertierbare Matrizen
+        if not M.is_invertible():
+            exit(1)
+
+        self.M = M  # invertierbare Matrix
+        self.y = y  # Vektor
+
+    def __call__(self, vector):
+        """Anwenden der Transformation auf den gegebenen Vektor"""
+
+        # Sollte `vector` eine Liste sein -> Typecast
+        if not isinstance(vector, sage.structure.element.Vector):
+            vector = vector(vector)
+
+        return (self.M * vector) + self.y
+
+    def inverse(self, vector):
+        """Anwenden der inversen Transformation auf den gegebenen Vektor"""
+
+        # Sollte `vector` eine Liste sein -> Typecast
+        if not isinstance(vector, sage.structure.element.Vector):
+            vector = vector(vector)
+
+        return self.M.inverse() * (vector - self.y)
diff --git a/classes/MatsumotoImaiAExample.py b/classes/MatsumotoImaiAExample.py
new file mode 100644
index 0000000000000000000000000000000000000000..228e8252ade232ac8d954ffc335d1a71086715a3
--- /dev/null
+++ b/classes/MatsumotoImaiAExample.py
@@ -0,0 +1,79 @@
+#!/usr/bin/sage
+# -*- coding: utf-8 -*-
+
+from __future__ import absolute_import, print_function
+from sage.all import *
+import copy as cp
+
+from .helpers.sage_extensions import random_value, random_invertible_matrix
+
+from .helpers.AffineTransformation import AffineTransformation
+from .helpers.PrivateKey import PrivateKey
+from .helpers.PrivateKey import PublicKey
+from .helpers.EncryptionScheme import EncryptionScheme
+
+
+class MatsumotoImaiAExample(EncryptionScheme):
+    """Matsumoto Imai Scheme A implementation"""
+
+    def phi(self, polynomail_a):
+        return polynomail_a.list()
+
+    def phi_inv(self, vector_a):  # -> b::Polynomial
+        return self.extension_field(vector_a)
+
+    def __init__(self, finite_field, n, keyfile=None):
+        self.finite_field = finite_field
+        self.n = n
+
+        # generate or load private & public key
+        if keyfile is not None:
+            self.private_key = PrivateKey(None, None, None, keyfile)
+            self.public_key = self.private_key.generate_public_key()
+        else:
+            # self.generate_keys()
+            self.generate_example_keys()
+
+    def generate_example_keys(self):
+        k = self.finite_field
+        (a,) = k.gens()
+        n = 3
+
+        ring = PolynomialRing(k, 'x')
+        (x,) = ring.gens()
+        gx = x**3 + x + 1
+
+        (self.theta, self.theta_invers) = (2, 26)
+
+        ML1 = matrix(k, [[a**2, a, a], [a, 1, 0], [1, 0, 1]])
+        yL1 = vector(k, [0, 1, a])
+        T = AffineTransformation(ML1, yL1)
+
+        ML2 = matrix(k, [[1, 0, a], [0, 1, a], [1, a, 0]])
+        yL2 = vector(k, [a, a**2, a**2])
+        S = AffineTransformation(ML2, yL2)
+
+        multivariate_ring = PolynomialRing(k, 'x1, x2, x3', n)
+        extension_field = PolynomialRing(
+            multivariate_ring, 't').quotient_ring(gx, 'T')
+        self.extension_field = extension_field
+        multi_vars = multivariate_ring.gens()
+
+        Sx = list(S(vector(multi_vars)))
+
+        pre_F = self.phi_inv(Sx)  # <- phi_invers
+
+        # Now the MAGIC happens
+        # post_F = self.F(pre_F)
+
+        post_F = extension_field("1 + (a + 1)*x1 + (a)*x2 + x3 + x1*x2 + (a)*x1*x3 + (a + 1)*x2*x3 + ((a) + (a)*x1 + x2 + (a + 1)*x3 + x1^2 + (a + 1)*x1*x2 + x2^2 + x2*x3)*T + ((a + 1) + (a + 1)*x1 + (a)*x2 + (a)*x3 + x1^2 + x1*x2 + (a)*x1*x3 + (a + 1)*x2^2 + (a)*x2*x3 + (a + 1)*x3^2)*T^2")
+
+        SPTx = T(vector(post_F.list()))
+
+        Pr = T.inverse(vector(post_F.list()))
+        self.private_key = PrivateKey(S, Pr, T)
+        self.public_key = PublicKey(SPTx)
+
+    def invert_MQ(self, msg):
+        X = self.phi_inv(list(msg))
+        return vector(self.phi(X**self.theta_invers))
diff --git a/classes/UnbalancedOilAndVinegarExample.py b/classes/UnbalancedOilAndVinegarExample.py
new file mode 100644
index 0000000000000000000000000000000000000000..a3d38a96becf9fedec131e5f5df82841c52fdad6
--- /dev/null
+++ b/classes/UnbalancedOilAndVinegarExample.py
@@ -0,0 +1,151 @@
+#!/usr/bin/sage
+# -*- coding: utf-8 -*-
+
+from __future__ import absolute_import, print_function
+from sage.all import *
+import copy as cp
+
+from .helpers.sage_extensions import random_value, random_invertible_matrix
+
+from .helpers.AffineTransformation import AffineTransformation
+from .helpers.PrivateKey import PrivateKey
+from .helpers.SignatureScheme import SignatureScheme
+
+
+class UnbalancedOilAndVinegarExample(SignatureScheme):
+    """Unalanced Oil and Vinegar Implementation"""
+
+    def __init__(self, finite_field, n, m, keyfile=None):
+        """
+        UOV wird mit dem Grundkörper `F`, Länge der Nachrichten `n`
+        und Länge der Signatur `m` initialisiert
+
+        Der Pfad zum privaten Schlüssel ist optional
+        """
+
+        # speichere die initialen Werte
+        self.finite_field = finite_field
+        self.ring = PolynomialRing(finite_field, 'x', n)
+
+        self.n = n  # Anzahl der Variablen
+        self.m = m  # Anzahl der Gleichungen
+
+        # wird ein privater Schlüssel als Dateipfad übergeben, so wird dieser
+        # geladen ansonsten werden mit `generate_keys` die Schlüssel erstellt
+        if keyfile is not None:
+            self.private_key = PrivateKey(None, None, None, keyfile)
+            self.public_key = self.private_key.generate_public_key()
+        else:
+            self.generate_keys(finite_field, n, m)
+
+    def generate_keys(self, F, n, m):
+        """
+        erstelle Privaten und öffentlichen Schlüssel aus gegebenem endlichen
+        Körper `F`, Anzahl der Variablen `n` und Anzahl der Gleichungen `m`
+        """
+
+        # oil and vinegar variables:
+        v = n - m
+        oil = m
+
+        # Zwei affine Abbildungen (T ist Identität)
+        # - S ist (n x n) und T ist (m x m)
+        S = AffineTransformation(
+            random_invertible_matrix(F, n), random_vector(F, n))
+        T = AffineTransformation(matrix.identity(F, m), vector(F, m))
+
+        # Generiere geheimes Polynom `Pr`
+        # - P ist (n x m)
+        alpha = []
+        beta = []
+        gamma = []
+        Pr = []
+
+        # x[0] .. x[n-1] als Variablen benutzbar machen
+        x = vector(self.ring.gens())
+
+        # für jedes Polynom Pr[i]
+        for i in xrange(0, oil):
+            # Zufällige Matrix Representation jedes Polynoms
+            # - Alpha (Wert) ist der Konstante Anteil
+            # - Beta (Vektor) ist der lineare Anteil
+            # - Gamma (Matrix) ist der gemischte und quadratische Anteil
+            alpha.append(random_value(F))
+            beta.append(random_vector(F, n))
+            gamma.append(random_matrix(F, n - m, n))
+
+            '''Baue Polynom folgender Form'''
+            #  poly = ((gamma[i] * x) * x) + (beta * x) + alpha[i]
+
+            # Konstanter Anteil
+            poly = alpha[i]
+
+            # Essigvariablen:
+            for j in xrange(0, v):
+                for k in xrange(0, n):
+                    poly += gamma[i][j, k] * x[j] * x[k]
+
+            # Essig- & Ölvariablen
+            for k in xrange(0, n):
+                poly += beta[i][k] * x[k]
+
+            Pr.append(poly)
+
+        # erstelle den geheimen und öffentlichen Schlüssel
+        self.private_key = PrivateKey(S, Pr, T)
+        self.public_key = self.private_key.generate_public_key()
+
+    def invert_MQ(self, msg):
+        vinegar_len = self.n - self.m
+        x = list(self.ring.gens())
+        F = self.finite_field
+
+        # wichtig ist, dass private_key.Pr `UOV`-Gestalt hat
+        Pr = cp.copy(self.private_key.Pr)
+
+        sig = []
+
+        """ Linearisierung """
+        # x[1] bis x[n-m] werden zufällig aus F gewählt
+        # Diese bilden den ersten Teil der Lösung
+        if vinegar_len == 1:
+            x[0] = 3
+            sig.append(x[0])
+        else:
+            for i in xrange(0, vinegar_len):
+                x[i] = random_value(F)
+                sig.append(x[i])
+
+        print("Zufällig belegte Werte", x)
+
+        # Durch einsetzen der belegten Variablen wird P linearisiert
+        for i in xrange(0, len(Pr)):
+            Pr[i] = Pr[i](x)
+
+        # Die gelösten Variablen werden entfernt
+        x = x[vinegar_len:]
+
+        """ Gleichungssystem lösen """
+        # Um mit sagemath das lineare Gleichungssystem zu loesen
+        # wird diese Form angestrebt: A*x - b = 0
+        A = matrix(F, len(x))  # Koeffizenten Matrix
+        b = vector(F, len(x))
+
+        # A[i] ist die Liste der Koeffizienten der neuen Monome von Pr[i]
+        # b[i] ist der konstante Anteil von Pr[i]
+        for i in xrange(0, len(x)):
+            for j in xrange(0, len(x)):
+                A[i, j] = Pr[i].monomial_coefficient(x[j])
+
+            b[i] = Pr[i].constant_coefficient()
+
+        # Die Nachricht muss von den Konstanten abgezogen werden
+        b = msg - b
+
+        # sagemath bietet eine einfache Methode die Lösung des GS zu finden
+        # sollte keine Lösung gefunden werden können muss die
+        for x in A.solve_right(b):
+            sig.append(x)
+
+        # Die Lösung von "Pr(sig) = msg" wird zurückgegeben
+        return vector(F, sig)
diff --git a/keys/bsp_uov.priv b/keys/bsp_uov.priv
index b58b64b7dff26ab5dfef0d56e179a060c63bb4f9..9888565e6ce5c97005eb2b57c3a08dfa7b77ac05 100644
Binary files a/keys/bsp_uov.priv and b/keys/bsp_uov.priv differ
diff --git a/keys/bsp_uov2.priv b/keys/bsp_uov2.priv
deleted file mode 100644
index 9888565e6ce5c97005eb2b57c3a08dfa7b77ac05..0000000000000000000000000000000000000000
Binary files a/keys/bsp_uov2.priv and /dev/null differ
diff --git a/keys/bsp_uov_old.priv b/keys/bsp_uov_old.priv
new file mode 100644
index 0000000000000000000000000000000000000000..b58b64b7dff26ab5dfef0d56e179a060c63bb4f9
Binary files /dev/null and b/keys/bsp_uov_old.priv differ