zupt/jasmin/zupt_aes_ctr.jazz
Cristian Cezar Moisés e5f5d32aab v2.2.2
2026-05-01 09:58:47 -03:00

122 lines
3 KiB
Text

/* Zupt — AES-256 Single Block Encrypt via AES-NI (Jasmin)
* Copyright (c) 2026 Cristian Cezar Moisés
* SPDX-License-Identifier: AGPL-3.0-or-later
*
* CT-REQUIRED: AES-NI has no data-dependent timing.
*
* FIX v2.0.0: replaced `stack u128[15] rk` with 15 individual
* `stack u128` variables. The array form uses byte-offset indexing
* in jasminc (rk.[1] → [rsp+1] instead of [rsp+16]), producing
* incorrect round key loads. Individual variables avoid the issue.
*/
inline fn key_expand_even(reg u128 t0, reg u128 assist) -> reg u128 {
reg u128 tmp;
assist = #VPSHUFD(assist, 0xFF);
tmp = #VPSLLDQ(t0, 4);
t0 ^= tmp;
tmp = #VPSLLDQ(t0, 4);
t0 ^= tmp;
tmp = #VPSLLDQ(t0, 4);
t0 ^= tmp;
t0 ^= assist;
return t0;
}
inline fn key_expand_odd(reg u128 t0, reg u128 t1) -> reg u128 {
reg u128 tmp assist;
assist = #VAESKEYGENASSIST(t0, 0);
assist = #VPSHUFD(assist, 0xAA);
tmp = #VPSLLDQ(t1, 4);
t1 ^= tmp;
tmp = #VPSLLDQ(t1, 4);
t1 ^= tmp;
tmp = #VPSLLDQ(t1, 4);
t1 ^= tmp;
t1 ^= assist;
return t1;
}
export fn zupt_aes256_blk(
reg u64 out_ptr,
reg ptr u128[1] in_blk,
reg ptr u128[2] key,
reg ptr u128[1] ctr_blk)
{
stack u128 rk0 rk1 rk2 rk3 rk4 rk5 rk6 rk7;
stack u128 rk8 rk9 rk10 rk11 rk12 rk13 rk14;
reg u128 t0 t1 assist b data;
t0 = key.[0];
t1 = key.[1];
rk0 = t0;
rk1 = t1;
assist = #VAESKEYGENASSIST(t1, 0x01);
t0 = key_expand_even(t0, assist);
rk2 = t0;
t1 = key_expand_odd(t0, t1);
rk3 = t1;
assist = #VAESKEYGENASSIST(t1, 0x02);
t0 = key_expand_even(t0, assist);
rk4 = t0;
t1 = key_expand_odd(t0, t1);
rk5 = t1;
assist = #VAESKEYGENASSIST(t1, 0x04);
t0 = key_expand_even(t0, assist);
rk6 = t0;
t1 = key_expand_odd(t0, t1);
rk7 = t1;
assist = #VAESKEYGENASSIST(t1, 0x08);
t0 = key_expand_even(t0, assist);
rk8 = t0;
t1 = key_expand_odd(t0, t1);
rk9 = t1;
assist = #VAESKEYGENASSIST(t1, 0x10);
t0 = key_expand_even(t0, assist);
rk10 = t0;
t1 = key_expand_odd(t0, t1);
rk11 = t1;
assist = #VAESKEYGENASSIST(t1, 0x20);
t0 = key_expand_even(t0, assist);
rk12 = t0;
t1 = key_expand_odd(t0, t1);
rk13 = t1;
assist = #VAESKEYGENASSIST(t1, 0x40);
t0 = key_expand_even(t0, assist);
rk14 = t0;
b = ctr_blk.[0];
b ^= rk0;
b = #VAESENC(b, rk1);
b = #VAESENC(b, rk2);
b = #VAESENC(b, rk3);
b = #VAESENC(b, rk4);
b = #VAESENC(b, rk5);
b = #VAESENC(b, rk6);
b = #VAESENC(b, rk7);
b = #VAESENC(b, rk8);
b = #VAESENC(b, rk9);
b = #VAESENC(b, rk10);
b = #VAESENC(b, rk11);
b = #VAESENC(b, rk12);
b = #VAESENC(b, rk13);
b = #VAESENCLAST(b, rk14);
data = in_blk.[0];
b ^= data;
[out_ptr + 0] = b;
reg u128 wipe;
wipe = rk0; wipe ^= wipe;
rk0 = wipe; rk1 = wipe; rk2 = wipe; rk3 = wipe;
rk4 = wipe; rk5 = wipe; rk6 = wipe; rk7 = wipe;
rk8 = wipe; rk9 = wipe; rk10 = wipe; rk11 = wipe;
rk12 = wipe; rk13 = wipe; rk14 = wipe;
}