Skip to main content

spongefish_pow/
keccak.rs

1use ::keccak::{Keccak, State1600};
2
3use super::PowStrategy;
4use crate::PoWSolution;
5
6#[derive(Clone, Copy)]
7pub struct KeccakPoW {
8    challenge: [u64; 4],
9    threshold: u64,
10    state: [u64; 25],
11}
12
13impl PowStrategy for KeccakPoW {
14    #[allow(clippy::cast_sign_loss)]
15    fn new(challenge: [u8; 32], bits: f64) -> Self {
16        let threshold = (64.0 - bits).exp2().ceil() as u64;
17        Self {
18            challenge: bytemuck::cast(challenge),
19            threshold,
20            state: [0; 25],
21        }
22    }
23
24    fn solution(&self, nonce: u64) -> PoWSolution {
25        PoWSolution {
26            challenge: bytemuck::cast(self.challenge),
27            nonce,
28        }
29    }
30
31    fn check(&mut self, nonce: u64) -> bool {
32        self.state[..4].copy_from_slice(&self.challenge);
33        self.state[4] = nonce;
34        for s in self.state.iter_mut().skip(5) {
35            *s = 0;
36        }
37        f1600(&mut self.state);
38        self.state[0] < self.threshold
39    }
40}
41
42fn f1600(state: &mut State1600) {
43    Keccak::new().with_f1600(|f1600| f1600(state));
44}
45
46#[test]
47fn test_pow_keccak() {
48    use crate::{convenience::*, PoWGrinder};
49
50    const BITS: f64 = 10.0;
51
52    // Test with a fixed challenge
53    let challenge = [42u8; 32];
54
55    // Generate a proof-of-work solution
56    let _solution = grind_pow::<KeccakPoW>(challenge, BITS).expect("Should find a valid solution");
57
58    // We can't extract the nonce directly from the solution (it's one-way),
59    // but we can verify by re-grinding and checking we get a valid solution
60    let mut grounder = PoWGrinder::<KeccakPoW>::new(challenge, BITS);
61    let _solution2 = grounder.grind().expect("Should find a valid solution");
62
63    // Both solutions should be valid (though they contain different nonces)
64    // We verify by checking that grinding succeeds
65    assert!(grind_pow::<KeccakPoW>(challenge, BITS).is_some());
66}