This project consists of an 8-bit RSA verilog design that implements the RSA (https://en.wikipedia.org/wiki/RSA_(cryptosystem)) encryption/decryption scheme with an 8-bit private/public key size.
The design implements modular exponentiation (https://en.wikipedia.org/wiki/Modular_exponentiation) through a series of Montgomery modular multiplication (https://en.wikipedia.org/wiki/Montgomery_modular_multiplication) to encrypt/decrypt a message using an 8-bit key.
Due to I/O constraints, a SPI slave peripheral has been created to load/read data into/from the design.
The SPI Slave peripheral implementation supports all 4 SPI mode of operations (CPOL is configurable through ui[2] and CPHA is configurable through ui[3]), 8 Configurable (Read/Write) 8-bit registers and 8 Status (Read only) 8-bit registers.
The RP2040 SPI1 peripheral shall be used to communicate with the RSA core. Configure RP2040 SPI1 peripheral to GPIOs 24 to 27.
Address | Type of register |
---|---|
0 | Configurable Read/Write register [0] |
1 | Configurable Read/Write register [1] - bit[1] Stop, bit[0] Start - Rising edge detector to trigger encryption/decryption |
2 | Configurable Read/Write register [2] - Plain text [7:0] |
3 | Configurable Read/Write register [3] - E [7:0] |
4 | Configurable Read/Write register [4] - M [7:0] |
5 | Configurable Read/Write register [5] - Montgomery Constant [7:0] |
6 | Configurable Read/Write register [6] |
7 | Configurable Read/Write register [7] - Spare [7:0] - Connected to 7-segment Display |
8 | Status Read Only register [0] - bit[0] IRQ - Encryption/decryption completed |
9 | Status Read Only register [1] - Fixed data 8'hC4 |
10 | Status Read Only register [2] - Fixed data 8'h10 |
11 | Status Read Only register [3] - Fixed data 8'hDE |
12 | Status Read Only register [4] - Fixed data 8'hAD |
13 | Status Read Only register [5] - Fixed data 8'h00 |
14 | Status Read Only register [6] - Encrypted/Decrypted data [7:0] |
15 | Status Read Only register [7] - Fixed data 8'hFF |
RP2040 SPI Master <--SPI--> SPI_WRAPPER <--regaccess--> User logic (RSA)
Bit: | <15> <14> <13> <12> <11> <10> <9> <8> <7> <6> <5> <4> <3> <2> <1> <0> |
MOSI: | 1 | Don't Care | Don't Care | Don't Care | addr[3] | addr[2] | addr[1] | addr[0] | data[7] | data[6] | data[5] | data[4] | data[3] | data[2] | data[1] | data[0] |
MISO: | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
CS: 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1
Bit: | <15> <14> <13> <12> <11> <10> <9> <8> <7> <6> <5> <4> <3> <2> <1> <0> |
MOSI: | 0 | Don't Care | Don't Care | Don't Care | addr[3] | addr[2] | addr[1] | addr[0] | Don't Care | Don't Care | Don't Care | Don't Care | Don't Care | Don't Care | Don't Care | Don't Care |
MISO: | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | data[addr][7] | data[addr][6] | data[addr][5] | data[addr][4] | data[addr][3] | data[addr][2] | data[addr][1] | data[addr][0] |
CS: 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1
Key generation example:
Private key {e, n} = {11, 91}
Public key {d, n} = {59, 91}
The plain text is limited to a number in the interval [0:91[, as per this example. Since the design uses the Montgomery mutiplication, a Montgomery Constant shall be used to map the plain text into the Montgomery integer domain.
Const = (2 ** (2 * hwbits)) mod n, where hwbits = (8 (RSA max key-lenght core support) + 2).
Const = (2 ** (2 * (8+2))) mod 91 = 74
Now, use SPI Master peripheral in RP2040 to start communication on SPI interface towards this design. Remember to configure the SPI mode in the RP2040 accordingly.
Steps for start an/a encryption/decryption process:
12 ^ 11 mod 91 = 743008370688 mod 91 = 38
https://github.com/calonso88/tt09_rsa/blob/main/test/test.py implements a self-checking test that verify the encrypted data produced by the RSA core against the predicted values produced locally on the test. The test randomize the elements for key generation and the plain text. All derived values needed for the encryption/decryption are calculated locally in the test through helper functions.
Not required.
# | Input | Output | Bidirectional |
---|---|---|---|
0 | gpio_start | spare[0] | irq |
1 | gpio_stop | spare[1] | ui[4] |
2 | cpol | spare[2] | ui[5] |
3 | cpha | spare[3] | spi_miso |
4 | spare[4] | spi_cs_n | |
5 | spare[5] | spi_clk | |
6 | spare[6] | spi_mosi | |
7 | spare[7] | ui[7] |