Skip to content

Latest commit

 

History

21 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FPGA RSA-SM4 Digital Envelope

English | 简体中文

An RSA-SM4 digital envelope implemented on a Zynq-7000 FPGA. The project combines an SM4 block cipher, Montgomery-based RSA modular exponentiation, and key encapsulation control in programmable logic. A BRAM/GPIO board interface, Vitis bare-metal application, and PyQt5 serial host complete the end-to-end path from host input to FPGA encryption and decryption.

From cryptographic RTL to Zynq board communication, this project delivers a well-structured and extensible digital envelope implementation for FPGA cryptographic acceleration, hardware-software co-design, and live demonstration.

Contents

Highlights

  • RSA-SM4 hybrid encryption — SM4 processes 128-bit data blocks while RSA encapsulates the 128-bit SM4 session key.
  • All-RTL cryptographic core — RSA modular exponentiation, Montgomery reduction, SM4 key expansion, all 32 rounds, and the control state machines are implemented in Verilog.
  • Pipelined SM4 datapath — the fully unrolled 32-round pipeline produces the corresponding out_sync approximately 32 clock cycles after in_sync.
  • Zynq PS/PL co-design — the PS exchanges data through BRAM and controls PL operations through EMIO GPIO.
  • End-to-end demonstration stack — Vitis bare-metal firmware, a Windows serial GUI, a prebuilt host executable, and a generated bitstream are included.

How It Works

A digital envelope combines the throughput of symmetric encryption with the key distribution capabilities of public-key cryptography.

Encryption

  1. The PL generates a 128-bit SM4 session key.
  2. The session key is split into two 64-bit segments and sent to the RSA modular exponentiation unit.
  3. Two 65-bit RSA results are concatenated into the 130-bit encrypted key CMKey.
  4. The SM4 key expansion module generates 32 round keys.
  5. Plaintext enters the SM4 encryption pipeline in 128-bit blocks.
  6. The board wrapper writes CMKey and the SM4 ciphertext back to BRAM.

Encryption timing

Decryption

  1. The 130-bit CMKey is read from BRAM or supplied through the de_cmkey interface.
  2. The two RSA ciphertext segments are processed sequentially to recover the 128-bit SM4 session key.
  3. The key expansion module supplies the SM4 round keys in reverse order.
  4. Ciphertext enters the SM4 decryption pipeline in 128-bit blocks and the recovered data is produced.

Decryption timing

System Architecture

┌──────────────────────── Windows Host ────────────────────────┐
│  PyQt5 serial GUI: select port, send data, display results   │
└───────────────────────────┬───────────────────────────────────┘
                            │ UART, 115200 baud by default
┌───────────────────────────▼───────────────────────────────────┐
│ Zynq Processing System                                       │
│  Vitis bare-metal app: commands, BRAM access, EMIO GPIO      │
└───────────────┬───────────────────────────────┬───────────────┘
                │ BRAM                          │ start/mode/done/reset
┌───────────────▼───────────────────────────────▼───────────────┐
│ Programmable Logic                                           │
│  envelope_top                                                │
│    ├── rdm_gen        128-bit session-key generator          │
│    ├── mod_exp        RSA modular exponentiation control     │
│    │    └── redc_x    Montgomery reduction                   │
│    └── sm4_top_parallel                                      │
│         ├── key_expansion_parallel   32-round key expansion  │
│         └── sm4_encdec_parallel      32-round data pipeline  │
└───────────────────────────────────────────────────────────────┘

The project provides two top-level integration options:

  • RSA-SM4/RSA-SM4_top.v is a streaming top level for integrating the cryptographic core into another RTL design. It directly exposes the encrypted session key and 128-bit data interfaces.
  • board_test/source_1/imports/RSA-SM4/evlp_top.v is the Zynq demonstration top level. It adds BRAM transfers, GPIO handshaking, and multi-block control.

Repository Structure

.
├── RSA-SM4/                       # Standalone cryptographic core
│   ├── RSA-SM4_top.v              # Streaming RSA-SM4 top level
│   ├── RSA/                       # RSA exponentiation and Montgomery reduction
│   └── SM4/                       # Constants, rounds, key expansion, and datapath
├── board_test/source_1/
│   ├── imports/RSA-SM4/           # Board wrapper and RTL source snapshot
│   ├── ip/blk_mem_gen_0/          # 32-bit × 1024-word BRAM configuration
│   └── new/cipher.coe             # BRAM initialization example
├── vitis/src/main.c               # Zynq PS bare-metal control application
├── Uart-host/                     # PyQt5 serial host and Windows executable
├── bit_stream/                    # Generated FPGA bitstream
├── Documents/                     # Timing, utilization, power, and interface figures
└── LICENSE                        # GNU AGPL-3.0

RSA-SM4/ contains the standalone core for module-level reuse, while board_test/.../RSA-SM4/ organizes the RTL around the complete Zynq board datapath.

RTL Integration

Streaming Top-Level Interface

RSA_SM4_top embeds the cryptographic core into a larger RTL design:

Signal Direction Width Description
clk Input 1 Operating clock
rst_n Input 1 Active-low asynchronous reset
crypt_pre Input 1 Start pulse, asserted for one clock cycle
den_sel Input 1 Mode select: 0 encrypt, 1 decrypt; hold stable during an operation
crypt_ready Output 1 RSA processing and SM4 key expansion complete
de_cmkey Input 130 RSA-encapsulated session key used for decryption
en_cmkey Output 130 RSA-encapsulated session key produced during encryption
input_stream Input 128 SM4 input block
output_stream Output 128 SM4 output block

