
Estensione ISA RISC-V per il calcolo segreto imposto dall'hardware utilizzando l'incapsulamento delle chiavi ML-KEM-512 e la crittografia SIMON-128, consentendo un'esecuzione data-oblivious con prestazioni quasi native.
<p align="center"> <img src="https://assets.kitploit.com/production/public/readmes/9608/67cb1dbfb4bdedcc5db7b59178bbc7a64f6e88cc7f73952ed87aad1b818d6698.png" alt="Mojo-V Logo" width="550"/> </p> # Mojo-V: Calcolo Segreto per RISC-V **Mojo-V** (pronunciato *“mojo-five”*) è una nuova estensione RISC-V che introduce capacità di programmazione orientate alla privacy per RISC-V. Mojo-V implementa il calcolo segreto, consentendo un'esecuzione sicura, efficiente e data-oblivious senza affidarsi a software fragili e alla fiducia del programmatore. Isolando i dati sensibili in registri segreti dedicati e cifrando la memoria con una chiave di terze parti, Mojo-V previene le divulgazioni e impone un calcolo che è sia cieco (nessuna divulgazione diretta) sia silenzioso (nessuna perdita tramite canali laterali). Il design si integra perfettamente nell'ISA RISC-V esistente con un solo bit di modalità e quattro nuove istruzioni, applicate interamente in fase di decodifica. I primi risultati mostrano velocità di esecuzione quasi native, offrendo al contempo un miglioramento delle prestazioni di oltre 5-7 ordini di grandezza rispetto alla crittografia completamente omomorfica (FHE), con una chiara tabella di marcia per l'integrazione in CPU, GPU e acceleratori specializzati. Per saperne di più... - Ecco un video introduttivo che descrive Mojo-V: https://www.youtube.com/watch?v=HUT46TcNyyM - Slide che forniscono una panoramica del progetto Mojo-V: https://drive.google.com/file/d/1VVzZqYHvQgnKMgXZjg7I_cX2GzF7awSN L'attuale specifica dell'estensione ISA Mojo-V (release 1.02): - [In formato PDF.] (https://drive.google.com/file/d/1yfiBqp0xyXD-S_G5d2o7Ggta5wI6nRot) Per contattare gli sviluppatori di Mojo-V: - Email: [[email protected]](mailto:[email protected]) # 🧩 Piattaforma di Riferimento Mojo-V — Release 1.03 ## 🚧 Stato del Progetto La piattaforma di riferimento Mojo-V release 1.03 implementa una piattaforma di riferimento basata sul simulatore Spike per RISC-V RV64GC e il compilatore EXO per la specifica ISA Mojo-V v1.02. L'implementazione attuale supporta modalità di cifratura veloce, forte e proof-carrying, insieme alla divulgazione sicura dei risultati di calcoli cifrati e alla generazione certificata di numeri casuali. La release include un'ampia gamma di test Mojo-V, benchmark orientati alla privacy e applicazioni dimostrative per la divulgazione sicura. Include inoltre la specifica completa dell'ISA Mojo-V e la documentazione per gli sviluppatori. Questa release è adatta all'uso come i) piattaforma di sviluppo di applicazioni Mojo-V, ii) golden model per la validazione di implementazioni hardware Mojo-V, e iii) implementazione di riferimento per l'analisi di sicurezza. Il lavoro attuale è focalizzato sullo sviluppo di i) un compilatore Mojo-V basato su LLVM, ii) un modello Mojo-V basato su gem5 per l'esplorazione e l'analisi architetturale, e iii) un'implementazione RTL SystemVerilog di riferimento CVA6 di RISC-V RV64GC con estensioni Mojo-V. **Versione della specifica:** 1.02 (Agosto 2026) **Contatto:** [[email protected]](mailto:[email protected]) ## Componenti attuali 1. **Specifica ISA Mojo-V v1.02** - rilasciata in `doc/` 2. **Spike (Instruction Set Simulator) con estensioni Mojo-V** - Mojo-V integrato in `riscv-isa-sim`, e completo per una CPU RV64GC con incapsulamento delle chiavi ML-KEM-512 per il caricamento dei data contract e crittografia simmetrica SIMON-128 per la protezione del calcolo segreto. - Per eseguire Spike con le estensioni Mojo-V abilitate, aggiungere il flag `--isa=rv64gc_zicond_zkmojov_zicntr` quando si esegue `spike` 3. **Data Contract Multi-tool** I data contract sono pacchetti cifrati che consentono all'hardware di una CPU Mojo-V di accedere alla chiave di accesso ai dati e alle informazioni di configurazione (ad es., modalità di cifratura della memoria) per un set di dati cifrati Mojo-V. Il DC Multi-tool abilita le seguenti capacità: * Gli sviluppatori hardware possono creare coppie di chiavi pubbliche/private ML-KEM512: le chiavi pubbliche sono condivise con i service provider, le chiavi private sono incorporate nell'implementazione hardware Mojo-V. * I proprietari dei dati possono creare data contract e cifrarli con le chiavi pubbliche ML-KEM512 dei service provider. L'hardware Mojo-V corrispondente può quindi eseguire calcolo segreto sui dati cifrati protetti di terze parti. 4. **Benchmark Mojo-V Bringup-Bench** - Batteria completa di test di sicurezza per RV64GC+Mojo-V - Batteria completa di test di attacco all'integrità per RV64GC+Mojo-V - Batteria completa di test delle librerie del compilatore EXO - Batterie complete di test delle librerie matematiche e di stringhe EXO - Numerosi benchmark orientati alla privacy costruiti con la libreria del compilatore EXO Mojo-V - Batteria completa di applicazioni dimostrative di divulgazione sicura - Batteria completa di applicazioni dimostrative di TRNG certificato - Esempi scritti a mano (ad es., bubble-sort) che mostrano Mojo-V nell'esecuzione di calcolo segreto Nota: il resto dei benchmark Bringup-bench non è ancora stato portato a Mojo-V. ## ⚙️ Compilazione ed Esecuzione della Piattaforma di Riferimento Mojo-V ### A. Installare un compilatore LLVM per RISC-V Avrai bisogno di un cross-compilatore RISC-V basato su LLVM in grado di produrre binari `RV64GC`. Ecco un buon punto di partenza: https://github.com/openssl/openssl ### B. Installare OpenSSL versione 3.6 o successiva Avrai bisogno di un'installazione per sviluppatori di OpenSSL versione 3.6 o successiva. Questa fornisce le librerie che implementano ML-KEM512, utilizzate da Spike per lo scambio protetto di chiavi. Ecco un buon punto di partenza: https://clang.llvm.org/get_started.html ### C. Clonare il repository Mojo-V```bash git clone https://github.com/toddmaustin/mojo-v.git cd mojo-v ``` ### D. Costruisci il simulatore Spike RISC-V con supporto Mojo-V```bash sudo apt-get install device-tree-compiler libboost-regex-dev libboost-system-dev cd riscv-isa-sim mkdir build cd build ../configure --prefix=$RISCV make ``` ### **E. Costruire e testare il Data Contract Multi-tool** I Data Contract sono pacchetti crittografati che consentono all'hardware di una CPU Mojo-V di accedere alla chiave di accesso ai dati e alle informazioni di configurazione (ad es. modalità di crittografia della memoria) per un dataset crittografato Mojo-V.``` cd dc-tool make clean build test ``` ### **E. Compilare ed eseguire i test benchmark Mojo-V Bringup-Bench** 1. **Compila il driver del dispositivo Spike** ```bash cd bringup-bench/target make ``` 2. **Configura il tuo compilatore** Modifica `../Makefile` e imposta `TARGET_CC` per il target `mojov` sulla posizione del tuo compilatore RISC-V basato su LVM Clang. 3. **Compila e testa i programmi di test Bringup-Bench** ```bash cd .. # go to the top-level bringup-bench directory make TARGET=mojov-spike mojov-tests # run all Mojo-V tests ``` In alternativa, puoi eseguire un singolo benchmark entrando nella sua directory ed eseguendo il seguente comando. ```bash cd ../mojov-test make TARGET=mojov-spike clean build test ``` ## 🧪 Panoramica dei test di Bringup-Bench Mojo-V | Program | Description | |:---------|:-------------| | `mojov-test` | Esempio introduttivo tratto dalle slide | | `mojov-test1` | Test di semantica dei registri segreti e della memoria cifrata | | `mojov-test2` | Benchmark di ordinamento a bolle intero data-oblivious scritto a mano con crittografia veloce Mojo-V (int,fast) | | `mojov-test3` | Benchmark di ordinamento a bolle a virgola mobile data-oblivious scritto a mano con crittografia veloce Mojo-V (fp,fast) | | `mojov-test4` | Benchmark di ordinamento a bolle intero data-oblivious scritto a mano con crittografia forte Mojo-V (int,strong) | | `mojov-test5` | Benchmark di ordinamento a bolle a virgola mobile data-oblivious scritto a mano con crittografia forte Mojo-V (fp,strong) | | `mojov-typetests` | Test di validazione del sistema di tipi per i tipi cifrati Mojo-V e l'uso della libreria EXO | | `mojov-pctests` | Suite di test di integrità scritta a mano per RV64GC+Mojo-V che include test positivi e negativi per il formato di cifratura proof-carrying di Mojo-V (proofcarrying) | | `mojov-sectests` | Suite di test di sicurezza scritta a mano per RV64GC+Mojo-V che include 130 test positivi + 245 negativi == 375 totali (int,fp,fast,strong) | | `mojov-stringtests` | Test di validazione della libreria EXO di stringhe cifrate per operazioni e confronti sicuri sulle stringhe | | `mojov-mathtests` | Test di validazione della libreria EXO di matematica cifrata per `_sincos`, `mojov_sin`, `mojov_cos`, `mojov_fabs`, `mojov_floor`, `mojov_pow`, `mojov_round` e `mojov_sqrt` | Questi benchmark di test dimostrano le regole ISA Mojo-V, il comportamento della libreria EXO e le semantiche di sicurezza. ## 🧪 Panoramica dei benchmark di Bringup-Bench Mojo-V L'attuale insieme di benchmark di bring-up include le seguenti applicazioni benchmark Mojo-V: | Program | Description | |:---------|:-------------| | `bitonic-sort` | Benchmark di ordinamento bitonico data-oblivious | | `bloom-filter` | Benchmark di appartenenza a un insieme tramite filtro di Bloom | | `bubble-sort` | Benchmark di ordinamento a bolle intero | | `bubble-sort-strong` | Benchmark di ordinamento a bolle intero configurato per la crittografia forte | | `chi-squared` | Benchmark statistico del chi-quadrato per la bontà di adattamento | | `distinctness` | Benchmark di analisi della distinzione (distinctness) | | `distinctness-Onlog2n` | Variante del benchmark di distinctness con strategia O(n log² n) | | `edit-distance` | Benchmark della distanza di editing (distanza tra stringhe) | | `eulers-approx` | Benchmark di approssimazione della costante/serie di Eulero | | `fft-int` | Benchmark FFT intero | | `flood-fill` | Benchmark flood-fill | | `flood-fill-On2` | Variante del benchmark flood-fill con comportamento O(n²) | | `fuzzy-match` | Benchmark di corrispondenza approssimata tra stringhe | | `gcd-list` | Benchmark del massimo comun divisore su una lista | | `gemm` | Benchmark di moltiplicazione generale di matrici | | `gemm-strong` | Benchmark GEMM configurato per la crittografia forte | | `grad-descent` | Benchmark di ottimizzazione con discesa del gradiente | | `heat-calc` | Benchmark di calcolo della trasmissione del calore/equazione del calore | | `heldkarp-tsp` | Benchmark del commesso viaggiatore con programmazione dinamica di Held-Karp su grafi cifrati | | `highlife` | Benchmark dell'automa cellulare HighLife con evoluzione cifrata dello stato della griglia | | `kadane` | Benchmark del massimo sottovettore (algoritmo di Kadane) | | `kalman-filter` | Benchmark del filtro di Kalman | | `kcore-decomp` | Benchmark di decomposizione in k-core di un grafo | | `kepler-calc` | Benchmark di calcolo numerico/equazione di Keplero | | `knapsack` | Benchmark di ottimizzazione dello zaino (knapsack) | | `lcs` | Benchmark data-oblivious della più lunga sottosequenza comune su stringhe cifrate | | `lda` | Benchmark di allocazione latente di Dirichlet (LDA) | | `manacher-lps` | Benchmark della più lunga sottostringa palindroma (algoritmo di Manacher) | | `mersenne` | Benchmark di calcolo dei numeri di Mersenne | | `minspan` | Benchmark della struttura di ricoprimento minima | | `monte-carlo` | Benchmark di simulazione Monte Carlo | | `moving-average` | Benchmark di analisi della media mobile | | `moving-average-fp64` | Benchmark di analisi della media mobile in FP64 | | `nbody-sim` | Benchmark di simulazione a N corpi | | `nonlinear-nn` | Benchmark di rete neurale non lineare | | `nr-solver` | Benchmark del risolutore di Newton-Raphson | | `ntt-kernel` | Benchmark del kernel di trasformata numerico-teorica (NTT) | | `packet-filter` | Benchmark di filtraggio dei pacchetti | | `pagerank` | Benchmark del grafo PageRank | | `parrondo` | Benchmark del processo/strategia di Parrondo | | `partition-equal` | Benchmark della partizione in sottoinsiemi a somma uguale (Partition Equal Subset Sum) su insiemi cifrati | | `pca-analysis` | Benchmark di analisi delle componenti principali | | `primal-test` | Benchmark di test di primalità | | `private-join` | Benchmark di join che preserva la privacy | | `psi` | Benchmark di intersezione privata di insiemi (PSI) | | `quartile-stats` | Benchmark di analisi dei tagli e delle medie dei quartili su dati cifrati | | `rabinkarp-search` | Benchmark di ricerca di pattern di Rabin-Karp | | `rad-to-deg` | Benchmark di conversione da radianti a gradi | | `randshell-sort` | Benchmark di Shell sort randomizzato | | `ransac` | Benchmark di adattamento del modello RANSAC | | `regex-match` | Benchmark di corrispondenza con espressioni regolari | | `risk-score` | Benchmark di analisi del punteggio di rischio | | `scrambled-compare` | Benchmark di confronto di stringhe scramble utilizzando la programmazione dinamica cifrata | | `seq-align` | Benchmark di allineamento globale di sequenze (Needleman-Wunsch) su stringhe cifrate | | `shortest-path` | Benchmark del percorso più breve su grafi | | `sieve` | Benchmark del crivello dei numeri primi | | `skeleton` | Benchmark scheletro/modello usato come baseline di bring-up | | `soundex` | Benchmark di codifica fonetica Soundex | | `string-search` | Benchmark di ricerca di stringhe | | `tea-cipher` | Benchmark del cifrario TEA | | `tiny-NN` | Benchmark di inferenza con rete neurale piccola | | `triangle-count` | Benchmark di conteggio dei triangoli in un grafo | | `variability-sample` | Benchmark di variabilità e statistiche campionarie | | `verlet` | Benchmark fisico di integrazione di Verlet | ## Panoramica dei dimostratori di divulgazione sicura Mojo-V Mojo-V include tre benchmark dimostrativi di divulgazione sicura in `bringup-bench`. Queste applicazioni utilizzano memoria cifrata proof-carrying e grant di dati cifrati per mostrare come un programma possa calcolare su input sensibili, divulgare solo risultati derivati esplicitamente autorizzati e intercettare i tentativi di riutilizzare un grant per un valore diverso, un input grezzo, un calcolo obsoleto, un grant manomesso o un predicato intermedio. | Program | Input sensibile | Divulgazioni autorizzate | Protezioni dimostrate | |:---------|:----------------|:------------------------|:--------------------------| | `private-auction` | Otto offerte private cifrate. | ID dell'offerente vincitore e valore dell'offerta vincente. | Trova l'offerta massima con confronti cifrati e `cmov()`, quindi valida i grant di dati per output. I casi negativi rifiutano grant non corrispondenti, la divulgazione grezza dell'offerta vincente, grant falsi o manomessi, grant obsoleti dopo la modifica dell'asta, valori derivati `winning_bid + 1` e predicati di confronto intermedi. | | `vote-tally` | Trentadue schede cifrate per tre candidati, incluse due schede non valide. | Conteggi aggregati per i candidati A, B e C, più predicati di validità delle singole schede. | Calcola tutti i conteggi dei candidati e i predicati di validità delle schede in forma cifrata. I casi negativi rifiutano l'uso di un grant di un conteggio per un altro conteggio, la divulgazione grezza delle schede, grant falsi o manomessi, grant obsoleti dopo la modifica delle schede, valori di conteggio derivati e predicati intermedi sulle schede. | | `gene-risk` | Otto dosaggi cifrati di marcatori SNP per un carico di lavoro genomico di rischio di esempio. | Un punteggio di rischio poligenico derivato e un intervallo di rischio basso/medio/alto. | Accumula un punteggio di rischio ponderato e deriva l'intervallo di rischio con predicati cifrati e `cmov()`. I casi negativi rifiutano l'uso incrociato dei grant di punteggio e intervallo, la divulgazione grezza dei marcatori, grant falsi o manomessi, grant obsoleti dopo la modifica del genoma, valori di punteggio derivati e predicati intermedi di alto rischio. | Ogni dimostratore è elencato in `MOJOV_DISCAPPS`, quindi fa parte della batteria di applicazioni di divulgazione sicura. Per eseguirne uno direttamente, entra nella directory del suo benchmark e usa il target Mojo-V, ad esempio:```bash cd bringup-bench/private-auction make TARGET=mojov-spike clean build test ``` Usare l'opzione `--mojov-arg=<n>` di Spike per selezionare il percorso positivo (`0`) o uno dei test di divulgazione negativi (`1` e superiori) quando si esegue manualmente un dimostratore. ## Panoramica dei dimostratori TRNG certificati Mojo-V Mojo-V include tre benchmark dimostrativi certificati di generatore di numeri veramente casuali (CERTRNG) in `bringup-bench`. Utilizzano siti `CERTRNG` distinti, calcolo cifrato con proof-carrying e nonce di richiesta per mostrare che un client può verificare dove valori casuali freschi sono entrati in una computazione approvata. I risultati rimangono cifrati fino alla convalida della ricevuta e al commitment. I casi negativi dimostrano che la casualità generata dal software, estrazioni mancanti o riutilizzate, assegnazioni di sito errate, richieste obsolete, grafi di computazione alterati e ricampionamento distorto non soddisfano la concessione onesta dei dati. Mostrano anche un limite importante: la casualità certificata da sola non può fermare il grinding se i risultati vengono divulgati (usando le istruzioni Mojo-V DISC o FDISC) prima del commitment. | Programma | Carico di lavoro casuale certificato | Comportamento positivo | Protezioni dimostrate | |:---------|:--------------------------|:------------------|:--------------------------| | `blind-audit` | Seleziona uno degli otto record di audit prendendo il minimo di otto priorità casuali distinte legate alla richiesta. | Certifica il grafo argmin fisso completo; mostra anche che le estrazioni non utilizzate non influiscono sulla ricevuta e che la divulgazione prematura abilita il grinding. | Rifiuta un obiettivo forzato, RNG software, un nonce mancante o obsoleto, riutilizzo di estrazioni, un candidato eliminato, siti scambiati e replay di una selezione precalcolata. | | `diffpriv-count` | Aggiunge rumore binomiale centrato, formato come differenza di due valori `Binomial(8, 1/2)` indipendenti, a un conteggio cifrato usando 16 siti casuali distinti. | Certifica il grafo preciso di generazione del rumore e di vincolo alla richiesta, mantenendo nascosti sia il rumore che la risposta fino alla convalida. | Rifiuta rumore omesso o indebolito, RNG software, ricampionamento favorevole e replay di richieste obsolete; la casualità non utilizzata non correlata rimane al di fuori della ricevuta. | | `certified-lotto` | Sceglie il partecipante idoneo con il punteggio più alto tra otto voci cifrate e usa priorità distinte legate alla richiesta per rompere i pareggi di punteggio. | Certifica ogni partecipante, sito casuale, mix di nonce e passo del torneo; dimostra anche il comportamento delle estrazioni non utilizzate e il pericolo di grinding da divulgazione prima del commitment. | Rifiuta un partecipante omesso, RNG software, un nonce saltato o obsoleto, riutilizzo di estrazioni, siti scambiati e un tie-breaker deterministico. | Questi dimostratori sono elencati in `MOJOV_CERTRNG_APPS`, quindi sono inclusi nella batteria di benchmark Mojo-V. Eseguine uno direttamente dalla sua directory, ad esempio:```bash cd bringup-bench/blind-audit make TARGET=mojov-spike clean build test ``` Usa l'opzione `--mojov-arg=<n>` di Spike quando esegui un dimostratore manualmente. Il caso `0` è il percorso onesto, i casi con numeri bassi sono controlli esplicativi riusciti, e i casi `10` e superiori sono attacchi che dovrebbero terminare con un'eccezione di sicurezza Mojo-V. La matrice esatta per ciascuna applicazione è documentata nel suo `README.md` locale del benchmark. ## 🛠️ Utilizzo del multi-tool per contratti dati Mojo-V Il multi-tool per contratti dati "dc-tool" viene utilizzato per creare e convalidare i contratti dati Mojo-V. Per creare una coppia di chiavi pubblica/privata ML-KEM512, esegui il seguente comando. Nota che la chiave pubblica deve essere condivisa con i fornitori di dati di terze parti per preparare i contratti dati. Le chiavi private vengono installate nell'hardware (o nel simulatore).```bash ./dc-tool keygen <pk_file> <sk_file> # public key in <pk_file>, private key in <sk_file> ``` Una volta che esiste una coppia di chiavi pubblica/privata, è quindi possibile creare contratti di dati crittografati. Un contratto di dati contiene una chiave di accesso ai dati crittografata (per consentire all'hardware Mojo-V di accedere a dati di terze parti) e una configurazione della modalità di memoria crittografata. Eseguire il seguente comando per creare un contratto di dati crittografato.```bash ./dc-tool dcgen <pk_file> {fast,strong,proof-carrying} <ct_file> # specify mem mode, contract in <ct_file> ``` Condividere un contratto dati cifrato con l'hardware Mojo-V che corrisponde alla chiave pubblica ML-KEM512 usata per cifrare il contratto consentirà alla CPU abilitata Mojo-V di eseguire calcoli segreti sui dati protetti di terze parti. Per verificare che il contratto cifrato sia valido, usa i seguenti comandi.```bash ./dc-tool dcchk <sk_file> <ct_file> # decrypt contract <ct_file> with secret key <sk_file> ./dc-tool dcchk-v <sk_file> <ct_file> # same as above, but also dump decrypted contents of <ct_file> ``` ## 🛠️ Opzioni specifiche di Mojo-V aggiunte al simulatore ISA RISC-V Spike Le seguenti opzioni sono state aggiunte a Spike, il simulatore ISA RISC-V standard.```bash --mojov-verbose Mojo-V setup processing is verbose --mojov-fast Use Mojo-V fast encryption mode (default mode) --mojov-strong Use Mojo-V strong encryption format (otherwise using data contract specified mode) --mojov-proofcarrying Use Mojo-V proof-carrying encryption format (otherwise use data contract specified mode) --mojov-arg=<n> Pass a numeric argument to a Mojo-V test code --mojov-pk=<pem_file> Load Mojo-V CPU public key from <pem_file> --mojov-sk=<pem_file> Load Mojo-V CPU secret key from <pem_file> ``` ## 🧠 Panoramica della programmazione Mojo-V Lo sviluppo software di Mojo-V utilizza attualmente la libreria del compilatore EXO e segue pratiche di codifica sicure e data-oblivious: 1. **Programmare con gli header della libreria EXO** - Includere `exo/mojov-exo.h` per accedere al framework di programmazione Mojo-V e alle astrazioni dei tipi cifrati. - Includere `exo/mojov-math.h` per accedere al supporto matematico cifrato e alle operazioni helper. 2. **Usare il calcolo data-oblivious per le variabili cifrate** - I valori cifrati devono essere manipolati con flusso di controllo e pattern di accesso alla memoria data-oblivious per preservare gli obiettivi di esecuzione silenziosa e resistenza ai canali laterali di Mojo-V. 3. **Seguire il tutorial di programmazione EXO** - Consultare la guida alla programmazione EXO: [exo/EXO-library-programming.md](https://github.com/toddmaustin/mojo-v/blob/main/exo/EXO-library-programming.md) 4. **Consultare i dettagli su struttura del compilatore e architettura nella documentazione EXO** - La struttura interna e il contesto progettuale per l'attuale approccio compilatore/libreria Mojo-V sono documentati in: [exo/EXO-library-overview.md](https://github.com/toddmaustin/mojo-v/blob/main/exo/EXO-library-overview.md) --- ## Licenze del codice Tutto il codice relativo a Mojo-V in questo repository è rilasciato sotto la licenza dello strumento che ha modificato (ad es., Spike, LLVM, Bringup-Bench). Si prega di consultare le rispettive directory degli strumenti per i dettagli sulle licenze. --- ## 💬 Domande e feedback Accogliamo con piacere contributi, segnalazioni di bug e suggerimenti! 📧 **Email:** [[email protected]](mailto:[email protected]) 🌐 **Home del progetto:** [https://github.com/toddmaustin/mojo-v](https://github.com/toddmaustin/mojo-v)