|
| 1 | +use co_noir::{Bn254, Rep3MpcNet}; |
| 2 | +use noirc_artifacts::program::ProgramArtifact; |
| 3 | +use rand::{Rng, distributions::Alphanumeric}; |
| 4 | +use serde::{Deserialize, Serialize}; |
| 5 | +use std::path::PathBuf; |
| 6 | + |
| 7 | +#[derive(Serialize, Deserialize, Debug)] |
| 8 | +pub struct ProverData { |
| 9 | + user1: User, |
| 10 | +} |
| 11 | + |
| 12 | +#[derive(Serialize, Deserialize, Debug)] |
| 13 | +struct User { |
| 14 | + age: u32, |
| 15 | + gender: u32, |
| 16 | + id: String, |
| 17 | + interests: Vec<u32>, |
| 18 | + region: u32, |
| 19 | + preferences: Preferences, |
| 20 | +} |
| 21 | + |
| 22 | +#[derive(Serialize, Deserialize, Debug)] |
| 23 | +struct Preferences { |
| 24 | + age_max: u32, |
| 25 | + age_min: u32, |
| 26 | + gender: u32, |
| 27 | +} |
| 28 | + |
| 29 | +pub async fn split_handler( |
| 30 | + payload: ProverData, |
| 31 | + program_artifact: &ProgramArtifact, |
| 32 | +) -> Result<Vec<String>, Box<dyn std::error::Error + Send + Sync + 'static>> { |
| 33 | + let prover_path1 = save_prover_data(&payload, false)?; |
| 34 | + let prover_path2 = save_prover_data(&payload, true)?; |
| 35 | + |
| 36 | + let shares1 = split_input(prover_path1, &program_artifact)?; |
| 37 | + let shares2 = split_input(prover_path2, &program_artifact)?; |
| 38 | + |
| 39 | + let mut out = shares1 |
| 40 | + .iter() |
| 41 | + .map(|d| hex::encode(d)) |
| 42 | + .collect::<Vec<String>>(); |
| 43 | + |
| 44 | + let out2 = shares2 |
| 45 | + .iter() |
| 46 | + .map(|d| hex::encode(d)) |
| 47 | + .collect::<Vec<String>>(); |
| 48 | + |
| 49 | + out.extend(out2); |
| 50 | + |
| 51 | + Ok(out) |
| 52 | +} |
| 53 | + |
| 54 | +fn split_input( |
| 55 | + input_path: PathBuf, |
| 56 | + program_artifact: &ProgramArtifact, |
| 57 | +) -> Result<Vec<Vec<u8>>, Box<dyn std::error::Error + Send + Sync + 'static>> { |
| 58 | + let inputs = co_noir::parse_input(input_path, &program_artifact)?; |
| 59 | + |
| 60 | + let mut rng = rand::thread_rng(); |
| 61 | + let shares = co_noir::split_input_rep3::<Bn254, Rep3MpcNet, _>(inputs, &mut rng); |
| 62 | + |
| 63 | + let out = shares |
| 64 | + .iter() |
| 65 | + .map(|share| bincode::serialize(share)) |
| 66 | + .collect::<Result<Vec<Vec<u8>>, _>>() |
| 67 | + .unwrap(); |
| 68 | + |
| 69 | + Ok(out) |
| 70 | +} |
| 71 | + |
| 72 | +fn save_prover_data( |
| 73 | + prover: &ProverData, |
| 74 | + as_user2: bool, |
| 75 | +) -> Result<PathBuf, Box<dyn std::error::Error + Send + Sync + 'static>> { |
| 76 | + let mut toml = toml::to_string(prover)?; |
| 77 | + if as_user2 { |
| 78 | + toml = toml.replace("user1", "user2"); |
| 79 | + } |
| 80 | + println!("toml: {}", toml); |
| 81 | + let file_path = write_file(None, &toml)?; |
| 82 | + Ok(file_path) |
| 83 | +} |
| 84 | + |
| 85 | +fn write_file( |
| 86 | + file_name: Option<&str>, |
| 87 | + data: &str, |
| 88 | +) -> Result<PathBuf, Box<dyn std::error::Error + Send + Sync + 'static>> { |
| 89 | + let dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tmp"); |
| 90 | + |
| 91 | + // create the directory if it doesn't exist |
| 92 | + std::fs::create_dir_all(dir.clone())?; |
| 93 | + |
| 94 | + let name = match file_name { |
| 95 | + Some(file_name) => file_name.to_string(), |
| 96 | + None => rand::thread_rng() |
| 97 | + .sample_iter(&Alphanumeric) |
| 98 | + .take(10) |
| 99 | + .map(char::from) |
| 100 | + .collect(), |
| 101 | + }; |
| 102 | + |
| 103 | + let file = dir.join(name); |
| 104 | + std::fs::write(file.clone(), data)?; |
| 105 | + Ok(file) |
| 106 | +} |
0 commit comments