[[insns-vaesd128, Vector AES-128 decrypt all-rounds]]
= vaesd128.[vv,vs]

Synopsis::
Vector AES-128 all rounds decryption instruction.

Mnemonic::
vaesd128.vv vd, vs2, vs1 +
vaesd128.vs vd, vs2, vs1

Encoding (Vector-Vector)::
[wavedrom, , svg]
....
{reg:[
{bits: 7, name: 'OP-V'},
{bits: 5, name: 'vd'},
{bits: 3, name: 'OPIVV'},
{bits: 5, name: 'vs1'},
{bits: 5, name: 'vs2'},
{bits: 1, name: '1'},
{bits: 6, name: 'funct6'},
]}
....

Encoding (Vector-Scalar)::
[wavedrom, , svg]
....
{reg:[
{bits: 7, name: 'OP-V'},
{bits: 5, name: 'vd'},
{bits: 3, name: 'OPMVV'},
{bits: 5, name: 'vs1'},
{bits: 5, name: 'vs2'},
{bits: 1, name: '1'},
{bits: 6, name: 'funct6'},
]}
....

Arguments::

[%autowidth]
[%header,cols="4,2,2,2,2,2"]
|===
|Register
|Direction
|EGW
|EGS 
|EEW
|Definition

| Vs1 | input  | 128  | 4 | 32 | Final Round key
| Vs2 | input  | 128  | 4 | 32 | Cipher text
| Vd  | output | 128  | 4 | 32 | Plain text 
|===

Description:: 
This instruction implements the entire AES-128 block cipher decryption
function. Starting with the final round key, it internally generates each of the earlier round keys
and performs each of the rounds.

It treats each `EGW=128` element group of `vd` as the plaintext
and `EGW=128` element group of `vs2` as the 128-bit encryption key.

The result (i.e. the plaintext) is written to `EGW=128` element groups of `vd`.

This instruction operates on element groups in the source and destination registers:

- Element Group Width (EGW) = 128 bits
- Effective Element Width (EEW) = 32 bits
- Element Group Size (EGS) = 4 elements

This instruction ignores `vtype.vsew`. +
The number of element groups to be processed is `vl`/`EGS`.
`vl` must be set to the number of `EEW=32` elements to be processed and 
therefore must be a multiple of `EGS=4`. + 
Likewise, `vstart` must be a multiple of `EGS=4`


Operation::
[source,sail]
--
function clause execute (VAES128D(vs2, vd, vv)) = {
  assert((vl%EGS)<>0)       // vl must be a multiple of EGS
  assert((vstart%EGS)<>0) //  vstart must be a multiple of EGS

  eg_len = (vl/EGS)
  eg_start = (vstart/EGS)
  
  foreach (i from eg_start to eg_len-1) {
    state : bits(128) = get_velem(vd, EGW=128, i);
    rkey  : bits(128) = get_velem(vs2, EGW=128, i);
    state = state ^ rkey;
    foreach(r from 1 to 10) {
      state = aes_inv_shift_rows(state);
      state = aes_inv_sub_bytes(state);
      state = state ^ rkey;
      state = aes_inv_mix_columns(state);
      rkey  = aes_128_reverse_key_schedule(r,rkey);
    }
    state = aes_inv_shift_rows(state);
    state = aes_inv_sub_bytes(state);
    state = state ^ rkey;
    set_velem(vd, EGW=128, i, state);
  }
  RETIRE_SUCCESS
}
--

Included in::
[%header,cols="4,2,2"]
|===
|Extension
|Minimum version
|Lifecycle state

| <<zvknf>>
| v0.1.0
| In Development
|===

