Source code for qrisp.algorithms.shor.crypto_tools
"""\********************************************************************************* Copyright (c) 2025 the Qrisp authors** This program and the accompanying materials are made available under the* terms of the Eclipse Public License 2.0 which is available at* http://www.eclipse.org/legal/epl-2.0.** This Source Code may also be made available under the following Secondary* Licenses when the conditions for such availability set forth in the Eclipse* Public License, v. 2.0 are satisfied: GNU General Public License, version 2* with the GNU Classpath Exception which is* available at https://www.gnu.org/software/classpath/license.html.** SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0********************************************************************************/"""importnumpyasnpfromqrisp.alg_primitives.arithmetic.modular_arithmeticimportmodinvfromqrisp.algorithms.shorimportshors_alg
[docs]defrsa_decrypt(ciphertext,e,N,backend=None):""" Decrypts an integer using factorization powered by Shor's algorithm. Parameters ---------- ciphertext : int The integer to be decrypted. e : int Public key 1. N : int Public key 2. backend : :ref:`BackendClient`, optional The backend to execute the quantum algorithm. By default the Qrisp simulator will be used. Returns ------- plaintext : int The decrypted integer. We decrypt the integer 2 using $N = 33$ and $e = 7$ >>> from qrisp.shor import rsa_decrypt >>> rsa_decrypt(2, 7, 33) 8 """ifnotbackendisNone:mes_kwargs={"backend":backend}else:mes_kwargs={}p=shors_alg(N,mes_kwargs=mes_kwargs)# Calculate the other factorq=N//p# Calculate the totientphi=(p-1)*(q-1)# Calculate the private keyd=modinv(e,phi)# Decrypt the ciphertextplaintext=pow(ciphertext,d,N)returnplaintext
[docs]defrsa_encrypt(p,q,e,message_int):""" Encrypts an integer using the private keys $p$, $q$ and a public key $e$. Parameters ---------- p : int Private key 1. q : int Private key 1. e : int Public key 2. message_int : int The integer to encrypt. Returns ------- ciphertext : int The encrypted integer. Examples -------- We encrypt the integer 8 using $p = 11$, $q = 3$ and $e = 7$ >>> from qrisp.shor import rsa_encrypt >>> rsa_encrypt(p = 11, q = 3, e = 7, message_int = 8) 2 """# Calculate the modulusN=p*q# Convert the message to an integer# message_int = int.from_bytes(message.encode(), 'big')# Encrypt the messageciphertext=pow(message_int,e,N)returnciphertext
[docs]defrsa_encrypt_string(p,q,e,message):""" Encrypts an arbitrary Python string using RSA. Parameters ---------- p : int Private key 1. q : int Private key 2. e : int Public key 1. message : string The message to encrypt. Returns ------- ciphertext : string A bitstring containing the encrypted message. Examples -------- We encrypt a string containing an important message >>> from qrisp.shor import rsa_encrypt_string >>> rsa_encrypt_string(p = 5, q = 13, e = 7, message = "Qrisp is awesome!") '01010000000101001010001100100110010010000101000010001101000010100011010101110011101000100100011100000100000100110111101000011000111110111111' """message_bitstring=" ".join(format(x,'b').zfill(7)forxinbytearray(message,'ascii')).replace(" ","")chunksize=(p*q).bit_length()-1chunks=[message_bitstring[i*chunksize:(i+1)*chunksize][::-1].zfill(chunksize)[::-1]foriinrange(int(np.ceil(len(message_bitstring)/chunksize)))]ciphertext=""foriinrange(len(chunks)):encrypted_int=rsa_encrypt(p,q,e,int(chunks[i],2))ciphertext+=bin(encrypted_int)[2:].zfill(chunksize+1)returnciphertext
[docs]defrsa_decrypt_string(e,N,ciphertext,backend=None):""" Decrypts a bitstring into a human readable string. Parameters ---------- e : int Public key 1. N : int Public key 2. ciphertext : string A bitstring, containing the encrypted message. backend : :ref:`BackendClient`, optional The backend to execute the quantum algorithm. By default the Qrisp simulator will be used. Returns ------- plaintext : string The decrypted string. Examples -------- We decrypt the message we encrypted in the example of :meth:`rsa_encrypt_string <qrisp.shor.rsa_encrypt_string>`. >>> ciphertext = '01010000000101001010001100100110010010000101000010001101000010100011010101110011101000100100011100000100000100110111101000011000111110111111' >>> from qrisp.shor import rsa_decrypt_string >>> rsa_decrypt_string(e = 7, N = 65, ciphertext = ciphertext) 'Qrisp is awesome!' """ifnotbackendisNone:mes_kwargs={"backend":backend}else:mes_kwargs={}p=shors_alg(N,mes_kwargs=mes_kwargs)# Calculate the other factorq=N//p# Calculate the totientphi=(p-1)*(q-1)# Calculate the private keyd=modinv(e,phi)chunksize=(N).bit_length()chunks=[ciphertext[i*chunksize:(i+1)*chunksize]foriinrange(int(np.ceil(len(ciphertext)/chunksize)))]plaintext_bitstring=""foriinrange(len(chunks)):cipher_int=int(chunks[i],2)plaintext_int=pow(cipher_int,d,N)plaintext_bitstring+=bin(plaintext_int)[2:].zfill(chunksize-1)returnbitstring_to_string(plaintext_bitstring)