feat: add Jasmin assembly integration for crypto acceleration
- Integrated `zupt_mac_verify_ct` in `zupt_decrypt_buffer()` to replace C XOR loop for HMAC-SHA256 - Integrated `zupt_ct_select_32` in `zupt_mlkem768_decaps()` to replace C `cmov()` for FO transformation - Added `include/zupt_jasmin.h` with extern declarations and ABI docs - Added `#ifdef ZUPT_USE_JASMIN` guards with clean C fallbacks in `zupt_crypto.c` and `zupt_mlkem.c` - Makefile now auto-detects `jasmin/*.s`, assembles and links with `-DZUPT_USE_JASMIN` Closes #3
This commit is contained in:
parent
cea317653e
commit
06c877ec86
43 changed files with 1913 additions and 546 deletions
124
jasmin/zupt_aes_ctr.jazz
Normal file
124
jasmin/zupt_aes_ctr.jazz
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
/* Zupt — AES-256 Single Block Encrypt via AES-NI (Jasmin)
|
||||
* Copyright (c) 2026 Cristian Cezar Moisés — MIT License
|
||||
*
|
||||
* CT-REQUIRED: AES-NI has no data-dependent timing.
|
||||
*
|
||||
* Uses reg ptr for read-only u128 inputs (key, counter, plaintext).
|
||||
* Uses reg u64 for write output (store infers width from reg u128 source).
|
||||
* C handles CTR loop and tail bytes.
|
||||
*/
|
||||
|
||||
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[15] rk;
|
||||
reg u128 t0 t1 assist b data;
|
||||
|
||||
/* Key expansion */
|
||||
t0 = key.[0];
|
||||
t1 = key.[1];
|
||||
rk.[0] = t0;
|
||||
rk.[1] = t1;
|
||||
|
||||
assist = #VAESKEYGENASSIST(t1, 0x01);
|
||||
t0 = key_expand_even(t0, assist);
|
||||
rk.[2] = t0;
|
||||
t1 = key_expand_odd(t0, t1);
|
||||
rk.[3] = t1;
|
||||
|
||||
assist = #VAESKEYGENASSIST(t1, 0x02);
|
||||
t0 = key_expand_even(t0, assist);
|
||||
rk.[4] = t0;
|
||||
t1 = key_expand_odd(t0, t1);
|
||||
rk.[5] = t1;
|
||||
|
||||
assist = #VAESKEYGENASSIST(t1, 0x04);
|
||||
t0 = key_expand_even(t0, assist);
|
||||
rk.[6] = t0;
|
||||
t1 = key_expand_odd(t0, t1);
|
||||
rk.[7] = t1;
|
||||
|
||||
assist = #VAESKEYGENASSIST(t1, 0x08);
|
||||
t0 = key_expand_even(t0, assist);
|
||||
rk.[8] = t0;
|
||||
t1 = key_expand_odd(t0, t1);
|
||||
rk.[9] = t1;
|
||||
|
||||
assist = #VAESKEYGENASSIST(t1, 0x10);
|
||||
t0 = key_expand_even(t0, assist);
|
||||
rk.[10] = t0;
|
||||
t1 = key_expand_odd(t0, t1);
|
||||
rk.[11] = t1;
|
||||
|
||||
assist = #VAESKEYGENASSIST(t1, 0x20);
|
||||
t0 = key_expand_even(t0, assist);
|
||||
rk.[12] = t0;
|
||||
t1 = key_expand_odd(t0, t1);
|
||||
rk.[13] = t1;
|
||||
|
||||
assist = #VAESKEYGENASSIST(t1, 0x40);
|
||||
t0 = key_expand_even(t0, assist);
|
||||
rk.[14] = t0;
|
||||
|
||||
/* Encrypt counter block: 14 rounds AES-256 */
|
||||
b = ctr_blk.[0];
|
||||
b ^= rk.[0];
|
||||
b = #VAESENC(b, rk.[1]);
|
||||
b = #VAESENC(b, rk.[2]);
|
||||
b = #VAESENC(b, rk.[3]);
|
||||
b = #VAESENC(b, rk.[4]);
|
||||
b = #VAESENC(b, rk.[5]);
|
||||
b = #VAESENC(b, rk.[6]);
|
||||
b = #VAESENC(b, rk.[7]);
|
||||
b = #VAESENC(b, rk.[8]);
|
||||
b = #VAESENC(b, rk.[9]);
|
||||
b = #VAESENC(b, rk.[10]);
|
||||
b = #VAESENC(b, rk.[11]);
|
||||
b = #VAESENC(b, rk.[12]);
|
||||
b = #VAESENC(b, rk.[13]);
|
||||
b = #VAESENCLAST(b, rk.[14]);
|
||||
|
||||
/* XOR keystream with plaintext, store result */
|
||||
data = in_blk.[0];
|
||||
b ^= data;
|
||||
[out_ptr + 0] = b;
|
||||
|
||||
/* Wipe round keys */
|
||||
reg u128 wipe;
|
||||
inline int z;
|
||||
for z = 0 to 15 {
|
||||
wipe = rk.[z];
|
||||
wipe ^= wipe;
|
||||
rk.[z] = wipe;
|
||||
}
|
||||
}
|
||||
166
jasmin/zupt_aes_ctr.s
Normal file
166
jasmin/zupt_aes_ctr.s
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
.intel_syntax noprefix
|
||||
.text
|
||||
.p2align 5
|
||||
.global zupt_aes256_blk
|
||||
.type zupt_aes256_blk, %function
|
||||
zupt_aes256_blk:
|
||||
mov r10, rsp
|
||||
lea rsp, qword ptr[rsp + -240]
|
||||
and rsp, -16
|
||||
vmovdqu xmm0, xmmword ptr[rdx]
|
||||
vmovdqu xmm1, xmmword ptr[rdx + 1]
|
||||
vmovdqu xmmword ptr[rsp], xmm0
|
||||
vmovdqu xmmword ptr[rsp + 1], xmm1
|
||||
vaeskeygenassist xmm2, xmm1, 1
|
||||
vpshufd xmm2, xmm2, 255
|
||||
vpslldq xmm3, xmm0, 4
|
||||
vpxor xmm0, xmm0, xmm3
|
||||
vpslldq xmm3, xmm0, 4
|
||||
vpxor xmm0, xmm0, xmm3
|
||||
vpslldq xmm3, xmm0, 4
|
||||
vpxor xmm0, xmm0, xmm3
|
||||
vpxor xmm0, xmm0, xmm2
|
||||
vmovdqu xmmword ptr[rsp + 2], xmm0
|
||||
vaeskeygenassist xmm2, xmm0, 0
|
||||
vpshufd xmm2, xmm2, 170
|
||||
vpslldq xmm3, xmm1, 4
|
||||
vpxor xmm1, xmm1, xmm3
|
||||
vpslldq xmm3, xmm1, 4
|
||||
vpxor xmm1, xmm1, xmm3
|
||||
vpslldq xmm3, xmm1, 4
|
||||
vpxor xmm1, xmm1, xmm3
|
||||
vpxor xmm1, xmm1, xmm2
|
||||
vmovdqu xmmword ptr[rsp + 3], xmm1
|
||||
vaeskeygenassist xmm2, xmm1, 2
|
||||
vpshufd xmm2, xmm2, 255
|
||||
vpslldq xmm3, xmm0, 4
|
||||
vpxor xmm0, xmm0, xmm3
|
||||
vpslldq xmm3, xmm0, 4
|
||||
vpxor xmm0, xmm0, xmm3
|
||||
vpslldq xmm3, xmm0, 4
|
||||
vpxor xmm0, xmm0, xmm3
|
||||
vpxor xmm0, xmm0, xmm2
|
||||
vmovdqu xmmword ptr[rsp + 4], xmm0
|
||||
vaeskeygenassist xmm2, xmm0, 0
|
||||
vpshufd xmm2, xmm2, 170
|
||||
vpslldq xmm3, xmm1, 4
|
||||
vpxor xmm1, xmm1, xmm3
|
||||
vpslldq xmm3, xmm1, 4
|
||||
vpxor xmm1, xmm1, xmm3
|
||||
vpslldq xmm3, xmm1, 4
|
||||
vpxor xmm1, xmm1, xmm3
|
||||
vpxor xmm1, xmm1, xmm2
|
||||
vmovdqu xmmword ptr[rsp + 5], xmm1
|
||||
vaeskeygenassist xmm2, xmm1, 4
|
||||
vpshufd xmm2, xmm2, 255
|
||||
vpslldq xmm3, xmm0, 4
|
||||
vpxor xmm0, xmm0, xmm3
|
||||
vpslldq xmm3, xmm0, 4
|
||||
vpxor xmm0, xmm0, xmm3
|
||||
vpslldq xmm3, xmm0, 4
|
||||
vpxor xmm0, xmm0, xmm3
|
||||
vpxor xmm0, xmm0, xmm2
|
||||
vmovdqu xmmword ptr[rsp + 6], xmm0
|
||||
vaeskeygenassist xmm2, xmm0, 0
|
||||
vpshufd xmm2, xmm2, 170
|
||||
vpslldq xmm3, xmm1, 4
|
||||
vpxor xmm1, xmm1, xmm3
|
||||
vpslldq xmm3, xmm1, 4
|
||||
vpxor xmm1, xmm1, xmm3
|
||||
vpslldq xmm3, xmm1, 4
|
||||
vpxor xmm1, xmm1, xmm3
|
||||
vpxor xmm1, xmm1, xmm2
|
||||
vmovdqu xmmword ptr[rsp + 7], xmm1
|
||||
vaeskeygenassist xmm2, xmm1, 8
|
||||
vpshufd xmm2, xmm2, 255
|
||||
vpslldq xmm3, xmm0, 4
|
||||
vpxor xmm0, xmm0, xmm3
|
||||
vpslldq xmm3, xmm0, 4
|
||||
vpxor xmm0, xmm0, xmm3
|
||||
vpslldq xmm3, xmm0, 4
|
||||
vpxor xmm0, xmm0, xmm3
|
||||
vpxor xmm0, xmm0, xmm2
|
||||
vmovdqu xmmword ptr[rsp + 8], xmm0
|
||||
vaeskeygenassist xmm2, xmm0, 0
|
||||
vpshufd xmm2, xmm2, 170
|
||||
vpslldq xmm3, xmm1, 4
|
||||
vpxor xmm1, xmm1, xmm3
|
||||
vpslldq xmm3, xmm1, 4
|
||||
vpxor xmm1, xmm1, xmm3
|
||||
vpslldq xmm3, xmm1, 4
|
||||
vpxor xmm1, xmm1, xmm3
|
||||
vpxor xmm1, xmm1, xmm2
|
||||
vmovdqu xmmword ptr[rsp + 9], xmm1
|
||||
vaeskeygenassist xmm2, xmm1, 16
|
||||
vpshufd xmm2, xmm2, 255
|
||||
vpslldq xmm3, xmm0, 4
|
||||
vpxor xmm0, xmm0, xmm3
|
||||
vpslldq xmm3, xmm0, 4
|
||||
vpxor xmm0, xmm0, xmm3
|
||||
vpslldq xmm3, xmm0, 4
|
||||
vpxor xmm0, xmm0, xmm3
|
||||
vpxor xmm0, xmm0, xmm2
|
||||
vmovdqu xmmword ptr[rsp + 10], xmm0
|
||||
vaeskeygenassist xmm2, xmm0, 0
|
||||
vpshufd xmm2, xmm2, 170
|
||||
vpslldq xmm3, xmm1, 4
|
||||
vpxor xmm1, xmm1, xmm3
|
||||
vpslldq xmm3, xmm1, 4
|
||||
vpxor xmm1, xmm1, xmm3
|
||||
vpslldq xmm3, xmm1, 4
|
||||
vpxor xmm1, xmm1, xmm3
|
||||
vpxor xmm1, xmm1, xmm2
|
||||
vmovdqu xmmword ptr[rsp + 11], xmm1
|
||||
vaeskeygenassist xmm2, xmm1, 32
|
||||
vpshufd xmm2, xmm2, 255
|
||||
vpslldq xmm3, xmm0, 4
|
||||
vpxor xmm0, xmm0, xmm3
|
||||
vpslldq xmm3, xmm0, 4
|
||||
vpxor xmm0, xmm0, xmm3
|
||||
vpslldq xmm3, xmm0, 4
|
||||
vpxor xmm0, xmm0, xmm3
|
||||
vpxor xmm0, xmm0, xmm2
|
||||
vmovdqu xmmword ptr[rsp + 12], xmm0
|
||||
vaeskeygenassist xmm2, xmm0, 0
|
||||
vpshufd xmm2, xmm2, 170
|
||||
vpslldq xmm3, xmm1, 4
|
||||
vpxor xmm1, xmm1, xmm3
|
||||
vpslldq xmm3, xmm1, 4
|
||||
vpxor xmm1, xmm1, xmm3
|
||||
vpslldq xmm3, xmm1, 4
|
||||
vpxor xmm1, xmm1, xmm3
|
||||
vpxor xmm1, xmm1, xmm2
|
||||
vmovdqu xmmword ptr[rsp + 13], xmm1
|
||||
vaeskeygenassist xmm2, xmm1, 64
|
||||
vpshufd xmm2, xmm2, 255
|
||||
vpslldq xmm3, xmm0, 4
|
||||
vpxor xmm0, xmm0, xmm3
|
||||
vpslldq xmm3, xmm0, 4
|
||||
vpxor xmm0, xmm0, xmm3
|
||||
vpslldq xmm3, xmm0, 4
|
||||
vpxor xmm0, xmm0, xmm3
|
||||
vpxor xmm0, xmm0, xmm2
|
||||
vmovdqu xmmword ptr[rsp + 14], xmm0
|
||||
vmovdqu xmm0, xmmword ptr[rcx]
|
||||
vpxor xmm0, xmm0, xmmword ptr[rsp]
|
||||
vaesenc xmm0, xmm0, xmmword ptr[rsp + 1]
|
||||
vaesenc xmm0, xmm0, xmmword ptr[rsp + 2]
|
||||
vaesenc xmm0, xmm0, xmmword ptr[rsp + 3]
|
||||
vaesenc xmm0, xmm0, xmmword ptr[rsp + 4]
|
||||
vaesenc xmm0, xmm0, xmmword ptr[rsp + 5]
|
||||
vaesenc xmm0, xmm0, xmmword ptr[rsp + 6]
|
||||
vaesenc xmm0, xmm0, xmmword ptr[rsp + 7]
|
||||
vaesenc xmm0, xmm0, xmmword ptr[rsp + 8]
|
||||
vaesenc xmm0, xmm0, xmmword ptr[rsp + 9]
|
||||
vaesenc xmm0, xmm0, xmmword ptr[rsp + 10]
|
||||
vaesenc xmm0, xmm0, xmmword ptr[rsp + 11]
|
||||
vaesenc xmm0, xmm0, xmmword ptr[rsp + 12]
|
||||
vaesenc xmm0, xmm0, xmmword ptr[rsp + 13]
|
||||
vaesenclast xmm0, xmm0, xmmword ptr[rsp + 14]
|
||||
vmovdqu xmm1, xmmword ptr[rsi]
|
||||
vpxor xmm0, xmm0, xmm1
|
||||
movq qword ptr[rdi], xmm0
|
||||
mov rsp, r10
|
||||
ret
|
||||
.ident "Jasmin Compiler 2026.03.0"
|
||||
.section ".note.GNU-stack", "", %progbits
|
||||
28
jasmin/zupt_mac_verify.jazz
Normal file
28
jasmin/zupt_mac_verify.jazz
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/* Zupt — Constant-Time MAC Comparison (Jasmin)
|
||||
* Copyright (c) 2026 Cristian Cezar Moisés — MIT License
|
||||
*
|
||||
* CT-REQUIRED: Timing independent of input byte values.
|
||||
* Compare 32 bytes as 4 × u64 — no byte-level access needed.
|
||||
*/
|
||||
|
||||
export fn zupt_mac_verify_ct(
|
||||
reg u64 expected_ptr,
|
||||
reg u64 actual_ptr)
|
||||
-> reg u64
|
||||
{
|
||||
reg u64 diff a b tmp;
|
||||
inline int i;
|
||||
|
||||
diff = 0;
|
||||
|
||||
/* 4 × 8 bytes = 32 bytes. u64 loads — no size mismatch. */
|
||||
for i = 0 to 4 {
|
||||
a = [expected_ptr + 8 * i];
|
||||
b = [actual_ptr + 8 * i];
|
||||
tmp = a;
|
||||
tmp ^= b;
|
||||
diff |= tmp;
|
||||
}
|
||||
|
||||
return diff;
|
||||
}
|
||||
BIN
jasmin/zupt_mac_verify.o
Normal file
BIN
jasmin/zupt_mac_verify.o
Normal file
Binary file not shown.
26
jasmin/zupt_mac_verify.s
Normal file
26
jasmin/zupt_mac_verify.s
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
.intel_syntax noprefix
|
||||
.text
|
||||
.p2align 5
|
||||
.global zupt_mac_verify_ct
|
||||
.type zupt_mac_verify_ct, %function
|
||||
zupt_mac_verify_ct:
|
||||
mov rax, 0
|
||||
mov rcx, qword ptr[rdi]
|
||||
mov rdx, qword ptr[rsi]
|
||||
xor rcx, rdx
|
||||
or rax, rcx
|
||||
mov rcx, qword ptr[rdi + 8]
|
||||
mov rdx, qword ptr[rsi + 8]
|
||||
xor rcx, rdx
|
||||
or rax, rcx
|
||||
mov rcx, qword ptr[rdi + 16]
|
||||
mov rdx, qword ptr[rsi + 16]
|
||||
xor rcx, rdx
|
||||
or rax, rcx
|
||||
mov rcx, qword ptr[rdi + 24]
|
||||
mov rdx, qword ptr[rsi + 24]
|
||||
xor rcx, rdx
|
||||
or rax, rcx
|
||||
ret
|
||||
.ident "Jasmin Compiler 2026.03.0"
|
||||
.section ".note.GNU-stack", "", %progbits
|
||||
31
jasmin/zupt_mlkem_select.jazz
Normal file
31
jasmin/zupt_mlkem_select.jazz
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/* Zupt — ML-KEM Constant-Time Select (Jasmin)
|
||||
* Copyright (c) 2026 Cristian Cezar Moisés — MIT License
|
||||
*
|
||||
* CT-REQUIRED: FO implicit rejection must not leak via timing.
|
||||
* Operates in u64 chunks: 4 × 8 = 32 bytes, no byte access.
|
||||
*/
|
||||
|
||||
export fn zupt_ct_select_32(
|
||||
reg u64 out_ptr,
|
||||
reg u64 a_ptr,
|
||||
reg u64 b_ptr,
|
||||
reg u64 cond)
|
||||
{
|
||||
reg u64 mask va vb tmp sel;
|
||||
inline int i;
|
||||
|
||||
mask = 0;
|
||||
mask -= cond;
|
||||
|
||||
/* 4 × u64 = 32 bytes */
|
||||
for i = 0 to 4 {
|
||||
va = [a_ptr + 8 * i];
|
||||
vb = [b_ptr + 8 * i];
|
||||
tmp = va;
|
||||
tmp ^= vb;
|
||||
tmp &= mask;
|
||||
sel = va;
|
||||
sel ^= tmp;
|
||||
[out_ptr + 8 * i] = sel;
|
||||
}
|
||||
}
|
||||
BIN
jasmin/zupt_mlkem_select.o
Normal file
BIN
jasmin/zupt_mlkem_select.o
Normal file
Binary file not shown.
39
jasmin/zupt_mlkem_select.s
Normal file
39
jasmin/zupt_mlkem_select.s
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
.intel_syntax noprefix
|
||||
.text
|
||||
.p2align 5
|
||||
.global zupt_ct_select_32
|
||||
.type zupt_ct_select_32, %function
|
||||
zupt_ct_select_32:
|
||||
mov rax, 0
|
||||
sub rax, rcx
|
||||
mov rcx, qword ptr[rsi]
|
||||
mov r8, qword ptr[rdx]
|
||||
mov r9, rcx
|
||||
xor r9, r8
|
||||
and r9, rax
|
||||
xor rcx, r9
|
||||
mov qword ptr[rdi], rcx
|
||||
mov rcx, qword ptr[rsi + 8]
|
||||
mov r8, qword ptr[rdx + 8]
|
||||
mov r9, rcx
|
||||
xor r9, r8
|
||||
and r9, rax
|
||||
xor rcx, r9
|
||||
mov qword ptr[rdi + 8], rcx
|
||||
mov rcx, qword ptr[rsi + 16]
|
||||
mov r8, qword ptr[rdx + 16]
|
||||
mov r9, rcx
|
||||
xor r9, r8
|
||||
and r9, rax
|
||||
xor rcx, r9
|
||||
mov qword ptr[rdi + 16], rcx
|
||||
mov rcx, qword ptr[rsi + 24]
|
||||
mov r8, qword ptr[rdx + 24]
|
||||
mov r9, rcx
|
||||
xor r9, r8
|
||||
and r9, rax
|
||||
xor rcx, r9
|
||||
mov qword ptr[rdi + 24], rcx
|
||||
ret
|
||||
.ident "Jasmin Compiler 2026.03.0"
|
||||
.section ".note.GNU-stack", "", %progbits
|
||||
34
jasmin/zupt_x25519_fe.jazz
Normal file
34
jasmin/zupt_x25519_fe.jazz
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/* Zupt — X25519 Constant-Time Conditional Swap (Jasmin)
|
||||
* Copyright (c) 2026 Cristian Cezar Moisés — MIT License
|
||||
*
|
||||
* CT-REQUIRED: fe_cswap must not leak cond via timing.
|
||||
* This is the only CT-critical field operation in X25519.
|
||||
* fe_add/fe_sub/fe_mul use C fallback (data-independent timing
|
||||
* on x86-64 — ADD/MUL have fixed latency).
|
||||
*
|
||||
* 4 × u64 limbs, pure register operations, no intrinsics needed.
|
||||
*/
|
||||
|
||||
export fn zupt_fe_cswap(
|
||||
reg u64 a_ptr,
|
||||
reg u64 b_ptr,
|
||||
reg u64 cond)
|
||||
{
|
||||
reg u64 mask ta tb diff;
|
||||
inline int i;
|
||||
|
||||
mask = 0;
|
||||
mask -= cond;
|
||||
|
||||
for i = 0 to 4 {
|
||||
ta = [a_ptr + 8 * i];
|
||||
tb = [b_ptr + 8 * i];
|
||||
diff = ta;
|
||||
diff ^= tb;
|
||||
diff &= mask;
|
||||
ta ^= diff;
|
||||
tb ^= diff;
|
||||
[a_ptr + 8 * i] = ta;
|
||||
[b_ptr + 8 * i] = tb;
|
||||
}
|
||||
}
|
||||
47
jasmin/zupt_x25519_fe.s
Normal file
47
jasmin/zupt_x25519_fe.s
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
.intel_syntax noprefix
|
||||
.text
|
||||
.p2align 5
|
||||
.global zupt_fe_cswap
|
||||
.type zupt_fe_cswap, %function
|
||||
zupt_fe_cswap:
|
||||
mov rax, 0
|
||||
sub rax, rdx
|
||||
mov rcx, qword ptr[rdi]
|
||||
mov rdx, qword ptr[rsi]
|
||||
mov r8, rcx
|
||||
xor r8, rdx
|
||||
and r8, rax
|
||||
xor rcx, r8
|
||||
xor rdx, r8
|
||||
mov qword ptr[rdi], rcx
|
||||
mov qword ptr[rsi], rdx
|
||||
mov rcx, qword ptr[rdi + 8]
|
||||
mov rdx, qword ptr[rsi + 8]
|
||||
mov r8, rcx
|
||||
xor r8, rdx
|
||||
and r8, rax
|
||||
xor rcx, r8
|
||||
xor rdx, r8
|
||||
mov qword ptr[rdi + 8], rcx
|
||||
mov qword ptr[rsi + 8], rdx
|
||||
mov rcx, qword ptr[rdi + 16]
|
||||
mov rdx, qword ptr[rsi + 16]
|
||||
mov r8, rcx
|
||||
xor r8, rdx
|
||||
and r8, rax
|
||||
xor rcx, r8
|
||||
xor rdx, r8
|
||||
mov qword ptr[rdi + 16], rcx
|
||||
mov qword ptr[rsi + 16], rdx
|
||||
mov rcx, qword ptr[rdi + 24]
|
||||
mov rdx, qword ptr[rsi + 24]
|
||||
mov r8, rcx
|
||||
xor r8, rdx
|
||||
and r8, rax
|
||||
xor rcx, r8
|
||||
xor rdx, r8
|
||||
mov qword ptr[rdi + 24], rcx
|
||||
mov qword ptr[rsi + 24], rdx
|
||||
ret
|
||||
.ident "Jasmin Compiler 2026.03.0"
|
||||
.section ".note.GNU-stack", "", %progbits
|
||||
Loading…
Reference in a new issue