/// Keccak-f1600 on ARMv8.4-A with FEAT_SHA3.
///
/// See p. K12.2.2 p. 11,749 of the ARM Reference manual.
/// Adapted from the Keccak-f1600 implementation in the XKCP/K12.
/// see <https://github.com/XKCP/K12/blob/df6a21e6d1f34c1aa36e8d702540899c97dba5a0/lib/ARMv8Asha3/KeccakP-1600-ARMv8Asha3.S#L69 >
#[ target_feature(enable =
"sha3" )]
pub unsafe fn f1600_armv8_sha3_asm(state: &
mut [u64;
25 ]) {
core::arch::asm!(
"
// Read state
ld1.
1 d {{ v0- v3}}, [x0],
#32
ld1.
1 d {{ v4- v7}}, [x0],
#32
ld1.
1 d {{ v8-v11}}, [x0],
#32
ld1.
1 d {{v12-v15}}, [x0],
#32
ld1.
1 d {{v16-v19}}, [x0],
#32
ld1.
1 d {{v20-v23}}, [x0],
#32
ld1.
1 d {{v24}}, [x0]
sub x0, x0,
#192
// Loop 24 rounds
// NOTE: This loop actually computes two f1600 functions in
// parallel, in both the lower and the upper 64-bit of the
// 128-bit registers v0-v24.
mov x8,
#24
0 : sub x8, x8,
#1
// Theta Calculations
eor3.
16 b v25, v20, v15, v10
eor3.
16 b v26, v21, v16, v11
eor3.
16 b v27, v22, v17, v12
eor3.
16 b v28, v23, v18, v13
eor3.
16 b v29, v24, v19, v14
eor3.
16 b v25, v25, v5, v0
eor3.
16 b v26, v26, v6, v1
eor3.
16 b v27, v27, v7, v2
eor3.
16 b v28, v28, v8, v3
eor3.
16 b v29, v29, v9, v4
rax1.
2 d v30, v25, v27
rax1.
2 d v31, v26, v28
rax1.
2 d v27, v27, v29
rax1.
2 d v28, v28, v25
rax1.
2 d v29, v29, v26
// Rho and Phi
eor.
16 b v0, v0, v29
xar.
2 d v25, v1, v30,
#64 -
1
xar.
2 d v1, v6, v30,
#64 -
44
xar.
2 d v6, v9, v28,
#64 -
20
xar.
2 d v9, v22, v31,
#64 -
61
xar.
2 d v22, v14, v28,
#64 -
39
xar.
2 d v14, v20, v29,
#64 -
18
xar.
2 d v26, v2, v31,
#64 -
62
xar.
2 d v2, v12, v31,
#64 -
43
xar.
2 d v12, v13, v27,
#64 -
25
xar.
2 d v13, v19, v28,
#64 -
8
xar.
2 d v19, v23, v27,
#64 -
56
xar.
2 d v23, v15, v29,
#64 -
41
xar.
2 d v15, v4, v28,
#64 -
27
xar.
2 d v28, v24, v28,
#64 -
14
xar.
2 d v24, v21, v30,
#64 -
2
xar.
2 d v8, v8, v27,
#64 -
55
xar.
2 d v4, v16, v30,
#64 -
45
xar.
2 d v16, v5, v29,
#64 -
36
xar.
2 d v5, v3, v27,
#64 -
28
xar.
2 d v27, v18, v27,
#64 -
21
xar.
2 d v3, v17, v31,
#64 -
15
xar.
2 d v30, v11, v30,
#64 -
10
xar.
2 d v31, v7, v31,
#64 -
6
xar.
2 d v29, v10, v29,
#64 -
3
// Chi and Iota
bcax.
16 b v20, v26, v22, v8
bcax.
16 b v21, v8, v23, v22
bcax.
16 b v22, v22, v24, v23
bcax.
16 b v23, v23, v26, v24
bcax.
16 b v24, v24, v8, v26
ld1r.
2 d {{v26}}, [x1],
#8
bcax.
16 b v17, v30, v19, v3
bcax.
16 b v18, v3, v15, v19
bcax.
16 b v19, v19, v16, v15
bcax.
16 b v15, v15, v30, v16
bcax.
16 b v16, v16, v3, v30
bcax.
16 b v10, v25, v12, v31
bcax.
16 b v11, v31, v13, v12
bcax.
16 b v12, v12, v14, v13
bcax.
16 b v13, v13, v25, v14
bcax.
16 b v14, v14, v31, v25
bcax.
16 b v7, v29, v9, v4
bcax.
16 b v8, v4, v5, v9
bcax.
16 b v9, v9, v6, v5
bcax.
16 b v5, v5, v29, v6
bcax.
16 b v6, v6, v4, v29
bcax.
16 b v3, v27, v0, v28
bcax.
16 b v4, v28, v1, v0
bcax.
16 b v0, v0, v2, v1
bcax.
16 b v1, v1, v27, v2
bcax.
16 b v2, v2, v28, v27
eor.
16 b v0,v0,v26
// Rounds loop
cbnz w8,
0 b
// Write state
st1.
1 d {{ v0- v3}}, [x0],
#32
st1.
1 d {{ v4- v7}}, [x0],
#32
st1.
1 d {{ v8-v11}}, [x0],
#32
st1.
1 d {{v12-v15}}, [x0],
#32
st1.
1 d {{v16-v19}}, [x0],
#32
st1.
1 d {{v20-v23}}, [x0],
#32
st1.
1 d {{v24}}, [x0]
",
in (
"x0" ) state.as_mut_ptr(),
in (
"x1" )
crate ::RC.as_ptr(),
clobber_abi(
"C" ),
options(nostack)
);
}
#[ cfg(all(test, target_feature =
"sha3" ))]
mod tests {
use super ::*;
#[ test]
fn test_keccak_f1600() {
// Test vectors are copied from XKCP (eXtended Keccak Code Package)
// https://github.com/XKCP/XKCP/blob/master/tests/TestVectors/KeccakF-1600-IntermediateValues.txt
let state_first = [
0 xF1258F7940E1DDE7,
0 x84D5CCF933C0478A,
0 xD598261EA65AA9EE,
0 xBD1547306F80494D,
0 x8B284E056253D057,
0 xFF97A42D7F8E6FD4,
0 x90FEE5A0A44647C4,
0 x8C5BDA0CD6192E76,
0 xAD30A6F71B19059C,
0 x30935AB7D08FFC64,
0 xEB5AA93F2317D635,
0 xA9A6E6260D712103,
0 x81A57C16DBCF555F,
0 x43B831CD0347C826,
0 x01F22F1A11A5569F,
0 x05E5635A21D9AE61,
0 x64BEFEF28CC970F2,
0 x613670957BC46611,
0 xB87C5A554FD00ECB,
0 x8C3EE88A1CCF32C8,
0 x940C7922AE3A2614,
0 x1841F924A2C509E4,
0 x16F53526E70465C2,
0 x75F644E97F30A13B,
0 xEAF1FF7B5CECA249,
];
let state_second = [
0 x2D5C954DF96ECB3C,
0 x6A332CD07057B56D,
0 x093D8D1270D76B6C,
0 x8A20D9B25569D094,
0 x4F9C4F99E5E7F156,
0 xF957B9A2DA65FB38,
0 x85773DAE1275AF0D,
0 xFAF4F247C3D810F7,
0 x1F1B9EE6F79A8759,
0 xE4FECC0FEE98B425,
0 x68CE61B6B9CE68A1,
0 xDEEA66C4BA8F974F,
0 x33C43D836EAFB1F5,
0 xE00654042719DBD9,
0 x7CF8A9F009831265,
0 xFD5449A6BF174743,
0 x97DDAD33D8994B40,
0 x48EAD5FC5D0BE774,
0 xE3B8C8EE55B7B03C,
0 x91A0226E649E42E9,
0 x900E3129E7BADD7B,
0 x202A9EC5FAA3CCE8,
0 x5B3402464E1C3DB6,
0 x609F4E62A44C1059,
0 x20D06CD26A8FBF5C,
];
let mut state = [
0 u64;
25 ];
unsafe { f1600_armv8_sha3_asm(&
mut state) };
assert_eq!(state, state_first);
unsafe { f1600_armv8_sha3_asm(&
mut state) };
assert_eq!(state, state_second);
}
}
Messung V0.5 in Prozent C=92 H=69 G=80
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-06-20)
¤
*© Formatika GbR, Deutschland