tlsn_core/attestation/
proof.rs1use std::fmt;
2
3use serde::{Deserialize, Serialize};
4
5use crate::{
6 attestation::{Attestation, Body, Header},
7 hash::HashAlgorithm,
8 merkle::{MerkleProof, MerkleTree},
9 serialize::CanonicalSerialize,
10 signing::{Signature, VerifyingKey},
11 CryptoProvider,
12};
13
14#[derive(Debug, Clone, Serialize, Deserialize)]
16pub struct AttestationProof {
17 signature: Signature,
18 header: Header,
19 body: BodyProof,
20}
21
22impl AttestationProof {
23 pub(crate) fn new(
24 provider: &CryptoProvider,
25 attestation: &Attestation,
26 ) -> Result<Self, AttestationError> {
27 let hasher = provider
28 .hash
29 .get(&attestation.header.root.alg)
30 .map_err(|e| AttestationError::new(ErrorKind::Provider, e))?;
31
32 let body = BodyProof::new(hasher, attestation.body.clone())?;
33
34 Ok(Self {
35 signature: attestation.signature.clone(),
36 header: attestation.header.clone(),
37 body,
38 })
39 }
40
41 pub fn verifying_key(&self) -> &VerifyingKey {
43 self.body.verifying_key()
44 }
45
46 pub fn verify(self, provider: &CryptoProvider) -> Result<Attestation, AttestationError> {
53 let signature_verifier = provider
54 .signature
55 .get(&self.signature.alg)
56 .map_err(|e| AttestationError::new(ErrorKind::Provider, e))?;
57
58 let body = self.body.verify_with_provider(provider, &self.header)?;
60
61 signature_verifier
63 .verify(
64 &body.verifying_key.data,
65 &CanonicalSerialize::serialize(&self.header),
66 &self.signature.data,
67 )
68 .map_err(|e| AttestationError::new(ErrorKind::Signature, e))?;
69
70 Ok(Attestation {
71 signature: self.signature,
72 header: self.header,
73 body,
74 })
75 }
76}
77
78#[derive(Debug, Clone, Serialize, Deserialize)]
80pub(crate) struct BodyProof {
81 body: Body,
82 proof: MerkleProof,
85}
86
87impl BodyProof {
88 pub(crate) fn new(
92 hasher: &dyn HashAlgorithm,
93 body: Body,
94 ) -> Result<BodyProof, AttestationError> {
95 let (indices, leaves): (Vec<_>, Vec<_>) = body
96 .hash_fields(hasher)
97 .into_iter()
98 .map(|(id, hash)| (id.0 as usize, hash))
99 .unzip();
100
101 let mut tree = MerkleTree::new(hasher.id());
102 tree.insert(hasher, leaves);
103
104 let proof = tree.proof(&indices);
105
106 Ok(BodyProof { body, proof })
107 }
108
109 pub(crate) fn verifying_key(&self) -> &VerifyingKey {
110 &self.body.verifying_key.data
111 }
112
113 pub(crate) fn verify_with_provider(
115 self,
116 provider: &CryptoProvider,
117 header: &Header,
118 ) -> Result<Body, AttestationError> {
119 let hasher = provider
120 .hash
121 .get(&header.root.alg)
122 .map_err(|e| AttestationError::new(ErrorKind::Provider, e))?;
123
124 let fields = self
125 .body
126 .hash_fields(hasher)
127 .into_iter()
128 .map(|(id, hash)| (id.0 as usize, hash));
129
130 self.proof
131 .verify(hasher, &header.root, fields)
132 .map_err(|e| AttestationError::new(ErrorKind::Body, e))?;
133
134 Ok(self.body)
135 }
136}
137
138#[derive(Debug, thiserror::Error)]
140pub struct AttestationError {
141 kind: ErrorKind,
142 source: Option<Box<dyn std::error::Error + Send + Sync>>,
143}
144
145impl AttestationError {
146 fn new<E>(kind: ErrorKind, source: E) -> Self
147 where
148 E: Into<Box<dyn std::error::Error + Send + Sync>>,
149 {
150 Self {
151 kind,
152 source: Some(source.into()),
153 }
154 }
155}
156
157impl fmt::Display for AttestationError {
158 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
159 f.write_str("attestation proof error: ")?;
160
161 match self.kind {
162 ErrorKind::Provider => f.write_str("provider error")?,
163 ErrorKind::Signature => f.write_str("signature error")?,
164 ErrorKind::Body => f.write_str("body proof error")?,
165 }
166
167 if let Some(source) = &self.source {
168 write!(f, " caused by: {}", source)?;
169 }
170
171 Ok(())
172 }
173}
174
175#[derive(Debug)]
176enum ErrorKind {
177 Provider,
178 Signature,
179 Body,
180}