use std::fs::File;
use std::io::{BufWriter, Write};
use std::path::Path;
use byteorder::{LittleEndian, WriteBytesExt};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let testdata_dir = Path::new("testdata");
std::fs::create_dir_all(testdata_dir)?;
generate_database(testdata_dir)?;
generate_account_mapping(testdata_dir)?;
generate_storage_mapping(testdata_dir)?;
println!("Test data generated in testdata/");
println!();
println!("To run PIR setup:");
println!(" cargo run --release --bin inspire-setup -- \\");
println!(" --database testdata/database.bin \\");
println!(" --entry-size 32 \\");
println!(" --output-dir testdata/pir");
println!();
println!("To query by index:");
println!(" cargo run --release --bin inspire-client -- \\");
println!(" --server http://localhost:3000 \\");
println!(" --secret-key testdata/pir/secret_key.json \\");
println!(" index 42");
Ok(())
}
fn generate_database(dir: &Path) -> Result<(), Box<dyn std::error::Error>> {
let path = dir.join("database.bin");
let file = File::create(&path)?;
let mut writer = BufWriter::new(file);
let num_entries = 1024;
let entry_size = 32;
for i in 0..num_entries {
let mut entry = [0u8; 32];
entry[0..8].copy_from_slice(&(i as u64).to_le_bytes());
for (j, byte) in entry.iter_mut().enumerate().take(entry_size).skip(8) {
*byte = ((i * 17 + j * 13) % 256) as u8;
}
writer.write_all(&entry)?;
}
writer.flush()?;
println!(
"Created {} ({} entries x {} bytes)",
path.display(),
num_entries,
entry_size
);
Ok(())
}
fn generate_account_mapping(dir: &Path) -> Result<(), Box<dyn std::error::Error>> {
let path = dir.join("account-mapping.bin");
let file = File::create(&path)?;
let mut writer = BufWriter::new(file);
let accounts: Vec<([u8; 20], u64)> = vec![
(
hex_to_address("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045"),
0,
),
(
hex_to_address("0000000000000000000000000000000000000001"),
10,
),
(
hex_to_address("0000000000000000000000000000000000000002"),
20,
),
(
hex_to_address("1111111111111111111111111111111111111111"),
100,
),
(
hex_to_address("2222222222222222222222222222222222222222"),
200,
),
(
hex_to_address("3333333333333333333333333333333333333333"),
300,
),
(
hex_to_address("4444444444444444444444444444444444444444"),
400,
),
(
hex_to_address("5555555555555555555555555555555555555555"),
500,
),
(
hex_to_address("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"),
777,
),
(
hex_to_address("cafebabecafebabecafebabecafebabecafebabe"),
999,
),
];
for (address, index) in &accounts {
writer.write_all(address)?;
writer.write_u64::<LittleEndian>(*index)?;
}
writer.flush()?;
println!("Created {} ({} accounts)", path.display(), accounts.len());
Ok(())
}
fn generate_storage_mapping(dir: &Path) -> Result<(), Box<dyn std::error::Error>> {
let path = dir.join("storage-mapping.bin");
let file = File::create(&path)?;
let mut writer = BufWriter::new(file);
let slots: Vec<([u8; 20], [u8; 32], u64)> = vec![
(
hex_to_address("1111111111111111111111111111111111111111"),
hex_to_slot("0000000000000000000000000000000000000000000000000000000000000000"),
100,
),
(
hex_to_address("1111111111111111111111111111111111111111"),
hex_to_slot("0000000000000000000000000000000000000000000000000000000000000001"),
101,
),
(
hex_to_address("1111111111111111111111111111111111111111"),
hex_to_slot("0000000000000000000000000000000000000000000000000000000000000002"),
102,
),
(
hex_to_address("1111111111111111111111111111111111111111"),
hex_to_slot("0000000000000000000000000000000000000000000000000000000000000003"),
103,
),
(
hex_to_address("1111111111111111111111111111111111111111"),
hex_to_slot("0000000000000000000000000000000000000000000000000000000000000004"),
104,
),
(
hex_to_address("2222222222222222222222222222222222222222"),
hex_to_slot("0000000000000000000000000000000000000000000000000000000000000000"),
200,
),
(
hex_to_address("2222222222222222222222222222222222222222"),
hex_to_slot("0000000000000000000000000000000000000000000000000000000000000001"),
201,
),
(
hex_to_address("2222222222222222222222222222222222222222"),
hex_to_slot("0000000000000000000000000000000000000000000000000000000000000002"),
202,
),
(
hex_to_address("2222222222222222222222222222222222222222"),
hex_to_slot("0000000000000000000000000000000000000000000000000000000000000003"),
203,
),
(
hex_to_address("2222222222222222222222222222222222222222"),
hex_to_slot("0000000000000000000000000000000000000000000000000000000000000004"),
204,
),
(
hex_to_address("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"),
hex_to_slot("0000000000000000000000000000000000000000000000000000000000000000"),
777,
),
(
hex_to_address("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"),
hex_to_slot("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
778,
),
(
hex_to_address("cafebabecafebabecafebabecafebabecafebabe"),
hex_to_slot("290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563"),
900,
),
(
hex_to_address("cafebabecafebabecafebabecafebabecafebabe"),
hex_to_slot("b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6"),
901,
),
(
hex_to_address("cafebabecafebabecafebabecafebabecafebabe"),
hex_to_slot("405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace"),
902,
),
(
hex_to_address("3333333333333333333333333333333333333333"),
hex_to_slot("0000000000000000000000000000000000000000000000000000000000000000"),
300,
),
(
hex_to_address("4444444444444444444444444444444444444444"),
hex_to_slot("0000000000000000000000000000000000000000000000000000000000000000"),
400,
),
(
hex_to_address("5555555555555555555555555555555555555555"),
hex_to_slot("0000000000000000000000000000000000000000000000000000000000000000"),
500,
),
(
hex_to_address("6666666666666666666666666666666666666666"),
hex_to_slot("0000000000000000000000000000000000000000000000000000000000000000"),
600,
),
(
hex_to_address("7777777777777777777777777777777777777777"),
hex_to_slot("0000000000000000000000000000000000000000000000000000000000000000"),
700,
),
];
for (address, slot, index) in &slots {
writer.write_all(address)?;
writer.write_all(slot)?;
writer.write_u64::<LittleEndian>(*index)?;
}
writer.flush()?;
println!("Created {} ({} slots)", path.display(), slots.len());
Ok(())
}
fn hex_to_address(hex: &str) -> [u8; 20] {
let hex = hex.strip_prefix("0x").unwrap_or(hex);
let mut bytes = [0u8; 20];
for (i, chunk) in hex.as_bytes().chunks(2).enumerate() {
if i >= 20 {
break;
}
let s = std::str::from_utf8(chunk).unwrap();
bytes[i] = u8::from_str_radix(s, 16).unwrap();
}
bytes
}
fn hex_to_slot(hex: &str) -> [u8; 32] {
let hex = hex.strip_prefix("0x").unwrap_or(hex);
let mut bytes = [0u8; 32];
for (i, chunk) in hex.as_bytes().chunks(2).enumerate() {
if i >= 32 {
break;
}
let s = std::str::from_utf8(chunk).unwrap();
bytes[i] = u8::from_str_radix(s, 16).unwrap();
}
bytes
}