Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Rsa Cipher
#1
Question 
I need help modifying the code to work for size 10, block_size=10. For size 8, block_size=8 works correctly if I have block_size=8
I tried to change the size to 10, but the problem is that in:lower_limit = 10 ** 11,upper_limit = 10 ** 12, the size sometimes does not fit and the code is generated incorrectly.

I would like it to work for block_size=10, but the length must be lower_limit = 10 ** 11,upper_limit = 10 ** 12

import random
from math import gcd
from sympy import mod_inverse, isprime

class SimpleRSA:
    def __init__(self):
        self.public_key = None
        self.private_key = None

    def generate_keypair(self):
        if self.public_key is not None and self.private_key is not None:
            return

        p = self.generate_large_prime()
        q = self.generate_large_prime()

        n = p * q
        phi = (p - 1) * (q - 1)

        e = random.randint(2, phi - 1)
        while gcd(e, phi) != 1:
            e = random.randint(2, phi - 1)

        d = mod_inverse(e, phi)

        self.public_key = (n, e)
        self.private_key = (n, d)

        print(f"p: {p}")
        print(f"q: {q}")
        print(f"n: {n}")

        return self.public_key, self.private_key

    def generate_large_prime(self):
        lower_limit = 10 ** 11
        upper_limit = 10 ** 12
        potential_prime = random.randint(lower_limit, upper_limit)
        while not isprime(potential_prime):
            potential_prime = random.randint(lower_limit, upper_limit)
        return potential_prime

    def encrypt(self, message):
        n, e = self.public_key
        binary_blocks = self.text_to_numeric_binary_blocks(message)

        print(f"binary_blocks: {binary_blocks}")

        encrypted_blocks = [pow(int(block, 2), e, n) for block in binary_blocks]

        print(f"encrypted_blocks: {encrypted_blocks}")

        return encrypted_blocks

    def decrypt(self, encrypted_blocks):
        n, d = self.private_key

        decrypted_blocks = [format(pow(block, d, n), '0b') for block in encrypted_blocks]

        print(f"decrypted_blocks: {decrypted_blocks}")

        decrypted_message = self.numeric_to_text_binary_blocks(decrypted_blocks)

        print(f"decrypted_message: {decrypted_message}")

        return decrypted_message


    def text_to_numeric_binary_blocks(self, text, block_size=10):
        text = text.encode()
        binary_blocks = [
            ''.join(format(byte, '08b') for byte in text[i:i + block_size]).ljust(block_size * 8, '0')
            for i in range(0, len(text), block_size)
        ]
        return binary_blocks

    def numeric_to_text_binary_blocks(self, binary_blocks, block_size=10):
        bytes_list = [int(block, 2).to_bytes(block_size, 'big') for block in binary_blocks]
        text = b''.join(bytes_list).decode(errors='replace').rstrip("\x00")
        return text


def test_encryption_decryption(message):
    rsa = SimpleRSA()
    public_key, private_key = rsa.generate_keypair()

    print(f"Original message: {message}")

    # Encryption
    encrypted_blocks = rsa.encrypt(message)
    print(f"Encrypted blocks: {encrypted_blocks}")

    # Decryption
    decrypted_message = rsa.decrypt(encrypted_blocks)
    print(f"Decrypted message: {decrypted_message}")

if __name__ == "__main__":

    test_encryption_decryption("kolotoč")
[Image: 1.PNG?ex=6575ac42&is=65633742&hm=a4d5b99...ormat=webp]

[Image: 2.PNG?ex=6575ac42&is=65633742&hm=b1b250b...ormat=webp]
Reply
#2
(Nov-26-2023, 12:16 PM)Paragoon2 Wrote: I would like it to work for block_size=10, but the length must be lower_limit = 10 ** 11,upper_limit = 10 ** 12
Why most you have that lower limit?
If you want to keep the block size as 10 bytes(80 bits),then n should be at least 80 bits long.
However,to provide a safety margin and to ensure that the RSA is secure n should be much larger (typically, 2048 bits or more in practical scenarios).
lower_limit = 10 ** 200  
upper_limit = 10 ** 201
Is this a task that you are given to try keep lower limit as low as possible?
Reply
#3
(Nov-26-2023, 03:48 PM)snippsat Wrote:
(Nov-26-2023, 12:16 PM)Paragoon2 Wrote: I would like it to work for block_size=10, but the length must be lower_limit = 10 ** 11,upper_limit = 10 ** 12
Why most you have that lower limit?
If you want to keep the block size as 10 bytes(80 bits),then n should be at least 80 bits long.
However,to provide a safety margin and to ensure that the RSA is secure n should be much larger (typically, 2048 bits or more in practical scenarios).
lower_limit = 10 ** 200  
upper_limit = 10 ** 201
Is this a task that you are given to try keep lower limit as low as possible?

Yes for task i must have block_size=10 and 10 ˆ11 > (p,q) <= 10 ˆ12
Reply
#4
The method text_to_numeric_binary_blocks,this padding might not be correctly handled during decryption.
The ljust method pads with zeros,which can alter the actual value of the data when converted back.
Try this.
def text_to_numeric_binary_blocks(self, text, block_size=10):
    text = text.encode()
    binary_blocks = [
        ''.join(format(byte, '08b') for byte in text[i:i + block_size])
        for i in range(0, len(text), block_size)
    ]
    return binary_blocks
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Cesar Cipher ForsakenDusk 5 481 Apr-07-2024, 04:30 PM
Last Post: Pedroski55
  RSA Cipher with blocks Paragoon2 0 497 Nov-26-2023, 04:35 PM
Last Post: Paragoon2
  Caesar Cipher Help pbrowne 2 2,187 Jun-30-2021, 02:36 PM
Last Post: deanhystad

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020