use age::secrecy::ExposeSecret;
use age::{Decryptor, Encryptor, decrypt, encrypt, x25519};
use num_bigint::BigUint;
use secretsharing_shamir::{BitSize, SS, Share};
use serde::{Deserialize, Serialize};
use std::fmt::Error;
use std::fs;
use std::io::{Read, Write};
use std::path::Path;
pub struct PPVSS {
N: u8,
T: u8,
Parties: Vec<Party>,
}
impl PPVSS {
pub fn new(
n: u8,
t: u8,
parties: Vec<Party>,
) -> Result<Self, Box<dyn std::error::Error>> {
Ok(Self {
N: n,
T: t,
Parties: parties,
})
}
pub fn share(&self, secret: BigUint) -> (Vec<Share>, BigUint) {
let prime_size = BitSize::BN254; let mut ss = SS::new(prime_size, true, self.T, &secret).unwrap();
let mut points: Vec<BigUint> = vec![]; for i in 0..self.N as usize {
points.push(prime_size.n_bit_random()); }
let shares = ss.gen_shares(&points);
let mut encrypted_shares: Vec<Share> = vec![];
for i in 0..self.N as usize {
let fi = shares[i].y().to_bytes_be();
let yi_vecu8 = encrypt(&self.Parties[i].public_key, &fi).unwrap();
let yi = BigUint::from_bytes_be(&yi_vecu8);
encrypted_shares.push(Share::new(shares[i].x().clone(), yi)); }
(encrypted_shares, BigUint::from(23u32))
}
pub fn verify(
n: u8,
pk: &[BigUint],
t: u8,
proof: BigUint,
) -> u8 {
11u8
}
pub fn reconstruct(&self, shares: Vec<Share>, SK: Vec<KeyPair>) -> Result<BigUint, Error> {
let mut decrypted_shares: Vec<Share> = vec![];
for i in 0..SK.len() as usize {
let fi = shares[i].y().to_bytes_be();
let fi_vecu8 = decrypt(&SK[i].private_key, &fi).unwrap();
let fi = BigUint::from_bytes_be(&fi_vecu8);
decrypted_shares.push(Share::new(shares[i].x().clone(), fi)); }
let rs = SS::reconstruct_secret(&BitSize::BN254.fixed_prime(), &decrypted_shares);
Ok(rs)
}
}
pub struct KeyPair {
private_key: x25519::Identity,
public_key: x25519::Recipient,
}
impl KeyPair {
pub fn generate() -> Self {
let private_key = x25519::Identity::generate();
let public_key = private_key.to_public();
Self {
private_key,
public_key,
}
}
pub fn save_private_key<P: AsRef<Path>>(
&self,
path: P,
) -> Result<(), Box<dyn std::error::Error>> {
let sk_str = self.private_key.to_string();
fs::write(path, sk_str.expose_secret())?;
Ok(())
}
pub fn save_public_key<P: AsRef<Path>>(
&self,
path: P,
) -> Result<(), Box<dyn std::error::Error>> {
let public_key_str = self.public_key.to_string();
fs::write(path, public_key_str)?;
Ok(())
}
pub fn load_from_private_key<P: AsRef<Path>>(
path: P,
) -> Result<Self, Box<dyn std::error::Error>> {
let private_key_str = fs::read_to_string(path)?;
let private_key: x25519::Identity = private_key_str.trim().parse()?;
let public_key = private_key.to_public();
Ok(Self {
private_key,
public_key,
})
}
pub fn public_key_string(&self) -> String {
self.public_key.to_string()
}
}
#[derive(Debug, Clone)]
pub struct Party {
public_key: x25519::Recipient,
share: Share, }
impl Party {
pub fn new<P: AsRef<Path>>(path: P) -> Self {
let public_key_str = fs::read_to_string(path).unwrap();
let public_key: x25519::Recipient = public_key_str.trim().parse().unwrap();
let empty_share = Share::new(BigUint::from(0u8), BigUint::from(0u8));
Self {
public_key: public_key,
share: empty_share,
}
}
pub fn encrypt(&self, data: &[u8]) -> Result<Vec<u8>, age::EncryptError> {
match age::encrypt(&self.public_key, data) {
Ok(ncryptd) => Ok(ncryptd),
Err(e) => Err(e), }
}
pub fn public_key_string(&self) -> String {
self.public_key.to_string()
}
}