mirror of
https://github.com/tlsnotary/ole-protocols.git
synced 2026-01-08 22:18:07 -05:00
Add attack on ghash which leaks the MAC key
This commit is contained in:
12
Cargo.lock
generated
12
Cargo.lock
generated
@@ -335,6 +335,17 @@ dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "delegate"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e018fccbeeb50ff26562ece792ed06659b9c2dae79ece77c4456bb10d9bf79b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.40",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "der"
|
||||
version = "0.7.8"
|
||||
@@ -584,6 +595,7 @@ dependencies = [
|
||||
name = "ole-protocols"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"delegate",
|
||||
"itybity",
|
||||
"mpz-share-conversion-core",
|
||||
"p256",
|
||||
|
||||
@@ -10,6 +10,7 @@ mpz-share-conversion-core = { git = "https://github.com/privacy-scaling-explorat
|
||||
p256 = { version = "0.13", features = ["arithmetic"] }
|
||||
itybity = "0.2"
|
||||
rand = "0.8"
|
||||
delegate = "0.12"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ mod verifier;
|
||||
|
||||
use crate::func::ole::Ole;
|
||||
use mpz_share_conversion_core::{fields::gf2_128::Gf2_128, Field};
|
||||
pub use prover::Prover;
|
||||
pub use prover::{MaliciousProver, Prover};
|
||||
pub use verifier::Verifier;
|
||||
|
||||
pub fn ghash(blocks: &[Gf2_128], prover: &mut Prover, verifier: &mut Verifier) -> Gf2_128 {
|
||||
@@ -33,6 +33,36 @@ pub fn ghash(blocks: &[Gf2_128], prover: &mut Prover, verifier: &mut Verifier) -
|
||||
ghash1 + ghash2
|
||||
}
|
||||
|
||||
/// The prover is malicious and will set r1 to zero
|
||||
pub fn ghash_with_input_zero_from_prover(
|
||||
blocks: &[Gf2_128],
|
||||
prover: &mut MaliciousProver,
|
||||
verifier: &mut Verifier,
|
||||
) -> Gf2_128 {
|
||||
let mut ole = Ole::default();
|
||||
|
||||
prover.preprocess_ole_input(&mut ole);
|
||||
verifier.preprocess_ole_input(&mut ole);
|
||||
|
||||
prover.preprocess_ole_output(&mut ole);
|
||||
verifier.preprocess_ole_output(&mut ole);
|
||||
|
||||
let d1 = prover.handshake_a_open_d();
|
||||
let d2 = verifier.handshake_a_open_d();
|
||||
let d = d1 + d2;
|
||||
|
||||
prover.handshake_a_set_di(d);
|
||||
verifier.handshake_a_set_di(d);
|
||||
|
||||
prover.handshake_a_set_hi();
|
||||
verifier.handshake_a_set_hi();
|
||||
|
||||
let ghash1 = prover.handshake_output_ghash(blocks);
|
||||
let ghash2 = verifier.handshake_output_ghash(blocks);
|
||||
|
||||
ghash1 + ghash2
|
||||
}
|
||||
|
||||
fn pascal_tri<T: Field>(n: usize) -> Vec<Vec<T>> {
|
||||
let mut pascal = vec![vec![T::one()]];
|
||||
|
||||
@@ -85,6 +115,24 @@ mod tests {
|
||||
assert_eq!(ghash, ghash_expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_malicious_prover() {
|
||||
let mut rng = thread_rng();
|
||||
let blocks: Vec<Gf2_128> = (0..10).map(|_| Gf2_128::rand(&mut rng)).collect();
|
||||
|
||||
let h1: Gf2_128 = Gf2_128::rand(&mut rng);
|
||||
let h2: Gf2_128 = Gf2_128::rand(&mut rng);
|
||||
let h = h1 + h2;
|
||||
|
||||
let mut prover = MaliciousProver::new(blocks.len(), h1);
|
||||
let mut verifier = Verifier::new(blocks.len(), h2);
|
||||
|
||||
let _ghash = ghash_with_input_zero_from_prover(&blocks, &mut prover, &mut verifier);
|
||||
|
||||
// Now we can extract the full MAC key from the prover's view
|
||||
assert_eq!(prover.inner.d_powers[1], h);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ghash_invariants() {
|
||||
let mut rng = thread_rng();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use super::pascal_tri;
|
||||
use crate::func::ole::Ole;
|
||||
use crate::func::Role;
|
||||
use delegate::delegate;
|
||||
use mpz_share_conversion_core::{
|
||||
fields::{compute_product_repeated, gf2_128::Gf2_128, UniformRand},
|
||||
Field,
|
||||
@@ -75,3 +76,31 @@ impl Prover {
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MaliciousProver {
|
||||
pub inner: Prover,
|
||||
}
|
||||
|
||||
impl MaliciousProver {
|
||||
/// Create a new malicious prover, which wraps an inner prover, but sets r1 to 0.
|
||||
pub fn new(block_num: usize, h1: Gf2_128) -> Self {
|
||||
let mut prover = Self {
|
||||
inner: Prover::new(block_num, h1),
|
||||
};
|
||||
|
||||
prover.inner.r1 = Gf2_128::zero();
|
||||
prover
|
||||
}
|
||||
|
||||
delegate! {
|
||||
to self.inner {
|
||||
pub fn preprocess_ole_input(&self, ole: &mut Ole<Gf2_128>);
|
||||
pub fn preprocess_ole_output(&mut self, ole: &mut Ole<Gf2_128>);
|
||||
pub fn handshake_a_open_d(&self) -> Gf2_128;
|
||||
pub fn handshake_a_set_di(&mut self, d: Gf2_128);
|
||||
pub fn handshake_a_set_hi(&mut self);
|
||||
pub fn handshake_output_ghash(&self, blocks: &[Gf2_128]) -> Gf2_128;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user