Crate cllw_ore
Expand description
§CLWW ORE
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.
- OpeCllw8
V1 - Fixed-size CLWW OPE ciphertext for integer types.
- OpeCllw8
Variable V1 - Variable-length CLWW OPE ciphertext for strings and byte slices.
- OreCllw8
V1 - Fixed-size CLWW ORE ciphertext for unsigned integer types.
- OreCllw8
Variable V1 - Variable-length CLWW ORE ciphertext for strings and byte slices.
Traits§
- Cllw
OpeEncrypt - Trait for types that can be encrypted using CLWW Order-Preserving Encryption.
- Cllw
OreDecrypt - Trait for types that can be decrypted from CLWW Order-Revealing Encryption.
- Cllw
OreEncrypt - 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.