示例#1
0
    def encrypt(self, plain_text, QB, E=None, P=None, output_type="x only"):
        if E is not None:
            self.E = E
        if P is not None:
            if isinstance(P, int):
                y2 = (fast_power(P, 3, self.E.modulus) +
                      (P * self.E.A) + self.E.B) % self.E.modulus
                y = mod_sqrt(y2, self.E.modulus)[0]
                self.P = (P, mod_sqrt(y, self.E.modulus)[0])
            self.P = P
        if QB is not None:
            if isinstance(QB, int):
                y2 = (fast_power(QB, 3, self.E.modulus) +
                      (QB * self.E.A) + self.E.B) % self.E.modulus
                y = mod_sqrt(y2, self.E.modulus)[0]
                QB = (QB, mod_sqrt(y, self.E.modulus)[0])

        M = self.E.msg_to_point(plain_text)

        k = random.randint(1, self.E.modulus)

        C1 = self.E.multiply(k, P)
        C2 = self.E.add(M, E.multiply(k, QB))
        if output_type == self.style[0]:
            return (C1, C2)
        elif output_type == self.style[1]:
            return (C1[0], C2[0])
        else:
            print("Invalid type")
            return None
示例#2
0
 def public_keygen(self,
                   E=None,
                   P=None,
                   private_key=None,
                   output_type="x only"):
     if E is not None:
         self.E = E
     if P is not None:
         if isinstance(P, int):
             y2 = (fast_power(P, 3, self.E.modulus) +
                   (P * self.E.A) + self.E.B) % self.E.modulus
             y = mod_sqrt(y2, self.E.modulus)[0]
             self.P = (P, mod_sqrt(y, self.E.modulus)[0])
         self.P = P
     if private_key is not None:
         self.private_key = private_key
     if None in [self.E, self.P, self.private_key]:
         return None
     self.QA = self.E.multiply(self.P, self.private_key)
     if output_type == self.style[0]:
         return self.QA
     elif output_type == self.style[1]:
         return self.QA[0]
     else:
         print("invalid type")
         return None
示例#3
0
    def decrypt(self,
                g=None,
                modulus=None,
                private_key=None,
                cipher_text_1=None,
                cipher_text_2=None):
        if private_key is not None:
            self.set_private_key(private_key)
        if g is not None:
            self.set_g(g)
        if modulus is not None:
            self.set_modulus(modulus)
        if cipher_text_1 is not None:
            self.set_cipher_text_1(cipher_text_1)
        if cipher_text_2 is not None:
            self.set_cipher_text_2(cipher_text_2)

        if None not in [
                self.private_key, self.g, self.modulus, self.cipher_text_1,
                self.cipher_text_2
        ]:
            x = mod_inv(
                fast_power(self.cipher_text_1, self.private_key, self.modulus),
                self.modulus)
            self.message = (x * self.cipher_text_2) % self.modulus
            return self.message
        else:
            return None
示例#4
0
 def test_fast_power_1(self):
     print("\n\nRunning test for src module: fast_power")
     x = 3
     e = 218
     m = 1000
     result = 489
     self.assertEqual(fast_power(x, e, m), result)
示例#5
0
def bsgs(
    g,
    h,
    p,
    smoothness=10000
):  # Solving x given g,h,p for the equation g^x (mod p) = h, so logg(h) (mod p) = x
    N = order(g, p, smoothness)
    n = int(sqrt(N)) + 1
    e = 1
    u = mod_inv(fast_power(g, n, p), p)
    uk = u
    gi = g
    hui = (h * uk) % p
    list_one = {gi: 1}
    list_two = {hui: 1}
    # Create the two list
    for i in range(2, n + 1):
        gi = (gi * g) % p
        uk = (uk * u) % p
        hui = (h * uk) % p
        list_one.update({gi: i})
        list_two.update({hui: i})
    # Now Check for a collision between the list
    for huk in list_two.keys():
        for gk in list_one.keys():
            if huk == gk:
                x = (list_one.get(gk) + (list_two.get(huk) * n)) % N
                xs = []
                for i in range(0, int(((p - 1) / N) + 1)):
                    xs.append(x + N * i)
                return xs
