Discussione Sicurezza informatica e le nuove sfide

Goclau

Utente Iron
14 Febbraio 2024
9
3
6
5
I computer sempre più veloci e le nuove sfide del calcolo quantistico stanno mettendo un po' di pensieri alla sicurezza informatica. Mi riferisco in particolare a RSA che pone la sua sicurezza nella difficoltà di fattorizzare semiprimi molto grandi, ma grandi quanto? La chiave più grande creata da RSA, fonti Internet, è di 4096 bit e ci sono voluti due mesi di calcolo per crearla. E' palese che il limite di questo metodo sta nella grandezza delle chiavi.
Io vorrei creare una discussione su un nuovo progetto, già sperimentato e funzionante ma ancora sconosciuto, su una evoluzione del sistema RSA.
Quello che io descriverò è un metodo di fattorizzazione a tempo zero su grandi semiprimi mi riferisco a semiprimi che sono 3 volte tanto di quello riportato sopra e cioè 13000 bit. Può darsi che pensiate sia una bufala ma vi posso garantire che è tutto vero e dimostrabile. Anzi, c'è la possibilità di provare sul vostro computer quanto verrà descritto sotto con uno script in Python aperto, gratuito, e pienamente ispezionabile.

Un Nuovo Algoritmo per la Fattorizzazione di Semiprimi a Tempo Zero


Introduzione

  • Contesto: I semiprimi, ovvero il prodotto di due numeri primi, sono ancora un tassello importante della crittografia in quanto la loro fattorizzazione è ancora uno dei nodi della matematica da sciogliere. Attualmente si usano algoritmi come L'ECM (Elliptic Curve Method) che è un algoritmo di fattorizzazione probabilistico ideato da H.W. Lenstra Jr. nel 1985, e NFS (Number Field Sieve – NFS) che si basa sulla ricerca di relazioni tra numeri "lisci" (con pochi fattori primi) in un corpo di numeri. Naturalmente anche questi algoritmi sono impotenti di fronte ai grandi semiprimi e la loro capacità di fattorizzazione si abbassa mano a mano che il semiprimo diventa più grande. Il punto debole potrebbe essere rappresentato con l’avvento dei computer quantistici, che con la loro capacità di calcolo potrebbero arrivare a raggiungere quello che noi adesso riteniamo sia un grande semiprimo, e cioè 3200 bit. Se mi posso esprimere in grandezza, un semiprimo a 5000 bit sarebbe molto complicato anche per gli stessi computer quantistici.


  • Obiettivo: E’ riuscire a creare un sistema di criptazione utilizzando fattori primi molto grandi per affrontare la sfida dei computer quantistici


Funzionamento dell’Algoritmo

Quello di cui vi voglio parlare oggi è un nuovo sistema di fattorizzazione a cui ho dato il nome di GC57, che riesce a fattorizzare a tempo zero semiprimi 2,3,4 volte più grandi degli attuali semiprimi che oggi vengono ritenuti sicuri, e cioè semiprimi di 13000 bit. Questo sistema di fattorizzazione sfrutta una proprietà particolare, e cioè la proprietà degli interi, o proprietà del resto. L’intero del numero ottenuto tramite il massimo divisore comune Euclideo, è sempre un fattore primo del semiprimo. Questo fino a un certo campo che può andare da 2^25 fino e oltre a 2^500. Mi spiego meglio: La chiave creata può fattorizzare una quantità di semiprimi di qualsiasi grandezza purché i due fattori primi si trovino dentro questo campo. Per esprimerlo nella forma matematica posso mostrare quanto segue:

  1. chiave
  2. campo=2^500
  3. Fattore primo p = x+(>1 <2^500) qualsiasi primo entro il campo di 2^500
  4. Fattore primo q = y+(>1 <2^500) qualsiasi primo entro il campo di 2^500
  5. Semiprimo n=pq
L’algoritmo GC57 riesce a fattorizzare qualsiasi semiprimo sia il prodotto di p e q entro questo campo, a tempo ZERO


Funzionamento del Programma di Criptazione

  1. Creazione del Database di Semiprimi. Questa operazione è importante per mantenere la fattorizzazione a tempo zero in quanto per trovare due fattori primi di dimensione 6000 bit e oltre, il sistema rimarrebbe impegnato per alcuni minuti obbligando il programma a rallentare. Questo database viene memorizzato sul computer e tenuto a disposizione del programma che ne caricherà uno a caso tra quelli memorizzati. Inoltre questa prassi agevola la diversificazione dei semiprimi utilizzati come per esempio tenere più semiprimi di grandezze diverse. Sarà poi il programma a distinguere quale chiave recuperare per fattorizzare il semiprimo selezionato
  2. La chiave, o le chiavi, se utilizziamo più grandezze di semiprimi, si trovano su una chiavetta usb che dovrà avere anche la persona che riceve i messaggi. Questo porta anche un altro vantaggio e cioè, se chi spedisce i messaggi dispone di tutte le chiavi mentre chi li riceve dispone solo di alcune chiavi, questi messaggi possono essere decifrati solo da chi ha la chiave giusta. Inoltre diventa molto conveniente quando si utilizza solo una cartella condivisa, o un cloud condiviso, perché ogni messaggio viene identificato per come è stato creato, e cioè da che tipo di semiprimo è stato creato.
  3. Quando si crea un messaggio, il programma carica un semiprimo, come ho riportato sopra, e lo fattorizza a tempo zero. Dal fattore primo di questo semiprimo ricava l’impronta digitale(SHA 256) e la passa alla codifica AES 256 che si occuperà di creare la chiave di codifica per cifrare il messaggio. Il messaggio cifrato verrà poi salvato nella cartella condivisa, o sul cloud condiviso, con all’interno il testo, l’impronta digitale criptata e il semiprimo.
    Fase 2, la Decriptazione
  4. Il messaggio viene caricato dalla persona a cui è destinato e tramite la stessa chiave utilizzata nella fase di criptazione, anch’essa depositata su una usb, viene estratto il semiprimo e fattorizzato a tempo zero, che poi viene passato all’SHA per rilevare l’impronta digitale con la quale AES decripterà il messaggio. Il messaggio verrà poi stampato sulla stampante privata, preferibilmente collegata tramite cavo, per poi essere cancellato dalla cartella o dal cloud condivisi.

Confronto con RSA

  • Velocità: RSA è relativamente lento rispetto agli algoritmi di crittografia simmetrica. Per questo motivo, viene generalmente utilizzato solo per scambiare chiavi simmetriche e per firmare digitalmente documenti, non per la crittografia di grandi quantità di dati. IL GC57 è molto veloce sia nel fattorizzare a tempo Zero, sia nel codificare grandi dati con gli algoritmi SHA, AES
  • Sicurezza RSA basa la sua sicurezza sulla difficoltà di fattorizzare numeri semiprimi grandi. Anche il GC57 si basa su questa difficoltà ma adotta un sistema che gli permette di fattorizzare semiprimi molto più grandi rispetto a RSA

