subspace_proof_of_time/
lib.rs#![cfg_attr(not(feature = "std"), no_std)]
mod aes;
use core::num::NonZeroU32;
use subspace_core_primitives::pot::{PotCheckpoints, PotOutput, PotSeed};
#[derive(Debug, thiserror::Error)]
pub enum PotError {
#[error(
"Iterations {iterations} are not multiple of number of checkpoints {num_checkpoints} \
times two"
)]
NotMultipleOfCheckpoints {
iterations: NonZeroU32,
num_checkpoints: u32,
},
}
pub fn prove(seed: PotSeed, iterations: NonZeroU32) -> Result<PotCheckpoints, PotError> {
if iterations.get() % u32::from(PotCheckpoints::NUM_CHECKPOINTS.get() * 2) != 0 {
return Err(PotError::NotMultipleOfCheckpoints {
iterations,
num_checkpoints: u32::from(PotCheckpoints::NUM_CHECKPOINTS.get()),
});
}
Ok(aes::create(
seed,
seed.key(),
iterations.get() / u32::from(PotCheckpoints::NUM_CHECKPOINTS.get()),
))
}
pub fn verify(
seed: PotSeed,
iterations: NonZeroU32,
checkpoints: &[PotOutput],
) -> Result<bool, PotError> {
let num_checkpoints = checkpoints.len() as u32;
if iterations.get() % (num_checkpoints * 2) != 0 {
return Err(PotError::NotMultipleOfCheckpoints {
iterations,
num_checkpoints,
});
}
Ok(aes::verify_sequential(
seed,
seed.key(),
checkpoints,
iterations.get() / num_checkpoints,
))
}