mirror of
https://github.com/tlsnotary/tlsn.git
synced 2026-01-09 14:48:13 -05:00
initial work on halfgate
This commit is contained in:
226
Cargo.lock
generated
226
Cargo.lock
generated
@@ -11,6 +11,18 @@ dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.72"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
@@ -29,10 +41,34 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.113"
|
||||
name = "js-sys"
|
||||
version = "0.3.56"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eef78b64d87775463c549fbd80e19249ef436ea3bf1de2a1eb7e717ec7fab1e9"
|
||||
checksum = "a38fc24e30fd564ce974c02bf1d337caddff65be6cc4735a1f7eab22a7440f04"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.116"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "565dbd88872dbe4cc8a46e527f26483c1d1f7afa6b884a3bd6cd893d4f98da74"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
@@ -40,12 +76,20 @@ version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5"
|
||||
|
||||
[[package]]
|
||||
name = "pop-mpc"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"rand",
|
||||
"regex",
|
||||
"ring",
|
||||
"rstest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -58,6 +102,24 @@ version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.4"
|
||||
@@ -115,8 +177,166 @@ version = "0.6.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.16.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"spin",
|
||||
"untrusted",
|
||||
"web-sys",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rstest"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d912f35156a3f99a66ee3e11ac2e0b3f34ac85a07e05263d05a7e2c8810d616f"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustc_version",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012"
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.86"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.10.2+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25f1af7423d8588a3d840681122e72e6a24ddbcb3f0ec385cac0d12d24256c06"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b21c0df030f5a177f3cba22e9bc4322695ec43e7257d865302900290bcdedca"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f4203d69e40a52ee523b2529a773d5ffc1dc0071801c87b3d270b471b80ed01"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfa8a30d46208db204854cadbb5d4baf5fcf8071ba5bf48190c3e59937962ebc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d958d035c4438e28c70e4321a2911302f10135ce78a9c7834c0cab4123d06a2"
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.56"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c060b319f29dd25724f09a2ba1418f142f539b2be99fbf4d2d5a8f7330afb8eb"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
@@ -6,6 +6,7 @@ edition = "2018"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
ring = "0.16.20"
|
||||
rand = "0.8.4"
|
||||
regex = "1.5.4"
|
||||
|
||||
|
||||
@@ -1,323 +1,37 @@
|
||||
// -*- mode: rust; -*-
|
||||
//
|
||||
// This file is part of `scuttlebutt`.
|
||||
// Copyright © 2019 Galois, Inc.
|
||||
// See LICENSE for licensing information.
|
||||
use core::ops::{BitXor, BitXorAssign};
|
||||
|
||||
//! Defines a block as a 128-bit value, and implements block-related functions.
|
||||
#[repr(transparent)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub struct Block(u128);
|
||||
|
||||
#[cfg(feature = "curve25519-dalek")]
|
||||
use crate::Aes256;
|
||||
#[cfg(feature = "curve25519-dalek")]
|
||||
use curve25519_dalek::ristretto::RistrettoPoint;
|
||||
use std::{
|
||||
arch::x86_64::*,
|
||||
hash::{Hash, Hasher},
|
||||
};
|
||||
|
||||
/// A 128-bit chunk.
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Block(pub __m128i);
|
||||
|
||||
union __U128 {
|
||||
vector: __m128i,
|
||||
bytes: u128,
|
||||
}
|
||||
|
||||
const ONE: __m128i = unsafe { (__U128 { bytes: 1 }).vector };
|
||||
const ONES: __m128i = unsafe {
|
||||
(__U128 {
|
||||
bytes: 0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF,
|
||||
})
|
||||
.vector
|
||||
};
|
||||
pub const BLOCK_LEN: usize = 16;
|
||||
|
||||
impl Block {
|
||||
/// Convert into a pointer.
|
||||
#[inline]
|
||||
pub fn as_ptr(&self) -> *const u8 {
|
||||
self.as_ref().as_ptr()
|
||||
}
|
||||
/// Convert into a mutable pointer.
|
||||
#[inline]
|
||||
pub fn as_mut_ptr(&mut self) -> *mut u8 {
|
||||
self.as_mut().as_mut_ptr()
|
||||
pub fn new(b: u128) -> Self {
|
||||
Self(b)
|
||||
}
|
||||
|
||||
/// Carryless multiplication.
|
||||
///
|
||||
/// This code is adapted from the EMP toolkit's implementation.
|
||||
#[inline]
|
||||
pub fn clmul(self, rhs: Self) -> (Self, Self) {
|
||||
unsafe {
|
||||
let x = self.0;
|
||||
let y = rhs.0;
|
||||
let zero = _mm_clmulepi64_si128(x, y, 0x00);
|
||||
let one = _mm_clmulepi64_si128(x, y, 0x10);
|
||||
let two = _mm_clmulepi64_si128(x, y, 0x01);
|
||||
let three = _mm_clmulepi64_si128(x, y, 0x11);
|
||||
let tmp = _mm_xor_si128(one, two);
|
||||
let ll = _mm_slli_si128(tmp, 8);
|
||||
let rl = _mm_srli_si128(tmp, 8);
|
||||
let x = _mm_xor_si128(zero, ll);
|
||||
let y = _mm_xor_si128(three, rl);
|
||||
(Block(x), Block(y))
|
||||
}
|
||||
pub fn zero() -> Self {
|
||||
Self(0)
|
||||
}
|
||||
|
||||
/// Hash an elliptic curve point `pt` and tweak `tweak`.
|
||||
///
|
||||
/// Computes the hash by computing `E_{pt}(tweak)`, where `E` is AES-256.
|
||||
#[cfg(feature = "curve25519-dalek")]
|
||||
#[inline]
|
||||
pub fn hash_pt(tweak: u128, pt: &RistrettoPoint) -> Self {
|
||||
let k = pt.compress();
|
||||
let c = Aes256::new(k.as_bytes());
|
||||
c.encrypt(Block::from(tweak))
|
||||
pub fn set_lsb(&mut self) {
|
||||
self.0 |= 1;
|
||||
}
|
||||
|
||||
/// Return the least significant bit.
|
||||
#[inline]
|
||||
pub fn lsb(&self) -> bool {
|
||||
unsafe { _mm_extract_epi8(_mm_and_si128(self.0, ONE), 0) == 1 }
|
||||
}
|
||||
/// Set the least significant bit.
|
||||
#[inline]
|
||||
pub fn set_lsb(&self) -> Block {
|
||||
unsafe { Block(_mm_or_si128(self.0, ONE)) }
|
||||
}
|
||||
/// Flip all bits.
|
||||
#[inline]
|
||||
pub fn flip(&self) -> Self {
|
||||
unsafe { Block(_mm_xor_si128(self.0, ONES)) }
|
||||
}
|
||||
|
||||
/// Try to create a `Block` from a slice of bytes. The slice must have exactly 16 bytes.
|
||||
#[inline]
|
||||
pub fn try_from_slice(bytes_slice: &[u8]) -> Option<Self> {
|
||||
if bytes_slice.len() != 16 {
|
||||
return None;
|
||||
}
|
||||
let mut bytes = [0; 16];
|
||||
bytes[..16].clone_from_slice(&bytes_slice[..16]);
|
||||
Some(Block::from(bytes))
|
||||
(self.0 & 1) == 1
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Block {
|
||||
#[inline]
|
||||
fn default() -> Self {
|
||||
unsafe { Block(_mm_setzero_si128()) }
|
||||
}
|
||||
}
|
||||
impl BitXor for Block {
|
||||
type Output = Self;
|
||||
|
||||
impl PartialEq for Block {
|
||||
#[inline]
|
||||
fn eq(&self, other: &Block) -> bool {
|
||||
unsafe {
|
||||
let neq = _mm_xor_si128(self.0, other.0);
|
||||
_mm_test_all_zeros(neq, neq) != 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Block {}
|
||||
|
||||
impl Ord for Block {
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
u128::from(*self).cmp(&u128::from(*other))
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for Block {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||
Some(u128::from(*self).cmp(&u128::from(*other)))
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<[u8]> for Block {
|
||||
#[inline]
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
unsafe { &*(self as *const Block as *const [u8; 16]) }
|
||||
}
|
||||
}
|
||||
|
||||
impl AsMut<[u8]> for Block {
|
||||
#[inline]
|
||||
fn as_mut(&mut self) -> &mut [u8] {
|
||||
unsafe { &mut *(self as *mut Block as *mut [u8; 16]) }
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::BitAnd for Block {
|
||||
type Output = Block;
|
||||
#[inline]
|
||||
fn bitand(self, rhs: Self) -> Self {
|
||||
unsafe { Block(_mm_and_si128(self.0, rhs.0)) }
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::BitAndAssign for Block {
|
||||
#[inline]
|
||||
fn bitand_assign(&mut self, rhs: Self) {
|
||||
unsafe { self.0 = _mm_and_si128(self.0, rhs.0) }
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::BitOr for Block {
|
||||
type Output = Block;
|
||||
#[inline]
|
||||
fn bitor(self, rhs: Self) -> Self {
|
||||
unsafe { Block(_mm_or_si128(self.0, rhs.0)) }
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::BitOrAssign for Block {
|
||||
#[inline]
|
||||
fn bitor_assign(&mut self, rhs: Self) {
|
||||
unsafe { self.0 = _mm_or_si128(self.0, rhs.0) }
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::BitXor for Block {
|
||||
type Output = Block;
|
||||
#[inline]
|
||||
fn bitxor(self, rhs: Self) -> Self {
|
||||
unsafe { Block(_mm_xor_si128(self.0, rhs.0)) }
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::BitXorAssign for Block {
|
||||
#[inline]
|
||||
fn bitxor_assign(&mut self, rhs: Self) {
|
||||
unsafe { self.0 = _mm_xor_si128(self.0, rhs.0) }
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for Block {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
let block: [u8; 16] = (*self).into();
|
||||
for byte in block.iter() {
|
||||
write!(f, "{:02X}", byte)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Block {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
let block: [u8; 16] = (*self).into();
|
||||
for byte in block.iter() {
|
||||
write!(f, "{:02X}", byte)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl rand::distributions::Distribution<Block> for rand::distributions::Standard {
|
||||
#[inline]
|
||||
fn sample<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> Block {
|
||||
Block::from(rng.gen::<u128>())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Block> for u128 {
|
||||
#[inline]
|
||||
fn from(m: Block) -> u128 {
|
||||
unsafe { *(&m as *const _ as *const u128) }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u128> for Block {
|
||||
#[inline]
|
||||
fn from(m: u128) -> Self {
|
||||
unsafe { std::mem::transmute(m) }
|
||||
// XXX: the below doesn't work due to pointer-alignment issues.
|
||||
// unsafe { *(&m as *const _ as *const Block) }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Block> for __m128i {
|
||||
#[inline]
|
||||
fn from(m: Block) -> __m128i {
|
||||
m.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<__m128i> for Block {
|
||||
#[inline]
|
||||
fn from(m: __m128i) -> Self {
|
||||
Block(m)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Block> for [u8; 16] {
|
||||
#[inline]
|
||||
fn from(m: Block) -> [u8; 16] {
|
||||
unsafe { *(&m as *const _ as *const [u8; 16]) }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<[u8; 16]> for Block {
|
||||
#[inline]
|
||||
fn from(m: [u8; 16]) -> Self {
|
||||
unsafe { std::mem::transmute(m) }
|
||||
// XXX: the below doesn't work due to pointer-alignment issues.
|
||||
// unsafe { *(&m as *const _ as *const Block) }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<[u16; 8]> for Block {
|
||||
#[inline]
|
||||
fn from(m: [u16; 8]) -> Self {
|
||||
unsafe { std::mem::transmute(m) }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Block> for [u32; 4] {
|
||||
#[inline]
|
||||
fn from(m: Block) -> Self {
|
||||
unsafe { *(&m as *const _ as *const [u32; 4]) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for Block {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
let v: u128 = (*self).into();
|
||||
v.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct Helperb {
|
||||
pub block: u128,
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl Serialize for Block {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let helper = Helperb {
|
||||
block: <u128>::from(*self),
|
||||
};
|
||||
helper.serialize(serializer)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl<'de> Deserialize<'de> for Block {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let helper = Helperb::deserialize(deserializer)?;
|
||||
Ok(Block::from(helper.block.to_le_bytes()))
|
||||
fn bitxor(self, other: Self) -> Self::Output {
|
||||
Self(self.0 ^ other.0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -326,50 +40,35 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_and() {
|
||||
let x = rand::random::<Block>();
|
||||
let y = x & Block(ONES);
|
||||
assert_eq!(x, y);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_or() {
|
||||
let x = rand::random::<Block>();
|
||||
let y = x | Block(ONES);
|
||||
assert_eq!(y, Block(ONES));
|
||||
let y = x | x;
|
||||
assert_eq!(x, y);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_xor() {
|
||||
let x = rand::random::<Block>();
|
||||
let y = rand::random::<Block>();
|
||||
let z = x ^ y;
|
||||
let z = z ^ y;
|
||||
assert_eq!(x, z);
|
||||
fn test_set_lsb() {
|
||||
let mut b = Block::new(2);
|
||||
b.set_lsb();
|
||||
assert_eq!(Block::new(3), b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_lsb() {
|
||||
let x = rand::random::<Block>();
|
||||
let x = x | Block(ONE);
|
||||
assert!(x.lsb());
|
||||
let x = x ^ Block(ONE);
|
||||
assert!(!x.lsb());
|
||||
let a = Block::new(0);
|
||||
assert_eq!(a.lsb(), false);
|
||||
let a = Block::new(1);
|
||||
assert_eq!(a.lsb(), true);
|
||||
let a = Block::new(2);
|
||||
assert_eq!(a.lsb(), false);
|
||||
let a = Block::new(3);
|
||||
assert_eq!(a.lsb(), true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_flip() {
|
||||
let x = rand::random::<Block>();
|
||||
let y = x.flip().flip();
|
||||
assert_eq!(x, y);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_conversion() {
|
||||
let x = rand::random::<u128>();
|
||||
let x_ = u128::from(Block::from(x));
|
||||
assert_eq!(x, x_);
|
||||
fn test_bitxor() {
|
||||
let mut a = Block::new(0);
|
||||
let mut b = Block::new(0);
|
||||
assert_eq!(a ^ b, Block::new(0));
|
||||
a = Block::new(1);
|
||||
assert_eq!(a ^ b, Block::new(1));
|
||||
b = Block::new(1);
|
||||
assert_eq!(a ^ b, Block::new(0));
|
||||
a = Block::new(0);
|
||||
b = Block::new(1);
|
||||
assert_eq!(a ^ b, Block::new(1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,3 +92,21 @@ impl From<std::num::ParseIntError> for CircuitParserError {
|
||||
CircuitParserError::ParseIntError
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Circuit Garbling
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum GarbleGeneratorError {
|
||||
UninitializedLabel(usize),
|
||||
}
|
||||
|
||||
impl Display for GarbleGeneratorError {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
match self {
|
||||
GarbleGeneratorError::UninitializedLabel(wire) => {
|
||||
write!(f, "Uninitialized label, wire {}", wire)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1
pop-mpc/src/garble/evaluator/mod.rs
Normal file
1
pop-mpc/src/garble/evaluator/mod.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub mod half_gate;
|
||||
@@ -1,2 +0,0 @@
|
||||
#[derive(Debug)]
|
||||
struct Garbler {}
|
||||
113
pop-mpc/src/garble/generator/half_gate.rs
Normal file
113
pop-mpc/src/garble/generator/half_gate.rs
Normal file
@@ -0,0 +1,113 @@
|
||||
use super::GarbledCircuitGenerator;
|
||||
use crate::block::Block;
|
||||
use crate::circuit::Circuit;
|
||||
use crate::errors::GarbleGeneratorError;
|
||||
use crate::gate::Gate;
|
||||
use crate::prg::PRG;
|
||||
|
||||
struct HalfGateGenerator<'a, P: PRG> {
|
||||
circ: &'a Circuit,
|
||||
delta: Block,
|
||||
public_labels: [Block; 2],
|
||||
wire_labels: Vec<(Block, Block)>,
|
||||
current_index: usize,
|
||||
prg: P,
|
||||
}
|
||||
|
||||
impl<'a, P: PRG> HalfGateGenerator<'a, P> {
|
||||
pub fn new(circ: &'a Circuit, mut prg: P) -> HalfGateGenerator<'a, P> {
|
||||
let mut delta: Block = prg.random_block();
|
||||
delta.set_lsb();
|
||||
let public_labels = [prg.random_block(), prg.random_block() ^ delta];
|
||||
|
||||
HalfGateGenerator {
|
||||
circ,
|
||||
delta,
|
||||
public_labels,
|
||||
wire_labels: Vec::new(),
|
||||
current_index: 0,
|
||||
prg,
|
||||
}
|
||||
}
|
||||
|
||||
fn public_label(&self, b: bool) -> Block {
|
||||
self.public_labels[b as usize]
|
||||
}
|
||||
|
||||
fn next_index(&mut self) -> usize {
|
||||
self.current_index += 1;
|
||||
self.current_index
|
||||
}
|
||||
|
||||
fn encode_and(&self, x_0: Block, y_0: Block) -> Block {
|
||||
let p_a = x_0.lsb();
|
||||
let p_b = y_0.lsb();
|
||||
let j = self.next_index();
|
||||
let k = self.next_index();
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, P: PRG> GarbledCircuitGenerator for HalfGateGenerator<'a, P> {
|
||||
fn encode_wire_labels(&mut self) -> Result<(), GarbleGeneratorError> {
|
||||
let mut wire_labels: Vec<Option<(Block, Block)>> = vec![None; self.circ.nwires];
|
||||
for i in 0..self.circ.ninput_wires {
|
||||
let z0 = self.prg.random_block();
|
||||
let z1 = z0 ^ self.delta;
|
||||
wire_labels[i] = Some((z0, z1));
|
||||
}
|
||||
for gate in self.circ.gates.iter() {
|
||||
let (zref, z0) = match *gate {
|
||||
Gate::Inv { xref, zref, .. } => {
|
||||
let x = wire_labels[xref]
|
||||
.ok_or_else(|| GarbleGeneratorError::UninitializedLabel(xref))?;
|
||||
(zref, x.0 ^ self.public_label(true))
|
||||
}
|
||||
Gate::Xor {
|
||||
xref, yref, zref, ..
|
||||
} => {
|
||||
let x = wire_labels[xref]
|
||||
.ok_or_else(|| GarbleGeneratorError::UninitializedLabel(xref))?;
|
||||
let y = wire_labels[yref]
|
||||
.ok_or_else(|| GarbleGeneratorError::UninitializedLabel(yref))?;
|
||||
(zref, x.0 ^ y.0)
|
||||
}
|
||||
Gate::And {
|
||||
xref, yref, zref, ..
|
||||
} => {
|
||||
let x = wire_labels[xref]
|
||||
.ok_or_else(|| GarbleGeneratorError::UninitializedLabel(xref))?;
|
||||
let y = wire_labels[yref]
|
||||
.ok_or_else(|| GarbleGeneratorError::UninitializedLabel(yref))?;
|
||||
(zref, x.0 ^ y.0)
|
||||
}
|
||||
};
|
||||
let z1 = z0 ^ self.delta;
|
||||
wire_labels[zref] = Some((z0, z1));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::prg::RandPRG;
|
||||
|
||||
#[test]
|
||||
fn test_encode_wire_labels() {
|
||||
let mut prg = RandPRG::new();
|
||||
let circ = Circuit::parse("circuits/adder64.txt").unwrap();
|
||||
let mut half_gate = HalfGateGenerator::new(&circ, prg);
|
||||
|
||||
half_gate.encode_wire_labels();
|
||||
//println!("{:?}", half_gate.wire_labels);
|
||||
println!(
|
||||
"{:?}",
|
||||
half_gate
|
||||
.wire_labels
|
||||
.iter()
|
||||
.map(|(a, b)| *b ^ half_gate.delta)
|
||||
.collect::<Vec<Block>>()
|
||||
);
|
||||
}
|
||||
}
|
||||
7
pop-mpc/src/garble/generator/mod.rs
Normal file
7
pop-mpc/src/garble/generator/mod.rs
Normal file
@@ -0,0 +1,7 @@
|
||||
pub mod half_gate;
|
||||
|
||||
use crate::errors::GarbleGeneratorError;
|
||||
|
||||
pub trait GarbledCircuitGenerator {
|
||||
fn encode_wire_labels(&mut self) -> Result<(), GarbleGeneratorError>;
|
||||
}
|
||||
@@ -1,2 +1,3 @@
|
||||
pub mod garbler;
|
||||
pub mod evaluator;
|
||||
pub mod generator;
|
||||
pub mod wire;
|
||||
|
||||
@@ -1,27 +1,14 @@
|
||||
use crate::block::Block;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum Wire {
|
||||
/// Representation of a Bool wire
|
||||
Bool(Block),
|
||||
}
|
||||
pub struct WireLabel(usize, Block);
|
||||
|
||||
impl std::default::Default for Wire {
|
||||
fn default() -> Self {
|
||||
Wire::Bool(Block::default())
|
||||
impl WireLabel {
|
||||
pub fn new(id: usize, block: Block) -> Self {
|
||||
WireLabel(id, block)
|
||||
}
|
||||
}
|
||||
|
||||
impl Wire {
|
||||
/// Unpack the wire represented by a `Block`
|
||||
pub fn from_block(inp: Block) -> Self {
|
||||
Wire::Bool(inp)
|
||||
}
|
||||
|
||||
/// Pack the wire into a `Block`.
|
||||
/// Pack the wire label into a `Block`.
|
||||
pub fn as_block(&self) -> Block {
|
||||
match self {
|
||||
Wire::Bool(b) => *b,
|
||||
}
|
||||
self.1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
#![allow(unused_imports)]
|
||||
#![allow(unused_variables)]
|
||||
|
||||
pub mod block;
|
||||
mod block;
|
||||
pub mod circuit;
|
||||
pub mod element;
|
||||
pub mod errors;
|
||||
pub mod garble;
|
||||
mod gate;
|
||||
mod prg;
|
||||
|
||||
28
pop-mpc/src/prg.rs
Normal file
28
pop-mpc/src/prg.rs
Normal file
@@ -0,0 +1,28 @@
|
||||
use crate::block::Block;
|
||||
use rand::rngs::ThreadRng;
|
||||
use rand::{thread_rng, CryptoRng, Rng};
|
||||
|
||||
pub struct RandPRG {
|
||||
rng: ThreadRng,
|
||||
}
|
||||
|
||||
pub trait PRG {
|
||||
fn random_block(&mut self) -> Block;
|
||||
}
|
||||
|
||||
impl RandPRG {
|
||||
pub fn new() -> Self {
|
||||
Self { rng: thread_rng() }
|
||||
}
|
||||
}
|
||||
|
||||
impl PRG for RandPRG {
|
||||
fn random_block(&mut self) -> Block {
|
||||
Block::new(self.rng.gen())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
}
|
||||
Reference in New Issue
Block a user