Skip to main content

race_core/
secret.rs

1use std::{collections::HashMap, sync::Arc};
2
3use race_api::error::{Error, Result};
4
5use crate::{
6    encryptor::EncryptorT,
7    types::{Ciphertext, DecisionId, RandomId, SecretDigest, SecretKey},
8};
9
10#[derive(Debug)]
11pub struct RandomSecretGroup {
12    size: usize,
13    mask: SecretKey,
14    locks: Vec<SecretKey>,
15}
16
17/// Represent a private state contains generated secrets.
18///
19/// # Random Secrets
20///
21/// A group of secrets will be created when a new randomness is
22/// initialized.  The group contains a mask secret and a list of lock
23/// secrets.  Use `mask`, `unmask` and `lock` to encrypt the
24/// ciphertexts from a randomness.
25///
26/// The mask secret should never be shared with others.  If all mask
27/// secrets are shared, then the whole randomness is possibly
28/// revealed.  We only share lock secrets When reveal or assign a
29/// random item.
30///
31/// # Decision Secrets
32///
33/// A decision is an immutable hidden answer from a player.  We
34/// generate the secret when encrypting the answer.  By sharing the
35/// secret, the answer is revealed.
36///
37#[derive(Debug)]
38pub struct SecretState {
39    encryptor: Arc<dyn EncryptorT>,
40    random_secrets: HashMap<RandomId, RandomSecretGroup>,
41    decision_secrets: HashMap<DecisionId, SecretKey>,
42}
43
44impl SecretState {
45    pub fn new(encryptor: Arc<dyn EncryptorT>) -> Self {
46        Self {
47            encryptor,
48            random_secrets: HashMap::new(),
49            decision_secrets: HashMap::new(),
50        }
51    }
52
53    pub fn clear(&mut self) {
54        self.random_secrets.clear();
55        self.decision_secrets.clear();
56    }
57
58    pub fn gen_random_secrets(&mut self, random_id: RandomId, size: usize) {
59        let g = RandomSecretGroup {
60            size,
61            mask: self.encryptor.gen_secret(),
62            locks: std::iter::repeat_with(|| self.encryptor.gen_secret())
63                .take(size)
64                .collect(),
65        };
66        self.random_secrets.insert(random_id, g);
67    }
68
69    pub fn is_random_loaded(&self, random_id: RandomId) -> bool {
70        self.random_secrets.contains_key(&random_id)
71    }
72
73    pub fn is_decision_loaded(&self, decision_id: DecisionId) -> bool {
74        self.decision_secrets.contains_key(&decision_id)
75    }
76
77    pub fn get_random_lock(&self, random_id: RandomId, index: usize) -> Result<SecretKey> {
78        if let Some(g) = self.random_secrets.get(&random_id) {
79            if let Some(k) = g.locks.get(index) {
80                Ok(k.clone())
81            } else {
82                Err(Error::InvalidKeyIndex)
83            }
84        } else {
85            Err(Error::InvalidRandomId)
86        }
87    }
88
89    pub fn get_decision_secret(&self, decision_id: DecisionId) -> Option<SecretKey> {
90        self.decision_secrets
91            .get(&decision_id)
92            .map(|s| s.to_owned())
93    }
94
95    pub fn mask(
96        &mut self,
97        random_id: RandomId,
98        mut ciphertexts: Vec<Ciphertext>,
99    ) -> Result<Vec<Ciphertext>> {
100        let g = self
101            .random_secrets
102            .get(&random_id)
103            .ok_or(Error::InvalidRandomId)?;
104
105        if g.size != ciphertexts.len() {
106            return Err(Error::InvalidCiphertextsSize(g.size as _, ciphertexts.len() as _));
107        }
108
109        ciphertexts.iter_mut().for_each(|c| {
110            self.encryptor.apply(&g.mask, c);
111        });
112
113        Ok(ciphertexts)
114    }
115
116    pub fn unmask(
117        &mut self,
118        random_id: RandomId,
119        mut ciphertexts: Vec<Ciphertext>,
120    ) -> Result<Vec<Ciphertext>> {
121        let g = self
122            .random_secrets
123            .get(&random_id)
124            .ok_or(Error::InvalidRandomId)?;
125
126        if g.size != ciphertexts.len() {
127            return Err(Error::InvalidCiphertextsSize(g.size as _, ciphertexts.len() as _));
128        }
129
130        ciphertexts.iter_mut().for_each(|c| {
131            self.encryptor.apply(&g.mask, c);
132        });
133
134        Ok(ciphertexts)
135    }
136
137    pub fn lock(
138        &mut self,
139        random_id: RandomId,
140        ciphertexts: Vec<Ciphertext>,
141    ) -> Result<Vec<(Ciphertext, SecretDigest)>> {
142        let g = self
143            .random_secrets
144            .get(&random_id)
145            .ok_or(Error::InvalidRandomId)?;
146
147        if g.size != ciphertexts.len() {
148            return Err(Error::InvalidCiphertextsSize(g.size as _, ciphertexts.len() as _));
149        }
150
151        Ok(ciphertexts
152            .into_iter()
153            .enumerate()
154            .map(|(i, mut c)| {
155                let lock = g.locks.get(i).unwrap();
156                let digest = self.encryptor.digest(lock);
157                self.encryptor.apply(lock, c.as_mut());
158                (c, digest)
159            })
160            .collect())
161    }
162
163    pub fn encrypt_answer(
164        &mut self,
165        decision_id: DecisionId,
166        answer: String,
167    ) -> Result<(Ciphertext, SecretDigest)> {
168        let secret = self.encryptor.gen_secret();
169        let mut ciphertext = answer.as_bytes().to_owned();
170        self.encryptor.apply(&secret, &mut ciphertext);
171        let digest = self.encryptor.digest(&secret);
172        self.decision_secrets.insert(decision_id, secret);
173        Ok((ciphertext, digest))
174    }
175
176    pub fn list_random_secrets(&self) -> Vec<&RandomSecretGroup> {
177        self.random_secrets.values().collect()
178    }
179
180    pub fn list_decision_secerts(&self) -> Vec<&SecretKey> {
181        self.decision_secrets.values().collect()
182    }
183}