Conclusioni

  • Il futuro dei computer quantistici potrebbe minare la sicurezza informatica di RSA. Per questo motivo ritengo che questo nuovo metodo di fattorizzazione a tempo zero su semiprimi che vanno oltre i 10000 bit, possa alzare l’asticella di difficoltà nel cercare di fattorizzarli anche sfruttando la super velocità quantistica
  • Implicazioni: Nuovi algoritmi su chiavi molto grandi
  • Sfide Future: Questo progetto è solo all’inizio e si presenta come una novità assoluta per la ricerca e lo sviluppo di nuovi metodi sulla sicurezza.
 
La chiave più grande creata da RSA, fonti Internet, è di 4096 bit e ci sono voluti due mesi di calcolo per crearla. E' palese che il limite di questo metodo sta nella grandezza delle chiavi.

è possibile creare chiavi molto più grandi, quelle che ho provato erano multiple di 8 bit come chiavi a 8192 o 15360 bit. Per creare una coppia di chiavi a 4096 bit il mio pc ci mette qualche secondo, questione di minuti per chiavi a 15360 bit, per cosa intendi che ci sono voluti due mesi?

Se mi posso esprimere in grandezza, un semiprimo a 5000 bit sarebbe molto complicato anche per gli stessi computer quantistici.
  • Obiettivo: E’ riuscire a creare un sistema di criptazione utilizzando fattori primi molto grandi per affrontare la sfida dei computer quantistici

Perché il tuo algoritmo dovrebbe essere sicuro da un attacco quantistico con una chiave a 5000 bit? Non penso funzioni così, ci sarà un motivo se il NIST ha selezionato e continua a cercare algoritmi post-quantum.


Del tuo algoritmo non ho capito molte cose e come fa a ottenerle tipo:
L’algoritmo GC57 riesce a fattorizzare qualsiasi semiprimo sia il prodotto di p e q entro questo campo, a tempo ZERO

taggo @St3ve che magari saprà aiutare.
 
  • Mi piace
Reazioni: --- Ra --- e St3ve
La chiave di 4096 bit è stata creata nel 2019 ed è una chiave a sicurezza elevata ma anche molto complicata da creare. Le chiavi RSA più comuni oggi sono a 2024 bit. Io non so di che chiavi stai parlando ma non sono sicuramente RSA. Ma comunque sarei curioso di vedere le chiavi su un semiprimo a15360 bit creata in pochi minuti.

Il mio progetto si basa sulla difficoltà nel fattorizzare grandi semiprimi, proprio com RSA. Un semiprimo a 5000 bit con due fattori primi di circa 2500 bit non può essere fattorizzato utilizzando la forza bruta(Brute Force) perciò devi utilizzare algoritmi come ECM o NFS. Questi algoritmi utilizzano delle probabilità o delle relazioni, come ho scritto sopra, ma sono totalmente inadatti sui grandi semiprimi. Figuriamoci se il semiprimo è 13000 bit.

Potresti essere più chiaro e definire le chiavi generate da un semiprimo a 15360 bit?

Il NIST(National Institute of Standards and Technology) ha i suoi ricercatori, di altissimo livello naturalmente, ma questo non preclude il fatto che una persona al di fuori del NIST possa essere in grado di trovare una soluzione. A questo proposito ti invito a fare una prova: fattorizza un semiprimo a 308 cifre, 1024 bit che non sia banale e cioè vicino a una potenza o a un quadrato. Se ci riesci vuol dire che hai trovato un buon metodo.

Per quanto riguarda il mio algoritmo GC57, riesce a fattorizzare semiprimi non banali di 13000 bit, e oltre, a tempo zero. Questa è una affermazione che lascia un po' disorientati perchè nessuno è a conoscenza di un tale algoritmo. Di solito la reazione è quella di pensare che è una bufala perchè se un tale algoritmo esistesse il mondo della sicurezza sarebbe in pericolo. Non è del tutto vero. L'algoritmo esiste e io sono colui che l'ha creato, ma la sicurezza degli RSA non è in pericolo perchè come gli RSA questo algoritmo ha i suoi campi di risoluzione e al momento non esce da questi campi. Questo però ha dato vita a un'altra cosa, e cioè a un altro tipo di sicurezza.

Che tu non abbia capito molte cose è normale, chiunque non capirebbe molte cose sul testo che ho scritto. Sono qui per questo, per rispondere a qualsiasi domanda
 
La chiave di 4096 bit è stata creata nel 2019 ed è una chiave a sicurezza elevata ma anche molto complicata da creare. Le chiavi RSA più comuni oggi sono a 2024 bit. Io non so di che chiavi stai parlando ma non sono sicuramente RSA. Ma comunque sarei curioso di vedere le chiavi su un semiprimo a15360 bit creata in pochi minuti.

Ti allego una chiave privata RSA con semiprimo a 16384 bit che ho appena generato col mio laptop in 3 minuti e 57 secondi. Probabilmente intendiamo cose diverse se no non si spiega, le chiavi più comuni RSA sono a 2048 e 4096, mai viste a 2024 bit personalmente.

Il NIST(National Institute of Standards and Technology) ha i suoi ricercatori, di altissimo livello naturalmente, ma questo non preclude il fatto che una persona al di fuori del NIST possa essere in grado di trovare una soluzione.

Non è quello che intendevo, sottolineavo il fatto che anche potendo ingrandire le chiavi si è scelto di cercare nuovi approcci e problemi matematici slegati dalla fattorizzazione, dove i "bruteforce" per mezzo di computer quantistici hanno un vantaggio importante.

Per quanto riguarda il mio algoritmo GC57, riesce a fattorizzare semiprimi non banali di 13000 bit, e oltre, a tempo zero. Questa è una affermazione che lascia un po' disorientati perchè nessuno è a conoscenza di un tale algoritmo. Di solito la reazione è quella di pensare che è una bufala perchè se un tale algoritmo esistesse il mondo della sicurezza sarebbe in pericolo. Non è del tutto vero. L'algoritmo esiste e io sono colui che l'ha creato, ma la sicurezza degli RSA non è in pericolo perchè come gli RSA questo algoritmo ha i suoi campi di risoluzione e al momento non esce da questi campi. Questo però ha dato vita a un'altra cosa, e cioè a un altro tipo di sicurezza.

Che tu non abbia capito molte cose è normale, chiunque non capirebbe molte cose sul testo che ho scritto. Sono qui per questo, per rispondere a qualsiasi domanda

Ottimo sono curioso di provarlo, hai già pubblicato qualche implementazione/prototipo o intendi farlo?
 

Allegati

  • rsa16384.pem.txt
    12.3 KB · Visualizzazioni: 2
  • Mi piace
