Skip to content

Commit adadb17

Browse files
authored
Merge pull request #3552 from autonomys/pot-avx512f+vaes
Faster PoT verification for CPUs that support AVX512F+VAES
2 parents 20ce4d9 + e1de749 commit adadb17

File tree

3 files changed

+427
-80
lines changed

3 files changed

+427
-80
lines changed

crates/subspace-proof-of-time/src/aes.rs

Lines changed: 107 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ pub(crate) fn create(seed: PotSeed, key: PotKey, checkpoint_iterations: u32) ->
1515
{
1616
cpufeatures::new!(has_aes, "aes");
1717
if has_aes::get() {
18+
// SAFETY: Checked `aes` feature
1819
return unsafe { x86_64::create(seed.as_ref(), key.as_ref(), checkpoint_iterations) };
1920
}
2021
}
@@ -51,6 +52,47 @@ pub(crate) fn verify_sequential(
5152
) -> bool {
5253
assert_eq!(checkpoint_iterations % 2, 0);
5354

55+
#[cfg(target_arch = "x86_64")]
56+
{
57+
cpufeatures::new!(has_avx512f_vaes, "avx512f", "vaes");
58+
if has_avx512f_vaes::get() {
59+
// SAFETY: Checked `avx512f` and `vaes` features
60+
return unsafe {
61+
x86_64::verify_sequential_avx512f_vaes(
62+
&seed,
63+
&key,
64+
checkpoints,
65+
checkpoint_iterations,
66+
)
67+
};
68+
}
69+
70+
cpufeatures::new!(has_avx2_vaes, "avx2", "vaes");
71+
if has_avx2_vaes::get() {
72+
// SAFETY: Checked `avx2` and `vaes` features
73+
return unsafe {
74+
x86_64::verify_sequential_avx2_vaes(&seed, &key, checkpoints, checkpoint_iterations)
75+
};
76+
}
77+
78+
cpufeatures::new!(has_aes_sse41, "aes", "sse4.1");
79+
if has_aes_sse41::get() {
80+
// SAFETY: Checked `aes` and `sse4.1` features
81+
return unsafe {
82+
x86_64::verify_sequential_aes_sse41(&seed, &key, checkpoints, checkpoint_iterations)
83+
};
84+
}
85+
}
86+
87+
verify_sequential_generic(seed, key, checkpoints, checkpoint_iterations)
88+
}
89+
90+
fn verify_sequential_generic(
91+
seed: PotSeed,
92+
key: PotKey,
93+
checkpoints: &PotCheckpoints,
94+
checkpoint_iterations: u32,
95+
) -> bool {
5496
let key = Array::from(*key);
5597
let cipher = Aes128::new(&key);
5698

@@ -94,6 +136,65 @@ mod tests {
94136
];
95137
const BAD_CIPHER: [u8; 16] = [22; 16];
96138

139+
fn verify_test(
140+
seed: PotSeed,
141+
key: PotKey,
142+
checkpoints: &PotCheckpoints,
143+
checkpoint_iterations: u32,
144+
) -> bool {
145+
let sequential = verify_sequential(seed, key, checkpoints, checkpoint_iterations);
146+
let sequential_generic =
147+
verify_sequential_generic(seed, key, checkpoints, checkpoint_iterations);
148+
assert_eq!(sequential, sequential_generic);
149+
150+
#[cfg(target_arch = "x86_64")]
151+
{
152+
cpufeatures::new!(has_avx512f_vaes, "avx512f", "vaes");
153+
if has_avx512f_vaes::get() {
154+
// SAFETY: Checked `avx512f` and `vaes` features
155+
let avx512f_vaes = unsafe {
156+
x86_64::verify_sequential_avx512f_vaes(
157+
&seed,
158+
&key,
159+
checkpoints,
160+
checkpoint_iterations,
161+
)
162+
};
163+
assert_eq!(sequential, avx512f_vaes);
164+
}
165+
166+
cpufeatures::new!(has_avx2_vaes, "avx2", "vaes");
167+
if has_avx2_vaes::get() {
168+
// SAFETY: Checked `avx2` and `vaes` features
169+
let avx2_vaes = unsafe {
170+
x86_64::verify_sequential_avx2_vaes(
171+
&seed,
172+
&key,
173+
checkpoints,
174+
checkpoint_iterations,
175+
)
176+
};
177+
assert_eq!(sequential, avx2_vaes);
178+
}
179+
180+
cpufeatures::new!(has_aes_sse41, "aes", "sse4.1");
181+
if has_aes_sse41::get() {
182+
// SAFETY: Checked `aes` and `sse4.1` features
183+
let aes = unsafe {
184+
x86_64::verify_sequential_aes_sse41(
185+
&seed,
186+
&key,
187+
checkpoints,
188+
checkpoint_iterations,
189+
)
190+
};
191+
assert_eq!(sequential, aes);
192+
}
193+
}
194+
195+
sequential
196+
}
197+
97198
#[test]
98199
fn test_create_verify() {
99200
let seed = PotSeed::from(SEED);
@@ -107,47 +208,42 @@ mod tests {
107208
assert_eq!(checkpoints, generic_checkpoints);
108209
}
109210

110-
assert!(verify_sequential(
111-
seed,
112-
key,
113-
&checkpoints,
114-
checkpoint_iterations,
115-
));
211+
assert!(verify_test(seed, key, &checkpoints, checkpoint_iterations,));
116212

117213
// Decryption of invalid cipher text fails.
118214
let mut checkpoints_1 = checkpoints;
119215
checkpoints_1[0] = PotOutput::from(BAD_CIPHER);
120-
assert!(!verify_sequential(
216+
assert!(!verify_test(
121217
seed,
122218
key,
123219
&checkpoints_1,
124220
checkpoint_iterations,
125221
));
126222

127223
// Decryption with wrong number of iterations fails.
128-
assert!(!verify_sequential(
224+
assert!(!verify_test(
129225
seed,
130226
key,
131227
&checkpoints,
132228
checkpoint_iterations + 2,
133229
));
134-
assert!(!verify_sequential(
230+
assert!(!verify_test(
135231
seed,
136232
key,
137233
&checkpoints,
138234
checkpoint_iterations - 2,
139235
));
140236

141237
// Decryption with wrong seed fails.
142-
assert!(!verify_sequential(
238+
assert!(!verify_test(
143239
PotSeed::from(SEED_1),
144240
key,
145241
&checkpoints,
146242
checkpoint_iterations,
147243
));
148244

149245
// Decryption with wrong key fails.
150-
assert!(!verify_sequential(
246+
assert!(!verify_test(
151247
seed,
152248
PotKey::from(KEY_1),
153249
&checkpoints,

0 commit comments

Comments
 (0)