Пример #1
0
 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
Пример #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
        return exp(ciphertext.ciphertext, d, n)
Пример #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
        return exp(signature.ciphertext, e, n)
Пример #4
0
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
Пример #5
0
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
Пример #6
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
        if type(message) is str:
            if len(message) > 32:
                raise ValueError("Please enter a smaller string")
            message = self.process_string(message)

        e, n = key
        return exp(message, e, n)
Пример #7
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
        if type(message) is str:
            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 exp(message, d, n)