Reazioni: MRPants e St3ve
La chiave più grande creata da RSA, fonti Internet, è di 4096 bit e ci sono voluti due mesi di calcolo per crearla.

La chiave di 4096 bit è stata creata nel 2019 ed è una chiave a sicurezza elevata ma anche molto complicata da creare. Le chiavi RSA più comuni oggi sono a 2024 bit. Io non so di che chiavi stai parlando ma non sono sicuramente RSA. Ma comunque sarei curioso di vedere le chiavi su un semiprimo a15360 bit creata in pochi minuti.
Da qualche anno a questa parte, quando crei una chiave RSA con GPG di default vai a creare una chiave con 3072 bit. Quelle a 2048 bit sono ancora piuttosto comuni, ma ormai ce ne saranno sempre meno. Il NIST consiglia almeno RSA 3072 per AES 128 e RSA 15360 per AES 256 (pdf). Se vuoi provare a generare una chiave, installa OpenSSL e poi lancia
Bash:
openssl genrsa -out private-key.pem 16384
dove l'ultimo numero indica la dimensione (in bit) della chiave. Per chiavi di 4096 bit ci vuole meno di 1 secondo, non certo 2 mesi, e per chiavi di 16384 (il massimo consigliato da openssl) parliamo di un paio di minuti. Con "chiave di sicurezza elevata" non so cosa intendi. Quelle generate da GPG e OpenSSL sono fanno già i dovuti controlli per verificare che i numeri primi scelti non siano fragili ad attacchi conosciuti (vedi, per esempio, la mia spiegazione di RSA).

Io vorrei creare una discussione su un nuovo progetto, già sperimentato e funzionante ma ancora sconosciuto, su una evoluzione del sistema RSA.
Quello che io descriverò è un metodo di fattorizzazione a tempo zero su grandi semiprimi mi riferisco a semiprimi che sono 3 volte tanto di quello riportato sopra e cioè 13000 bit.
Detta così non sembra un evoluzione di RSA, non hai descritto un algoritmo di crittografia, hai praticamente parlato di un attacco a RSA.

Può darsi che pensiate sia una bufala ma vi posso garantire che è tutto vero e dimostrabile. Anzi, c'è la possibilità di provare sul vostro computer quanto verrà descritto sotto con uno script in Python aperto, gratuito, e pienamente ispezionabile.
Ottimo! Cosa stiamo aspettando? Postacelo qui, magari anche i sorgenti visto che è open source.

RSA non è in pericolo perchè come gli RSA questo algoritmo ha i suoi campi di risoluzione e al momento non esce da questi campi.
Non ho capito cosa intendi con campi però vabbé, la cosa più interessante è che dici di avere il codice pronto e che è open source.
 
Ultima modifica:
Si probabilmente intendiamo due cose diverse. La chiave viene generata su un modulo e questo modulo è il semiprimo. Il semiprimo non è la chiave. Quando io parlo di 2024 parlo dei bit del semiprimo. Se si scoprissero i due o uno dei fattori primi che compongono questo semiprimo, la chiave sarebbe compromessa. Per questo probabilmente parliamo di due cose diverse. Tu ti riferisci alla chiave mentre io mi riferisco al semiprimo. Un semiprimo a più di 16000 bit avrebbe due fattori primi di circa 8000 bit e questo porterebbe a un calcolo astronomico che non finirebbe mai. Prova a calcolare il Totiente su un numero a 8000 bit. Ma anche solo su un numero a 2024 bit e vedrai che quei tre minuti diventano 3 giorni.

Per quanto riguarda programma GC57Crypto, così l'ho chiamato perchè utilizza il GC57 assieme ad HSA 256 AES 256, è funzionante e già testato. Scritto in Python. Lo potete utilizzare sul vostro computer, insieme a un vostro amico che dista svariati km da voi, o anche sperimentarlo su due computer nella stessa rete, e potrete scambiarvi messaggi che vi garantisco nessuno li potrà leggere senza la chiave

L'unica cosa che dovete sapere è come impostare le cartelle contenenti i semiprimi e quelle condivise per scambiarvi i messaggi, e la chiave che si trova su una USB


'Non ho capito cosa intendi con campi però vabbé, la cosa più interessante è che dici di avere il codice pronto e che è open source.'

Questo te lo spiego perchè è importante:
pensa di avere due numeri X e Y e che il campo sia di 2^200. Questi due numeri sono creati con una serie di addizioni di numeri primi elevati a delle potenze. 3^15+7^20+31^40......+101^80. naturalmente questi non saranno numeri primi ma sono numeri composti. Ora fai conto di prendere un numero a caso tra 1 e 2^200 e di aggiungerlo al numero composto, questo per tutti e due i numeri. La possibilità che questi diventino numeri primi è molto remota perciò applichi l'algoritmo di Rabin-Miller per verificare se il numero è primo. Se non lo è incrementi di 1 fino a quando non lo trovi. Alla fine avrai il numero composto X + numero random da 1 a 2^200 + n, e così anche per Y. Trovati i due numeri primi otterrai il semiprimo n=pq.
La chiave, e questa è la parte incredibile di questo sistema, riuscirà a fattorizzare qualsiasi semiprimo uscito da questo calcolo.

Ok. un passo alla volta.

Solo un paio di domande. Conosci Python? lo hai installato sul computer?
 
Tu ti riferisci alla chiave mentre io mi riferisco al semiprimo. Un semiprimo a più di 16000 bit avrebbe due fattori primi di circa 8000 bit e questo porterebbe a un calcolo astronomico che non finirebbe mai. Prova a calcolare il Totiente su un numero a 8000 bit. Ma anche solo su un numero a 2024 bit e vedrai che quei tre minuti diventano 3 giorni.
La funzione toziente, quella che nella guida che ti ho linkato in precedenza io ho chiamato $$\(\phi$$\) di Eulero, si usa nella dimostrazione di RSA, ma non nella generazione di chiavi e né nella fase di cifrazione e decifrazione. Non hai bisogno di calcolarla. Se hai i due primi la ottieni con una semplice moltiplicazione, e se hai solo il loro prodotto allora calcolarla è equivalente a risolvere il problema della fattorizzazione (dimostrato qui). Il fatto che sia difficile fattorizzare numeri grossi è il motivo per cui RSA è considerato sicuro, quindi per il crittosistema è un bene che sia difficile calcolare la funzione toziente senza conoscere i fattori primi perché, se fosse altrimenti, sarebbe rotto.

Sì, un semiprimo di 16000 bit usato in RSA ha fattori primi di circa 8000 bit. Con OpenSSL vai a generare la chiave, non stai fattorizzando niente, quindi in pochi minuti finisci tutto. RSA 16384 non è molto diffuso perché è piuttosto lento, inoltre il tempo e la sicurezza non scalano linearmente e di pari passo. Per farti capire, RSA 4096 è significativamente (più del doppio) più lento di RSA 2048 ed è solo pochi bit più sicuro.

