Achilles' Tent Notes #9 written by Nathan Lilienthal on October 15, 2019.
- Achilles’ Tent Notes #8
- Achilles’ Tent Notes #9
- Achilles’ Tent Notes #10
- Achilles’ Tent Notes #11
- Achilles’ Tent Notes #12
- Achilles’ Tent Notes #13
Surface Obliv-Rust
Below are the first highlights for obliv additions to the surface Rust language.
- New type:
type Obliv<T>; // or simply type obliv τ - New
obliv ifexpression:obliv if e1 { e2 } else { e3 }fn add(x: obliv u32, y: obliv u32) -> obliv u32 { obliv if x == y { x * 2 } else { x + y } } - New
obliv matchexpression:obliv match e { ... }fn oadd1(i: obliv Option<u32>) -> obliv Option<u32> { obliv match i { Some(n) => Some(n + 1), None => None, } } - Either a new function declaration:
obliv fn foo(a: &u32, b: &mut u32) -> &mut u32Or, a new reference qualifier in signature:
fn bar(a: &u32, b: &frz u32) -> &frz u32 // `baz` is forbidden in obliv context, has &mut. fn baz(a: &u32, b: &mut u32) // `bat` also has an &mut making it forbidden in obliv context, // however takes an &frz, what does this mean? fn bat(a: &mut u32, b: &frz u32)
Formal Obliv-Oxide
Together with changes to the underlying Oxide formalism. Please note that this section is incomplete with respect to syntax, and possibly semantics. Please read as notes.
- Syntax
ω ::= uniq | frzn | shrdWe must be able to “freeze” references until we “thaw” them in an
alwaysblock. We can interpretuniqas unique and mutable,frznas unique but not mutable, and finallyshrdas simply immutable.obliv τ ::= obliv bool | obliv int | ... | obliv [τ; n] | obliv [obliv τ; n]Oblivious base types are defined, I’m using
intas a placeholder for more underlying numeric (and other sized) types. As well as a compositeobliv []type. Also note that both PIR and ORAM structures fit these types respectively.e ::= ... | conceal(e) | reveal(e) | obliv if e1 { e2 } else { e3 } | always { e } - Typing Rules
conceal&revealprimitives:e: τ e: obliv τ ------------------- ------------ conceal(e): obliv τ reveal(e): τobliv if:e1: obliv bool e2, e3: τ ---------------------------------------- obliv if e1 { e2 } else { e3 } : obliv τAnd, returning functions (The case is the same for functions of no arguments):
e1: obliv bool e2, e3: fn(τ*) -> τ ------------------------------------------------- obliv if e1 { e2 } else { e3 }: fn(τ*) -> obliv τHowever, I’m unsure still at this time if the next rule should result in type
fn(&frz)orfn(&mut).e1: obliv bool e2, e3: fn(mut τ*) -> τ ----------------------------------------------------- obliv if e1 { e2 } else { e3 }: fn(frz τ*) -> obliv τDo we need the notion of a function with explicit
fn foo(mut x: u32, frz: u32)? Trait definition functions, for example, don’t allow patterns in the arguments.always: TODO - Operational semantics
obliv if e1 { |a1,...,an| e2 } else { |a1,...,an| e3 } => |a1,...,an| { obliv if e1 { e2 } else { e3 } }This is a somewhat straightforward reduction, if you ignore the details of
&frzand&mutfor a moment:obliv if e1 { |&a1,...,&an| e2 } else { |&a1,...,&an| e3 } => |&a1,...,&an| { obliv if e1 { e2 } else { e3 } } - Safety
Math
obliv num / obliv numshould never panic- The
impl Divfor oblivious types should have a well defined division by 0 value. Users can choose a well behavedn/dfor short syntax, and manually check forif d == 0 - Otherwise,
checked_divwill be available which returns anobliv Option, forcing the user to handle then/0case
- The
Open Questions
- What is an
obliv &, if anything fiat-cryptoRust extraction- Still need to play with running the extraction more
- Questions about what types to expose for the underlying algebraic structures
- Possibly use λ-rust for some parts of Rust that Oxide doesn’t reason about, e.g.
unsafe
nixpulvis