def solve(self, target):
     assert type(self.base) == type(
         target), 'Element and base are not the same type.'
     curr = target
     conn = self.get_conn()
     cursor = conn.cursor()
     cursor.execute(
         f'prepare sel as select log from {self.table} where hash=$1')
     for i in range(0, self.step):
         h = hash(curr)
         cursor.execute(f'execute sel ({h})')
         line = cursor.fetchone()
         if not line:
             curr *= self.base
             continue
         [first] = line
         if exp(self.base, first) == curr:
             return first - i
         rest = cursor.fetchall()
         for c in rest:
             if exp(self.base, c) == curr:
                 return c - i
         return None
         curr *= self.base
     print('Aborting discrete logarithm.')
     return None
Exemple #2
0
    def decrypt(self, ciphertext):
        """RSA Decryption

        Args:
            ciphertext: Ciphertext object to decrypt

        REFERENCES
        ==========
        https://en.wikipedia.org/wiki/RSA_(cryptosystem)#Decryption
        """

        d, n = self.__private_key
        if ciphertext.is_str:
            return self.recover_string(exp(ciphertext.text, d, n))
        return exp(ciphertext.text, d, n)
Exemple #3
0
    def verify(self, signature, key):
        """RSA signature verification

        Args:
            signature: signature we want to verify
            key: public key of the person who's signature we want to verify

        REFERENCES
        ==========
        https://en.wikipedia.org/wiki/RSA_(cryptosystem)#Signing_messages
        """

        e, n = key
        if signature.is_str:
            return self.recover_string(exp(signature.text, e, n))
        return exp(signature.text, e, n)
Exemple #4
0
    def sign(self, message):
        """RSA signing
        Similar to RSA encryption but we use private key to sign.
        Note that this is merely for proof of concept and should not be used
        in production

        Args:
                message: message to sign

        REFERENCES
        ==========
        https://en.wikipedia.org/wiki/RSA_(cryptosystem)#Signing_messages
        """
        # If input is string, convert it to long first
        self.is_str = 0
        if type(message) is str:
            self.is_str = 1
            if len(message) > 32:
                raise ValueError("Please enter a smaller string")
            message = self.process_string(message)

        assert message.bit_length() <= self.n.bit_length()

        d, n = self.__private_key
        return Ciphertext(exp(message, d, n), self.is_str)
 def check_if_composite_using(a):
     x = exp(a, d, n)
     if x == 1 or x == n - 1:
         return False  # probably prime
     for _ in range(s):
         x = (x * x) % n  # check for each a^((2^i)*d)
         if x == n - 1:
             return False  # probably prime
     return True  # definitely composite
def fermats_test(n, k=10):
    """Fermat's Primality test
    Returns True(probably prime) if n is prime, Flase if n is composite.

    Args:
        n: integer to be tested for primality
        k: number of iterations of the Fermat's Primality Test

    NOTES
    =====
    Not very efficient for large integers as exp is costly
    Carmichael numbers can bypass this test
    https://en.wikipedia.org/wiki/Fermat_primality_test#Flaw

    REFERENCES
    ==========
    https://en.wikipedia.org/wiki/Primality_test#Fermat_primality_test

    EXAMPLES
    ========
    >>> fermats_test(5)
    True
    >>> fermats_test(4)
    False
    >>> fermats_test(341)
    False

    The test may fail for n = 561 = 3.11.17, the smallest Carmichael number if
    we add the condition that the chosen 'a' values have to be co-prime to n.
    >>> fermats_test(561)
    False
    """
    if n == 2:
        return True
    if not n % 2:
        return False

    # Check if a^(n-1) = 1 mod n for k different a values
    for _ in range(k):
        a = random.randint(2, n - 1)
        if exp(a, n - 1, n) != 1:
            return False
    return True