Per quanto riguarda programma GC57Crypto, così l'ho chiamato perchè utilizza il GC57 assieme ad HSA 256 AES 256, è funzionante e già testato. Scritto in Python.
Dove troviamo il codice sorgente?
 
Ultima modifica:
il codice sorgente te lo posso postare qui o lo scarichi da GitHub. Ma questo dipende se lo vuoi solo visionare o testare sul tuo computer.
I programmi che ho utilizzato per il mio test sono 4. codifica_a, decodifica_a, codifica_b, decodifica_b. Questo perchè ho utilizzato due cartelle A e B.: A trasmette su A e Riceve su B, mentre B trasmette su B e riceve su A. Le cartelle sono sul computer ma condivise da un cloud. Perciò su un computer sono installati i due programmi A e sull'altro i due programmi B.

comunque questi sono i due programmi A, più due file di semiprimi e le rispettive chiavi

.
Python:
# Invio Messaggi Criptati
import tkinter as tk
from tkinter import *
from PIL import Image, ImageTk
import os
from tkinter import messagebox
from tkinter import simpledialog
from tkinter import filedialog
from Crypto.Cipher import AES
from Crypto.Hash import SHA256
from math import gcd
from random import randint
import pickle
import win32print
import win32ui
import win32con

programma_invia_a = "C:\\DCP/Dropbox/cartella_a"


apri_dati = simpledialog.askstring("USB", "Inserisci la porta USB se diversa da D")
if not apri_dati:
    apri_dati = "d"


# file_path = os.path.join(apri_dati)


usb_path = apri_dati + ":\\"
if os.path.exists(usb_path):
    try:
        storage_devices = os.listdir(usb_path)
    except FileNotFoundError:
        pass
else:
    messagebox.showwarning(
        "Attenzione", "Chiavetta USB non trovata nella lettera di unità " + apri_dati
    )
    quit()


def apri_file():
    global codice_selezionato, chiave, filename
    filename = filedialog.askopenfilename(
        title="Apri file",
        initialdir="c:\\semiprimi",  # Cartella iniziale predefinita
        # filetypes=(("Tutti i File", "*.*"),("File di testo", "*.txt")),
    )
  
    if filename=='':
        prewin.destroy()
        quit() 

    semipsel = filename.split("/")
    codice_selezionato = semipsel[2]
    chiave_usb = apri_dati + ":\\chiave_" + codice_selezionato

    if os.path.exists(chiave_usb):
        with open(chiave_usb, "r") as leggif:
            leggi1 = int(leggif.readline())
            leggi2 = int(leggif.readline())
            leggi3 = int(leggif.readline())
            chiave = leggi1**leggi2
            prewin.destroy()  # Chiude la finestra tkinter dopo aver selezionato il file

    else:
        messagebox.showerror("Errore", "Dati su USB non trovati")
        prewin.destroy()  # Chiude la finestra tkinter dopo aver selezionato il file
        quit()


def on_exit():
    prewin.destroy()
    quit()


prewin = tk.Tk()
larghezza = prewin.winfo_screenwidth()
altezza = prewin.winfo_screenheight()
prewin.title("Seleziona BIT di Codifica")
prewin.configure(bg="yellow")
prewin.geometry(f"{'300'}x{'100'}+{larghezza//2}+{altezza//3}")

label = tk.Label(
    prewin, text="Seleziona BIT di Codifica", bg="yellow", font="arial 12 bold"
)
label.pack(pady=10)

select_button = tk.Button(prewin, width=10, text="APRI", bg="green", command=apri_file)
select_button.pack(pady=5)
prewin.protocol("WM_DELETE_WINDOW", on_exit)

prewin.mainloop()


def carica_semiprimo_random(nome_file):
    with open(nome_file, "r") as file:
        righe = file.readlines()
        codice_random = randint(0, len(righe) - 1)  # Genera un indice casuale
        n = righe[codice_random]
    return int(n.strip())


def factorize(semiprime):
    a = semiprime % chiave
    b = semiprime - a
    for i in range(10):
        key = gcd(a, b)
        if key != 1:
            break
        a = a + chiave
        b = b - chiave
    return key


def generate_aes_key(prime_factor):
    hash_object = SHA256.new(data=str(prime_factor).encode())
    return hash_object.digest()


def encrypt_message(message, aes_key):
    cipher = AES.new(aes_key, AES.MODE_GCM)
    ciphertext, tag = cipher.encrypt_and_digest(message.encode())
    return ciphertext, cipher.nonce, tag


def elaborazione_email():
    message_to_encrypt = tw1.get("1.0", END)
    if message_to_encrypt == "" or len(message_to_encrypt) < 20:
        messagebox.showerror(
            "Attenzione:", "Messaggio inesistente o più corto di 20 caratteri"
        )
        return
    # Carica un semiprimo casuale dal file
    nome_file = filename
    semiprime = carica_semiprimo_random(nome_file)
    # Genera chiave AES utilizzando il fattore primo
    secret_key = factorize(semiprime)
    aes_key = generate_aes_key(secret_key)
    message_to_encrypt = message_to_encrypt.strip()
    ciphertext, nonce, tag = encrypt_message(message_to_encrypt, aes_key)
    memorizza_file = "send_mess_" + codice_selezionato
    with open(memorizza_file, "wb") as file:
        pickle.dump((ciphertext, nonce, tag, str(semiprime)), file)
    messagebox.showinfo("Via E-mail:", "Messaggio creato con successo")


def elaborazione_cloud():
    message_to_encrypt = tw1.get("1.0", END)
    if message_to_encrypt == "" or len(message_to_encrypt) < 20:
        messagebox.showerror(
            "Attenzione:", "Messaggio inesistente o più corto di 20 caratteri"
        )
        return
    # Carica un semiprimo casuale dal file
    nome_file = filename
    semiprime = carica_semiprimo_random(nome_file)
    # Genera chiave AES utilizzando il fattore primo
    secret_key = factorize(semiprime)
    aes_key = generate_aes_key(secret_key)
    message_to_encrypt = message_to_encrypt.strip()
    ciphertext, nonce, tag = encrypt_message(message_to_encrypt, aes_key)
    memorizza_file = programma_invia_a+"/send_mess_" + codice_selezionato

    with open(memorizza_file, "wb") as file:
        pickle.dump((ciphertext, nonce, tag, str(semiprime)), file)
    messagebox.showinfo("Via Cloud:", "Messaggio creato con successo")


