Skip to content

Commit

Permalink
Zvksed: add "vsm4k.vi" instruction
Browse files Browse the repository at this point in the history
Vector SM4 KeyExpansion, four rounds of the SM4 Key expansion
are performed.

Note: zvksed_box_lookup & zvksed_sm4_sbox are created to work with
32bit values since sbox_lookup & sm4_sbox are used for 8bit values.

The bits in uimm[4..3] are ignored. Round group numbers range from 0
to 7 and indicate which group of four round keys are being generated.

Signed-off-by: Charalampos Mitrodimas <[email protected]>
  • Loading branch information
Charalampos Mitrodimas committed May 4, 2023
1 parent cd3ab8d commit 077d173
Showing 1 changed file with 81 additions and 0 deletions.
81 changes: 81 additions & 0 deletions model/riscv_insts_zvksed.sail
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
* ----------------------------------------------------------------------
*/

val zvk_check_elements : (int, int, int, int) -> bool
function zvk_check_elements(VLEN, num_elem, LMUL, SEW) = {
((unsigned(vl)%num_elem) != 0) | ((unsigned(vstart)%num_elem) != 0) | (LMUL*VLEN) < (num_elem*SEW)
}

val rol32 : forall 'm, 32 - 'm >= 0 & 'm >= 0. (bits(32), int('m)) -> bits(32)
function rol32(X,N) = (X << N) | (X >> (32 - N))

Expand Down Expand Up @@ -51,3 +56,79 @@ function sm4_subword(x) = {
val sm4_round : (bits(32), bits(32)) -> bits(32)
function sm4_round(X, S) =
((X) ^ ((S) ^ rol32((S), 2) ^ rol32((S), 10) ^ rol32((S), 18) ^ rol32((S), 24)))

/* VSM4K.VI */

union clause ast = RISCV_VSM4K_VI : (regidx, bits(5), regidx)

mapping clause encdec = RISCV_VSM4K_VI(vs2, uimm, vd) if (haveRVV() & haveZvksed())
<-> 0b1000011 @ vs2 @ uimm @ 0b010 @ vd @ 0b1110111 if (haveRVV() & haveZvksed())

mapping clause assembly = RISCV_VSM4K_VI(vs2, uimm, vd)
<-> "vsm4k.vi" ^ spc() ^ vreg_name(vd)
^ sep() ^ vreg_name(vs2)
^ sep() ^ reg_name(uimm)

function clause execute (RISCV_VSM4K_VI(vs2, uimm, vd)) = {
let SEW = get_sew();
let LMUL_pow = get_lmul_pow();
let LMUL = if LMUL_pow < 0 then 0 else LMUL_pow;
let VLEN = int_power(2, get_vlen_pow());
let num_elem = get_num_elem(LMUL_pow, SEW);

if (zvk_check_elements(VLEN, num_elem, LMUL, SEW) == false)
then {
handle_illegal();
RETIRE_FAIL
} else {
let 'n = num_elem;
let 'm = SEW;
assert('m == 32);

let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2);
let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd);
result : vector('n, dec, bits('m)) = undefined;

rk : bits(128) = undefined;

B : bits(32) = zeros();
S : bits(32) = zeros();
rk7_to_rk4 : bits(128) = zeros();
rnd : bits(3) = uimm[2..0]; // Lower 3 bits

eg_len = (unsigned(vl) / 'n);
eg_start = (unsigned(vstart) / 'n);

foreach (i from eg_start to (eg_len - 1)) {
assert(0 <= ((i * 4) + 3) & ((i * 4) + 3) < 'n);
rk[31..0] = vs2_val[i*4+0];
rk[63..32] = vs2_val[i*4+1];
rk[95..64] = vs2_val[i*4+2];
rk[127..96] = vs2_val[i*4+3];

B = rk[63..32] ^ rk[95..64] ^ rk[127..96] ^ zvksed_sm4_sbox(to_bits(32, 4 * unsigned(rnd)));
S = sm4_subword(B);
rk7_to_rk4[31..0] = round_key(rk[31..0], S);

B = rk[95..64] ^ rk[127..96] ^ rk7_to_rk4[31..0] ^ zvksed_sm4_sbox(to_bits(32, 4 * unsigned(rnd) + 1));
S = sm4_subword(B);
rk7_to_rk4[63..32] = round_key(rk[63..32], S);

B = rk[127..96] ^ rk7_to_rk4[31..0] ^ rk7_to_rk4[63..32] ^ zvksed_sm4_sbox(to_bits(32, 4 * unsigned(rnd) + 2));
S = sm4_subword(B);
rk7_to_rk4[95..64] = round_key(rk[95..64], S);

B = rk7_to_rk4[31..0] ^ rk7_to_rk4[63..32] ^ rk7_to_rk4[95..64] ^ zvksed_sm4_sbox(to_bits(32, 4 * unsigned(rnd) + 3));
S = sm4_subword(B);
rk7_to_rk4[127..96] = round_key(rk[127..96], S);

result[i*4+0] = rk7_to_rk4[31..0];
result[i*4+1] = rk7_to_rk4[63..32];
result[i*4+2] = rk7_to_rk4[95..64];
result[i*4+3] = rk7_to_rk4[127..96];
};

write_single_vreg(num_elem, 'm, vd, result);
RETIRE_SUCCESS
}
}

0 comments on commit 077d173

Please sign in to comment.