OXYGENHUB
◆ v0.4.0 oxygen / vendor / crc-fast / src / arch / aarch64 / aes_sha3.rs
5.7 KiB · Rust · last changed Strata: the cloud stores send through ureq, so every release target links 1 month ago source blame history raw
2cd40ea1 Andy McCall ↶ 1
// Copyright 2025 Don MacAskill. Licensed under MIT or Apache-2.0.
2
3
//! This module provides AArch64-specific implementations of the ArchOps trait for architectures
4
//! with AES+SHA3 support.
5
6
#![cfg(target_arch = "aarch64")]
7
8
use crate::arch::aarch64::aes::Aarch64AesOps;
9
use crate::traits::ArchOps;
10
use core::arch::aarch64::*;
11
12
/// AArch64 AES+SHA3 tier - delegates to AES tier and overrides XOR3 operations
13
/// Provides EOR3 instruction for optimal XOR3 performance
14
#[derive(Debug, Copy, Clone)]
15
pub struct Aarch64AesSha3Ops(Aarch64AesOps);
16
17
impl Default for Aarch64AesSha3Ops {
18
    fn default() -> Self {
19
        Self::new()
20
    }
21
}
22
23
impl Aarch64AesSha3Ops {
24
    #[inline(always)]
25
    pub fn new() -> Self {
26
        Self(Aarch64AesOps)
27
    }
28
}
29
30
// SHA3 tier implementation - delegates to AES tier and overrides XOR3
31
impl ArchOps for Aarch64AesSha3Ops {
32
    type Vector = uint8x16_t;
33
34
    // Delegate methods to the base AES implementation
35
    #[inline(always)]
36
    unsafe fn create_vector_from_u64_pair(
37
        &self,
38
        high: u64,
39
        low: u64,
40
        reflected: bool,
41
    ) -> Self::Vector {
42
        self.0.create_vector_from_u64_pair(high, low, reflected)
43
    }
44
45
    #[inline(always)]
46
    unsafe fn create_vector_from_u64_pair_non_reflected(
47
        &self,
48
        high: u64,
49
        low: u64,
50
    ) -> Self::Vector {
51
        self.0.create_vector_from_u64_pair_non_reflected(high, low)
52
    }
53
54
    #[inline(always)]
55
    unsafe fn create_vector_from_u64(&self, value: u64, high: bool) -> Self::Vector {
56
        self.0.create_vector_from_u64(value, high)
57
    }
58
59
    #[inline(always)]
60
    unsafe fn extract_u64s(&self, vector: Self::Vector) -> [u64; 2] {
61
        self.0.extract_u64s(vector)
62
    }
63
64
    #[inline(always)]
65
    unsafe fn extract_poly64s(&self, vector: Self::Vector) -> [u64; 2] {
66
        self.0.extract_poly64s(vector)
67
    }
68
69
    #[inline(always)]
70
    unsafe fn xor_vectors(&self, a: Self::Vector, b: Self::Vector) -> Self::Vector {
71
        self.0.xor_vectors(a, b)
72
    }
73
74
    #[inline(always)]
75
    unsafe fn load_bytes(&self, ptr: *const u8) -> Self::Vector {
76
        self.0.load_bytes(ptr)
77
    }
78
79
    #[inline(always)]
80
    unsafe fn load_aligned(&self, ptr: *const [u64; 2]) -> Self::Vector {
81
        self.0.load_aligned(ptr)
82
    }
83
84
    #[inline(always)]
85
    unsafe fn shuffle_bytes(&self, data: Self::Vector, mask: Self::Vector) -> Self::Vector {
86
        self.0.shuffle_bytes(data, mask)
87
    }
88
89
    #[inline(always)]
90
    unsafe fn blend_vectors(
91
        &self,
92
        a: Self::Vector,
93
        b: Self::Vector,
94
        mask: Self::Vector,
95
    ) -> Self::Vector {
96
        self.0.blend_vectors(a, b, mask)
97
    }
98
99
    #[inline(always)]
100
    unsafe fn shift_left_8(&self, vector: Self::Vector) -> Self::Vector {
101
        self.0.shift_left_8(vector)
102
    }
103
104
    #[inline(always)]
105
    unsafe fn set_all_bytes(&self, value: u8) -> Self::Vector {
106
        self.0.set_all_bytes(value)
107
    }
108
109
    #[inline(always)]
110
    unsafe fn create_compare_mask(&self, vector: Self::Vector) -> Self::Vector {
111
        self.0.create_compare_mask(vector)
112
    }
113
114
    #[inline(always)]
115
    unsafe fn and_vectors(&self, a: Self::Vector, b: Self::Vector) -> Self::Vector {
116
        self.0.and_vectors(a, b)
117
    }
118
119
    #[inline(always)]
120
    unsafe fn shift_right_32(&self, vector: Self::Vector) -> Self::Vector {
121
        self.0.shift_right_32(vector)
122
    }
123
124
    #[inline(always)]
125
    unsafe fn shift_left_32(&self, vector: Self::Vector) -> Self::Vector {
126
        self.0.shift_left_32(vector)
127
    }
128
129
    #[inline(always)]
130
    unsafe fn create_vector_from_u32(&self, value: u32, high: bool) -> Self::Vector {
131
        self.0.create_vector_from_u32(value, high)
132
    }
133
134
    #[inline(always)]
135
    unsafe fn shift_left_4(&self, vector: Self::Vector) -> Self::Vector {
136
        self.0.shift_left_4(vector)
137
    }
138
139
    #[inline(always)]
140
    unsafe fn shift_right_4(&self, vector: Self::Vector) -> Self::Vector {
141
        self.0.shift_right_4(vector)
142
    }
143
144
    #[inline(always)]
145
    unsafe fn shift_right_8(&self, vector: Self::Vector) -> Self::Vector {
146
        self.0.shift_right_8(vector)
147
    }
148
149
    #[inline(always)]
150
    unsafe fn shift_right_5(&self, vector: Self::Vector) -> Self::Vector {
151
        self.0.shift_right_5(vector)
152
    }
153
154
    #[inline(always)]
155
    unsafe fn shift_right_6(&self, vector: Self::Vector) -> Self::Vector {
156
        self.0.shift_right_6(vector)
157
    }
158
159
    #[inline(always)]
160
    unsafe fn shift_right_7(&self, vector: Self::Vector) -> Self::Vector {
161
        self.0.shift_right_7(vector)
162
    }
163
164
    #[inline(always)]
165
    unsafe fn shift_right_12(&self, vector: Self::Vector) -> Self::Vector {
166
        self.0.shift_right_12(vector)
167
    }
168
169
    #[inline(always)]
170
    unsafe fn shift_left_12(&self, vector: Self::Vector) -> Self::Vector {
171
        self.0.shift_left_12(vector)
172
    }
173
174
    #[inline(always)]
175
    unsafe fn carryless_mul_00(&self, a: Self::Vector, b: Self::Vector) -> Self::Vector {
176
        self.0.carryless_mul_00(a, b)
177
    }
178
179
    #[inline(always)]
180
    unsafe fn carryless_mul_01(&self, a: Self::Vector, b: Self::Vector) -> Self::Vector {
181
        self.0.carryless_mul_01(a, b)
182
    }
183
184
    #[inline(always)]
185
    unsafe fn carryless_mul_10(&self, a: Self::Vector, b: Self::Vector) -> Self::Vector {
186
        self.0.carryless_mul_10(a, b)
187
    }
188
189
    #[inline(always)]
190
    unsafe fn carryless_mul_11(&self, a: Self::Vector, b: Self::Vector) -> Self::Vector {
191
        self.0.carryless_mul_11(a, b)
192
    }
193
194
    // Override XOR3 to use SHA3 EOR3 instruction when available
195
    #[inline]
196
    #[target_feature(enable = "sha3")]
197
    unsafe fn xor3_vectors(
198
        &self,
199
        a: Self::Vector,
200
        b: Self::Vector,
201
        c: Self::Vector,
202
    ) -> Self::Vector {
203
        // SHA3 tier always uses EOR3 instruction
204
        // Feature detection is handled at the dispatch level
205
        veor3q_u8(a, b, c)
206
    }
207
}