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