1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
//! Implementation of the double ratchet system/encryption as specified by [Signal][1]. //! //! The implementation follows the cryptographic recommendations provided by [Signal][2]. //! The AEAD Algorithm uses a constant Nonce. This might be changed in the future. //! //! # Example Usage: //! //! ## Standard: //! ``` //! use double_ratchet_2::ratchet::Ratchet; //! //! let sk = [1; 32]; // Initial Key created by a symmetric key agreement protocol //! let (mut bob_ratchet, public_key) = Ratchet::init_bob(sk); // Creating Bobs Ratchet (returns Bobs PublicKey) //! let mut alice_ratchet = Ratchet::init_alice(sk, public_key); // Creating Alice Ratchet with Bobs PublicKey //! let data = b"Hello World".to_vec(); // Data to be encrypted //! //! let (header, encrypted) = alice_ratchet.ratchet_encrypt(&data); // Encrypting message with Alice Ratchet (Alice always needs to send the first message) //! let decrypted = bob_ratchet.ratchet_decrypt(&header, &encrypted); // Decrypt message with Bobs Ratchet //! assert_eq!(data, decrypted) //! ``` //! //! ## With lost message: //! ``` //! # use double_ratchet_2::ratchet::Ratchet; //! //! let sk = [1; 32]; // Initial Key created by a symmetric key agreement protocol //! let (mut bob_ratchet, public_key) = Ratchet::init_bob(sk); // Creating Bobs Ratchet (returns Bobs PublicKey) //! let mut alice_ratchet = Ratchet::init_alice(sk, public_key); // Creating Alice Ratchet with Bobs PublicKey //! let data = b"Hello World".to_vec(); // Data to be encrypted //! //! let (header1, encrypted1) = alice_ratchet.ratchet_encrypt(&data); // Lost message //! let (header2, encrypted2) = alice_ratchet.ratchet_encrypt(&data); // Successful message //! //! let decrypted2 = bob_ratchet.ratchet_decrypt(&header2, &encrypted2); // Decrypting second message first //! let decrypted1 = bob_ratchet.ratchet_decrypt(&header1, &encrypted1); // Decrypting latter message //! //! let comp = decrypted1 == data && decrypted2 == data; //! assert!(comp); //! ``` //! //! ## Encryption before recieving inital message //! //! ```should_panic //! use double_ratchet_2::ratchet::Ratchet; //! let sk = [1; 32]; //! //! let (mut bob_ratchet, _) = Ratchet::init_bob(sk); //! let data = b"Hello World".to_vec(); //! //! let (_, _) = bob_ratchet.ratchet_encrypt(&data); //! ``` //! //! ## Encryption after recieving initial message //! However bob can (of course) also encrypt messages. This is possible, after decrypting the first message from alice. //! //! ``` //! use double_ratchet_2::ratchet::Ratchet; //! let sk = [1; 32]; //! //! let (mut bob_ratchet, public_key) = Ratchet::init_bob(sk); //! let mut alice_ratchet = Ratchet::init_alice(sk, public_key); //! //! let data = b"Hello World".to_vec(); //! //! let (header1, encrypted1) = alice_ratchet.ratchet_encrypt(&data); //! let _decrypted1 = bob_ratchet.ratchet_decrypt(&header1, &encrypted1); //! //! let (header2, encrypted2) = bob_ratchet.ratchet_encrypt(&data); //! let decrypted2 = alice_ratchet.ratchet_decrypt(&header2, &encrypted2); //! //! assert_eq!(data, decrypted2); //! ``` //! ## Constructing and Deconstructing Headers //! //! ``` //! # use double_ratchet_2::ratchet::Ratchet; //! # use double_ratchet_2::header::Header; //! # let sk = [1; 32]; //! # let (mut bob_ratchet, public_key) = Ratchet::init_bob(sk); //! # let mut alice_ratchet = Ratchet::init_alice(sk, public_key); //! # let data = b"hello World".to_vec(); //! # let (header, _) = alice_ratchet.ratchet_encrypt(&data); //! let header_bytes: Vec<u8> = header.clone().into(); //! let header_const = Header::from(header_bytes); //! assert_eq!(header, header_const); //! ``` //! //! # Features //! //! Currently the crate only supports one feature: ring. If feature is enabled the crate switches //! to ring-compat and uses ring as backend for Sha512 Hashing. May result in slightly better performance. //! //! //! TODO: //! - [x] Standard Double Ratchet //! - [ ] [Double Ratchet with encrypted headers][3] //! //! [1]: https://signal.org/docs/specifications/doubleratchet/ //! [2]: https://signal.org/docs/specifications/doubleratchet/#recommended-cryptographic-algorithms //! [3]: https://signal.org/docs/specifications/doubleratchet/#double-ratchet-with-header-encryption #![no_std] #![allow(stable_features)] extern crate alloc; pub use x25519_dalek::PublicKey; mod aead; mod dh; mod kdf_root; mod kdf_chain; /// Providing essential functions pub mod ratchet; /// Message Header pub mod header;