Skip to content

Commit

Permalink
Zvksed: add "vsm4r.[vv,vs]" instructions
Browse files Browse the repository at this point in the history
Vector SM4 Rounds, four rounds of SM4 Encryption/Decryption are
performed.

The four words of current state are read in as a 4-element group from
'vd' and the round keys are read in from the corresponding 4-element
group in vs2 (vector-vector form) or the scalar element group in
vs2 (vector-scalar form). The next four words of state are generated
by iteratively XORing the last three words of the state with the
corresponding round key, performing a byte-wise substitution, and then
performing XORs between rotated versions of this value and the
corresponding current state.

Signed-off-by: Charalampos Mitrodimas <[email protected]>
  • Loading branch information
Charalampos Mitrodimas committed Mar 30, 2023
1 parent 54d13fc commit e1615cc
Showing 1 changed file with 83 additions and 0 deletions.
83 changes: 83 additions & 0 deletions model/riscv_insts_zvksed.sail
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,86 @@ function clause execute (RISCV_VSM4K_VI(vs2, uimm, vd)) = {
RETIRE_SUCCESS
}
}

/* VSM4R.[VV,VS] */

mapping vv_or_vs : string <-> bits(7) = {
"vv" <-> 0b1010001,
"vs" <-> 0b1010011,
}

mapping vsm4r_mnemonic : bits(7) <-> string = {
0b1010001 <-> "vsm4r.vv",
0b1010011 <-> "vsm4r.vs",
}

union clause ast = RISCV_VSM4R_VV_VS : (regidx, regidx, string)

mapping clause encdec = RISCV_VSM4R_VV_VS(vs2, vd, suffix) if (haveRVV() & haveZvksed())
<-> vv_or_vs(suffix) @ vs2 @ 0b10000 @ 0b010 @ vd @ 0b1110111 if (haveRVV() & haveZvksed())

mapping clause assembly = RISCV_VSM4R_VV_VS(vs2, vd, suffix)
<-> vsm4r_mnemonic(vv_or_vs(suffix)) ^ spc() ^ vreg_name(vd)
^ sep() ^ vreg_name(vs2)

function clause execute (RISCV_VSM4R_VV_VS(vs2, vd, suffix)) = {
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);
assert(0 <= 3 & 3 < 'n);

let vm_val : vector('n, dec, bool) = read_vmask(num_elem, 0b1, vreg_name("v0"));
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;
mask : vector('n, dec, bool) = undefined;

(result, mask) = init_masked_result(num_elem, SEW, LMUL_pow, vd_val, vm_val);

B : bits(32) = zeros();
S : bits(32) = zeros();

x7_to_x4 : bits(128) = zeros();

foreach (i from 0 to (num_elem - 1)) {
let keyelem = if suffix == "vv" then i else 0;
rk3_to_rk0 = to_bits(128, unsigned(vs2_val[keyelem]));
x3_to_x0 = to_bits(128, unsigned(vd_val[i]));

B = x3_to_x0[63..32] ^ x3_to_x0[95..64] ^ x3_to_x0[127..96] ^ rk3_to_rk0[31..0];
S = sm4_subword(B);
x7_to_x4[31..0] = sm4_round(x3_to_x0[31..0], S);

B = x3_to_x0[95..64] ^ x3_to_x0[127..96] ^ x7_to_x4[31..0] ^ rk3_to_rk0[63..32];
S = sm4_subword(B);
x7_to_x4[63..32] = sm4_round(x3_to_x0[63..32], S);

B = x3_to_x0[127..96] ^ x7_to_x4[31..0] ^ x7_to_x4[63..32] ^ rk3_to_rk0[95..64];
S = sm4_subword(B);
x7_to_x4[95..64] = sm4_round(x3_to_x0[95..64], S);

B = x7_to_x4[31..0] ^ x7_to_x4[63..32] ^ x7_to_x4[95..64] ^ rk3_to_rk0[127..96];
S = sm4_subword(B);
x7_to_x4[127..96] = sm4_round(x3_to_x0[127..96], S);

result[0] = x7_to_x4[31..0];
result[1] = x7_to_x4[63..32];
result[2] = x7_to_x4[95..64];
result[3] = x7_to_x4[127..96];
};

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

0 comments on commit e1615cc

Please sign in to comment.