def carica_immagine():
    # Apri un'immagine utilizzando PIL
    img = Image.open("C:\\avviso/logo_a.jpg")

    # Converte l'immagine in un formato compatibile con Tkinter
    img_tk = ImageTk.PhotoImage(img)

    # Aggiungi l'immagine al canvas
    canvas.create_image(0, 0, anchor=tk.NW, image=img_tk)

    # Memorizza un riferimento all'immagine per evitare che venga eliminata dalla Garbage Collection
    canvas.image = img_tk


def on_enter(event):
    b1.config(
        bg=passa_button
    )  # Cambia il colore di sfondo a blu quando il mouse entra nel pulsante


def on_leave(event):
    b1.config(bg=fondo_button)  # Ripristina il colore di sfondo


def on_enter1(event):
    b2.config(
        bg=passa_button
    )  # Cambia il colore di sfondo a blu quando il mouse entra nel pulsante


def on_leave1(event):
    b2.config(bg=fondo_button)  # Ripristina il colore di sfondo


def cancella():
    tw1.delete("1.0", END)
    return


def stampa_messaggio():
    testo = tw1.get("1.0", tk.END).strip()
    if testo == "":
        messagebox.showerror("Attenzione:", "Nessun testo Da stampare")
        return
    stampa(testo)


def stampa(testo):
    printer_name = win32print.GetDefaultPrinter()
    hprinter = win32print.OpenPrinter(printer_name)
    hdc = win32ui.CreateDC()
    hdc.CreatePrinterDC(printer_name)

    # Ottieni le dimensioni della pagina
    width = hdc.GetDeviceCaps(win32con.PHYSICALWIDTH)
    height = hdc.GetDeviceCaps(win32con.PHYSICALHEIGHT)

    # Calcola il numero massimo di caratteri per riga basato sulla larghezza della pagina
    max_chars_per_line = int(width / hdc.GetTextExtent("X")[0])

    # Dividi il testo in righe più corte
    lines = []
    line = ""
    for word in testo.split():
        if len(line) + len(word) + 1 <= max_chars_per_line:
            line += word + " "
        else:
            lines.append(line.strip())
            line = word + " "
    if line:
        lines.append(line.strip())

    hdc.StartDoc("Stampa")
    hdc.StartPage()

    # Stampare le righe di testo
    y = 100
    for line in lines:
        hdc.TextOut(100, y, line)
        y += hdc.GetTextExtent(line)[1]  # spazio per la prossima riga

    hdc.EndPage()
    hdc.EndDoc()
    hdc.DeleteDC()
    win32print.ClosePrinter(hprinter)


# *************************************************
# *       dimensione e colori
# *************************************************
finestra_x = 600
finestra_y = 500
finestra = str(finestra_x) + "x" + str(finestra_y)
fondo_finestra = "#36648B"
fondo_text = "#808080"
fondo_button = "#20B2AA"
passa_button = "#C0FF3E"
fondo_button2 = "#71C671"
fondo_entry = "#C1C1C1"
# *************************************************
# *        Finestra principale
# *************************************************
root = tk.Tk()
root.title("Invio Documenti Criptati   IDC")
root.geometry(finestra + "+200+50")
root.config(bg=fondo_finestra)
# Creazione del canvas
px = finestra_x - 130
py = finestra_y - 130
canvas = tk.Canvas(root, width=130, height=130)
canvas.place(x=px, y=py)
px = 10
py = 10
tw1 = tk.Text(
    root,
    wrap=WORD,
    width=64,
    height=17,
    bg=fondo_text,
    font="helvetica, 12",
    cursor="left_ptr",
)
tw1.place(x=px, y=py)

px = 150
py = 330

b1 = tk.Button(
    root,
    text="Stampa",
    bg=fondo_button,
    font="arial, 12 bold",
    width=10,
    cursor="hand2",
    command=stampa_messaggio,
)
b1.place(x=px, y=py)
b1.bind("<Enter>", on_enter)
b1.bind("<Leave>", on_leave)

px = px + 150
py = 330

b2 = tk.Button(
    root,
    text="Cancella",
    bg=fondo_button,
    font="arial, 12 bold",
    width=10,
    cursor="hand2",
    command=cancella,
)
b2.place(x=px, y=py)
b2.bind("<Enter>", on_enter1)
b2.bind("<Leave>", on_leave1)

px = 20
py = 330 + 70

b3 = tk.Button(
    root,
    text="Invia Per E-mail",
    bg=fondo_button2,
    font="arial, 12 bold",
    width=13,
    cursor="hand2",
    command=elaborazione_email,
    state="disabled",
)
b3.place(x=px, y=py)

py = py + 50

b4 = tk.Button(
    root,
    text="Invia Con Cloud",
    bg=fondo_button2,
    font="arial, 12 bold",
    width=13,
    cursor="hand2",
    command=elaborazione_cloud,
)
b4.place(x=px, y=py)

py = py + 3
px = px + 150
e2 = tk.Entry(root, width=20, font="arial, 14", bg=fondo_entry, justify="center")
e2.insert(0, "Cartella cloud su PC")
e2.place(x=px, y=py)

py = py + -50
e3 = tk.Entry(root, width=20, font="arial, 14", bg=fondo_entry, justify="center")
e3.insert(0, "Non Disponibile")
e3.place(x=px, y=py)

# Carica l'immagine automaticamente quando la finestra si apre
carica_immagine()

root.mainloop()

E questo è il decodificatore

Python:
# Decodifica Messaggio Criptati
import tkinter as tk
from tkinter import *
from PIL import Image, ImageTk
import os
from tkinter import messagebox
from tkinter import simpledialog
from Crypto.Cipher import AES
from Crypto.Hash import SHA256
from math import gcd
from random import randint
import pickle
from tkinter import filedialog
import win32print
import win32ui
import win32con

programma_riceve_a='C:\\DCP/Dropbox/cartella_b'

apri_dati = simpledialog.askstring("USB", "Inserisci la porta USB se diversa da D")
if not apri_dati:
    apri_dati = "d"


# file_path = os.path.join(apri_dati)


usb_path = apri_dati + ":\\"
if os.path.exists(usb_path):
    try:
        storage_devices = os.listdir(usb_path)
    except FileNotFoundError:
        pass
else:
    messagebox.showwarning(
        "Attenzione", "Chiavetta USB non trovata nella lettera di unità " + apri_dati
    )
    quit()


def apri_file():
    global codice_selezionato, chiave, filename
    filename = filedialog.askopenfilename(
        title="Apri file",
        initialdir=programma_riceve_a,  # Cartella iniziale predefinita
        # filetypes=(("Tutti i File", "*.*"),("File di testo", "*.txt")),
    )

    if filename=='':
        prewin.destroy()
        quit() 

    if "\\" in filename:
        # Se il percorso utilizza '\', usa split('\\')
        semipsel = filename.split("\\")
    else:
        # Altrimenti, usa split('/')
        semipsel = filename.split("/")

    files = semipsel[-1].split("_")
    codice_selezionato = files[2]
    chiave_usb = os.path.join(apri_dati + ":", "chiave_" + codice_selezionato)

    if os.path.exists(chiave_usb):
        with open(chiave_usb, "r") as leggif:
            leggi1 = int(leggif.readline())
            leggi2 = int(leggif.readline())
            leggi3 = int(leggif.readline())
            chiave = leggi1**leggi2
            prewin.destroy()  # Chiude la finestra tkinter dopo aver selezionato il file
    else:
        messagebox.showerror("Errore", "Dati su USB non trovati")
        prewin.destroy()  # Chiude la finestra tkinter dopo aver selezionato il file
        quit()


