Skip to content

Commit

Permalink
add SPCOT in mpz-ot-core (#77)
Browse files Browse the repository at this point in the history
* add lpn and optimizations with multi threads

* update comments

* finish ggm reconstruction, still need optimization

* clippy

* cargo ciplly

* add comments on public functions

* add pado as a contributor

* add assertion and modify documentation

* fix minor bugs

* rebase dev

* fmt

* add spcot sender low-level apis

* update spcot msgs

* update spcot sender, add structure of spcot receiver

* update spcot receiver functions

* add spcot receiver extend

* simplify msg types

* add spcot receiver functions

* add ideal cot functionality

* refactor

* add spcot test

* add comments

* cargo clippy

* clippy

* update message types and modify accordingly

* optimize with batch check

* optimize chi seed with Fiat-Shamir

* cargo clippy

* update exec_counter in expand

* set ideal module

* clean up code

* minor

* fmt

* change the type of length to u32

* slightly optimize generation of ms

* update vs length type to u32

* replace with mod tests
  • Loading branch information
xiangxiecrypto authored Oct 25, 2023
1 parent af36089 commit 832c434
Show file tree
Hide file tree
Showing 10 changed files with 830 additions and 0 deletions.
1 change: 1 addition & 0 deletions ot/mpz-ot-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ itybity.workspace = true
opaque-debug.workspace = true
cfg-if.workspace = true
enum-try-as-inner = { tag = "0.1.0", git = "https://github.com/sinui0/enum-try-as-inner" }
bytemuck = { workspace = true, features = ["derive"] }

[dev-dependencies]
rstest.workspace = true
Expand Down
6 changes: 6 additions & 0 deletions ot/mpz-ot-core/src/ferret/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
//! An implementation of the [`Ferret`](https://eprint.iacr.org/2020/924.pdf) protocol.
pub mod spcot;

/// Computational security parameter
pub const CSP: usize = 128;
25 changes: 25 additions & 0 deletions ot/mpz-ot-core/src/ferret/spcot/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//! Errors that can occur when using the SPCOT.
/// Errors that can occur when using the SPCOT sender.
#[derive(Debug, thiserror::Error)]
#[allow(missing_docs)]
pub enum SenderError {
#[error("invalid state: expected {0}")]
InvalidState(String),
#[error("invalid length: expected {0}")]
InvalidLength(String),
}

/// Errors that can occur when using the SPCOT receiver.
#[derive(Debug, thiserror::Error)]
#[allow(missing_docs)]
pub enum ReceiverError {
#[error("invalid state: expected {0}")]
InvalidState(String),
#[error("invalid input: expected {0}")]
InvalidInput(String),
#[error("invalid length: expected {0}")]
InvalidLength(String),
#[error("consistency check failed")]
ConsistencyCheckFailed,
}
82 changes: 82 additions & 0 deletions ot/mpz-ot-core/src/ferret/spcot/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
//! Implementation of the Single-Point COT (spcot) protocol in the [`Ferret`](https://eprint.iacr.org/2020/924.pdf) paper.
pub mod error;
pub mod msgs;
pub mod receiver;
pub mod sender;

#[cfg(test)]
mod tests {
use mpz_core::prg::Prg;

use super::{receiver::Receiver as SpcotReceiver, sender::Sender as SpcotSender};
use crate::ferret::CSP;
use crate::ideal::ideal_cot::{CotMsgForReceiver, CotMsgForSender, IdealCOT};

#[test]
fn spcot_test() {
let mut ideal_cot = IdealCOT::init();
let sender = SpcotSender::new();
let receiver = SpcotReceiver::new();

let mut prg = Prg::new();
let sender_seed = prg.random_block();
let delta = ideal_cot.delta;

let mut sender = sender.setup(delta, sender_seed);
let mut receiver = receiver.setup();

let h1 = 8;
let alpha1 = 3;

// Extend once
let (msg_for_sender, msg_for_receiver) = ideal_cot.extend(h1);

let CotMsgForReceiver { rs, ts } = msg_for_receiver;
let CotMsgForSender { qs } = msg_for_sender;
let maskbits = receiver.extend_mask_bits(h1, alpha1, &rs).unwrap();

let msg_from_sender = sender.extend(h1, &qs, maskbits).unwrap();

receiver.extend(h1, alpha1, &ts, msg_from_sender).unwrap();

// Extend twice
let h2 = 4;
let alpha2 = 2;

let (msg_for_sender, msg_for_receiver) = ideal_cot.extend(h2);

let CotMsgForReceiver { rs, ts } = msg_for_receiver;
let CotMsgForSender { qs } = msg_for_sender;

let maskbits = receiver.extend_mask_bits(h2, alpha2, &rs).unwrap();

let msg_from_sender = sender.extend(h2, &qs, maskbits).unwrap();

receiver.extend(h2, alpha2, &ts, msg_from_sender).unwrap();

// Check
let (msg_for_sender, msg_for_receiver) = ideal_cot.extend(CSP);

let CotMsgForReceiver {
rs: x_star,
ts: z_star,
} = msg_for_receiver;

let CotMsgForSender { qs: y_star } = msg_for_sender;

let check_from_receiver = receiver.check_pre(&x_star).unwrap();

let (mut output_sender, check) = sender.check(&y_star, check_from_receiver).unwrap();

let output_receiver = receiver.check(&z_star, check).unwrap();

output_sender
.iter_mut()
.zip(output_receiver.iter())
.all(|(vs, (ws, alpha))| {
vs[*alpha as usize] ^= delta;
vs == ws
});
}
}
45 changes: 45 additions & 0 deletions ot/mpz-ot-core/src/ferret/spcot/msgs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//! Messages for the SPCOT protocol
use mpz_core::{hash::Hash, Block};
use serde::{Deserialize, Serialize};

/// A SPCOT message.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[allow(missing_docs)]
pub enum Message<CotMsg> {
CotMsg(CotMsg),
MaskBits(MaskBits),
ExtendFromSender(ExtendFromSender),
CheckFromReceiver(CheckFromReceiver),
CheckFromSender(CheckFromSender),
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
/// The mask bits sent from the receiver.
pub struct MaskBits {
/// The mask bits sent from the receiver.
pub bs: Vec<bool>,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
/// The extend messages that sent from the sender.
pub struct ExtendFromSender {
/// The mask `m0` and `m1`.
pub ms: Vec<[Block; 2]>,
/// The sum of the ggm tree leaves and delta.
pub sum: Block,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
/// The consistency check message sent from the receiver.
pub struct CheckFromReceiver {
/// The `x'` from the receiver.
pub x_prime: Vec<bool>,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
/// The consistency check message sent from the sender.
pub struct CheckFromSender {
/// The hashed `V` from the sender.
pub hashed_v: Hash,
}
Loading

0 comments on commit 832c434

Please sign in to comment.