1use {
2 crate::{ PublicIdentity, PublicIdentityInterface },
3 copernica_common::{constants::*, u8_to_u64, u16_to_u8, u64_to_u8 },
4 anyhow::{Result, anyhow},
5 std::fmt,
6 core::hash::{Hash}
7};
8pub fn bloom_filter_index(
9 s: &str,
10) -> Result<BFI> {
11 use std::str;
12 use cryptoxide::digest::Digest as _;
13 let mut hash_orig = [0; 32];
14 let mut b = cryptoxide::blake2b::Blake2b::new(32);
15 b.input(&s.as_bytes());
16 b.result(&mut hash_orig);
17 let mut bloom_filter_index_array: BFI = BFI::new();
18 let mut count = 0;
19 for n in 0..BLOOM_FILTER_INDEX_ELEMENT_LENGTH {
20 let mut hash_derived = [0; 32];
21 let mut b = cryptoxide::blake2b::Blake2b::new(32);
22 let mut s: String = "".into();
23 for byte in hash_orig.iter() {
24 s.push_str(format!("{:x}", byte).as_str());
25 }
26 s.push_str(format!("{}", n).as_str());
27 b.input(&s.as_bytes());
28 b.result(&mut hash_derived);
29 s = "".into();
30 for byte in hash_derived.iter() {
31 s.push_str(format!("{:x}", byte).as_str());
32 }
33 let subs = s
34 .as_bytes()
35 .chunks(16)
36 .map(str::from_utf8)
37 .collect::<Result<Vec<&str>, _>>()?;
38 let mut index: u64 = 0;
39 for sub in subs {
40 let o = u64::from_str_radix(&sub, 16)?;
41 index = (index + o) % BLOOM_FILTER_LENGTH as u64;
42 }
43 bloom_filter_index_array.0[count] = index as u16;
44 count += 1;
45 }
46 Ok(bloom_filter_index_array)
47}
48#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Debug, Hash)]
49pub struct BFI(pub [u16; BLOOM_FILTER_INDEX_ELEMENT_LENGTH]);
50impl BFI {
51 pub fn new() -> Self {
52 Self([0; BLOOM_FILTER_INDEX_ELEMENT_LENGTH as usize])
53 }
54 pub fn to_bytes(&self) -> [u8; BFI_BYTE_SIZE] {
55 let mut bbfi: [u8; BFI_BYTE_SIZE] = [0; BFI_BYTE_SIZE];
56 let mut count = 0;
57 for i in self.0.iter() {
58 let two_u8 = u16_to_u8(*i);
59 bbfi[count] = two_u8[0];
60 bbfi[count+1] = two_u8[1];
61 count+=2;
62 }
63 bbfi
64 }
65 pub fn from_bytes(bbfi: [u8; BFI_BYTE_SIZE]) -> Self {
66 Self([((bbfi[0] as u16) << 8) | bbfi[1] as u16,
67 ((bbfi[2] as u16) << 8) | bbfi[3] as u16,
68 ((bbfi[4] as u16) << 8) | bbfi[5] as u16,
69 ((bbfi[6] as u16) << 8) | bbfi[7] as u16])
70 }
71}
72#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Debug, Hash)]
73pub struct BFIS(pub [BFI; BFI_COUNT]);
74impl BFIS {
75 pub fn new(bfis: [BFI; BFI_COUNT]) -> Self {
76 Self(bfis)
77 }
78}
79#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
80pub struct HBFI {
81 pub request_pid: PublicIdentityInterface,
83 pub response_pid: PublicIdentity,
84 pub req: BFI, pub res: BFI, pub app: BFI, pub m0d: BFI, pub fun: BFI, pub arg: BFI, pub frm: u64, }
92impl HBFI {
93 pub fn new(request_pid: PublicIdentityInterface
94 ,response_pid: PublicIdentity
95 , app: &str
96 , m0d: &str
97 , fun: &str
98 , arg: &str
99 ) -> Result<HBFI> {
100 Ok(HBFI {
101 request_pid: request_pid.clone(),
102 response_pid: response_pid.clone(),
103 req: request_pid.bloom_filter_index()?,
104 res: bloom_filter_index(&format!("{}", response_pid))?,
105 app: bloom_filter_index(app)?,
106 m0d: bloom_filter_index(m0d)?,
107 fun: bloom_filter_index(fun)?,
108 arg: bloom_filter_index(arg)?,
109 frm: 0,
110 })
111 }
112 pub fn to_bfis(&self) -> BFIS {
113 BFIS::new([ self.req.clone()
114 , self.res.clone()
115 , self.app.clone()
116 , self.m0d.clone()
117 , self.fun.clone()
118 , self.arg.clone()
119 ])
120 }
121 pub fn offset(mut self, frm: u64) -> Self {
122 self.frm = frm;
123 self
124 }
125 pub fn encrypt_for(&self, request_pid: PublicIdentityInterface) -> Result<Self> {
126 Ok(HBFI { request_pid: request_pid.clone()
127 , response_pid: self.response_pid.clone()
128 , req: request_pid.bloom_filter_index()?
129 , res: self.res.clone()
130 , app: self.app.clone()
131 , m0d: self.m0d.clone()
132 , fun: self.fun.clone()
133 , arg: self.arg.clone()
134 , frm: self.frm.clone()
135 })
136 }
137 pub fn cleartext_repr(&self) -> Result<Self> {
138 let absent_request_pid = PublicIdentityInterface::Absent;
139 Ok(HBFI { request_pid: absent_request_pid.clone()
140 , response_pid: self.response_pid.clone()
141 , req: absent_request_pid.bloom_filter_index()?
142 , res: self.res.clone()
143 , app: self.app.clone()
144 , m0d: self.m0d.clone()
145 , fun: self.fun.clone()
146 , arg: self.arg.clone()
147 , frm: self.frm.clone()
148 })
149 }
150 pub fn from_bytes(data: &[u8]) -> Result<Self> {
151 match data.len() {
152 CYPHERTEXT_HBFI_SIZE => {
153 let mut bfis: Vec<BFI> = Vec::with_capacity(BFI_COUNT);
154 let mut count = 0;
155 for _ in 0..BFI_COUNT {
156 let mut bbfi = [0u8; BFI_BYTE_SIZE];
157 bbfi.clone_from_slice(&data[count..count+BFI_BYTE_SIZE]);
158 bfis.push(BFI::from_bytes(bbfi));
159 count += BFI_BYTE_SIZE;
160 }
161 let mut frm = [0u8; FRAME_SIZE];
162 frm.clone_from_slice(&data[HBFI_FRAME_START..HBFI_FRAME_END]);
163 let frm: u64 = u8_to_u64(frm);
164 let mut res_key = [0u8; ID_SIZE + CC_SIZE];
165 res_key.clone_from_slice(&data[HBFI_RESPONSE_KEY_START..HBFI_RESPONSE_KEY_END]);
166 let mut req_key = [0u8; ID_SIZE + CC_SIZE];
167 req_key.clone_from_slice(&data[HBFI_REQUEST_KEY_START..HBFI_REQUEST_KEY_END]);
168 Ok(HBFI { response_pid: PublicIdentity::from(res_key)
169 , request_pid: PublicIdentityInterface::new(PublicIdentity::from(req_key))
170 , res: bfis[0].clone()
171 , req: bfis[1].clone()
172 , app: bfis[2].clone()
173 , m0d: bfis[3].clone()
174 , fun: bfis[4].clone()
175 , arg: bfis[5].clone()
176 , frm})
177 },
178 CLEARTEXT_HBFI_SIZE => {
179 let mut bfis: Vec<BFI> = Vec::with_capacity(BFI_COUNT);
180 let mut count = 0;
181 for _ in 0..BFI_COUNT {
182 let mut bbfi = [0u8; BFI_BYTE_SIZE];
183 bbfi.clone_from_slice(&data[count..count+BFI_BYTE_SIZE]);
184 bfis.push(BFI::from_bytes(bbfi));
185 count += BFI_BYTE_SIZE;
186 }
187 let mut frm = [0u8; FRAME_SIZE];
188 frm.clone_from_slice(&data[HBFI_FRAME_START..HBFI_FRAME_END]);
189 let frm: u64 = u8_to_u64(frm);
190 let mut res_key = [0u8; ID_SIZE + CC_SIZE];
191 res_key.clone_from_slice(&data[HBFI_RESPONSE_KEY_START..HBFI_RESPONSE_KEY_END]);
192 Ok(HBFI { response_pid: PublicIdentity::from(res_key)
193 , request_pid: PublicIdentityInterface::Absent
194 , res: bfis[0].clone()
195 , req: bfis[1].clone()
196 , app: bfis[2].clone()
197 , m0d: bfis[3].clone()
198 , fun: bfis[4].clone()
199 , arg: bfis[5].clone()
200 , frm})
201 }
202 _ => Err(anyhow!("Length of data used to reconstruct a HBFI is unrecognised")),
203 }
204
205 }
206 pub fn as_bytes(&self) -> Vec<u8> {
207 let mut buf: Vec<u8> = vec![];
208 let res = self.res.to_bytes();
209 let req = self.req.to_bytes();
210 let app = self.app.to_bytes();
211 let m0d = self.m0d.to_bytes();
212 let fun = self.fun.to_bytes();
213 let arg = self.arg.to_bytes();
214 let frm = &u64_to_u8(self.frm);
215 let mut ids_buf: Vec<u8> = vec![];
216 match &self.request_pid {
217 PublicIdentityInterface::Present { public_identity } => {
218 ids_buf.extend_from_slice(self.response_pid.key().as_ref());
219 ids_buf.extend_from_slice(self.response_pid.chain_code().as_ref());
220 ids_buf.extend_from_slice(public_identity.key().as_ref());
221 ids_buf.extend_from_slice(public_identity.chain_code().as_ref());
222 },
223 PublicIdentityInterface::Absent => {
224 ids_buf.extend_from_slice(self.response_pid.key().as_ref());
225 ids_buf.extend_from_slice(self.response_pid.chain_code().as_ref());
226 },
227 }
228 buf.extend_from_slice(&res);
229 buf.extend_from_slice(&req);
230 buf.extend_from_slice(&app);
231 buf.extend_from_slice(&m0d);
232 buf.extend_from_slice(&fun);
233 buf.extend_from_slice(&arg);
234 buf.extend_from_slice(frm);
235 buf.extend_from_slice(&ids_buf);
236 buf
237 }
238}
239impl fmt::Debug for HBFI {
240 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
241 match &*self {
242 HBFI { request_pid, response_pid, res, req, app, m0d, fun, arg, frm } =>
243 write!(f, "req_pid:{:?},res_pid:{:?},req:{:?},res:{:?},app:{:?},m0d:{:?},fun:{:?},arg:{:?},frm:{:?}", request_pid, response_pid, req, res, app, m0d, fun, arg, frm),
244 }
245 }
246}
247impl fmt::Display for HBFI {
248 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
249 match &*self {
250 HBFI { request_pid, response_pid, res, req, app, m0d, fun, arg, frm } =>
251 write!(f, "req_pid:{:?},res_pid:{:?},req:{:?},res:{:?},app:{:?},m0d:{:?},fun:{:?},arg:{:?},frm:{:?}", request_pid, response_pid, req, res, app, m0d, fun, arg, frm),
252 }
253 }
254}
255#[cfg(test)]
256mod tests {
257 use super::*;
258
259 #[test]
260 fn test_bloom_filter_index() {
261 let actual = bloom_filter_index("9".into()).unwrap();
262 let expected: [u16; BLOOM_FILTER_INDEX_ELEMENT_LENGTH as usize] =
263 [19283, 50425, 20212, 47266];
264 assert_eq!(actual, expected);
265 }
266}