示例#6
0
def primality_test(n,
                   certainty=50000
                   ):  #returns true if n is prime, if composite returns false
    if not isinstance(n, int):
        raise ValueError("n cannot be anything but an int you gave: " +
                         str(type(n)))
    elif n < 1:
        raise ValueError("n cannot be less than 0")
    elif n == 1:
        return True
    elif n % 2 == 0:
        return False
    else:
        for i in range(0, certainty):
            a = random.randint(2, n - 1)
            if eea(a, n).get("gcd") != 1: return False
            k = 1
            q = (n - 1) / 2
            while q % 2 == 0:
                k = k + 1
                q = q / 2
            a = fast_power(a, q, n)
            if a == 1: continue
            while k > 1:
                if a == -1: break
                a = (a * a) % n
                k = k - 1
            if a == -1: continue
        return True
示例#7
0
def order(g, p, smooth=10000):
    # Naive order method
    if p < 1000:
        for i in range(1, p):
            if fast_power(g, i, p) == 1:
                ord = i
                return ord
    h = p - 1
    divisors = naive_factor(h).get("divisors")
    # Prime factors and divisors retrieved
    for ord in sorted(
            divisors
    ):  # This should iterate smallest to largest, that way we get teh smallest divisor of e
        result = fast_power(g, ord, p)
        if result == 1:  # divisor is the order of g
            return ord
示例#8
0
    def decrypt(self, c1, c2, QA=None):
        if QA is not None:
            self.QA = QA
        if isinstance(c1, int):
            y2 = (fast_power(c1, 3, self.E.modulus) +
                  (c1 * self.E.A) + self.E.B) % self.E.modulus
            y = mod_sqrt(y2, self.E.modulus)[0]
            c1 = (c1, y)
        if isinstance(c2, int):
            y2 = (fast_power(c2, 3, self.E.modulus) +
                  (c2 * self.E.A) + self.E.B) % self.E.modulus
            y = mod_sqrt(y2, self.E.modulus)[0]
            c2 = (c2, y)

        param2 = self.E.multiply(self.private_key, c1)
        param2[1] = -param2[1]
        return self.E.point_to_msg(self.E.add(c2, param2))
示例#9
0
 def test_bsgs_1(self):  # Book Example
     print("\n\nRunning test for cryptanalysis module: bsgs")
     g = 9704
     exp_x = 1159
     p = 17389
     h = fast_power(g, exp_x, p)
     xs = bsgs(g, h, p)
     self.assertIn(exp_x, xs)
示例#10
0
 def gen_symmetric_key(self, B=None, private_key=None, p=None):
     if B is not None: self.set_public_key(B)
     if private_key is not None: self.set_private_key(private_key)
     if p is not None: self.set_modulus(p)
     if None not in (self.B, self.private_key, self.p):
         self.symmetric_key = fast_power(self.B, self.private_key, self.p)
         return self.symmetric_key
     else:
         return None
示例#11
0
 def gen_my_public_key(self, g=None, private_key=None, p=None):
     if g is not None: self.set_generator(g)
     if private_key is not None: self.set_private_key(private_key)
     if p is not None: self.set_modulus(p)
     if None not in (self.g, self.private_key, self.p):
         self.A = fast_power(self.g, self.private_key, self.p)
         return self.A
     else:
         return None
示例#12
0
 def __init__(self, E, P):
     self.E = E
     self.style = ["whole point", "x only"]
     if isinstance(P, int):
         y2 = (fast_power(P, 3, self.E.modulus) +
               (P * self.E.A) + self.E.B) % self.E.modulus
         y = mod_sqrt(y2, self.E.modulus)[0]
         self.P = (P, mod_sqrt(y, self.E.modulus)[0])
     self.P = P
示例#13
0
 def encrypt(self, m, N = None, e = None):
     if N is not None:
         self.N = N
     if e is not None:
         self.e = e
     self.m = m
     if None in [self.N, self.e, self.m]:
         raise ValueError("m, e, or N is None")
     self.c = fast_power(self.m, self.e, self.N)
     return self.c
示例#14
0
def pollard(N):
    a = 2
    p = None
    for j in range(2, 1000):
        a = fast_power(a, j, N)
        d = eea(a-1, N).get("gcd")
        if d > 1 and d < N:
            p = d
            break
    return p
示例#15
0
def legendre_symbol(a, modulus):
    ap = fast_power(a, (modulus-1)/2, modulus)
    l_symb = None
    if a==0:
        l_symb = 0
    elif ap == 1: # a is a quadratic residue mod modulus
        l_symb = 1
    elif ap == ((-1) % modulus):# a is a non-quadratic residue mod modulus
        l_symb = -1
    return l_symb
示例#16
0
 def encrypt(self,
             message=None,
             g=None,
             public_key=None,
             modulus=None,
             k=None):
     if g is not None:
         self.set_g(g)
     if public_key is not None:
         self.set_public_key(public_key)
     if modulus is not None:
         self.set_modulus(modulus)
     #Validate k
     if k is None:
         if self.modulus is not None:
             self.k = random.randint(2, self.modulus - 2)
             #print("k: "+str(self.k))
         else:
             return None
     elif k <= 1 or k >= self.modulus - 1:
         print("Invalid k value")
         return None
     else:
         self.k = k
     if isinstance(message, int):
         #Validate message
         if message <= 2 or message >= self.modulus - 1:
             print("Invalid message size, must be in range 2-p-2")
             return None
         else:
             if None not in [self.g, self.public_key]:
                 self.message = message
                 self.cipher_text_1 = fast_power(self.g, self.k,
                                                 self.modulus)
                 self.cipher_text_2 = (self.message * fast_power(
                     self.public_key, self.k, self.modulus)) % self.modulus
                 return [self.cipher_text_1, self.cipher_text_2]
             else:
                 print("g or public key is none")
                 return None
     else:
         return None
示例#17
0
def pohlig_hellman(
    g, h, p
):  #Solving x given g,h,p for the equation g^x (mod p) = h, so logg(h) (mod p) = x
    n = p - 1
    congruences_and_mods = []
    prime_factors = naive_factor(n, 10000).get("prime_factors_dict")
    for factor in prime_factors.keys():
        modulo = factor**prime_factors.get(factor)
        gi = fast_power(g, n / modulo, p)
        hi = fast_power(h, n / modulo, p)
        ax = bsgs(
            gi, hi,
            p)[0]  # retuns a list of solutions, we just want the first one
        congruences_and_mods.append((ax, modulo))
    x = crt(congruences_and_mods)
    N = order(g, p, 10000)
    xs = []
    for i in range(1, int(((p - 1) / N) + 1)):
        xs.append(int((x + N * i) % n))
    return xs
示例#18
0
 def gen_public_key(self, private_key=None, g=None, modulus=None):
     if private_key is not None:
         self.set_private_key(private_key)
     if g is not None:
         self.set_g(g)
     if modulus is not None:
         self.set_modulus(modulus)
     if None in [self.private_key, self.modulus, self.g]:
         return None
     else:
         self.public_key = fast_power(self.g, self.private_key,
                                      self.modulus)
         return self.public_key
示例#19
0
 def decrypt(self, c, p = None, q = None, e = None):
     if q is not None and p is not None:
         self.q = q
         self.p = p
         self. N = self.p * self.q
     if e is not None:
         self.e = e
     self.c = c
     if None in [self.N, self.p, self.q, self.e, self.c]:
         raise ValueError("c, e, p, q, or N is None")
     g = eea(self.p - 1, self.q-1).get("gcd")
     self.d = int(mod_inv(self.e % ((self.p-1)*(self.q-1)/g), (self.p-1)*(self.q-1)/g))
     self.m = fast_power(self.c, self.d, self.N)
     return self.m
