tor_hscrypto/pow/v1/
verify.rs
1use crate::pow::err::Error;
4use crate::pow::v1::challenge::Challenge;
5use crate::pow::v1::{err::RuntimeErrorV1, err::SolutionErrorV1, types::Instance, types::Solution};
6use equix::{EquiXBuilder, HashError, RuntimeOption};
7
8use super::Seed;
9
10pub struct Verifier {
15 instance: Instance,
17 equix: EquiXBuilder,
19}
20
21impl Verifier {
22 pub fn new(instance: Instance) -> Self {
24 Self {
25 instance,
26 equix: Default::default(),
27 }
28 }
29
30 pub fn new_with_equix(instance: Instance, equix: EquiXBuilder) -> Self {
32 Self { instance, equix }
33 }
34
35 pub fn runtime(&mut self, option: RuntimeOption) -> &mut Self {
39 self.equix.runtime(option);
40 self
41 }
42
43 pub fn check(&self, solution: &Solution) -> Result<(), Error> {
47 match self.check_seed(solution) {
48 Err(e) => Err(Error::BadSolution(e.into())),
49 Ok(()) => {
50 let challenge = Challenge::new(&self.instance, solution.effort(), solution.nonce());
51 match challenge.check_effort(&solution.proof_to_bytes()) {
52 Err(e) => Err(Error::BadSolution(e.into())),
53 Ok(()) => match self.equix.verify(challenge.as_ref(), solution.proof()) {
54 Ok(()) => Ok(()),
55 Err(equix::Error::HashSum) => {
56 Err(Error::BadSolution(SolutionErrorV1::HashSum.into()))
57 }
58 Err(equix::Error::Hash(HashError::ProgramConstraints)) => Err(
59 Error::BadSolution(SolutionErrorV1::ChallengeConstraints.into()),
60 ),
61 Err(e) => Err(Error::VerifyRuntime(RuntimeErrorV1::EquiX(e).into())),
62 },
63 }
64 }
65 }
66 }
67
68 fn check_seed(&self, solution: &Solution) -> Result<(), SolutionErrorV1> {
73 if solution.seed_head() == self.instance.seed().head() {
74 Ok(())
75 } else {
76 Err(SolutionErrorV1::Seed)
77 }
78 }
79
80 pub fn seed(&self) -> &Seed {
82 self.instance.seed()
83 }
84}