ouisync/protocol/
proof.rs1use super::repository::RepositoryId;
2use crate::{
3 crypto::{
4 sign::{Keypair, PublicKey, Signature},
5 Hash, Hashable,
6 },
7 version_vector::VersionVector,
8};
9use serde::{Deserialize, Serialize};
10use std::ops::Deref;
11use thiserror::Error;
12
13#[derive(Clone, Eq, PartialEq, Debug)]
16pub struct Proof(UntrustedProof);
17
18impl Proof {
19 pub fn new(
21 writer_id: PublicKey,
22 version_vector: VersionVector,
23 hash: Hash,
24 write_keys: &Keypair,
25 ) -> Self {
26 let signature_material = signature_material(&writer_id, &version_vector, &hash);
27 let signature = write_keys.sign(signature_material.as_ref());
28
29 Self::new_unchecked(writer_id, version_vector, hash, signature)
30 }
31
32 pub fn new_unchecked(
36 writer_id: PublicKey,
37 version_vector: VersionVector,
38 hash: Hash,
39 signature: Signature,
40 ) -> Self {
41 Self(UntrustedProof {
42 writer_id,
43 version_vector,
44 hash,
45 signature,
46 })
47 }
48
49 pub fn into_version_vector(self) -> VersionVector {
50 self.0.version_vector
51 }
52}
53
54impl Deref for Proof {
55 type Target = UntrustedProof;
56
57 fn deref(&self) -> &Self::Target {
58 &self.0
59 }
60}
61
62#[derive(Clone, Eq, PartialEq, Debug, Serialize, Deserialize)]
63pub struct UntrustedProof {
64 pub writer_id: PublicKey,
65 pub version_vector: VersionVector,
66 pub hash: Hash,
67 pub signature: Signature,
68}
69
70impl UntrustedProof {
71 pub fn verify(self, repository_id: &RepositoryId) -> Result<Proof, ProofError> {
72 let signature_material =
73 signature_material(&self.writer_id, &self.version_vector, &self.hash);
74 if repository_id
75 .write_public_key()
76 .verify(signature_material.as_ref(), &self.signature)
77 {
78 Ok(Proof(self))
79 } else {
80 Err(ProofError)
81 }
82 }
83}
84
85impl From<Proof> for UntrustedProof {
86 fn from(proof: Proof) -> Self {
87 proof.0
88 }
89}
90
91fn signature_material(writer_id: &PublicKey, version_vector: &VersionVector, hash: &Hash) -> Hash {
92 (writer_id, version_vector, hash).hash()
93}
94
95#[derive(Debug, Error)]
96#[error("proof is invalid")]
97pub struct ProofError;