def on_exit():
    prewin.destroy()
    quit()


prewin = tk.Tk()
larghezza = prewin.winfo_screenwidth()
altezza = prewin.winfo_screenheight()
prewin.title("Seleziona il File Da Decriptare")
prewin.configure(bg="orange")
prewin.geometry(f"{'300'}x{'100'}+{larghezza//2}+{altezza//3}")

label = tk.Label(
    prewin, text="Seleziona File per la Decodifica", bg="orange", font="arial 12 bold"
)
label.pack(pady=10)

select_button = tk.Button(prewin, width=10, text="APRI", bg="green", command=apri_file)
select_button.pack(pady=5)
prewin.protocol("WM_DELETE_WINDOW", on_exit)
prewin.mainloop()


def factorize(semiprime, chiave):
    a = semiprime % chiave
    b = semiprime - a
    for i in range(10):
        key = gcd(a, b)
        if key != 1:
            break
        a = a + chiave
        b = b - chiave
    return key


def generate_aes_key(prime_factor):
    hash_object = SHA256.new(data=str(prime_factor).encode())
    return hash_object.digest()

    # Stampa i dati letti


def decrypt_message(ciphertext, aes_key, nonce, tag):
    cipher = AES.new(aes_key, AES.MODE_GCM, nonce=nonce)
    plaintext = cipher.decrypt_and_verify(ciphertext, tag)
    return plaintext.decode()


def decodifica():

    path = programma_riceve_a+"/send_mess_" + codice_selezionato
    with open(path, "rb") as file:
        ciphertext, nonce, tag, semiprime = pickle.load(file)
    semiprime = int(semiprime)
    secret_key_received = factorize(semiprime, chiave)
    aes_key_received = generate_aes_key(secret_key_received)
    decrypted_message = decrypt_message(ciphertext, aes_key_received, nonce, tag)
    tw1.delete("1.0", END)
    tw1.insert("1.0", decrypted_message)


def carica_immagine():
    # Apri un'immagine utilizzando PIL
    img = Image.open("C:\\avviso/logo_a.jpg")

    # Converte l'immagine in un formato compatibile con Tkinter
    img_tk = ImageTk.PhotoImage(img)

    # Aggiungi l'immagine al canvas
    canvas.create_image(0, 0, anchor=tk.NW, image=img_tk)

    # Memorizza un riferimento all'immagine per evitare che venga eliminata dalla Garbage Collection
    canvas.image = img_tk


def on_enter(event):
    b1.config(
        bg=passa_button
    )  # Cambia il colore di sfondo a blu quando il mouse entra nel pulsante


def on_leave(event):
    b1.config(bg=fondo_button)  # Ripristina il colore di sfondo


def on_enter1(event):
    b2.config(
        bg=passa_button
    )  # Cambia il colore di sfondo a blu quando il mouse entra nel pulsante


def on_leave1(event):
    b2.config(bg=fondo_button)  # Ripristina il colore di sfondo


def cancella():
    tw1.delete("1.0", END)
    return


def stampa_messaggio():
    testo = tw1.get("1.0", tk.END).strip()
    if testo == "":
        messagebox.showerror("Attenzione:", "Nessun testo Da stampare")
        return

    stampa(testo)


def stampa(testo):
    printer_name = win32print.GetDefaultPrinter()
    hprinter = win32print.OpenPrinter(printer_name)
    hdc = win32ui.CreateDC()
    hdc.CreatePrinterDC(printer_name)

    # Ottieni le dimensioni della pagina
    width = hdc.GetDeviceCaps(win32con.PHYSICALWIDTH)
    height = hdc.GetDeviceCaps(win32con.PHYSICALHEIGHT)

    # Calcola il numero massimo di caratteri per riga basato sulla larghezza della pagina
    max_chars_per_line = int(width / hdc.GetTextExtent("X")[0])

    # Dividi il testo in righe più corte
    lines = []
    line = ""
    for word in testo.split():
        if len(line) + len(word) + 1 <= max_chars_per_line:
            line += word + " "
        else:
            lines.append(line.strip())
            line = word + " "
    if line:
        lines.append(line.strip())

    hdc.StartDoc("Stampa")
    hdc.StartPage()

    # Stampare le righe di testo
    y = 100
    for line in lines:
        hdc.TextOut(100, y, line)
        y += hdc.GetTextExtent(line)[1]  # spazio per la prossima riga

    hdc.EndPage()
    hdc.EndDoc()
    hdc.DeleteDC()
    win32print.ClosePrinter(hprinter)
    if os.path.exists(filename):
        os.remove(filename)
    root.destroy()
    quit()


# *************************************************
# *       dimensione e colori
# *************************************************
finestra_x = 600
finestra_y = 500
finestra = str(finestra_x) + "x" + str(finestra_y)
fondo_finestra = "#6E8B3D"
fondo_text = "#808080"
fondo_button = "#20B2AA"
passa_button = "#C0FF3E"
fondo_button2 = "#71C671"
fondo_entry = "#C1C1C1"
# *************************************************
# *        Finestra principale
# *************************************************
root = tk.Tk()
root.title("Decodifica Documento Criptato  DDC")
root.geometry(finestra + "+1000+50")
root.config(bg=fondo_finestra)
# Creazione del canvas
px = finestra_x - 130
py = finestra_y - 130
canvas = tk.Canvas(root, width=130, height=130)
canvas.place(x=px, y=py)
px = 10
py = 10
tw1 = tk.Text(
    root, width=64, height=17, bg=fondo_text, font="helvetica, 12", cursor="left_ptr"
)
tw1.place(x=px, y=py)

px = 150
py = 330

b1 = tk.Button(
    root,
    text="Stampa",
    bg=fondo_button,
    font="arial, 12 bold",
    width=10,
    cursor="hand2",
    command=stampa_messaggio,
)
b1.place(x=px, y=py)
b1.bind("<Enter>", on_enter)
b1.bind("<Leave>", on_leave)

px = px + 150
py = 330

b2 = tk.Button(
    root,
    text="Cancella",
    bg=fondo_button,
    font="arial, 12 bold",
    width=10,
    cursor="hand2",
    command=cancella,
)
b2.place(x=px, y=py)
b2.bind("<Enter>", on_enter1)
b2.bind("<Leave>", on_leave1)

