Skip to content

Commit

Permalink
Merge pull request #7 from marph91/add-usage-and-documentation
Browse files Browse the repository at this point in the history
Add usage and documentation
  • Loading branch information
marph91 authored Aug 8, 2021
2 parents 690cbbc + 253a473 commit 43fdc85
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 85 deletions.
44 changes: 32 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@

VHDL implementation of the symmetric block cipher AES, as specified in the [NIST FIPS 197](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.197.pdf), respectively [NIST SP 800-38A](https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf).

Currently supported:
Features:

- Interface bitwidth of 8, 32 and 128.
- Key bitwidth of 128 and 256, i. e. AES-128 and AES-256.
- Interface width of 8, 32 and 128 bit.
- Key width of 128 and 256 bit, i. e. AES-128 and AES-256.
- The following modes:

| Mode | Encryption | Decryption |
Expand All @@ -21,17 +21,37 @@ Currently supported:
| OFB | :heavy_check_mark: | :heavy_check_mark: |
| CTR | :x: | :x: |

## Example results
Development status:

The following results are obtained from a synthesis with Xilinx Vivado. For synthesis results with ghdl, yosys and nextpnr, you can check the github actions workflow.
- [x] VHDL design
- [x] Functional simulation
- [x] Implementation
- [ ] Test on FPGA (it was reported that the design was successfully ran on an Altera Max 10 Board at 50 MHz)

- Device: Xilinx Zynq 7010
- Configuration: AES-256 encryption in ECB mode with an interface bitwidth of 32 bit
## Usage

The core expects key, iv (optional) and plaintext/ciphertext (depending if encrypting or decrypting) through `islv_data`. A new set of key and iv should be signalised by assigning `isl_new_key_iv` for one cycle. Valid inputs should be marked by assigning the `isl_valid` signal. Accordingly, the output `oslv_data` is valid when the signal `osl_valid` is assigned. New input data can be transmitted only when the output is fully done.

Example for AES-256 encryption in CFB mode with an interface bitwidth of 32 bit:

![AES toplevel waveform](https://svg.wavedrom.com/github/marph91/yaaes/add-usage-and-documentation/doc/aes_toplevel_waveform.json)

## Resource usage

The following results are obtained from a local synthesis for Lattice ECP5, using the open source toolchain (ghdl, yosys and nextpnr). For more details, see the synthesis workflow.

- Device: ULX3S
- Configuration: as in the example above
- Results:
- latency: 36 cycles (after initial key transmission)
- 1353 LUT, 1242 FF
- 0.171 ns worst negative slack at 200 MHz
- Resources:
- TRELLIS_SLICE: 3109/41820 7%
- DCCA: 1/ 56 1%
- Target frequency: 100 MHz
- Maximum frequency: 121 MHz

## Performance

## Testsuite
From the testsuite runs, the following metrics can be derived (configuration as above):

The requirements for running the testsuite are [GHDL](https://github.com/tgingold/ghdl), [VUnit](https://github.com/vunit/vunit) and [Pycryptodome](https://github.com/Legrandin/pycryptodome). To run the testsuite itself, simply execute `cd sim/vunit && ./run.py`.
- Latency: 37 cycles (after initial key and iv transmission)
- Throughput: One input of 128 bit each 42 cycles → 3 bit per clock cycle → 300 Mbps at 100 MHz
40 changes: 40 additions & 0 deletions doc/aes_toplevel_waveform.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"signal": [
{
"name": "isl_clk",
"wave": "p..................|.........|....."
},
{},
{
"name": "isl_new_key_iv",
"wave": "010................|.........|....."
},
{
"name": "isl_valid",
"wave": "0.1...............0|....1...0|....."
},
{
"name": "islv_data",
"wave": "x.3.......4...5...x|....5...x|.....",
"data": [
"key",
"iv",
"first plaintext",
"next plaintext"
]
},
{},
{
"name": "oslv_data",
"wave": "x..................|6...x....|6...x",
"data": [
"first ciphertext",
"next ciphertext"
]
},
{
"name": "osl_valid",
"wave": "0..................|1...0....|1...0"
}
]
}
4 changes: 2 additions & 2 deletions sim/vunit/aes/src/tb_aes.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ begin
port map (
isl_clk => sl_clk,
isl_valid => sl_valid_in,
islv_plaintext => slv_data_in,
islv_data => slv_data_in,
isl_new_key_iv => sl_new_key_iv,
oslv_ciphertext => slv_data_out,
oslv_data => slv_data_out,
osl_valid => sl_valid_out
);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env python3

"""Do selftests for the AES VHDL design."""
"""Do a loopback test for the AES VHDL design. I. e. encrypt and decrypt afterwards."""


import itertools
Expand All @@ -9,8 +9,8 @@


def create_test_suite(lib):
"""Create a testsuite for the aes selftests."""
tb_aes = lib.entity("tb_aes_selftest")
"""Create a testsuite for the aes loopback test."""
tb_aes = lib.entity("tb_aes_loopback")

# simulate two rounds of en- and decrypting for each chaining mode
test_params = itertools.product(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ library test_lib;
library vunit_lib;
context vunit_lib.vunit_context;

entity tb_aes_selftest is
entity tb_aes_loopback is
generic (
runner_cfg : string;

Expand All @@ -28,9 +28,9 @@ entity tb_aes_selftest is
G_IV : string;
G_BITWIDTH_KEY: integer
);
end entity tb_aes_selftest;
end entity tb_aes_loopback;

architecture rtl of tb_aes_selftest is
architecture rtl of tb_aes_loopback is
constant C_CLK_PERIOD : time := 10 ns;
signal sl_clk : std_logic := '0';

Expand Down Expand Up @@ -63,9 +63,9 @@ begin
port map (
isl_clk=> sl_clk,
isl_valid => r_encrypt.sl_valid_in,
islv_plaintext => r_encrypt.slv_data_in,
islv_data => r_encrypt.slv_data_in,
isl_new_key_iv => r_encrypt.sl_new_key_iv,
oslv_ciphertext => r_encrypt.slv_data_out,
oslv_data => r_encrypt.slv_data_out,
osl_valid => r_encrypt.sl_valid_out
);

Expand All @@ -80,9 +80,9 @@ begin
port map (
isl_clk => sl_clk,
isl_valid => r_decrypt.sl_valid_in,
islv_plaintext => r_decrypt.slv_data_in,
islv_data => r_decrypt.slv_data_in,
isl_new_key_iv => r_decrypt.sl_new_key_iv,
oslv_ciphertext => r_decrypt.slv_data_out,
oslv_data => r_decrypt.slv_data_out,
osl_valid => r_decrypt.sl_valid_out
);

Expand Down
Loading

0 comments on commit 43fdc85

Please sign in to comment.