Pure Rust implementation of the Double Ratchet algorithm

Overview

Double Ratchet

A pure Rust implementation of the Double Ratchet, as specified by Trevor Perrin and Moxie Marlinspike.

The Double Ratchet allows two users to communicate securely: it provides its users with a confidential and authentic channel, which includes forward secrecy and future secrecy. After initialization with a shared secret key and an authenticated public key, the Double Ratchet will automatically handle all key management required to support this channel, which includes handling the decryption of messages that arrive out-of-order.

The Double Ratchet itself requires a public key crypto system that can perform Diffie-Hellman (DH) operations, a secret key crypto system that provides authenticated encryption with associated data (AEAD) and two key derivation functions (KDF). This crate aims to be agnostic towards the implementation of these functions: users of the crate implement the CryptoProvider trait and the DoubleRatchet struct should take care of the rest (but contact me if you have a use-case where the interface is not sufficient and I'll see if I can accommodate).

Examples

The following example corresponds to the way the Double Ratchet is used in the Signal protocol. For more details about the implementation, see tests/signal.rs, which also supplies SignalCryptoProvider. We assume that Alice and Bob share a secret key SK and Alice knows Bob's public key.

use double_ratchet::{DoubleRatchet};
use rand_os::RandOs;
let mut rng = OsRng::new().unwrap();

type DR = DoubleRatchet
   ;


   // Alice intializes and sends the first message

   let 
   mut alice 
   = DR
   ::
   new_alice(
   &SK, bobs_public_prekey, 
   None, 
   &
   mut rng);

   let pt0 
   = 
   b"Hello Bob";

   let (h0, ct0) 
   = alice.
   ratchet_encrypt(pt0, 
   b"A2B", 
   &
   mut rng);


   // Bob initializes and receives the first message

   let 
   mut bob 
   = DR
   ::
   new_bob(
   &SK, bobs_prekey_pair, 
   None);

   assert_eq!(
    
   Ok(
   Vec
   ::
   from(
   &pt0[..])),
    bob.
   ratchet_decrypt(
   &h0, 
   &ct0, 
   b"A2B")
);


   // After receiving the first message, Bob can send his replies

   let pt1 
   = 
   b"Hi Alice";

   let (h1, ct1) 
   = alice.
   ratchet_encrypt(pt1, 
   b"B2A", 
   &
   mut rng);

   let pt2 
   = 
   b"How are you?";

   let (h2, ct2) 
   = bob.
   ratchet_encrypt(pt2, 
   b"B2A", 
   &
   mut rng);

   assert_eq!(
    
   Ok(
   Vec
   ::
   from(
   &pt_b_0[..])),
    alice.
   ratchet_decrypt(
   &h_b_0, 
   &ct_b_0, 
   b"B2A")
);


   // Note that Alice has not yet received Bob's first message...

   let pt3 
   = 
   b"Good and you?";

   let (h3, ct3) 
   = alice.
   ratchet_encrypt(pt3, 
   b"A2B", 
   &
   mut rng);

   assert_eq!(
    
   Ok(
   Vec
   ::
   from(
   &pt3[..])),
    bob.
   ratchet_decrypt(
   &h3, 
   &ct3, 
   b"A2B")
);

   // ...but when she does get it she will be able to decrypt

   assert_eq!(
    
   Ok(
   Vec
   ::
   from(
   &pt1[..])),
    alice.
   ratchet_decrypt(
   &h1, 
   &ct1, 
   b"B2A")
);
  

Installation

The Double Ratchet crate is distributed through crates.io: install it by adding the following to your Cargo.toml:

[dependencies]
double-ratchet = "0.1"

The std feature is enabled by default. If you don't want to use std, compile with --no-default-features.

Documentation

The documentation is available here.

Future plans

This isn't even my final form! I intend to add at least the following features and am open for suggestions for more features.

  • a Header Encrypted variant of the Double Ratchet
  • generalize the KeyStore to allow automatic deletion of very old keys
  • provide a way for saving/restoring a DoubleRatchet to storage
  • Provide a non-allocating interface for encryption/decryption
You might also like...
Execute genetic algorithm (GA) simulations in a customizable and extensible way.

genevo genevo provides building blocks to run simulations of optimization and search problems using genetic algorithms (GA). The vision for genevo is

A Trig-less Line of Sight Algorithm in Two Dimensions

In many examples of 2D line-of-sight algorithms, expensive operations like trigonometry are used. Additionally, some methods have intentional inaccuracies in them for the sake of simplicity. Here, we give an algorithm which does not fudge the numbers, and uses only basic arithmetic: addition, subtraction, multiplication, and division. This is not intended to replace the existing algorithms, or even be more efficient in practice.

The labs of Raft consensus algorithm based on MadSim.

MadRaft The labs of Raft consensus algorithm based on MadSim. Some codes are derived from MIT 6.824 and PingCAP Talent Plan: Raft Lab. Thanks for thei

Maximum Relevance - Minimum redundancy feature selection algorithm

mrmr Maximum Relevance - Minimum redundancy feature selection algorithm implemented in Rust. Usage CLI app. It gets input from a csv dataset with head

Library that implements different versions of PPMD algorithm (compress and decompress)

ppmd-rs Library that implements different versions of PPMD algorithm (compress and decompress) Dependencies Rust 1.58 or newer Cargo How to build Clon

Online algorithm for mean and variance, with support for uneven weights

welford Online algorithm for mean and variance, with support for uneven weights. This implements the Welford's online algorithm for computing mean and

Rust implementation of real-coded GA for solving optimization problems and training of neural networks
Rust implementation of real-coded GA for solving optimization problems and training of neural networks

revonet Rust implementation of real-coded genetic algorithm for solving optimization problems and training of neural networks. The latter is also know

Raft implementation in Rust

rsraft Raft implementation in Rust. The aim of this project is implementing the Raft Consensus Algorithm as described in the paper, with the goal of f

Comments
  • Only DH ratchet once in a while?

    Only DH ratchet once in a while?

    Hi, I have a pretty specific use case where the symmetric ractherts should happen for every message exchange, but DH ratchet should only happen once in a while. Let's say every ten messaegs.

    Is there any way to do this in your library, or do you need to do a DH exchange every time?

    opened by S3j5b0 2
  • DH ratchet only happening in intervals?

    DH ratchet only happening in intervals?

    Hi, I have a usecase, where the protocol should happen on some consttained devices.

    Because of that I have been trying to explore whether it is possible to only let the DH ratchet happen once a while, and being initiated by bob. I have tried fiddling with it myself to see if I could make it work, but I have been having some trouble in how to manage the state of the protocol

    Could this be done? where the dh ratchet only happens something like with every fith message sent?

    opened by S3j5b0 0
  • Updated to newest versions of dependencies.

    Updated to newest versions of dependencies.

    Please Review My Changes Extremely Carefully!

    As I don't fully understand your code I tried to update the decencies and apply the api changes so the code would compile. However I'm not completely confident, that everything I've done was right and as this is security software I want to be sure it's actually as secure as it can be.

    Thanks for writing this amazing crate! 😄 I want to use it in production soon so I figured I try to update it. Have an amazing day!

    opened by umgefahren 1
Owner
Sebastian
Sebastian
Rust implementation of AstroBWT Proof-Of-Work algorithm

AstroBWT AstroBWT is a proof-of-work (PoW) algorithm based on Burrows-Wheeler transform (BWT). Developed and used by the DERO Project for Mobile (arm)

null 6 Mar 7, 2022
A rust implementation of Alexey Akhunov's multiproof algorithm

multiproof.rs A rust implementation of Alexey Akhunov's multiproof algorithm. At the time of creation, multiproof is still a work in progress and this

Guillaume Ballet 30 Aug 24, 2022
A Rust implementation of the AGCWD algorithm

AGCWD is described in the paper "Efficient Contrast Enhancement Using Adaptive Gamma Correction With Weighting Distribution".

Takeru Ohta 2 Jan 17, 2022
A SIMD-accelerated Adler-32 rolling hash algorithm implementation.

simd-adler32 A SIMD-accelerated Adler-32 rolling hash algorithm implementation. Features No dependencies Support no_std (with default-features = false

Marvin Countryman 23 Dec 19, 2022
An implementation of the A-Star pathfinding algorithm tailored for traversing a bespoke collection of weighted hexagons.

An implementation of the A-Star pathfinding algorithm tailored for traversing a bespoke collection of weighted hexagons. It's intended to calculate the most optimal path to a target hexagon where you are traversing from the centre of one hexagon to the next along a line orthogonal to a hexagon edge

null 19 Dec 11, 2022
A simple implementation of the astar pathfinding algorithm from red blob games

A simple implementation of the astar pathfinding algorithm from red blob games. In order to use the pathfinder you must have a path map for it to navi

sark 6 Nov 22, 2022
nsga is an opinionated implementation of the NSGA-II (Non-dominated Sorting Genetic Algorithm)

nsga nsga is an opinionated implementation of the NSGA-II (Non-dominated Sorting Genetic Algorithm), a multi-objective genetic optimization algorithm.

Max Kuznetsov 8 Oct 1, 2022
Genetic Algorithm library in Rust

RsGenetic Summary and Features RsGenetic is a framework for executing genetic algorithms in Rust. It is designed to have a simple but modular API. Exa

Mathieu De Coster 74 Dec 27, 2022
Example of a genetic algorithm in Rust and Python

Example of a genetic algorithm in Rust and Python Monkey typewriter Finding the phrase 'To be or not to be. That is the question.' Inspired by the exa

sotrh 2 Jan 27, 2022
hubpack is an algorithm for converting Rust values to bytes and back.

hubpack is an algorithm for converting Rust values to bytes and back. It was originally designed for encoding messages sent between embedded programs. It is designed for use with serde.

Cliff L. Biffle 6 Nov 11, 2022