#![cfg_attr(docsrs, feature(doc_cfg))]
use std::sync::{Arc, Mutex};
#[cfg(feature = "gmp")]
pub mod gmp;
#[cfg(feature = "bigint")]
pub mod bigint;
const BASE: i64 = 65537;
pub trait BigInt:
Clone
+ Sized
+ Send
+ Sync
+ Eq
+ PartialOrd
+ std::ops::Neg
+ for<'a> std::ops::Add<&'a Self, Output = Self>
+ for<'a> std::ops::Sub<&'a Self, Output = Self>
+ for<'a> std::ops::Mul<&'a Self, Output = Self>
+ for<'a> std::ops::Div<&'a Self, Output = Self>
+ for<'a> std::ops::Rem<&'a Self, Output = Self>
{
fn from_i64(v: i64) -> Self;
fn from_bytes_be(bytes: &[u8]) -> Self;
fn to_bytes_be(&self) -> Vec<u8>;
fn gcdext<'a>(&self, y: &'a Self) -> (Self, Self, Self);
fn powm<'a>(&self, e: &'a Self, m: &Self) -> Self;
fn size_in_bits(&self) -> usize;
}
#[derive(Clone)]
pub struct Accumulator<T: BigInt> {
n: T,
d: Option<T>,
z: T,
}
impl<T: BigInt> Accumulator<T> {
pub fn with_private_key(
n: &T,
d: &T,
) -> Self {
Accumulator {
n: n.clone(),
d: Some(d.clone()),
z: T::from_i64(BASE),
}
}
pub fn with_public_key(
n: &T,
) -> Self {
Accumulator {
n: n.clone(),
d: None,
z: T::from_i64(BASE),
}
}
pub fn get_public_key(
&self,
) -> T {
self.n.clone()
}
pub fn add(
&mut self,
x: &T,
) -> T {
let w = self.z.clone();
self.z = self.z.powm(&x, &self.n);
w
}
pub fn del(
&mut self,
x: &T,
) -> Result<T, MissingPrivateKeyError> {
let d = match self.d.as_ref() {
Some(d) => d,
None => return Err(MissingPrivateKeyError {}),
};
let x_i = x.powm(&T::from_i64(-1), &d);
self.z = self.z.powm(&x_i, &self.n);
Ok(self.z.clone())
}
pub fn prove(
&self,
x: &T,
) -> Result<T, MissingPrivateKeyError> {
let d = match self.d.as_ref() {
Some(d) => d,
None => return Err(MissingPrivateKeyError {}),
};
let x_i = x.powm(&T::from_i64(-1), &d);
Ok(self.z.powm(&x_i, &self.n))
}
pub fn verify(
&self,
x: &T,
w: &T,
) -> Result<(), ElementNotFoundError> {
let w_x = w.powm(x, &self.n);
if self.z != w_x {
Err(ElementNotFoundError {})
} else {
Ok(())
}
}
pub fn get_value(
&self,
) -> T {
self.z.clone()
}
pub fn set_value(
&mut self,
z: &T,
) {
self.z = z.clone();
}
}
#[derive(Default)]
#[derive(Clone)]
pub struct Update<T: BigInt> {
n: T,
z: T,
pi_a: T,
pi_d: T,
}
impl<'u, T: 'u + BigInt> Update<T> {
pub fn new(
acc: &Accumulator<T>,
) -> Self {
Update {
n: acc.get_public_key(),
z: acc.get_value(),
pi_a: T::from_i64(1),
pi_d: T::from_i64(1),
}
}
pub fn from_products(
acc: &Accumulator<T>,
pi_a: &T,
pi_d: &T,
) -> Self {
Update {
n: acc.get_public_key(),
z: acc.get_value(),
pi_a: pi_a.clone(),
pi_d: pi_d.clone(),
}
}
pub fn add(
&mut self,
x: &T,
) {
self.pi_a = self.pi_a.clone() * x;
}
pub fn del(
&mut self,
x: &T,
) {
self.pi_d = self.pi_d.clone() * x;
}
pub fn get_add(
&self,
) -> T {
self.pi_a.clone()
}
pub fn get_del(
&self,
) -> T {
self.pi_d.clone()
}
pub fn update_witness(
&self,
x: &T,
w: &T,
) -> T {
let (_, a, b) = self.pi_d.gcdext(&x);
(w.powm(&(a * &self.pi_a), &self.n)
* &self.z.powm(&b, &self.n))
% &self.n
}
pub fn update_witnesses<
IA: Iterator<Item = &'u mut (T, T)> + Send,
IS: Iterator<Item = &'u mut (T, T)> + Send,
>(
&self,
additions: Arc<Mutex<IA>>,
staticels: Arc<Mutex<IS>>,
) {
loop {
let update;
let (x, w, u) = {
match staticels.lock().unwrap().next() {
Some((x, w)) => (x, w, self),
None => {
match additions.lock().unwrap().next() {
Some((x, w)) => {
update = Update {
n: self.n.clone(),
z: self.z.clone(),
pi_a: self.pi_a.clone() / x,
pi_d: self.pi_d.clone(),
};
(x, w, &update)
}
None => break,
}
}
}
};
*w = u.update_witness(&x, &w);
}
}
}
#[derive(Debug)]
pub struct MissingPrivateKeyError;
impl std::fmt::Display for MissingPrivateKeyError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Missing private key")
}
}
#[derive(Debug)]
pub struct ElementNotFoundError;
impl std::fmt::Display for ElementNotFoundError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Element not found")
}
}