ab_proof_of_space/
shim.rs1#[cfg(feature = "alloc")]
5use crate::TableGenerator;
6use crate::{PosTableType, Table};
7use ab_core_primitives::pos::{PosProof, PosSeed};
8use core::iter;
9
10#[derive(Debug, Default, Clone)]
14#[cfg(feature = "alloc")]
15pub struct ShimTableGenerator;
16
17#[cfg(feature = "alloc")]
18impl TableGenerator<ShimTable> for ShimTableGenerator {
19 fn generate(&mut self, seed: &PosSeed) -> ShimTable {
20 ShimTable::generate(seed)
21 }
22}
23
24#[derive(Debug)]
28pub struct ShimTable {
29 #[cfg(feature = "alloc")]
30 seed: PosSeed,
31}
32
33impl ab_core_primitives::solutions::SolutionPotVerifier for ShimTable {
34 fn is_proof_valid(seed: &PosSeed, challenge_index: u32, proof: &PosProof) -> bool {
35 let Some(correct_proof) = find_proof(seed, challenge_index) else {
36 return false;
37 };
38
39 &correct_proof == proof
40 }
41}
42
43impl Table for ShimTable {
44 const TABLE_TYPE: PosTableType = PosTableType::Shim;
45 #[cfg(feature = "alloc")]
46 type Generator = ShimTableGenerator;
47
48 #[cfg(feature = "alloc")]
49 fn generate(seed: &PosSeed) -> ShimTable {
50 Self { seed: *seed }
51 }
52
53 #[cfg(feature = "alloc")]
54 fn find_proof(&self, challenge_index: u32) -> Option<PosProof> {
55 find_proof(&self.seed, challenge_index)
56 }
57
58 fn is_proof_valid(seed: &PosSeed, challenge_index: u32, proof: &PosProof) -> bool {
59 <Self as ab_core_primitives::solutions::SolutionPotVerifier>::is_proof_valid(
60 seed,
61 challenge_index,
62 proof,
63 )
64 }
65}
66
67fn find_proof(seed: &PosSeed, challenge_index: u32) -> Option<PosProof> {
68 let quality = *blake3::hash(&challenge_index.to_le_bytes()).as_bytes();
69 if quality[0] % 3 > 0 {
70 let mut proof = PosProof::default();
71 proof
72 .iter_mut()
73 .zip(seed.iter().chain(iter::repeat(quality.iter()).flatten()))
74 .for_each(|(output, input)| {
75 *output = *input;
76 });
77
78 Some(proof)
79 } else {
80 None
81 }
82}
83
84#[cfg(all(feature = "alloc", test))]
85mod tests {
86 use super::*;
87
88 #[test]
89 fn basic() {
90 let seed = PosSeed::from([
91 35, 2, 52, 4, 51, 55, 23, 84, 91, 10, 111, 12, 13, 222, 151, 16, 228, 211, 254, 45, 92,
92 198, 204, 10, 9, 10, 11, 129, 139, 171, 15, 23,
93 ]);
94
95 let table = ShimTable::generate(&seed);
96
97 assert!(table.find_proof(1).is_none());
98
99 {
100 let challenge_index = 0;
101 let proof = table.find_proof(challenge_index).unwrap();
102 assert!(ShimTable::is_proof_valid(&seed, challenge_index, &proof));
103 }
104 }
105}