Function core::arch::riscv64::sm4ed

source ·
pub unsafe fn sm4ed(rs1: u32, rs2: u32, const BS: u8) -> u32
🔬This is a nightly-only experimental API. (riscv_ext_intrinsics #114544)
Available on RISC-V RV64 and target feature zksed only.
Expand description

Accelerates the block encrypt/decrypt operation of the SM4 block cipher [5, 31].

Implements a T-tables in hardware style approach to accelerating the SM4 round function. A byte is extracted from rs2 based on bs, to which the SBox and linear layer transforms are applied, before the result is XOR’d with rs1 and written back to rd. This instruction exists on RV32 and RV64 base architectures. On RV64, the 32-bit result is sign extended to XLEN bits. This instruction must always be implemented such that its execution latency does not depend on the data being operated on.

Source: RISC-V Cryptography Extensions Volume I: Scalar & Entropy Source Instructions

Version: v1.0.1

Section: 3.43

§Note

The BS parameter is expected to be a constant value and only the bottom 2 bits of bs are used.

§Safety

This function is safe to use if the zksed target feature is present.

§Details

Accelerates the round function F in the SM4 block cipher algorithm

This instruction is included in extension Zksed. It’s defined as:

SM4ED(x, a, BS) = x ⊕ T(ai)
... where
ai = a.bytes[BS]
T(ai) = L(τ(ai))
bi = τ(ai) = SM4-S-Box(ai)
ci = L(bi) = bi ⊕ (bi ≪ 2) ⊕ (bi ≪ 10) ⊕ (bi ≪ 18) ⊕ (bi ≪ 24)
SM4ED = (ci ≪ (BS * 8)) ⊕ x

where represents 32-bit xor, and ≪ k represents rotate left by k bits. As is defined above, T is a combined transformation of non linear S-Box transform τ and linear layer transform L.

In the SM4 algorithm, the round function F is defined as:

F(x0, x1, x2, x3, rk) = x0 ⊕ T(x1 ⊕ x2 ⊕ x3 ⊕ rk)
... where
T(A) = L(τ(A))
B = τ(A) = (SM4-S-Box(a0), SM4-S-Box(a1), SM4-S-Box(a2), SM4-S-Box(a3))
C = L(B) = B ⊕ (B ≪ 2) ⊕ (B ≪ 10) ⊕ (B ≪ 18) ⊕ (B ≪ 24)

It can be implemented by sm4ed instruction like:

let a = x1 ^ x2 ^ x3 ^ rk;
let c0 = sm4ed(x0, a, 0);
let c1 = sm4ed(c0, a, 1); // c1 represents c[0..=1], etc.
let c2 = sm4ed(c1, a, 2);
let c3 = sm4ed(c2, a, 3);
return c3; // c3 represents c[0..=3]
Run