示例#20
0
    def test_bsgs_2(self):
        primes = small_primes_generator(
            1000)  # Change this to increase/decrease duration of test
        del primes[0]  # delete 2, all of these are trivial
        del primes[0]  # delete 3
        del primes[0]  # delte 5

        for prime in primes:
            for j in range(1, 10):
                g = random.randint(2, prime - 1)
                for i in range(1, 10):
                    expected_x = random.randint(1, prime - 1)
                    h = fast_power(g, expected_x, prime)
                    xs = bsgs(g, h, prime)
                    #print(" | prime: "+str(prime) + " | g: "+str(g) + " | exp_x: "+str(expected_x)+" | h: "+str(h)+ " | xs: " + str(xs))
                    self.assertIn(expected_x, xs)
示例#21
0
 def symmetric_keygen(self, QB, private_key=None, output_type="x only"):
     if private_key is not None:
         self.private_key = private_key
     if QB is not None:
         self.QB = QB
     if None in [self.E, self.private_key]:
         return None
     if isinstance(self.QB, int):
         y2 = (fast_power(self.QB, 3, self.E.modulus) +
               (self.QB * self.E.A) + self.E.B) % self.E.modulus
         y = mod_sqrt(y2, self.E.modulus)[0]
         self.QB = (self.QB, y)
     print("QB:")
     print(QB)
     sym_point = self.E.multiply(self.QB, self.private_key)
     sym_key = sym_point[0]
     if output_type == self.style[0]:
         return sym_point
     elif output_type == self.style[1]:
         return sym_key
     else:
         print("invalid output type")
         return None
示例#22
0
def mod_sqrt(a, modulus):
    root1 = None
    root2 = None
    if legendre_symbol(a, modulus) != 1:
        root1 = None
        root2 = None
    elif modulus % 2 == 0:  # Non-prime modulus's are not supported
        print("Not a prime")
        root1 = None
        root2 = None
    elif modulus % 8 == 1 or modulus % 8 == 5:
        s = 0
        m = None
        n = modulus - 1
        while n % 2 == 0:
            n = n / 2
            s += 1
        m = n
        e = s
        z = random.randint(1, modulus - 1)
        while legendre_symbol(z,
                              modulus) != -1:  # z is a non-quadratic residue
            z = random.randint(1, modulus - 1)
        c = fast_power(z, m, modulus)
        x = fast_power(a, (m + 1) / 2, modulus)
        t = fast_power(a, m, modulus)
        while t != 1:
            i = 1
            for i in range(1, e):
                if fast_power(t, 2**i, modulus) == 1:
                    break
            b = fast_power(c, 2**(e - i - 1), modulus)
            x = (b * x) % modulus
            t = (t * b * b) % modulus
            c = (b * b) % modulus
            e = i
        root1 = x
        root2 = modulus - x
    elif modulus % 8 == 3 or modulus % 8 == 7:
        x = fast_power(a, (modulus + 1) / 4, modulus)
        root1 = x
        root2 = (-x) % modulus
    return (root1, root2)
示例#23
0
 def test_fast_power_4(self):
     x = 11
     e = 7234592359-1
     m = 7234592359
     result = 1
     self.assertEqual(fast_power(x, e, m), result)
示例#24
0
 def test_fast_power_3(self):
     x = 11
     e = 12314
     m = 7234592359
     result = 1369450571
     self.assertEqual(fast_power(x, e, m), result)
示例#25
0
 def test_fast_power_2(self):
     x = 5
     e = 718
     m = 23451
     result = 3739
     self.assertEqual(fast_power(x, e, m), result)
示例#26
0
 def calculate_y2(self, x):
     return (fast_power(x, 3, self.modulus) +
             (self.A * x) + self.B) % self.modulus