Crate oram

Source
Expand description

An implementation of Oblivious RAM (ORAM) for the secure enclave setting.

⚠️ Warning: This implementation has not been audited. Use at your own risk!

§Overview

This crate implements an oblivious RAM protocol (ORAM) for (secure) enclave applications.

This crate assumes that ORAM clients are running inside a secure enclave architecture that provides memory encryption. It does not perform encryption-on-write and thus is not secure without memory encryption.

§Design

This crate implements the Path ORAM protocol, with oblivious client data structures based on the Oblix paper. See the Path ORAM retrospective paper for a high-level introduction to ORAM and Path ORAM, and for more detailed references.

§Example

The below example reads a database from memory into an ORAM, thus permitting secret-dependent accesses.

use oram::{Address, BlockSize, BlockValue, Oram, DefaultOram};

const BLOCK_SIZE: BlockSize = 64;
const DB_SIZE: Address = 64;
let mut rng = rand::rngs::OsRng;

// Initialize an ORAM to store 64 blocks of 64 bytes each.
let mut oram = DefaultOram::<BlockValue<BLOCK_SIZE>>::new(DB_SIZE, &mut rng)?;

// Read a database (here, an array of byte arrays) into the ORAM.
for (i, bytes) in DATABASE.iter().enumerate() {
    oram.write(i as Address, BlockValue::new(*bytes), &mut rng)?;
}

// Now you can safely make secret-dependent accesses to your database.
let secret = 42;
let _ = oram.read(secret, &mut rng)?;

§Advanced

ORAMs can store arbitrary structs implementing OramBlock. We provide implementations of OramBlock for u8, u16, u32, u64, i8, i16, i32, i64, and BlockValue<const B: BlockSize>.

The DefaultOram used in the above example should have good performance in most use cases. But the underlying algorithms have several tunable parameters that impact performance. The following example instantiates the same ORAM struct as above, but using the PathOram interface which exposes these parameters.

use oram::{Address, BlockSize, BlockValue, BucketSize,
            Oram, PathOram, StashSize, RecursionCutoff};
use oram::path_oram::{DEFAULT_BLOCKS_PER_BUCKET, DEFAULT_RECURSION_CUTOFF,
            DEFAULT_POSITIONS_PER_BLOCK, DEFAULT_STASH_OVERFLOW_SIZE};

const RECURSION_CUTOFF: RecursionCutoff = DEFAULT_RECURSION_CUTOFF;
const BUCKET_SIZE: BucketSize = DEFAULT_BLOCKS_PER_BUCKET;
const POSITIONS_PER_BLOCK: BlockSize = DEFAULT_POSITIONS_PER_BLOCK;
const INITIAL_STASH_OVERFLOW_SIZE: StashSize = DEFAULT_STASH_OVERFLOW_SIZE;

let mut oram = PathOram::<
    BlockValue<BLOCK_SIZE>,
    BUCKET_SIZE,
    POSITIONS_PER_BLOCK,
    >::new_with_parameters(DB_SIZE, &mut rng, INITIAL_STASH_OVERFLOW_SIZE, RECURSION_CUTOFF)?;

See PathOram for an explanation of these parameters and their possible settings.

Re-exports§

pub use crate::path_oram::DefaultOram;
pub use crate::path_oram::PathOram;

Modules§

linear_time_oram
A simple linear-time implementation of Oblivious RAM.
path_oram
An implementation of Path ORAM.

Structs§

BlockValue
An OramBlock consisting of unstructured bytes.

Enums§

OramError
A list of error types which are produced during ORAM protocol execution.

Traits§

Oram
Represents an oblivious RAM (ORAM) mapping addresses of type Address to values of type V: OramBlock.
OramBlock
A “trait alias” for ORAM blocks: the values read and written by ORAMs.

Type Aliases§

Address
The numeric type used to specify the size of an ORAM in blocks, and to index into the ORAM.
BlockSize
The numeric type used to specify the size of an ORAM block in bytes.
BucketSize
The numeric type used to specify the size of an ORAM bucket in blocks.
RecursionCutoff
The numeric type used to specify the cutoff size below which PathOram uses a linear position map instead of a recursive one.
StashSize
Numeric type used to represent the size of a Path ORAM stash in blocks.