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