# Function sm4ed

Source

    pub 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.

## §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]