px = 20
py = 330 + 70

b3 = tk.Button(
    root,
    text="Decodifica da E-mail",
    bg=fondo_button2,
    font="arial, 12 bold",
    width=17,
    cursor="hand2",
    state="disabled",
)
b3.place(x=px, y=py)

py = py + 50

b4 = tk.Button(
    root,
    text="Decodifica da Cloud",
    bg=fondo_button2,
    font="arial, 12 bold",
    width=17,
    cursor="hand2",
    command=decodifica,
)
b4.place(x=px, y=py)

py = py + 3
px = px + 190
e2 = tk.Entry(root, width=25, font="arial, 12", bg=fondo_entry, justify="center")
e2.insert(0, filename)
e2.place(x=px, y=py)

py = py + -50
e3 = tk.Entry(root, width=20, font="arial, 14", bg=fondo_entry, justify="center")
e3.insert(0, "Non Disponibile")
e3.place(x=px, y=py)


# Carica l'immagine automaticamente quando la finestra si apre
carica_immagine()

root.mainloop()


I file dei semiprimi da 13000 e 12000 bit sono allegati

questa è la chiave per fattorizzare a tempo zero i semiprimo di 13076

6366805760909027985741435139224233
58
13076

questa è la chiave per i semiprimi a 12072

40967604360149386602897961230262027
52
12072
Messaggio unito automaticamente:

è possibile creare chiavi molto più grandi, quelle che ho provato erano multiple di 8 bit come chiavi a 8192 o 15360 bit. Per creare una coppia di chiavi a 4096 bit il mio pc ci mette qualche secondo, questione di minuti per chiavi a 15360 bit, per cosa intendi che ci sono voluti due mesi?



Perché il tuo algoritmo dovrebbe essere sicuro da un attacco quantistico con una chiave a 5000 bit? Non penso funzioni così, ci sarà un motivo se il NIST ha selezionato e continua a cercare algoritmi post-quantum.


Del tuo algoritmo non ho capito molte cose e come fa a ottenerle tipo:


taggo @St3ve che magari saprà aiutare.
Chiedo scusa, avevi ragione. La mia era una notizia sbagliata quella dei due mesi.
 

Allegati

  • 13076b.txt
    38.3 KB · Visualizzazioni: 2
  • 12072b.txt
    35.5 KB · Visualizzazioni: 1
e questa è la chiave per fattorizzare a tempo zero il semiprimo
6366805760909027985741435139224233
58
13076
Questa è la parte importante. O almeno lo sono i primi due numeri, visto che non ho capito bene a cosa ti serve il terzo. In che modo generi questi numeri? Se puoi, posta il codice, perché questa è veramente la parte più importante non visibile dal codice che hai postato. Idealmente dovremmo capire il modo in cui generi quei numeri lì e il modo in cui calcoli la coppia di numeri primi a partire (presuppongo) da questa chiave.

Comunque, citando le tue stesse parole, questa è la chiave. Letteralmente. Se io ho i primi due numeri che hai scritto nella parte di messaggio che ho citato, riesco a fattorizzare in tempo zero il numerone che hai scritto sopra. Quindi, alla peggio, proprio senza sapere quello che faccio, devo provare tutti i numeri finché non li trovo. In RSA 2048 la chiave è di circa 1024 bit, nel tuo algoritmo la chiave è di
$$\[\lceil \lg(6366805760909027985741435139224233) + \lg(58) \rceil = 118 \text{bits}$$\]che è comunque un numero grande, ma certo intimorisce molto meno. Adesso bisogna capire in che modo scegli quei due numeri, ma è piuttosto chiaro che quello che stai facendo è, vagamente, una variante di RSA dove i numeri primi non sono scelti "a caso con qualche accortezza" (come ho spiegato nella guida), ma sono scelti con un criterio ben preciso e potenzialmente anche molto fragile. Praticamente, oltre a essere esposto agli attacchi basati sulla fattorizzazione (come RSA), sei anche esposto agli attacchi che mirano a trovare questa chiave di 118 bit. In un certo senso non importa se i tuoi numeri primi sono astronomici, fossero anche 100000 bit, perché la chiave alla fine non lo è.

Nota: In RSA 2048 la chiave (i.e., il numero primo) è di circa 1024 bit, ma la sicurezza (anch'essa misurata in bit) è ben inferiore. Nel tuo algoritmo vale lo stesso discorso. Se hai una chiave di 118 bit non puoi avere una sicurezza superiore a 118 bit, ma realisticamente (sicuramente) il tuo algoritmo è molto più insicuro.
 
Comunque, citando le tue stesse parole, questa è la chiave. Letteralmente. Se io ho i primi due numeri che hai scritto nella parte di messaggio che ho citato, riesco a fattorizzare in tempo zero il numerone che hai scritto sopra. Quindi, alla peggio, proprio senza sapere quello che faccio, devo provare tutti i numeri finché non li trovo. In RSA 2048 la chiave è di circa 1024 bit, nel tuo algoritmo la chiave è di
Mi spieghi cosa intendi? La chiave è 6513 bit perchè se guardi il programma la chiave è 6366805760909027985741435139224233^58. La chiave è chiaramente l'elemento segreto che non và assolutamente reso pubblico, come la chiave privata di RSA. Di chiavi ne esistono infinite per ogni bit che intendi creare. Qui per esempio parliamo di semiprimi a 13076 bit, puoi creare infinite chiavi con dimensioni analoghe a queste
Per quanto riguarda la scelta random, prova a calcolare che i fattori primi che vengono generati per creare il semiprimo, vengono generati in un campo random di 2^275, in questo caso specifico, ma potrebbero essere generati in un campo di 2^500 o maggiore. Questo vuol dire che la tua chiave fattorizza a tempo zero qualsiasi semiprimi generato in questo campo. Se provi a fare una stima, potresti criptare lo stesso messaggio per miliardi di volte generando sempre una codifica diversa.

Mi piacerebbe che tu provassi il programma per verificarne le potenzialità. Se non vuoi impostare tutte queste cartelle dimmelo che ti do i primi programmi con cui ho eseguito i primi test e che usano solo una cartella di prova, non condivisa. Se hai bisogno che ti passi lelenco delle librerie usate dal programma te le posto qui

Di seguito pubblicherò anche lo script che crea le chiavi.
 
Mi spieghi cosa intendi? La chiave è 6513 bit perchè se guardi il programma la chiave è 6366805760909027985741435139224233^58.
Non è in quel modo che si calcola l'entropia. È vero che $$\(6366805760909027985741435139224233^{58}$$\) è un numero grande, ma non è un numero qualunque. È un numero nella forma $$\(x^y$$\). Se tu mi trasmetti la coppia $$\((x,y)$$\), che sono 118 bit di informazione, io posso calcolare quel numerone che tu dici essere di 6513 bit. Per farti capire meglio di cosa sto parlando, cosa dovrei fare per attaccare il tuo algoritmo vs. l'algoritmo RSA?
  • Nel tuo algoritmo, procedendo in modo molto ignorante, con un bruteforce secco, mi basta provare tutte le coppie $$\((x,y)$$\) finché non trovo quella giusta. Per ognuna di queste coppie, calcolo $$\(x^y$$\) e butto questo numero dentro la tua funzione factorize per vedere cosa succede. Prima o poi funzionerà.
  • In RSA, sempre in modo molto ignorante, con un bruteforce, dovrei provare tutti i numeri primi da 2 fino a un numeraccio di 1024 bit. A essere un po' meno fessi potrei testare soltanto i numeri primi di 1024 bit, ma non cambierebbe quasi niente perché, a conti fatti, ucciderei soltanto un bit. Nella pratica l'algoritmo ignorante si chiama trial division, e prova tutti i numeri dispari invece che solo i numeri primi, perché generare un numero primo è più impegnativo di fare una divisione e vedere cosa succede.
Quello che voglio farti capire è che i numeri primi scelti da RSA sono essenzialmente random, mentre i numeri primi scelti dal tuo algoritmo derivano da una coppia $$\((x, y)$$\) di numeri relativamente piccoli: calcoli $$\(x^y$$\) e poi fai qualche manipolazione numerico-algoritmica per beccare due numeri primi che poi moltiplicherai tra loro. È una cosa completamente diversa. Se poi andiamo a usare un algoritmo serio invece che l'algoritmo ignorante, i bit di sicurezza di RSA colano a picco (ma non abbastanza da renderlo insicuro!) e i bit di sicurezza del tuo algoritmo seguiranno a ruota.

Mi piacerebbe che tu provassi il programma per verificarne le potenzialità. Se non vuoi impostare tutte queste cartelle dimmelo che ti do i primi programmi con cui ho eseguito i primi test e che usano solo una cartella di prova, non condivisa. Se hai bisogno che ti passi lelenco delle librerie usate dal programma te le posto qui
Che sia sicuro o meno, anzitutto ti faccio i complimenti per avere un programma fatto e finito. Su questo forum ho già incontrato gente che parla di algoritmi di fattorizzazione magici e super efficienti, ma poi si è sempre presentata con un pugno di mosche in mano perché ci vuole un certo impegno per realizzare la propria idea. Comunque sì, posso dargli un'occhiata. L'ideale sarebbe avere proprio il codice sorgente dei primi programmi "bozza", senza interfaccia grafica e altri fronzoli, in modo di ragionare sull'algoritmo senza farsi distrarre dal codice boilerplate che implementa la chat e tutto il resto.

Comunque un'idea di cosa sta succedendo me la sono fatta e, mi spiace deluderti, non è niente di particolarmente rilevante: hai un numero $$\(n=pq$$\) composto da due numeri primi $$\(p$$\) e $$\(q$$\) che non sono realmente random, ma sono stati generati in qualche modo attraverso un numero $$\(x^y$$\). Anche senza avere $$\(p$$\) e $$\(q$$\), chiaramente riesci a fattorizzare $$\(n$$\) molto velocemente.
 
Ultima modifica:
Innanzi tutto grazie, ci tengo veramente a sapere il tuo parere. Anzi, visto la tua competenza mi piacerebbe anche provare a testare il programma con due persone distanti. Soprattutto la velocità con cui si può dialogore in piena sicurezza. Naturalmente, se ti va.
Comunque un'idea di cosa sta succedendo me la sono fatta e, mi spiace deluderti, non è niente di particolarmente rilevante: hai un numero composto da due numeri primi e che non sono realmente random, ma sono stati generati in qualche modo attraverso un numero . Anche senza avere e , chiaramente riesci a fattorizzare molto velocemente.
Su questo dissento un po' perchè:
1)neanche gli RSA sono totalmente random perchè devono rispettare determinate regole
2)I fattori primi che utilizzo io partono si da una base n^e ma la x che viene aggiunta ha un campo enorme ed è come se tu dovessi cercare un fattore primo da 0 a 2^500 però partendo, non da zero, ma da un numero grandissimo. Questo porta una certa difficoltà di calcolo
3)Supponi di dover cercare la chiave per fattorizzare il semiprimo, non il fattore primo che sarebbe enorme, ma solo la chiave. in questo caso la chiave è un numero primo di 34 cifre elevato alla 58. Per riuscire a indovinare la chiave mi dovresti prima di tutto indovinare il fattore primo o cercarlo con la forza bruta, ma ad ogni fattore primo che controlli dovresti anche elevarlo a potenza per un tot di volte per cercare la potenza giusta.
4)quella chiave che ti ho mostrato è una chiave standard che io utilizzo per me, ma se volessi creare una chiave sicura, molto sicura, innanzi tutto alzerei i bit dei semiprimi portandoli a 20 30 40 mila, e poi utilizzarei un fattore primo RSA per creare la chiave elevata a potenza.

Questo esperimento l'ho già fatto, ho usato una fattore primo RSA elevato a potenza per dei semiprimi a 8000 bit. La cosa ha funzionato bene e la velocità non cambia, sempre a tempo zero.

Io sono convinto che queste chiavi siano molto complicate da trovare ma sicuramente anche in questo caso, come nel caso RSA, bisognerebbe individuare quali fattori primi sono più adatti..

Comunque. il progetto è aperto e sarei veramente onorato se tu, o altri come te, lo studiassero e cercassero di renderlo unico. Io vorrei che il progetto GC57 fosse libero e a disposizione di tutti. Se sei daccordo posterei nel dettaglio come si crea una chiave e il programma, sempre in python, che genera queste chiavi

Ti mostro la chiave creata con un fattore primo RSA. In questo caso il suo campo di fattorizzazione è 1.000.000.000*2^500 perciò un miliardo per 2 alla 500.
45781226558405483659061848084517523520699343530928680581341722632979022195694540925115045343036422766517577151510311704787018021623802339596981670905605736891^8
questa è la chiave per risolvere tutti i semiprimi che si trovano in quel campo e che verranno fattorizzati a tempo zero

Un'altra cosa che io ritengo importante e che si differenzia dai fattori primi RSA è che la distanza tra i due fattori primi che io utilizzo, può essere molto ampia, anzi, con più lo è con più il campo si allunga. Per esempio nel caso di 13076 bit, il fattore primo p è di circa 6000 bit, mentre il fattore primo q è maggiore di 7000 bit. Questo rende ancora più difficoltosa la ricerca.
 
Scusate, e scusa St3ve, mi sono lasciato trasportare un po' dall'entusiamo. Comunque la mia offerta rimane valida, se qualcuno vuole partecipare a questo progetto mettendoci la propria competenza, è ben accetto.