The SM4 submodule uses in_sync and out_sync as data-valid markers, making it easy to connect to an upstream data source, FIFO, or another streaming module.

RSA Parameters

The default RSA parameters are defined in RSA-SM4/RSA/mod_exp.v:

Parameter Default Description
n 21536215303153667899 65-bit modulus
e 17 Public exponent
d 11401525742632630793 Private exponent
q 1411149436910194189 Montgomery precomputed parameter
r2 15661607970342841481 Montgomery precomputed parameter

To customize the RSA key, configure n, e, d, and the Montgomery precomputed parameters together for the target datapath width.

Board-Level GPIO Mapping

envelope_top and the Vitis application use the following EMIO signals:

Function PL Signal PS Pin Active Level
Start GPIO_in[0] 54 High pulse
Mode GPIO_in[1] 55 0 encrypt, 1 decrypt
Done GPIO_out[1] 56 Active high
Reset GPIO_in[3] 57 A high PS output resets the PL logic

The Vitis example accesses BRAM through XPAR_BRAM_0_BASEADDR; the original project address shown in the source comments is 0x40000000. Use the xparameters.h generated for the target platform when porting the design.

Board Data Protocol

The board wrapper stores one digital envelope using the following byte layout:

Byte Offset Logical Bit Range Content
0..19 0..159 160-bit envelope header: two RSA key-cipher segments occupy the first 130 bits and the remaining 30 bits provide alignment
20.. 160.. SM4 ciphertext, beginning at BRAM address 20

The BRAM IP is configured for a 32-bit data width and a depth of 1024 words. The board controller assembles every four words into one 128-bit SM4 block and writes the result with all byte lanes enabled.

The serial protocol uses a simple two-stage text exchange:

Encrypt: host sends "0\n" -> waits about 1 second -> sends plaintext and newline
Decrypt: host sends "1\n" -> waits about 1 second -> sends envelope hex and newline

After an operation completes, the Vitis application returns the result through standard output. Encryption produces a continuous hexadecimal envelope; decryption produces the recovered text.

Implementation Results

Timing

All user-specified timing constraints are met, with a Setup WNS of 5.839 ns and a Hold WHS of 0.117 ns.

Timing report

Power

The post-synthesis on-chip power estimate is 0.426 W, consisting of 0.317 W dynamic power and 0.109 W static power, demonstrating an efficient FPGA cryptographic datapath.

Power report

Utilization

RSA_SM4_top uses 8,878 Slice LUTs, 7,106 Slice Registers, and 74 DSPs. On the xc7z020, these figures correspond to approximately 16.7% of the available LUTs, 6.7% of the registers, and 33.6% of the DSPs, leaving ample capacity for additional control and communication logic.

Utilization report

Requirements

FPGA and Embedded Toolchain

  • ALINX Zynq-7000 development platform with an xc7z020 device
  • AMD/Xilinx Vivado with support for the included XCI
  • AMD/Xilinx Vitis for the Zynq bare-metal application
  • JTAG programmer and USB-to-UART connection

Use the included bitstream and host application for a quick end-to-end demonstration, or integrate the RTL, BRAM XCI, and Vitis source into a Zynq design with platform-specific PS, BRAM, GPIO, UART, and address-map settings.

Host

  • Windows
  • USB-to-UART driver
  • Prebuilt Uart-host/main.exe

Quick Start

1. Get the Project

git clone https://github.com/7urtle/FPGA-RSA-SM4-Digital-Envelope.git
cd FPGA-RSA-SM4-Digital-Envelope

2. Prepare the Board

  1. Connect to the xc7z020 device in Vivado Hardware Manager.
  2. Program the PL with bit_stream/digital_envelope_host_sucess.bit or a locally generated bitstream.
  3. Build and run vitis/src/main.c on the matching Vitis hardware platform.
  4. Connect the board UART and confirm that Ready: appears in the terminal.

3. Connect the Host

  1. Run Uart-host/main.exe.
  2. Select Refresh and choose the board's serial port.
  3. Connect with the default 115200 / 8-N-1 settings.
  4. Enter the data and select Encrypt or Decrypt.
  5. Read the FPGA result in the receive area.

Host Application

The GUI provides serial-port discovery, baud-rate/data-bit/stop-bit/parity settings, character encoding, hexadecimal send/receive modes, and dedicated encryption and decryption controls. Its default configuration is:

Baud rate: 115200
Data bits: 8
Stop bits: 1
Parity: None
Encoding: UTF-8
  • Encrypt — enter plaintext without spaces and select Encrypt. The receive area displays the hexadecimal envelope containing the encapsulated key and SM4 ciphertext.
  • Decrypt — paste the complete hexadecimal envelope and select Decrypt. The receive area displays the recovered plaintext.
  • Hexadecimal options — these options control raw byte conversion at the serial layer. Leave them disabled for the standard button workflow so that 0, 1, and newline characters are transmitted as text.

License and Acknowledgments

This project is released under the GNU Affero General Public License v3.0. Review the complete license before copying, modifying, or distributing the project.

The serial host is based in part on PyQt-multifunctional-uart-helper. Thanks to its original author for the foundation.

About

A RSA-SM4 digital envelope based on Zynq-7000s board.

Topics

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages