aven_protocol/claim/
codec.rs1use anyhow::{Result, ensure};
2use ed25519_dalek::{Signature, VerifyingKey};
3
4pub use crate::codec::{bytes, cce, hash};
5
6use super::{CLAIM_BYTES, GENESIS_BYTES, Genesis, LocalSharedStatePackageContext};
7
8pub const MEMBERSHIP_SIGN: &str = "aven-e2ee/v1/membership/sign";
9
10pub fn state_hash(state: &[u8]) -> [u8; 32] {
11 hash(&cce("aven-e2ee/v1/membership/state", &[state]))
12}
13
14pub fn membership_core(
16 vault: &[u8],
17 sequence: u64,
18 head: &[u8],
19 signer: &[u8],
20 action: u8,
21 body: &[u8],
22 state: &[u8],
23) -> Vec<u8> {
24 let mut out = vec![1];
25 bytes(&mut out, vault);
26 out.extend(sequence.to_be_bytes());
27 bytes(&mut out, head);
28 out.push(1);
29 bytes(&mut out, signer);
30 out.push(action);
31 bytes(&mut out, body);
32 bytes(&mut out, &state_hash(state));
33 out
34}
35
36pub fn valid(condition: bool) -> Result<()> {
37 ensure!(condition, "error seed-claim-invalid");
38 Ok(())
39}
40
41pub struct Reader<'a>(pub &'a [u8]);
42
43impl<'a> Reader<'a> {
44 pub fn take(&mut self, n: usize) -> Result<&'a [u8]> {
45 valid(n <= self.0.len())?;
46 let (value, rest) = self.0.split_at(n);
47 self.0 = rest;
48 Ok(value)
49 }
50
51 pub fn array<const N: usize>(&mut self) -> Result<[u8; N]> {
52 Ok(self.take(N)?.try_into()?)
53 }
54
55 pub fn blob(&mut self, n: usize) -> Result<&'a [u8]> {
56 valid(u32::from_be_bytes(self.array()?) as u64 == n as u64)?;
57 self.take(n)
58 }
59
60 pub fn end(self) -> Result<()> {
61 valid(self.0.is_empty())
62 }
63}
64
65pub fn claim_record(request: &[u8]) -> Result<&[u8]> {
66 valid(request.len() == CLAIM_BYTES)?;
67 let mut reader = Reader(request);
68 valid(reader.take(6)? == b"AVCL\0\x01")?;
69 let record = reader.blob(GENESIS_BYTES)?;
70 reader.end()?;
71 Ok(record)
72}
73
74type Components<'a> = (&'a [u8], &'a [u8], &'a [u8], &'a [u8]);
75
76pub fn components(record: &[u8]) -> Result<Components<'_>> {
77 valid(record.len() == GENESIS_BYTES)?;
78 let mut reader = Reader(record);
79 valid(reader.take(1)? == [1])?;
80 let parts = (
81 reader.blob(229)?,
82 reader.blob(280)?,
83 reader.blob(312)?,
84 reader.blob(64)?,
85 );
86 reader.end()?;
87 Ok(parts)
88}
89
90pub(super) fn parse(record: &[u8]) -> Result<Genesis> {
91 let (core, state, attachments, signature) = components(record)?;
92 let mut r = Reader(state);
93 valid(r.take(7)? == b"AVGS\0\x01\x01")?;
94 let vault_id = r.array()?;
95 valid(r.take(4)? == [0, 0, 0, 1])?;
96 let device = r.array()?;
97 let signing_public = r.array()?;
98 let hpke_public = r.array()?;
99 let verifier = r.array()?;
100 valid(r.take(4)? == 1_u32.to_be_bytes())?;
101 let claim = r.array()?;
102 valid(r.take(1)? == [1])?;
103 let generation_id = r.array()?;
104 let generation_commitment = r.array()?;
105 valid(r.take(8)? == [0; 8])?;
106 r.end()?;
107
108 let mut r = Reader(core);
109 valid(r.take(1)? == [1])?;
110 valid(r.blob(32)? == vault_id)?;
111 valid(r.take(8)? == [0; 8])?;
112 valid(r.blob(32)? == [0; 32])?;
113 valid(r.take(1)? == [1])?;
114 valid(r.blob(32)? == device)?;
115 valid(r.take(1)? == [1])?;
116 let mut body = Reader(r.blob(70)?);
117 valid(body.take(6)? == b"AVGC\0\x01")?;
118 let setup = body.array()?;
119 valid(body.take(32)? == claim)?;
120 body.end()?;
121 valid(r.blob(32)? == state_hash(state))?;
122 r.end()?;
123
124 let mut r = Reader(attachments);
125 valid(r.take(9)? == b"AVGA\0\x01\x01\x01\x01")?;
126 valid(r.blob(32)? == device)?;
127 valid(r.blob(32)? == hpke_public)?;
128 r.blob(32)?;
129 r.blob(191)?;
130 r.end()?;
131
132 let public = VerifyingKey::from_bytes(&signing_public)
133 .map_err(|_| anyhow::anyhow!("error seed-claim-signature"))?;
134 let signature = Signature::from_slice(signature)
135 .map_err(|_| anyhow::anyhow!("error seed-claim-signature"))?;
136 public
137 .verify_strict(&cce(MEMBERSHIP_SIGN, &[core, attachments]), &signature)
138 .map_err(|_| anyhow::anyhow!("error seed-claim-signature"))?;
139 Ok(Genesis {
140 record: record.try_into()?,
141 context: LocalSharedStatePackageContext {
142 vault_id,
143 generation_id,
144 },
145 setup,
146 claim,
147 device,
148 signing_public,
149 hpke_public,
150 verifier,
151 generation_commitment,
152 })
153}