def solovay_strassen(n, k=10):
    """Solovay Strassen Primality Test
    Returns False is n is composite, True(probably prime) otherwise.

    Args:
        n: integer to be tested for primality
        k: number of iterations to run the test

    NOTES
    =====
    It is possible for the algorithm to return an incorrect answer.
    If the input n is indeed prime, then the output will always correctly be
    probably prime. However, if the input n is composite then it is possible
    for the output to be incorrectly probably prime.
    The number n is then called a Euler-Jacobi pseudoprime.

    The probability of failure is at most 2^(-k)

    REFERENCES
    ==========
    https://en.wikipedia.org/wiki/Solovay%E2%80%93Strassen_primality_test

    EXAMPLES
    >>> solovay_strassen(561)
    False
    >>> solovay_strassen(29)
    True
    >>> solovay_strassen(221)
    False
    """

    if n == 2:
        return True
    if n == 1 or n % 2 == 0:
        return False

    for _ in range(k):
        a = random.randint(2, n - 1)
        x = (jacobi(a, n) + n) % n  # map -1 to n - 1
        if x == 0 or exp(a, (n - 1) // 2, n) != x:
            return False
    return True
Exemple #8
0
    def encrypt(self, message, key):
        """RSA Encryption

        Args:
            message: message to encrypt
            key: public key to use for encryption

        REFERENCES
        ==========
        https://en.wikipedia.org/wiki/RSA_(cryptosystem)#Encryption
        """

        # If input is string, convert it to long first
        self.is_str = 0
        if type(message) is str:
            self.is_str = 1
            if len(message) > 32:
                raise ValueError("Please enter a smaller string")
            message = self.process_string(message)

        assert message.bit_length() <= self.n.bit_length()

        e, n = key
        return Ciphertext(exp(message, e, n), self.is_str)
    def precomp(self):
        conn = self.get_conn()
        cursor = conn.cursor()
        cursor.itersize = 10000
        batch_size = 500
        conn.set_session(autocommit=False)

        # Check if table has elements
        try:
            cursor.execute(
                f'insert into {self.table}(hash, log) values (1, 1)')
            conn.commit()
        except psycopg2.IntegrityError as e:
            if e.pgcode == '23505':
                print(
                    'Database seems to have already been filled (at least',
                    'partially). We do not currently support filling',
                    'databases in multiple sessions. If you believe the',
                    'database is incomplete, please drop the table and run',
                    'precomputation again.',
                )
                return
            else:
                raise e

        i = 1
        mult = exp(self.base, self.step)

        total = (self.maximum - self.minimum) // self.step + 1
        preparation = (
            f'prepare ins as insert into {self.table}(hash, log) values ' +
            ','.join([
                '(${}, ${})'.format(2 * i + 1, 2 * (i + 1))
                for i in range(batch_size)
            ]) + ';')
        cursor.execute(preparation)
        z = self.group.random()
        one = z / z
        curr = self.base**(self.minimum * one)
        for i in range(total // batch_size):
            L = []
            for j in range(batch_size):
                if (i * batch_size + j) % 100000 == 0:
                    print(
                        f'Precomputation step {i * batch_size + j} out of {total}.'
                    )
                    ratio = (i * batch_size + j) / int(total)
                    print('|' + '=' * (round(40 * ratio)) + ' ' *
                          (40 - round(40 * ratio)) +
                          f'| {round(ratio * 100)}%')
                h = hash(curr)
                L.append(h)
                L.append(self.minimum + self.step * (i * batch_size + j))
                curr *= mult
            ins = 'execute ins (' + ','.join([str(x) for x in L]) + ');'
            cursor.execute(ins)
            if (i * batch_size) % 1000000 == 0:
                conn.commit()
        conn.commit()
        k = (total // batch_size) * batch_size
        while k < total + 1:
            curr *= mult
            h = hash(curr)
            cursor.execute('insert into {}(hash, log) values ({}, {})'.format(
                self.table, h, self.minimum + self.step * k))
            k += 1
        conn.commit()
#!/usr/bin/env python
# coding: utf-8

from utils import multiplication_entiere, produit, affiche_table_multiplicative, exp, inverse, subgroup, generateurs

if __name__ == '__main__':
	print "Hello world!"

	print "multiplication_entiere(2, 5) =", multiplication_entiere(2, 5)

	n = 8
	poly = (0b1 << 8) ^ (0b1 << 4) ^ (0b1 << 3) ^ (0b1 << 1) ^ 0b1
	print produit(n, poly, 45, 72)

	affiche_table_multiplicative(3, poly & 0b1111)

	alpha = 0b10
	for i in xrange(1, 2**3):
		print "alpha **", i, ":", exp(3, poly & 0b1111, alpha, i)
	
	print inverse(3, poly & 0b1111, 1)
	print inverse(3, poly & 0b1111, 0b10)
	print inverse(3, poly & 0b1111, 0b11)
	print inverse(3, poly & 0b1111, 0b100)

	print subgroup(3, poly & 0b1111, 0b10)
	
	print generateurs(3, poly & 0b1111)
	print generateurs(8, poly)