diff --git a/README.md b/README.md index 5cf2eab..274e120 100644 --- a/README.md +++ b/README.md @@ -14,3 +14,19 @@ blockchains. The project is still at the very beginning. To compile the workspace and run the tests just run `cargo t`. +## StoffelVM + +StoffelVM can be run as a standalone VM. Just pass some bytecode to it and start +the execution. + +```rust +use vm::StoffelVM; + +// Some fictious bytecode +let mut bytecode: Vec = vec![0x01, 0x02, 0x03, 0x04]; + +// Instantiate a new VM and run it +let mut vm = StoffelVM::new(); +vm.load_byte_code(&byte_code); +vm.execute(); +``` diff --git a/types/src/numbers/bit.rs b/types/src/numbers/bit.rs index f5bab08..0b0d759 100644 --- a/types/src/numbers/bit.rs +++ b/types/src/numbers/bit.rs @@ -1,40 +1,15 @@ -use super::secret_sharing::SecretSharing; -use super::MPCType; +use super::{Number, SecretSharing}; use std::ops::{Add, Mul}; /// Public bit type /// /// This type is used for providing arithmetic for bits #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Copy, Default)] -pub struct PubBit(bool); +pub struct PubBit(T); -impl MPCType for PubBit { - fn square(self) -> Self { - todo!(); - } - - fn pow(self, exp: usize) -> Self { - todo!(); - } - - fn min(self, a: Self) -> Self { - todo!(); - } - - fn max(self, a: Self) -> Self { - todo!(); - } - - fn if_else(self, a: Self, b: Self) -> Self { - todo!(); - } - - fn cond_swap(self, a: Self, b: Self) -> (Self, Self) { - todo!(); - } -} +impl Number for PubBit {} -impl Add for PubBit { +impl Add for PubBit { type Output = Self; fn add(self, rhs: Self) -> Self { @@ -42,7 +17,7 @@ impl Add for PubBit { } } -impl Mul for PubBit { +impl Mul for PubBit { type Output = Self; fn mul(self, rhs: Self) -> Self { @@ -55,35 +30,15 @@ impl Mul for PubBit { /// This type wraps different implementations for secret bit types /// in order to provide a stable API for every type it wraps. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)] -pub struct SecBit(T); +pub struct SecBit(T); -impl MPCType for SecBit { - fn square(self) -> Self { - todo!(); - } - - fn pow(self, exp: usize) -> Self { - todo!(); - } - - fn min(self, a: Self) -> Self { - todo!(); - } - - fn max(self, a: Self) -> Self { - todo!(); - } - - fn if_else(self, a: Self, b: Self) -> Self { - todo!(); - } +impl Number for SecBit {} - fn cond_swap(self, a: Self, b: Self) -> (Self, Self) { - todo!(); - } +impl SecretSharing for SecBit { + type Public = PubBit; } -impl Add for SecBit { +impl Add for SecBit { type Output = Self; fn add(self, rhs: Self) -> Self { @@ -91,7 +46,7 @@ impl Add for SecBit { } } -impl Mul for SecBit { +impl Mul for SecBit { type Output = Self; fn mul(self, rhs: Self) -> Self { @@ -99,3 +54,9 @@ impl Mul for SecBit { } } +impl std::fmt::Display for SecBit { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let out = self.0.to_string(); + write!(f, "{}", out.trim_start_matches('0')) + } +} diff --git a/types/src/numbers/fixed.rs b/types/src/numbers/fixed.rs index dce4e6d..26199cb 100644 --- a/types/src/numbers/fixed.rs +++ b/types/src/numbers/fixed.rs @@ -1,40 +1,15 @@ -use super::secret_sharing::SecretSharing; -use super::MPCType; +use super::{Number, SecretSharing}; use std::ops::{Add, Mul}; /// Public fixed point type /// /// This type is used for providing arithmetic for fixed point numbers #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Copy, Default)] -pub struct PubFixed(); +pub struct PubFixed(T); -impl MPCType for PubFixed { - fn square(self) -> Self { - todo!(); - } - - fn pow(self, exp: usize) -> Self { - todo!(); - } - - fn min(self, a: Self) -> Self { - todo!(); - } - - fn max(self, a: Self) -> Self { - todo!(); - } - - fn if_else(self, a: Self, b: Self) -> Self { - todo!(); - } - - fn cond_swap(self, a: Self, b: Self) -> (Self, Self) { - todo!(); - } -} +impl Number for PubFixed {} -impl Add for PubFixed { +impl Add for PubFixed { type Output = Self; fn add(self, rhs: Self) -> Self { @@ -42,7 +17,7 @@ impl Add for PubFixed { } } -impl Mul for PubFixed { +impl Mul for PubFixed { type Output = Self; fn mul(self, rhs: Self) -> Self { @@ -55,35 +30,15 @@ impl Mul for PubFixed { /// This type wraps different implementations for secret fixed point types /// in order to provide a stable API for every type it wraps. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)] -pub struct SecFixed(T); +pub struct SecFixed(T); -impl MPCType for SecFixed { - fn square(self) -> Self { - todo!(); - } - - fn pow(self, exp: usize) -> Self { - todo!(); - } - - fn min(self, a: Self) -> Self { - todo!(); - } - - fn max(self, a: Self) -> Self { - todo!(); - } - - fn if_else(self, a: Self, b: Self) -> Self { - todo!(); - } +impl Number for SecFixed {} - fn cond_swap(self, a: Self, b: Self) -> (Self, Self) { - todo!(); - } +impl SecretSharing for SecFixed { + type Public = PubFixed; } -impl Add for SecFixed { +impl Add for SecFixed { type Output = Self; fn add(self, rhs: Self) -> Self { @@ -91,7 +46,7 @@ impl Add for SecFixed { } } -impl Mul for SecFixed { +impl Mul for SecFixed { type Output = Self; fn mul(self, rhs: Self) -> Self { @@ -99,3 +54,9 @@ impl Mul for SecFixed { } } +impl std::fmt::Display for SecFixed { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let out = self.0.to_string(); + write!(f, "{}", out.trim_start_matches('0')) + } +} diff --git a/types/src/numbers/float.rs b/types/src/numbers/float.rs index 1f42631..f49ce2b 100644 --- a/types/src/numbers/float.rs +++ b/types/src/numbers/float.rs @@ -1,40 +1,15 @@ -use super::secret_sharing::SecretSharing; -use super::MPCType; +use super::{Number, SecretSharing}; use std::ops::{Add, Mul}; /// Public floating point type /// /// This type is used for providing arithmetic for floating point numbers #[derive(Debug, Clone, PartialEq, PartialOrd, Copy, Default)] -pub struct PubFloat(f32); +pub struct PubFloat(T); -impl MPCType for PubFloat { - fn square(self) -> Self { - todo!(); - } - - fn pow(self, exp: usize) -> Self { - todo!(); - } - - fn min(self, a: Self) -> Self { - todo!(); - } - - fn max(self, a: Self) -> Self { - todo!(); - } - - fn if_else(self, a: Self, b: Self) -> Self { - todo!(); - } - - fn cond_swap(self, a: Self, b: Self) -> (Self, Self) { - todo!(); - } -} +impl Number for PubFloat {} -impl Add for PubFloat { +impl Add for PubFloat { type Output = Self; fn add(self, rhs: Self) -> Self { @@ -42,7 +17,7 @@ impl Add for PubFloat { } } -impl Mul for PubFloat { +impl Mul for PubFloat { type Output = Self; fn mul(self, rhs: Self) -> Self { @@ -55,35 +30,15 @@ impl Mul for PubFloat { /// This type wraps different implementations for secret floating point types /// in order to provide a stable API for every type it wraps. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)] -pub struct SecFloat(T); +pub struct SecFloat(T); -impl MPCType for SecFloat { - fn square(self) -> Self { - todo!(); - } - - fn pow(self, exp: usize) -> Self { - todo!(); - } - - fn min(self, a: Self) -> Self { - todo!(); - } - - fn max(self, a: Self) -> Self { - todo!(); - } - - fn if_else(self, a: Self, b: Self) -> Self { - todo!(); - } +impl Number for SecFloat {} - fn cond_swap(self, a: Self, b: Self) -> (Self, Self) { - todo!(); - } +impl SecretSharing for SecFloat { + type Public = PubFloat; } -impl Add for SecFloat { +impl Add for SecFloat { type Output = Self; fn add(self, rhs: Self) -> Self { @@ -91,7 +46,7 @@ impl Add for SecFloat { } } -impl Mul for SecFloat { +impl Mul for SecFloat { type Output = Self; fn mul(self, rhs: Self) -> Self { @@ -99,3 +54,9 @@ impl Mul for SecFloat { } } +impl std::fmt::Display for SecFloat { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let out = self.0.to_string(); + write!(f, "{}", out.trim_start_matches('0')) + } +} diff --git a/types/src/numbers/gf2.rs b/types/src/numbers/gf2.rs index 52d1f69..e7a5f58 100644 --- a/types/src/numbers/gf2.rs +++ b/types/src/numbers/gf2.rs @@ -1,40 +1,15 @@ -use super::secret_sharing::SecretSharing; -use super::MPCType; +use super::Number; use std::ops::{Add, Mul}; /// Public Gf2 type /// /// This type is used for providing finite field arithmetic over two elements #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Copy)] -pub struct PubGf2([bool; N]); +pub struct PubGf2([T; N]); -impl MPCType for PubGf2 { - fn square(self) -> Self { - todo!(); - } - - fn pow(self, exp: usize) -> Self { - todo!(); - } +impl Number for PubGf2 {} - fn min(self, a: Self) -> Self { - todo!(); - } - - fn max(self, a: Self) -> Self { - todo!(); - } - - fn if_else(self, a: Self, b: Self) -> Self { - todo!(); - } - - fn cond_swap(self, a: Self, b: Self) -> (Self, Self) { - todo!(); - } -} - -impl Add for PubGf2 { +impl Add for PubGf2 { type Output = Self; fn add(self, rhs: Self) -> Self { @@ -42,7 +17,7 @@ impl Add for PubGf2 { } } -impl Mul for PubGf2 { +impl Mul for PubGf2 { type Output = Self; fn mul(self, rhs: Self) -> Self { @@ -50,9 +25,9 @@ impl Mul for PubGf2 { } } -impl Default for PubGf2 { +impl Default for PubGf2 { fn default() -> Self { - PubGf2([false; N]) + PubGf2([T::default(); N]) } } @@ -61,35 +36,11 @@ impl Default for PubGf2 { /// This type wraps different implementation for secret Gf2 types /// in order to provide a stable API for every type it wraps. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)] -pub struct SecGf2(T); - -impl MPCType for SecGf2 { - fn square(self) -> Self { - todo!(); - } - - fn pow(self, exp: usize) -> Self { - todo!(); - } +pub struct SecGf2(T); - fn min(self, a: Self) -> Self { - todo!(); - } - - fn max(self, a: Self) -> Self { - todo!(); - } +impl Number for SecGf2 {} - fn if_else(self, a: Self, b: Self) -> Self { - todo!(); - } - - fn cond_swap(self, a: Self, b: Self) -> (Self, Self) { - todo!(); - } -} - -impl Add for SecGf2 { +impl Add for SecGf2 { type Output = Self; fn add(self, rhs: Self) -> Self { @@ -97,7 +48,7 @@ impl Add for SecGf2 { } } -impl Mul for SecGf2 { +impl Mul for SecGf2 { type Output = Self; fn mul(self, rhs: Self) -> Self { @@ -105,3 +56,9 @@ impl Mul for SecGf2 { } } +impl std::fmt::Display for SecGf2 { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let out = self.0.to_string(); + write!(f, "{}", out.trim_start_matches('0')) + } +} diff --git a/types/src/numbers/int.rs b/types/src/numbers/int.rs deleted file mode 100644 index 885aa1a..0000000 --- a/types/src/numbers/int.rs +++ /dev/null @@ -1,170 +0,0 @@ -use super::secret_sharing::{shamir::Shamir, SecretSharing}; -use super::MPCType; -use ark_ff::{BigInteger256, PrimeField}; -use num_bigint::BigUint; -use std::ops::{Add, Mul}; -use thiserror::Error; - -/// Public integer -/// -/// This type is used for providing public integers of arbitrary size. -#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Copy, Default)] -pub struct PubInt(BigInteger256); - -impl MPCType for PubInt { - fn square(self) -> Self { - todo!(); - } - - fn pow(self, exp: usize) -> Self { - todo!(); - } - - fn min(self, a: Self) -> Self { - todo!(); - } - - fn max(self, a: Self) -> Self { - todo!(); - } - - fn if_else(self, a: Self, b: Self) -> Self { - todo!(); - } - - fn cond_swap(self, a: Self, b: Self) -> (Self, Self) { - todo!(); - } -} - -impl Add for PubInt { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - todo!(); - } -} - -impl Mul for PubInt { - type Output = Self; - - fn mul(self, rhs: Self) -> Self { - todo!(); - } -} - -/// Secret integer type -/// -/// This type wraps different implementation for secret integers -/// in order to provide a stable API for every type it wraps. -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)] -pub struct SecInt(T); - -impl + Mul> MPCType for SecInt { - fn square(self) -> Self { - todo!(); - } - - fn pow(self, exp: usize) -> Self { - todo!(); - } - - fn min(self, a: Self) -> Self { - todo!(); - } - - fn max(self, a: Self) -> Self { - todo!(); - } - - fn if_else(self, a: Self, b: Self) -> Self { - todo!(); - } - - fn cond_swap(self, a: Self, b: Self) -> (Self, Self) { - todo!(); - } -} - -impl> Add for SecInt { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - SecInt(self.0 + rhs.0) - } -} - -impl> Mul for SecInt { - type Output = Self; - - fn mul(self, rhs: Self) -> Self::Output { - SecInt(self.0 * rhs.0) - } -} - -impl SecInt> { - /// Creates a new secret integer using a Shamir secret - /// - /// This will return a Shamir secret wrapped in a `SecInt` - pub fn new(integer: impl Into) -> Result { - let integer: BigUint = integer.into(); - Ok(SecInt( - Shamir::::new(integer).map_err(|_| IntegerError::Init)?, - )) - } -} - -impl std::fmt::Display for SecInt { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let out = self.0.to_string(); - write!(f, "{}", out.trim_start_matches('0')) - } -} - -#[derive(Debug, Error)] -pub enum IntegerError { - #[error("Unable to initialize SecInt")] - Init, -} - -#[cfg(test)] -mod tests { - use ark_bls12_381::{Fr, FrParameters}; - use ark_ff::Fp256; - - use super::*; - - #[test] - fn sec_int_shamir_new() { - let _secret_int = SecInt::>>::new(42_u64).unwrap(); - } - - #[test] - fn sec_int_shamir_add() { - let secret_int_1 = SecInt::>::new(42_u64).unwrap(); - let secret_int_2 = SecInt::>::new(2_u64).unwrap(); - - assert_eq!( - secret_int_1 + secret_int_2, - SecInt::>::new(44_u64).unwrap() - ); - } - - #[test] - fn sec_int_shamir_multiply() { - let secret_int_1 = SecInt::>::new(42_u64).unwrap(); - let secret_int_2 = SecInt::>::new(2_u64).unwrap(); - - assert_eq!( - secret_int_1 * secret_int_2, - SecInt::>::new(84_u64).unwrap() - ); - } - - #[test] - fn sec_int_shamir_display() { - let secret_int = SecInt::>::new(42_u64).unwrap(); - - assert_eq!(secret_int.to_string(), "2A"); - } -} diff --git a/types/src/numbers/int/ark_integer.rs b/types/src/numbers/int/ark_integer.rs new file mode 100644 index 0000000..355f039 --- /dev/null +++ b/types/src/numbers/int/ark_integer.rs @@ -0,0 +1,31 @@ +use crate::numbers::Number; +use ark_ff::BigInteger256; +use num_bigint::BigUint; +use std::ops::{Add, Mul}; + +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Copy, Default)] +pub struct ArkInt(BigInteger256); + +impl ArkInt { + pub fn new(int: BigUint) -> Result { + Ok(ArkInt(BigInteger256::try_from(int)?)) + } +} + +impl Number for ArkInt {} + +impl Add for ArkInt { + type Output = Self; + + fn add(self, rhs: Self) -> Self::Output { + todo!(); + } +} + +impl Mul for ArkInt { + type Output = Self; + + fn mul(self, rhs: Self) -> Self::Output { + todo!(); + } +} diff --git a/types/src/numbers/int/mod.rs b/types/src/numbers/int/mod.rs new file mode 100644 index 0000000..578b37f --- /dev/null +++ b/types/src/numbers/int/mod.rs @@ -0,0 +1,120 @@ +use super::{Number, SecretSharing}; +use ark_ff::PrimeField; +use num_bigint::BigUint; +use std::ops::{Add, Mul}; + +mod ark_integer; +use ark_integer::ArkInt; + +/// Public integer +/// +/// This type is used for providing public integers of arbitrary size. +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Copy, Default)] +pub struct PubInt(T) +where + T: Number; + +impl Number for PubInt {} + +impl Add for PubInt { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + todo!(); + } +} + +impl Mul for PubInt { + type Output = Self; + + fn mul(self, rhs: Self) -> Self { + todo!(); + } +} + +/// Secret integer type +/// +/// This type wraps different implementation for secret integers +/// in order to provide a stable API for every type it wraps. +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)] +pub struct SecInt(T); + +impl Number for SecInt {} + +impl SecretSharing for SecInt { + type Public = PubInt; +} + +impl Add for SecInt { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + SecInt(self.0 + rhs.0) + } +} + +impl Mul for SecInt { + type Output = Self; + + fn mul(self, rhs: Self) -> Self::Output { + SecInt(self.0 * rhs.0) + } +} + +impl SecInt { + /// Creates a new secret integer using an ark prime field + /// + /// This will return a `SecInt` using an ark prime field + /// as the underlying representation + pub fn new(integer: impl Into) -> Self { + let integer: BigUint = integer.into(); + SecInt(T::from(integer)) + } +} + +impl std::fmt::Display for SecInt { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let out = self.0.to_string(); + write!(f, "{}", out) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::numbers::Number; + use ark_bls12_381::Fr; + + impl Number for Fr {} + + #[test] + fn sec_int_new() { + let _secret_int = SecInt::::new(42_u64); + } + + #[test] + fn sec_int_add() { + let secret_int_1 = SecInt::::new(42_u64); + let secret_int_2 = SecInt::::new(2_u64); + + assert_eq!(secret_int_1 + secret_int_2, SecInt::::new(44_u64)); + } + + #[test] + fn sec_int_multiply() { + let secret_int_1 = SecInt::::new(42_u64); + let secret_int_2 = SecInt::::new(2_u64); + + assert_eq!(secret_int_1 * secret_int_2, SecInt::::new(84_u64)); + } + + #[test] + fn sec_int_display() { + let secret_int = SecInt::::new(42_u64); + + assert_eq!( + secret_int.to_string(), + "Fp256 \"(000000000000000000000000000000000000000000000000000000000000002A)\"" + ); + } +} diff --git a/types/src/numbers/mod.rs b/types/src/numbers/mod.rs index e16394d..797ee3f 100644 --- a/types/src/numbers/mod.rs +++ b/types/src/numbers/mod.rs @@ -5,27 +5,52 @@ pub mod gf2; pub mod int; use std::ops::{Add, Mul}; -pub mod secret_sharing; - /// This trait is a catch-all for a type that is used /// within MPC protocols. -pub trait MPCType: Sized + Add + Mul + Copy + Default { +pub trait Number: + Add + Mul + Copy + Default + std::fmt::Debug + 'static +{ /// Returns the square of an MPCType - fn square(self) -> Self; + fn square(self) -> Self { + todo!(); + } /// Returns the power of itself to an exponent - fn pow(self, exp: usize) -> Self; + fn pow(self, exp: usize) -> Self { + todo!(); + } /// Returns the minimum between itself and another MPCType - fn min(self, a: Self) -> Self; + fn min(self, a: Self) -> Self { + todo!(); + } /// Returns the maximum between itself and another MPCType - fn max(self, b: Self) -> Self; + fn max(self, b: Self) -> Self { + todo!(); + } /// Returns a if self == 1 and b if self == 0 - fn if_else(self, a: Self, b: Self) -> Self; + fn if_else(self, a: Self, b: Self) -> Self { + todo!(); + } /// Returns (a, b) if self == 0 and (b, a) if self == 1 - fn cond_swap(self, a: Self, b: Self) -> (Self, Self); + fn cond_swap(self, a: Self, b: Self) -> (Self, Self) { + todo!(); + } } +/// An abstraction for communication +/// in MPC protocols +pub trait SecretSharing { + type Public; + + fn share(&self) { + todo!(); + } + + fn open(&self) -> Self::Public { + todo!(); + } +} diff --git a/types/src/numbers/secret_sharing/mod.rs b/types/src/numbers/secret_sharing/mod.rs deleted file mode 100644 index 584213d..0000000 --- a/types/src/numbers/secret_sharing/mod.rs +++ /dev/null @@ -1,13 +0,0 @@ -use thiserror::Error; - -pub mod shamir; - -pub trait SecretSharing: Copy + Default { - fn share(&mut self) -> Result<(), SecretSharingError>; -} - -#[derive(Debug, Error)] -pub enum SecretSharingError { - #[error("SecretSharingError: {0}")] - ShamirError(#[from] shamir::ShamirError), -} diff --git a/types/src/numbers/secret_sharing/shamir.rs b/types/src/numbers/secret_sharing/shamir.rs deleted file mode 100644 index 4aebbda..0000000 --- a/types/src/numbers/secret_sharing/shamir.rs +++ /dev/null @@ -1,110 +0,0 @@ -use super::{SecretSharing, SecretSharingError}; -use ark_ff::{Field, PrimeField}; -use num_bigint::BigUint; -use std::ops::{Add, Mul}; -use thiserror::Error; - -/// A Shamir secret -/// -/// This type is used to represent a secret-shared value using polynomials. -/// It can be used as an inner representation of some integer value. -#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default)] -pub struct Shamir(T); - -impl Shamir { - /// Create a new Shamir secret - /// - /// This implementation uses the BLS12-381 prime field. - pub fn new(integer: BigUint) -> Result, ShamirError> { - let field_element = T::from(integer); - Ok(Shamir(field_element)) - } -} - -impl From for Shamir { - fn from(element: T) -> Self { - Shamir(element) - } -} - -impl Add for Shamir { - type Output = Self; - - fn add(self, rhs: Self) -> Self::Output { - Shamir(self.0 + rhs.0) - } -} - -impl Mul for Shamir { - type Output = Self; - - fn mul(self, rhs: Self) -> Self::Output { - Shamir(self.0 * rhs.0) - } -} - -impl std::fmt::Display for Shamir { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", &self.0.into_repr()) - } -} - -impl SecretSharing for Shamir { - fn share(&mut self) -> Result<(), SecretSharingError> { - todo!() - } -} - -#[derive(Debug, Error)] -pub enum ShamirError { - #[error("Unable to convert element into prime field")] - PrimeFieldConvert, - #[error("Unable to create sharing")] - CreateSharing, - #[error("Not enough evaluation points to reconstruct secret")] - Underdetermined, -} - -#[cfg(test)] -mod tests { - use ark_bls12_381::Fr; - - use super::*; - - #[test] - fn shamir_new() { - let _shamir_1 = Shamir::::new(0_u64.into()).unwrap(); - let _shamir_2 = Shamir::::new(2310498322_u64.into()).unwrap(); - } - - #[test] - fn shamir_add() { - let shamir_1 = Shamir::::new(5_u64.into()).unwrap(); - let shamir_2 = Shamir::::new(3_u64.into()).unwrap(); - - assert_eq!( - shamir_1 + shamir_2, - Shamir::::new(8_u64.into()).unwrap() - ); - } - - #[test] - fn shamir_multiply() { - let shamir_1 = Shamir::::new(42_u64.into()).unwrap(); - let shamir_2 = Shamir::::new(5_u64.into()).unwrap(); - - assert_eq!( - shamir_1 * shamir_2, - Shamir::::new(210_u64.into()).unwrap() - ); - } - - #[test] - fn shamir_display() { - let shamir_1 = Shamir::::new(42_u64.into()).unwrap(); - assert_eq!( - shamir_1.to_string(), - "000000000000000000000000000000000000000000000000000000000000002A" - ); - } -} diff --git a/vm/Cargo.toml b/vm/Cargo.toml index a8be430..fe7e762 100644 --- a/vm/Cargo.toml +++ b/vm/Cargo.toml @@ -7,3 +7,9 @@ edition = "2021" [dependencies] types = {path = "../types"} + +futures = { version = "0.3" } +tokio = {version = "0.2", features = ["full"] } +ark-ff = "0.3" +ark-poly = "0.3" +ark-ec = "0.3" diff --git a/vm/src/instructions/arithmetic.rs b/vm/src/instructions/arithmetic.rs new file mode 100644 index 0000000..149e0ee --- /dev/null +++ b/vm/src/instructions/arithmetic.rs @@ -0,0 +1,827 @@ +use crate::processors::arithmetic::ArithmeticProcessor; +use types::numbers::{Number, SecretSharing}; + +// Assign immediate value to clear register +pub fn ldi( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Assign immeidate value to secret register +pub fn ldsi( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Assign clear register to clear memory value(s) by immediate address +pub fn stmc( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Assign secret register to secret memory value(s) by immediate address +pub fn stms( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Assign clear memory value(s) to clear register by register address +pub fn ldmci( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Assign secret memory value(s) to secret register by register address +pub fn ldmsi( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Assign clear register to clear memory value(s) by register address +pub fn stmci( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Assign secret register to secret memory value(s) by register address +pub fn stmsi( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Copy clear register +pub fn movc( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Copy secret register +pub fn movs( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Store number of current thread in clear integer register +pub fn ldtn( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Require on computation modulus +// @dev: Do we need to keep this? +pub fn reqbl( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Custom preprocessed data usage +pub fn use_prep( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Matrix multiplication usage +pub fn use_matmul( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Clear addition +pub fn addc( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Secret addition +pub fn adds( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Mixed addition +pub fn addm( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Addition of clear register and immediate value +pub fn addci( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Addition of secret register and immediate value +pub fn addsi( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Clear subtraction +pub fn subc( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Secret subtraction +pub fn subs( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Subtract clear from secret value +pub fn subml( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Subtract secret from clear value +pub fn submr( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Subtraction immediate value from clear register +pub fn subci( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Subtraction immediate value from secret register +pub fn subsi( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Subtraction of clear register from immediate value +pub fn subcfi( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Subtraction of secret register from immediate value +pub fn subsfi( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Clear multiplcation +pub fn mulc( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Multiply secret and clear value +pub fn mulm( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Multipleication of clear register and immediate value +pub fn mulci( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Multiplication of secret register and immediate value +pub fn mulsi( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Clear division +pub fn divc( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Division of secret register and immediate value +pub fn divci( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Clear modular reduction +pub fn modc( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Modular reduction of clear register and immediate value +pub fn modci( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Clear legendre symbol computation over prime p +pub fn legendrec( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Clear truncated hash computation +pub fn digestc( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Inverse of power of two modulo prime +pub fn inv2m( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Clear integer floor division +pub fn floordivc( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Store fresh random triples in secret register +pub fn triple( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Store fresh random bits in secret register +pub fn bit( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Store fresh random squares in secret register +pub fn square( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Store fresh random inverses in secret register +pub fn inv( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Store custom preprocessed data in secret register +pub fn prep( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Store fresh length-restricted random shares in secret register +pub fn randoms( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Store fresh random input maskes in secret register and clear regiser of the relevant player +pub fn inputmaskreg( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Store shares of a fresh secret random element in secret register +pub fn randomfulls( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Read a variable number of clear values in internal representation from socket for a specified +// client id and store them in clear registers +pub fn readsocketc( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Read a variable number of secret values in internal representation from socket for a specified +// client id and store them in secret registers +pub fn readsockets( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Write a variable number of secret shares from registers into a socket for a specified client id +pub fn writesockets( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Read a variable number of 32-bit integers from socket for a specified client id and store them in clear integer registers +pub fn writesocketshare( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Open a server socket on a party-specific port number and listen for client connections +// @dev: Does this need to be an opcode? +pub fn listen( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Wait for a connection at the given port and write socket handle to clear integer register +// @dev: Does this need to be an opcode? +pub fn acceptclientconnection< + T: Number + SecretSharing, + U: Number, + const M: usize, + const N: usize, +>( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Close connection to client +// @dev: Does this need to be an opcode? +pub fn closeclientconnection< + T: Number + SecretSharing, + U: Number, + const M: usize, + const N: usize, +>( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Logical AND of clear registers +pub fn andc( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Logical XOR of clear registers +pub fn xorc( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Logical OR of clear registers +pub fn orc( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Logical AND of clear registers and immediate value +pub fn andci( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Logical XOR of clear register and immediate value +pub fn xorci( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Logical OR of clear register and immediate value +pub fn orci( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Clear logical NOT of a constant number of bits of clear register +pub fn notc( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Bitwise left shift of clear register +pub fn shlc( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Bitwise right shift of clear register +pub fn shrc( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Bitwise left shift of clear by immediate value +pub fn shlci( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Bitwise right shift of clear register by immediate value +pub fn shrci( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Bitwise right shift of secret register by immediate value +pub fn shrsi( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Reveat secret registers to clear registers +pub fn open( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Element-wise mupleication of secret registers +pub fn muls( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Constant-vector mutiplication of secret registers +pub fn mulrs( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Dot product of secret register +pub fn dotprods( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Probabilistic truncation if supported by protocol +pub fn trunc_pr( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Secret matrix multiplication from registers +pub fn matmuls( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Secret matrix multiplication reading directly from memory +pub fn matmulsm( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Secret 2D convolution +pub fn conv2ds( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Force MAC check in current thread and all idle thread if current thread is the main thread +pub fn check( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Debugging output of clear register +// @dev: Should we keep this? +pub fn printreg( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Store insecure random value of specified length in clear integer register +pub fn rand( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Output clear register +pub fn printregplain( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Store publc input in clear register +pub fn pubinput( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Output floating-number from clear registers +pub fn printfloatplain( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Write shares to Persistence/Transactions-P.data +pub fn writefileshare( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Read shares from Persistence/Transactions-P.data +pub fn readfileshare( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Conditionally output four bytes +pub fn condprintstr( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Convert clear integer register to clear register +pub fn convint( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Convert clear integer register to clear register +pub fn convmodp( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Create incremental clear integer +pub fn incint( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Randomly shuffles clear integer vector with public randomness +pub fn shuffle( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Conditionally output clear register +pub fn condprintplain( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// edaBit usage +pub fn use_edabit( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Binary integer output +pub fn intoutput( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Binary floating-point output +pub fn floatoutput( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Store private input in secret registers +pub fn inputmixed( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Store private input in secret registers +pub fn inputmixedreg( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Store private input in secret registers +pub fn rawinput( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Private input from cint +pub fn inputpersonal( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Bitwise XOR of single secret and clear bit registers +pub fn xorm( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Copy clear bit register vector to clear regiser by bit +pub fn convbitvec( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Copy secret bit register +pub fn mov( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Copy clear bit memory cell with run-time address to clear bit register +pub fn ldmcbi( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +// Copy clear bit register to clear bit memory cell with run-time address +pub fn stmcbi( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +pub fn gldsi( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +pub fn gstms( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +pub fn gldmsi( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +pub fn gstmsi( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +pub fn gmovs( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +pub fn gadds( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +pub fn gaddm( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +pub fn gaddsi( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +pub fn gsubs( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +pub fn gsubsi( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +pub fn gsubsfi( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +pub fn gsubml( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +pub fn gsubmr( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +pub fn gmulm( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +pub fn gmulsi( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +pub fn gtriple( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +pub fn gbit( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} + +pub fn gconvint( + ap: &mut ArithmeticProcessor, +) { + todo!(); +} diff --git a/vm/src/instructions/boolean.rs b/vm/src/instructions/boolean.rs new file mode 100644 index 0000000..4107469 --- /dev/null +++ b/vm/src/instructions/boolean.rs @@ -0,0 +1,340 @@ +use crate::stoffel_vm::StoffelVM; +use types::numbers::{Number, SecretSharing}; + +// Copy private input to secret bit register vectors +pub fn inputb( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Copy private input secret bit registers bit by bit +pub fn inputbvec( + vm: &mut StoffelVM, +) { + todo!(); +} + +pub fn ldmsd( + vm: &mut StoffelVM, +) { + todo!(); +} + +pub fn stmsd( + vm: &mut StoffelVM, +) { + todo!(); +} + +pub fn ldmsdi( + vm: &mut StoffelVM, +) { + todo!(); +} + +pub fn stmsdi( + vm: &mut StoffelVM, +) { + todo!(); +} + +pub fn stmsdci( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Bitwise XOR of secret bit register +pub fn xors( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Bitwise XOR of two single clear bit registers +pub fn xorcb( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Bitwise XOR of single clear bit register and immediate +pub fn xorcbi( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Bitwise NOT of secret register vector +pub fn nots( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Bitwise NOT of secret register vector +pub fn notcb( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Constant-vector AND of secret bit registeers +pub fn andrs( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Bitwise AND of secret bit register vector +pub fn ands( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Integer addition two single clear bit registers +pub fn addcb( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Integer addition single clear bit register and immediate +pub fn addcbi( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Integer multiplication single clear bit register and immediate +pub fn mulcbi( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Secret bit register decomposition +pub fn bitdecs( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Secret bit register decomposition +pub fn bitcoms( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Secret bit register decomposition +pub fn bitdecc( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Right shift of clear bit register by immediate +pub fn shrcbi( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Left shift of clear bit register by immediate +pub fn shlcbi( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Store immediate in secret bit register +pub fn ldbits( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Copy secret bit memory cell with compile-time address to secret bit register +pub fn ldmsb( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Copy secret bit register to secret bit memory cell with compile-time address +pub fn stmsb( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Copy secret bit memory cell with run-time address to secret bit register +pub fn ldmsbi( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Copy secret bit register to secret bit memory cell with run-time address +pub fn stmsbi( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Copy clear bit memory cell with compile-time address to clear bit register +pub fn ldmcb( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Copy clear bit register to cleare bit memory cell with compile-time address +pub fn stmcb( + vm: &mut StoffelVM, +) { + todo!(); +} + +pub fn movsb( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Secret bit register vector transpose +pub fn trans( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Copy fresh secret random bit to secret bit register +pub fn bitb( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Reveal secret bit register vectors and copy result to clear bit register vectors +pub fn reveal( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Signed output of clear bit register +pub fn printregsigned( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Debug output of clear bit register +pub fn printregb( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Output clear bit register +pub fn printregplainb( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Output floating-number from clear bit registers +pub fn printfloatplainb( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Conditionally output four bytes +pub fn condprintstrb( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Bitwise AND of single secret and clear bit registers +pub fn andm( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Copy clear integer register to secret bit register +pub fn convsint( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Copy clear integer register to clear bit register +pub fn convcint( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Copy clear register vector by bit to clear bit register vectors +pub fn convcintvec( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Copy clear bit register to clear integer register +pub fn convcbit( + vm: &mut StoffelVM, +) { + todo!(); +} + +pub fn convcbitvec( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Copy clear bit register vector to secret bit register vector +pub fn convcbit2s( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Store fresh random daBits in secret register +// @dev: Do we need to keep this? +pub fn dabit( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Store frehs random loose edaBits in secret register +// @dev: Do we need to keep this? +pub fn edabit( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Store fresh random strict edaBits in secret register +pub fn sedabit( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Local share conversion +pub fn split( + vm: &mut StoffelVM, +) { + todo!(); +} diff --git a/vm/src/instructions/common.rs b/vm/src/instructions/common.rs new file mode 100644 index 0000000..c440661 --- /dev/null +++ b/vm/src/instructions/common.rs @@ -0,0 +1,307 @@ +// VM Instructions that are common to both GC and Arithmetic circuits + +use types::numbers::{Number, SecretSharing}; + +use crate::stoffel_vm::StoffelVM; + +// Output a single byte +pub fn printchr( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Output four bytes +pub fn printstr( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Set number of digits after decimal point for PRINTFLOATPLAIN +// @dev: Do we need this? +pub fn printfloatprec( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Store immediate value in clear integer register +pub fn ldint( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Clear integer register addition +pub fn addint( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Clera integer register subtraction +pub fn subint( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Clear integer register multiplication +pub fn mulint( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Clear integer register division with floor rounding +pub fn divint( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Unconditional relative jump in the bytecode +pub fn jmp( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Conditional relative jump in the bytecode +// NZ = Not Zero +pub fn jmpnz( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Conditional relative jump in the bytecode +pub fn jmpeqz( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Clear integer zero test +pub fn eqzc( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Clear integer less than zero test +pub fn ltzc( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Clear integer less than comparison +pub fn ltc( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Clear integer greater than comparison +pub fn gtc( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Clear integer equality test +pub fn eqc( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Unconditional relative jump in the bytecode +pub fn jmpi( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Assign clear integer memory value(s) to clear integer register by immediate address +pub fn ldmint( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Assign clear integer memory value(s) to clear integer register by immeiate address +pub fn stmint( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Assign clear integer memory value(s) to clear integer register by register address +pub fn ldminti( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Assign clear integer to clear integer memory value(s) by register address +pub fn stminti( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Pushes clear integer register to the thread-local stack +pub fn pushint( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Pops from the thread-local stack to clear integer +pub fn popint( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Copy clear integer register +pub fn movint( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Clear integer bit decomposition +pub fn bitdecint( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Store the argument passed to the current thread in clear integer register +pub fn ldarg( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Copy clear integer register to the thread argument +pub fn starg( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Output time since start of computation +pub fn time( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Start timer +pub fn start( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Stop timer +pub fn stop( + vm: &mut StoffelVM, +) { + todo!(); +} + +pub fn gldms( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Assign clear memory value(s) to clear register by immediate address +pub fn ldmc( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Assign secret memory value(s) to secret register by immediate address +pub fn ldms( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Output clear integer register +// @dev: Should we keep this? +pub fn printint( + vm: &mut StoffelVM, +) { + todo!(); +} + +pub fn gldmc( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Start tape/bytecode file in another thread +pub fn run_tape( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Join thread +pub fn join_tape( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Crash runtime if the register's value is > 0 +pub fn crash( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Offline data usage +pub fn use_off( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Input usage +pub fn use_inp( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Store number of players in clear integer register +pub fn nplayers( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Store maximal number of corrupt players in clear integer register +pub fn threshold( + vm: &mut StoffelVM, +) { + todo!(); +} + +// Store current player number in clear integer register +pub fn playerid( + vm: &mut StoffelVM, +) { + todo!(); +} diff --git a/vm/src/instructions/mod.rs b/vm/src/instructions/mod.rs new file mode 100644 index 0000000..11dd217 --- /dev/null +++ b/vm/src/instructions/mod.rs @@ -0,0 +1,5 @@ +pub mod arithmetic; +pub mod boolean; +pub mod common; +pub mod opcodes; + diff --git a/vm/src/instructions.rs b/vm/src/instructions/opcodes.rs similarity index 98% rename from vm/src/instructions.rs rename to vm/src/instructions/opcodes.rs index 7e8f8fe..89e7625 100644 --- a/vm/src/instructions.rs +++ b/vm/src/instructions/opcodes.rs @@ -2,7 +2,8 @@ /// These are the instructions for the StoffelMPC VM. These instructions are taken from the MP-SPDZ's VM instructions /// These instructions may be reduced or added to at a later time. -pub enum Instructions { +#[derive(Debug, Clone, Copy)] +pub enum Opcodes { /// Emulation CISC = 0x00, /// Load/store @@ -188,4 +189,3 @@ pub enum Instructions { INITSECURESOCKET = 0x1BA, RESPSECURESOCKET = 0x1BB, } - diff --git a/vm/src/lib.rs b/vm/src/lib.rs new file mode 100644 index 0000000..3b4dada --- /dev/null +++ b/vm/src/lib.rs @@ -0,0 +1,9 @@ +#![feature(derive_default_enum)] + +mod instructions; +mod processors; +mod program; +mod state; +pub mod stoffel_vm; + +pub use stoffel_vm::StoffelVM; diff --git a/vm/src/main.rs b/vm/src/main.rs index 40845b5..f328e4d 100644 --- a/vm/src/main.rs +++ b/vm/src/main.rs @@ -1,27 +1 @@ -mod instructions; - fn main() {} - -pub struct StoffelVM { - stack: Vec, - memory: Vec, - code: Vec, - sp: u32, - fp: u32, - ip: u32, - log_level: (), -} - -impl StoffelVM { - pub fn new() -> Self { - todo!() - } - - pub fn run(&mut self) { - loop { - todo!() - } - } - - fn load_code(&mut self) {} -} diff --git a/vm/src/processors/arithmetic.rs b/vm/src/processors/arithmetic.rs new file mode 100644 index 0000000..1170a0b --- /dev/null +++ b/vm/src/processors/arithmetic.rs @@ -0,0 +1,70 @@ +use types::numbers::{Number, SecretSharing}; + +use super::Processor; +use crate::state::{GlobalMemory, Registers, StackRegisters}; + +#[derive(Debug, Clone, Default)] +pub struct ArithmeticProcessor +{ + pub stack: StackRegisters, + pub registers: Registers, +} + +impl Processor + for ArithmeticProcessor +{ + type Memory = GlobalMemory; + + fn clear_registers(&mut self) { + todo!() + } + + fn get_program_counter(&self) -> usize { + todo!() + } + + fn get_program_size(&self) -> usize { + todo!() + } + + fn execute(&mut self) { + todo!() + } + + fn jump(&mut self) { + todo!() + } + + fn relative_jump(&mut self) { + todo!() + } + + fn increment_program_counter(&mut self) { + todo!() + } + + fn read_tape(&self) { + todo!() + } + + fn receive_tape(&self) { + todo!() + } + + fn receive_private_input(&self, to_store_in_memory: bool) { + todo!() + } + + fn give_private_output(&self, to_store_in_memory: bool) { + todo!() + } + + fn memory(&self) -> Self::Memory { + todo!() + } +} + +impl + ArithmeticProcessor +{ +} diff --git a/vm/src/processors/boolean.rs b/vm/src/processors/boolean.rs new file mode 100644 index 0000000..6848f4d --- /dev/null +++ b/vm/src/processors/boolean.rs @@ -0,0 +1,69 @@ +use crate::state::{GlobalMemory, Registers, StackRegisters}; +use types::numbers::{Number, SecretSharing}; + +use super::Processor; + +#[derive(Debug, Clone, Default)] +pub struct BooleanProcessor { + pub stack: StackRegisters, + pub registers: Registers, +} + +impl Processor + for BooleanProcessor +{ + type Memory = GlobalMemory; + + fn clear_registers(&mut self) { + todo!() + } + + fn get_program_counter(&self) -> usize { + todo!() + } + + fn get_program_size(&self) -> usize { + todo!() + } + + fn execute(&mut self) { + todo!() + } + + fn jump(&mut self) { + todo!() + } + + fn relative_jump(&mut self) { + todo!() + } + + fn increment_program_counter(&mut self) { + todo!() + } + + fn read_tape(&self) { + todo!() + } + + fn receive_tape(&self) { + todo!() + } + + fn receive_private_input(&self, to_store_in_memory: bool) { + todo!() + } + + fn give_private_output(&self, to_store_in_memory: bool) { + todo!() + } + + fn memory(&self) -> Self::Memory { + todo!() + } +} + +impl + BooleanProcessor +{ +} diff --git a/vm/src/processors/mod.rs b/vm/src/processors/mod.rs new file mode 100644 index 0000000..ac9b145 --- /dev/null +++ b/vm/src/processors/mod.rs @@ -0,0 +1,23 @@ +/// A Processor is component of the MPC VM that handles the core processing within the MPC VM +pub mod arithmetic; +pub mod boolean; + +pub use arithmetic::ArithmeticProcessor; +pub use boolean::BooleanProcessor; + +pub trait Processor: std::fmt::Debug { + type Memory; + + fn clear_registers(&mut self); + fn get_program_counter(&self) -> usize; + fn get_program_size(&self) -> usize; + fn execute(&mut self); + fn jump(&mut self); + fn relative_jump(&mut self); + fn increment_program_counter(&mut self); + fn read_tape(&self); + fn receive_tape(&self); + fn receive_private_input(&self, to_store_in_memory: bool); + fn give_private_output(&self, to_store_in_memory: bool); + fn memory(&self) -> Self::Memory; +} diff --git a/vm/src/program.rs b/vm/src/program.rs new file mode 100644 index 0000000..6970d43 --- /dev/null +++ b/vm/src/program.rs @@ -0,0 +1,18 @@ +use super::instructions::opcodes::Opcodes; + +#[derive(Debug)] +pub struct Program(Vec); + +impl Program { + pub fn new() -> Self { + Program(vec![]) + } + + pub fn parse_bytes(&mut self, bytes: impl AsRef<[u8]>) { + todo!(); + } + + fn execute() { + todo!(); + } +} diff --git a/vm/src/state.rs b/vm/src/state.rs new file mode 100644 index 0000000..75f4435 --- /dev/null +++ b/vm/src/state.rs @@ -0,0 +1,134 @@ +use types::numbers::{ + bit::{PubBit, SecBit}, + fixed::{PubFixed, SecFixed}, + float::{PubFloat, SecFloat}, + gf2::{PubGf2, SecGf2}, + int::{PubInt, SecInt}, + Number, SecretSharing, +}; + +#[derive(Clone, Debug, Default)] +pub struct StackRegisters { + secret_int_memory: StackRegister>, + pub_int_memory: StackRegister>, + + secret_fixed_memory: StackRegister>, + pub_fixed_memory: StackRegister>, + + secret_float_memory: StackRegister>, + pub_float_memory: StackRegister>, + + secret_bit_memory: StackRegister>, + pub_bit_memory: StackRegister>, + + secret_gf2_memory: StackRegister>, + public_gf2_memory: StackRegister>, +} + +#[derive(Clone, Debug, Default)] +pub struct Registers { + secret_int_memory: Register, N>, + pub_int_memory: Register, N>, + + secret_fixed_memory: Register, N>, + pub_fixed_memory: Register, N>, + + secret_float_memory: Register, N>, + pub_float_memory: Register, N>, + + secret_bit_memory: Register, N>, + pub_bit_memory: Register, N>, + + secret_gf2_memory: Register, N>, + public_gf2_memory: Register, N>, +} + +#[derive(Clone, Debug, Default)] +pub struct GlobalMemory { + secret_int_memory: Memory>, + pub_int_memory: Memory>, + + secret_fixed_memory: Memory>, + pub_fixed_memory: Memory>, + + secret_float_memory: Memory>, + pub_float_memory: Memory>, + + secret_bit_memory: Memory>, + pub_bit_memory: Memory>, + + secret_gf2_memory: Memory>, + public_gf2_memory: Memory>, +} + +#[derive(Clone, Debug)] +struct Register([T; N]); + +impl Default for Register { + fn default() -> Self { + Self([T::default(); N]) + } +} + +impl Register { + fn read(&self, i: usize) -> T { + self.0[i] + } + + fn write(&mut self, i: usize, element: T) { + self.0[i] = element; + } +} + +#[derive(Clone, Debug, Default)] +struct StackRegister(Vec); + +impl StackRegister { + fn push(&mut self, element: T) { + self.0.push(element); + } + + fn pop(&mut self) -> T { + self.0.pop().unwrap() + } + + fn peek(&self, location: usize) -> Option<&T> { + self.0.get(location) + } + + fn poke(&mut self, location: usize, element: T) { + if location > self.0.len() { + panic!("location is out of range"); + } + self.0[location] = element; + } +} + +#[derive(Clone, Debug, Default)] +struct Memory(Vec); + +impl Memory { + fn new() -> Self { + todo!(); + } + + fn read() -> T { + todo!(); + } + + fn write() { + todo!(); + } + + fn allocate() { + todo!(); + } + + fn deallocate() { + todo!(); + } + + fn resize() { + todo!(); + } +} diff --git a/vm/src/stoffel_vm.rs b/vm/src/stoffel_vm.rs new file mode 100644 index 0000000..9c2bcac --- /dev/null +++ b/vm/src/stoffel_vm.rs @@ -0,0 +1,65 @@ +use super::processors::{ArithmeticProcessor, BooleanProcessor, Processor}; +use super::program::Program; +use super::state::GlobalMemory; +use std::sync::{Arc, Mutex}; +use types::numbers::{Number, SecretSharing}; + +#[derive(Debug, Clone, Copy, Default)] +pub enum VMMode { + #[default] + Normal, + Debug, + Optimized, +} + +#[derive(Debug)] +pub struct StoffelVM { + processors: Vec>>>, + program_counter: usize, + global_memory: Arc>>, + mode: VMMode, + code: Program, +} + +impl StoffelVM { + pub fn new() -> Self { + Self { + processors: vec![ + Box::new(ArithmeticProcessor::::default()), + Box::new(BooleanProcessor::::default()), + ], + program_counter: 0, + global_memory: Arc::new(Mutex::new(GlobalMemory::::default())), + mode: VMMode::default(), + code: Program::new(), + } + } + + pub fn load_byte_code(&mut self, bytes: impl AsRef<[u8]>) { + self.code.parse_bytes(bytes.as_ref()) + } + + pub fn execute(&mut self) -> i32 { + todo!(); + } + + pub fn load_schedule() { + todo!(); + } + + pub fn set_mode(&mut self, mode: VMMode) { + todo!(); + } + + pub fn start_timer() { + todo!(); + } + + pub fn stop_timer() { + todo!(); + } + + pub fn get_current_program_counter(&self) -> usize { + self.program_counter + } +}