Skip to main content

Crate cllw_ore

Crate cllw_ore 

Expand description

§CLWW ORE

Crates.io Version docs.rs Built by CipherStash

Website | Docs | Discussions

§Fast, efficient Order-Revealing and Order-Preserving Encryption

This crate implements the Order-Revealing Encryption (ORE) and Order-Preserving Encryption (OPE) schemes from Chenette, Lewi, Weis and Wu (Stanford, 2015 — hence “CLWW”).

Both schemes are faster and more space efficient than the “Block” ORE scheme developed by Lewi and Wu a year later, but have weaker security properties. The OPE variant additionally produces ciphertexts that compare under standard lexicographic byte ordering, with no custom comparator required — making it usable directly with operators like <, > and BETWEEN in databases that already know how to compare opaque byte strings.

At CipherStash, we use the ORE variant for encrypting terms in our encrypted JSON indexer. For ordered range queries on encrypted columns we prefer ORE with a custom operator family/class, falling back to the OPE variant only when the database doesn’t provide those. For everything else we use the Block scheme; see ore.rs for more information.

§CipherStash

CLWW ORE is brought to you by the team at CipherStash.

§Features

  • Order-Revealing: Relative order of plaintexts can be determined at query time
  • Deterministic: The same plaintext always produces the same ciphertext for a given key
  • Constant-Time: Operations use constant-time algorithms to prevent timing attacks
  • Multiple Types: Support for integers (u16, u32, u64, u128), strings, and byte slices

§Basic Usage

use cllw_ore::Key;
use std::cmp::Ordering;

// Create an encryption key
let key = Key::from([0u8; 32]);

// Encrypt integers
let ct1 = key.encrypt(10u32).unwrap();
let ct2 = key.encrypt(20u32).unwrap();

// Compare encrypted values
assert_eq!(ct1.cmp(&ct2), Ordering::Less);

// Decrypt values
assert_eq!(key.decrypt(ct1).unwrap(), 10u32);
assert_eq!(key.decrypt(ct2).unwrap(), 20u32);

§Supported Types

§Unsigned Integers

use cllw_ore::Key;

let key = Key::from([0u8; 32]);

// u16, u32, u64, u128 are all supported
let ct16 = key.encrypt(100u16).unwrap();
let ct32 = key.encrypt(1000u32).unwrap();
let ct64 = key.encrypt(10000u64).unwrap();
let ct128 = key.encrypt(100000u128).unwrap();

assert_eq!(key.decrypt(ct32).unwrap(), 1000u32);

§Strings

use cllw_ore::Key;

let key = Key::from([0u8; 32]);

let ct1 = key.encrypt("alice").unwrap();
let ct2 = key.encrypt("bob").unwrap();

assert!(ct1 < ct2);
assert_eq!(key.decrypt(ct1).unwrap(), "alice");

§Byte Slices

use cllw_ore::Key;

let key = Key::from([0u8; 32]);
let data: &[u8] = &[0xFF, 0x00, 0xAB];

let ciphertext = key.encrypt(data).unwrap();
let decrypted = ciphertext.decrypt_to_bytes(&key, None).unwrap();

assert_eq!(data, decrypted.as_slice());

§Using Salts for Domain Separation

use cllw_ore::{Key, CllwOreEncrypt, CllwOreDecrypt};

let key = Key::from([0u8; 32]);
let salt = b"my-domain";

// Encrypt with a salt
let ct = 42u32.encrypt_with_salt(&key, Some(salt)).unwrap();

// Must use the same salt to decrypt
let pt = ct.decrypt_with_salt(&key, Some(salt)).unwrap();
assert_eq!(pt, 42u32);

Structs§

Error
An error occurred during encryption or decryption.
Key
A 256-bit encryption key for CLWW Order-Revealing Encryption.
OpeCllw8V1
Fixed-size CLWW OPE ciphertext for integer types.
OpeCllw8VariableV1
Variable-length CLWW OPE ciphertext for strings and byte slices.
OreCllw8V1
Fixed-size CLWW ORE ciphertext for unsigned integer types.
OreCllw8VariableV1
Variable-length CLWW ORE ciphertext for strings and byte slices.

Traits§

CllwOpeEncrypt
Trait for types that can be encrypted using CLWW Order-Preserving Encryption.
CllwOreDecrypt
Trait for types that can be decrypted from CLWW Order-Revealing Encryption.
CllwOreEncrypt
Trait for types that can be encrypted using CLWW Order-Revealing Encryption.

Functions§

encrypt_ope_bits
Encrypts a bit stream into an OPE ciphertext whose lex order matches the plaintext order exactly.
encrypt_ore_bits
Encrypts a bit stream into a CLLW ORE ciphertext.
orderize_string
Normalizes the string use Unicode = NFKC normalization, and then removes any characters that are not alphanumeric, whitespace, or ASCII punctuation. This is a “rough” collation that is used to orderize strings for encryption.