1use crate::crypto::{Rsa, RsaParameter};
2use num_bigint_dig::BigUint;
3use rand::prelude::SliceRandom;
4use rand::{CryptoRng, RngCore};
5use serde::{Deserialize, Serialize};
6use std::convert::TryInto;
7use uuid::Uuid;
8
9#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
10pub struct Deck {
28 num_cards: u32,
29 shuffle_id: Uuid,
30}
31
32impl Deck {
33 pub fn new(num_cards: u32, shuffle_id: Uuid) -> Deck {
36 Deck {
37 num_cards,
38 shuffle_id,
39 }
40 }
41
42 fn encode_card(card: u32, shuffle_id: Uuid) -> BigUint {
45 (BigUint::from(1u32) << 160)
46 + (BigUint::from(card) << 128)
47 + BigUint::from(shuffle_id.as_u128())
48 }
49
50 fn decode_card(card: BigUint) -> Option<(u32, Uuid)> {
51 if card.bits() != 161 {
52 return None;
53 }
54 let card = card.to_bytes_be();
55 let id = u32::from_be_bytes(card[1..5].try_into().unwrap());
56 let uuid = Uuid::from_bytes(card[5..].try_into().unwrap());
57 Some((id, uuid))
58 }
59
60 fn to_encrypted_deck(&self) -> EncryptedDeck {
61 let cards = (0..self.num_cards)
62 .into_iter()
63 .map(|i| Deck::encode_card(i, self.shuffle_id))
64 .collect();
65 EncryptedDeck { cards }
66 }
67
68 pub fn get_cards(&self) -> Vec<BigUint> {
69 let deck = self.to_encrypted_deck();
70 deck.cards
71 }
72}
73
74#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
75pub struct EncryptedDeck {
76 cards: Vec<BigUint>,
77}
78
79impl Deck {
81 pub fn shuffle_encrypt<Rng: CryptoRng + RngCore>(
82 &self,
83 rsa_parameter: &RsaParameter,
84 rng: &mut Rng,
85 ) -> (EncryptedDeck, Rsa) {
86 let deck: EncryptedDeck = self.to_encrypted_deck();
87 deck.shuffle_encrypt(rsa_parameter, rng)
88 }
89
90 pub fn is_shuffle_encrypt_valid(&self, key: &Rsa, encrypted_deck: &EncryptedDeck) -> bool {
91 let deck: EncryptedDeck = self.to_encrypted_deck();
92 deck.is_shuffle_encrypt_valid(key, encrypted_deck)
93 }
94}
95
96impl EncryptedDeck {
97 fn encrypt(&self, key: &Rsa) -> EncryptedDeck {
98 let cards = self.cards.iter().map(|c| key.encrypt(c.clone())).collect();
99 EncryptedDeck { cards }
100 }
101
102 fn decrypt(&self, key: &Rsa) -> EncryptedDeck {
103 let cards = self.cards.iter().map(|c| key.decrypt(c.clone())).collect();
104 EncryptedDeck { cards }
105 }
106}
107
108impl EncryptedDeck {
110 pub fn shuffle_encrypt<Rng: CryptoRng + RngCore>(
111 &self,
112 rsa_parameter: &RsaParameter,
113 shuffle_rng: &mut Rng,
114 ) -> (EncryptedDeck, Rsa) {
115 let os_rng = &mut rand::rngs::OsRng;
116 let key = Rsa::gen_with_parameter(rsa_parameter.clone(), os_rng);
117 let mut deck = self.encrypt(&key);
118 deck.cards.shuffle(shuffle_rng);
119 (deck, key)
120 }
121
122 pub fn is_shuffle_encrypt_invalid(&self, num_cards: u32) -> bool {
124 if num_cards != self.cards.len() as u32 {
125 return true;
126 }
127 let num_cards = self.cards.len();
128 let mut cards = self.cards.clone();
129 cards.sort();
130 cards.dedup();
131 num_cards != cards.len()
132 }
133
134 pub fn is_shuffle_encrypt_valid(&self, key: &Rsa, result: &EncryptedDeck) -> bool {
136 let mut decrypted_result = result.decrypt(key);
137 decrypted_result.cards.sort();
138 let mut cards = self.cards.clone();
139 cards.sort();
140 cards == decrypted_result.cards
141 }
142}
143
144impl EncryptedDeck {
146 fn card_specific(&self, shuffle_key: &Rsa, keys: &[Rsa]) -> EncryptedDeck {
147 let cards = self
148 .cards
149 .iter()
150 .zip(keys)
151 .map(|(card, key)| shuffle_key.decrypt(key.encrypt(card.clone())))
152 .collect();
153 EncryptedDeck { cards }
154 }
155
156 pub fn encrypt_card_specific(
159 &self,
160 shuffle_key: &Rsa,
161 rsa_parameter: &RsaParameter,
162 ) -> (EncryptedDeck, Vec<Rsa>) {
163 let os_rng = &mut rand::rngs::OsRng;
164 let keys: Vec<Rsa> = (0..self.cards.len())
165 .into_iter()
166 .map(|_| Rsa::gen_with_parameter(rsa_parameter.clone(), os_rng))
167 .collect();
168 let deck = self.card_specific(shuffle_key, &keys);
169 (deck, keys)
170 }
171
172 pub fn is_encrypt_card_specific_invalid(&self, num_cards: u32) -> bool {
174 num_cards != self.cards.len() as u32
175 }
176
177 pub fn is_encrypt_card_specific_valid(
181 &self,
182 shuffle_key: &Rsa,
183 result: &EncryptedDeck,
184 keys: &[Rsa],
185 ) -> bool {
186 &self.card_specific(shuffle_key, keys) == result
187 }
188}
189
190impl EncryptedDeck {
191 pub fn from_biguints(cards: Vec<BigUint>) -> Self {
192 Self { cards }
193 }
194
195 pub fn decrypt_card(
203 &self,
204 card_id: u32,
205 shuffle_id: Uuid,
206 own_key: &Rsa,
207 other_keys: &[Rsa],
208 ) -> Option<u32> {
209 let decrypted = other_keys.iter().fold(
210 own_key.decrypt(self.cards[card_id as usize].clone()),
211 |card, key| key.decrypt(card),
212 );
213 let (card, uuid) = Deck::decode_card(decrypted)?;
214 if uuid == shuffle_id && card < self.cards.len() as u32 {
215 Some(card)
216 } else {
217 None
218 }
219 }
220
221 pub fn get_cards(&self) -> Vec<BigUint> {
222 self.cards.clone()
223 }
224}
225
226#[cfg(test)]
227mod test {
228 use super::*;
229 use crate::crypto::Prime;
230 use rand::thread_rng;
231
232 #[test]
233 fn encode_card() {
234 let expected = [
235 1u8, 0, 0, 0, 14, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
236 ];
237 assert_eq!(
238 Deck::encode_card(14, Uuid::from_slice(&expected[5..]).unwrap()).to_bytes_be(),
239 expected
240 )
241 }
242
243 #[test]
244 fn decode_card() {
245 let expected = [
246 1u8, 0, 0, 0, 14, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
247 ];
248 let card = BigUint::from_bytes_be(&expected);
249 assert_eq!(
250 Deck::decode_card(card),
251 Some((14, Uuid::from_bytes(expected[5..].try_into().unwrap())))
252 );
253 }
254
255 #[test]
256 fn decode_card_err() {
257 let expected = [
258 1u8, 0, 0, 0, 14, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
259 ];
260 assert_eq!(
261 Deck::decode_card(BigUint::from_bytes_be(&expected[1..])),
262 None
263 );
264 assert_eq!(
265 Deck::decode_card(BigUint::from_bytes_be(&expected) << 1),
266 None
267 );
268 }
269
270 #[test]
271 fn shuffle_encrypt() {
272 let rng = &mut thread_rng();
273 let primes = [Prime::random(128, rng), Prime::random(128, rng)];
274 let rsa_parameter = RsaParameter::from_primes(&primes);
275 let uuid = Uuid::from_u128(0x_1905709b_e2ae_469c_9589_4e37dcf3e5bc);
276 let deck = Deck::new(4, uuid);
277 let (encrypted_deck, key) = deck.shuffle_encrypt(&rsa_parameter, rng);
278 assert!(deck.is_shuffle_encrypt_valid(&key, &encrypted_deck));
279 }
280
281 #[test]
282 fn encrypt_card_specific() {
283 let rng = &mut thread_rng();
284 let primes = [Prime::random(128, rng), Prime::random(128, rng)];
285 let rsa_parameter = RsaParameter::from_primes(&primes);
286 let uuid = Uuid::from_u128(0x_1905709b_e2ae_469c_9589_4e37dcf3e5bc);
287 let deck = Deck::new(4, uuid);
288 let (encrypted_deck, key) = deck.shuffle_encrypt(&rsa_parameter, rng);
289 assert!(deck.is_shuffle_encrypt_valid(&key, &encrypted_deck));
290
291 let (phase_2, phase_2_keys) = encrypted_deck.encrypt_card_specific(&key, &rsa_parameter);
292 assert!(encrypted_deck.is_encrypt_card_specific_valid(&key, &phase_2, &phase_2_keys));
293 }
294
295 #[test]
296 fn decode() {
297 let rng = &mut thread_rng();
298 let primes = [Prime::random(128, rng), Prime::random(128, rng)];
299 let rsa_parameter = RsaParameter::from_primes(&primes);
300 let uuid = Uuid::from_u128(0x_1905709b_e2ae_469c_9589_4e37dcf3e5bc);
301 let deck = Deck::new(16, uuid);
302 let (encrypted_deck, key) = deck.shuffle_encrypt(&rsa_parameter, rng);
303 assert!(deck.is_shuffle_encrypt_valid(&key, &encrypted_deck));
304
305 let (phase_2, phase_2_keys) = encrypted_deck.encrypt_card_specific(&key, &rsa_parameter);
306 assert!(encrypted_deck.is_encrypt_card_specific_valid(&key, &phase_2, &phase_2_keys));
307
308 let mut decrypted: Vec<u32> = phase_2_keys
309 .iter()
310 .enumerate()
311 .map(|(i, key)| {
312 phase_2
313 .decrypt_card(i as u32, uuid.clone(), key, &[])
314 .unwrap()
315 })
316 .collect();
317 decrypted.sort();
318 assert_eq!(decrypted, (0..16).collect::<Vec<_>>());
319 }
320
321 #[test]
322 fn encrypt_card_2() {
323 let rng = &mut thread_rng();
324 let primes = [Prime::random(128, rng), Prime::random(128, rng)];
325 let rsa_parameter = RsaParameter::from_primes(&primes);
326 let shuffle_id = Uuid::from_u128(0x_1905709b_e2ae_469c_9589_4e37dcf3e5bc);
327 let deck = Deck::new(1, shuffle_id);
328
329 let (a_phase_1, a_shuffle_key) = deck.shuffle_encrypt(&rsa_parameter, rng);
331 assert!(deck.is_shuffle_encrypt_valid(&a_shuffle_key, &a_phase_1));
332 let (b_phase_1, b_shuffle_key) = a_phase_1.shuffle_encrypt(&rsa_parameter, rng);
333 assert!(a_phase_1.is_shuffle_encrypt_valid(&b_shuffle_key, &b_phase_1));
334
335 let (a_phase_2, a_phase_2_keys) =
337 b_phase_1.encrypt_card_specific(&a_shuffle_key, &rsa_parameter);
338 assert!(b_phase_1.is_encrypt_card_specific_valid(
339 &a_shuffle_key,
340 &a_phase_2,
341 &a_phase_2_keys
342 ));
343 let (b_phase_2, b_phase_2_keys) =
344 a_phase_2.encrypt_card_specific(&b_shuffle_key, &rsa_parameter);
345 assert!(a_phase_2.is_encrypt_card_specific_valid(
346 &b_shuffle_key,
347 &b_phase_2,
348 &b_phase_2_keys
349 ));
350
351 assert_eq!(
353 b_phase_2.decrypt_card(
354 0,
355 shuffle_id,
356 &a_phase_2_keys[0],
357 &[b_phase_2_keys[0].clone()]
358 ),
359 Some(0)
360 );
361 assert_eq!(
362 b_phase_2.decrypt_card(
363 0,
364 shuffle_id,
365 &b_phase_2_keys[0],
366 &[a_phase_2_keys[0].clone()]
367 ),
368 Some(0)
369 );
370 }
371
372 #[test]
373 fn serialize_encrypted() {
374 let encrypted_deck = EncryptedDeck {
375 cards: vec![BigUint::from(0x_1905709b_e2ae_469c_9589_4e37dcf3e5bc_u128)],
376 };
377 assert_eq!(
378 serde_json::to_string(&encrypted_deck).unwrap(),
379 r#"{"cards":[[3706971580,2508803639,3803072156,419786907]]}"#.to_owned()
380 );
381 }
382}