1use crate::{key_provider::Static, Error, KeyProvider, Root};
5
6pub(crate) type KeyId = [u8; 8];
12
13#[derive(Debug)]
18pub struct Field {
19 field_key: Static,
22}
23
24impl Field {
25 pub(crate) fn new(root: &Root, collection: &[u8], name: &[u8]) -> Result<Field, Error> {
34 Ok(Field {
35 field_key: Self::field_key_provider(root, collection, name)?,
36 })
37 }
38
39 pub(crate) fn subkey(&self, subkey: &mut [u8], identifier: &[u8]) -> Result<(), Error> {
47 self.field_key.derive_key(subkey, identifier)
48 }
49
50 pub fn key_id(&self) -> Result<KeyId, Error> {
62 let mut id: KeyId = Default::default();
63 self.field_key.derive_key(&mut id, b"Field.key_id")?;
64 Ok(id)
65 }
66
67 fn field_key_provider(root: &Root, collection: &[u8], name: &[u8]) -> Result<Static, Error> {
78 let mut id = Vec::<u8>::with_capacity(
80 collection
81 .len()
82 .saturating_add(name.len())
83 .saturating_add(1),
84 );
85
86 id.extend(collection);
87 id.push(0);
88 id.extend(name);
89
90 let mut field_key: [u8; 32] = Default::default();
91 root.derive_key(&mut field_key, &id)?;
92
93 Static::new(&field_key)
94 }
95}
96
97#[cfg(test)]
98mod tests {
99 use super::*;
100 use crate::key_provider::Static;
101 use hex_literal::hex;
102 use std::sync::Arc;
103
104 #[test]
105 fn has_a_key_id() {
106 let rk = Arc::new(Static::new(b"this is a suuuuper long test key").unwrap());
107 let f = Root::new(rk)
108 .unwrap()
109 .field(b"users", b"full_name")
110 .unwrap();
111
112 assert_eq!(hex!["494d15e1 4ab748dd"], f.key_id().unwrap());
113 }
114
115 #[test]
116 fn different_fields_have_different_key_ids() {
117 let rk = Arc::new(Static::new(b"this is a suuuuper long test key").unwrap());
118 let root = Root::new(rk).unwrap();
119 let f1 = root.field(b"users", b"full_name").unwrap();
120 let f2 = root.field(b"users", b"date_of_birth").unwrap();
121
122 assert_ne!(f1.key_id().unwrap(), f2.key_id().unwrap());
123 }
124
125 #[test]
126 fn generates_subkey() {
127 let rk = Arc::new(Static::new(b"this is a suuuuper long test key").unwrap());
128 let f = Root::new(rk)
129 .unwrap()
130 .field(b"users", b"full_name")
131 .unwrap();
132
133 let mut smol_sk: [u8; 4] = Default::default();
134 f.subkey(&mut smol_sk, b"bob").unwrap();
135
136 assert_eq!(hex!["f2c1753f"], smol_sk);
137
138 let mut sk: [u8; 16] = Default::default();
139 f.subkey(&mut sk, b"bob").unwrap();
140
141 assert_eq!(hex!["f2c1753f 31c6cffe 6c387563 84ada729"], sk);
142
143 let mut sk: [u8; 32] = Default::default();
144 f.subkey(&mut sk, b"bob").unwrap();
145
146 assert_eq!(
147 hex!["f2c1753f 31c6cffe 6c387563 84ada729 480d6f9f 9dd228ae 5ccd833b b8eee70f"],
148 sk
149 );
150 }
151}