[[insns-vaese128, Vector AES-128 encrypt all-rounds]]
= vaese128.[vv,vs]

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

Mnemonic::
vaese128.vv vd, vs2, vs1 +
vaese128.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 | Cipher key
| Vs2 | input  | 128  | 4 | 32 | Plain text
| Vd  | output | 128  | 4 | 32 | Cipher text
|===

Description:: 
This instruction implements the entire AES-128 block cipher encryption
function. It internally generates each of the round keys and performs each of the rounds.

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

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

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 (VAES128E(vs1, 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(vs1, EGW=128, i);
    state = state ^ rkey;
    foreach(r from 0 to 10) {
      state = aes_fwd_sub_bytes(state);
      state = aes_fwd_shift_rows(state);
      state = aes_fwd_mix_columns(state);
      state = state ^ rkey;
      rkey  = aes_128_forward_key_schedule(rkey);
    }
    state = aes_fwd_sub_bytes(state);
    state = aes_fwd_shift_rows(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
|===

