subspace_proof_of_time/
lib.rs1#![cfg_attr(target_arch = "aarch64", feature(array_chunks))]
4#![cfg_attr(target_arch = "x86_64", feature(stdarch_x86_avx512))]
5#![feature(portable_simd)]
6#![no_std]
7
8mod aes;
9
10use core::num::NonZeroU32;
11use subspace_core_primitives::pot::{PotCheckpoints, PotSeed};
12
13#[derive(Debug, thiserror::Error)]
15pub enum PotError {
16 #[error(
18 "Iterations {iterations} are not multiple of number of checkpoints {num_checkpoints} \
19 times two"
20 )]
21 NotMultipleOfCheckpoints {
22 iterations: NonZeroU32,
24 num_checkpoints: u32,
26 },
27}
28
29pub fn prove(seed: PotSeed, iterations: NonZeroU32) -> Result<PotCheckpoints, PotError> {
33 if iterations.get() % u32::from(PotCheckpoints::NUM_CHECKPOINTS.get() * 2) != 0 {
34 return Err(PotError::NotMultipleOfCheckpoints {
35 iterations,
36 num_checkpoints: u32::from(PotCheckpoints::NUM_CHECKPOINTS.get()),
37 });
38 }
39
40 Ok(aes::create(
41 seed,
42 seed.key(),
43 iterations.get() / u32::from(PotCheckpoints::NUM_CHECKPOINTS.get()),
44 ))
45}
46
47pub fn verify(
51 seed: PotSeed,
52 iterations: NonZeroU32,
53 checkpoints: &PotCheckpoints,
54) -> Result<bool, PotError> {
55 let num_checkpoints = checkpoints.len() as u32;
56 if iterations.get() % (num_checkpoints * 2) != 0 {
57 return Err(PotError::NotMultipleOfCheckpoints {
58 iterations,
59 num_checkpoints,
60 });
61 }
62
63 Ok(aes::verify_sequential(
64 seed,
65 seed.key(),
66 checkpoints,
67 iterations.get() / num_checkpoints,
68 ))
69}