distributed_cards/
deck.rs

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)]
10/// The [Deck] struct is the starting point to shuffle. It contains n cards. The deck doesn't care
11/// what cards it represents.
12///
13/// # Example
14///
15/// ```
16/// # use distributed_cards::{Deck, Prime, RsaParameter};
17/// # use uuid::Uuid;
18/// # use rand::thread_rng;
19/// let rng = &mut thread_rng();
20/// let primes = [Prime::random(128, rng), Prime::random(128, rng)]; // each participant contributes one prime
21/// let rsa_parameter = RsaParameter::from_primes(&primes);
22/// let uuid = Uuid::from_u128(0x_1905709b_e2ae_469c_9589_4e37dcf3e5bc); // must be unique and unpredictable for each shuffle
23/// let deck = Deck::new(104, uuid);
24/// let (encrypted_deck, key) = deck.shuffle_encrypt(&rsa_parameter, rng);
25/// assert!(deck.is_shuffle_encrypt_valid(&key, &encrypted_deck));
26/// ```
27pub struct Deck {
28    num_cards: u32,
29    shuffle_id: Uuid,
30}
31
32impl Deck {
33    /// Creates a new deck with n cards numbered 0 up to n-1. The given shuffle_id must be unique
34    /// over all shuffles, but both parameters have to be the same for each participant
35    pub fn new(num_cards: u32, shuffle_id: Uuid) -> Deck {
36        Deck {
37            num_cards,
38            shuffle_id,
39        }
40    }
41
42    // output format of card: [1] [4 byte card_id] [16 byte shuffle_id]
43    // the number of bits required should always be exactly 161
44    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
79/// 1st shuffling phase
80impl 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
108/// 1st shuffling phase
109impl 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    /// returns true if the shuffle_encrypt deck is obviously tampered with, doesn't catch all cases
123    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    /// checks if the shuffle_encrypt mechanism was executed correctly and it can be reversed again
135    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
144// 2nd shuffling phase
145impl 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    /// removes shuffling key from cards and encrypts each card with a unique random key
157    /// returns the deck and all card specific keys
158    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    /// returns true if the shuffle_encrypt deck is obviously tampered with, doesn't catch all cases
173    pub fn is_encrypt_card_specific_invalid(&self, num_cards: u32) -> bool {
174        num_cards != self.cards.len() as u32
175    }
176
177    /// checks whether the encrypt_card_specific function was executed correctly
178    /// needs to know the keys involved, so can only be called for peers after the game has ended
179    /// and everyone published all their keys
180    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    /// Returns None on error. The caller has to check whether there are duplicate cards in the deck
196    /// If there are duplicates the peer who put the first card specific keys on the deck tampered
197    /// with the deck
198    ///
199    /// # Panics
200    ///
201    /// If card_id >= num_cards
202    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        // shuffle phase 1
330        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        // shuffle phase 2
336        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        // decrypt ingame
352        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}