mod bin;
mod buf_ext;
mod counting_writer;
mod json;
use {
self::{
bin::{deserialize_from_bytes, read_bin, serialize_to_bytes, write_bin, Compression},
buf_ext::BufExt,
counting_writer::CountingWriter,
json::{read_json, write_json},
},
crate::{NoirProof, NoirProofScheme, Prover, Verifier},
anyhow::Result,
serde::{Deserialize, Serialize},
std::{ffi::OsStr, path::Path},
tracing::instrument,
};
pub trait FileFormat: Serialize + for<'a> Deserialize<'a> {
const FORMAT: [u8; 8];
const EXTENSION: &'static str;
const VERSION: (u16, u16);
const COMPRESSION: Compression;
}
impl FileFormat for NoirProofScheme {
const FORMAT: [u8; 8] = *b"NrProScm";
const EXTENSION: &'static str = "nps";
const VERSION: (u16, u16) = (1, 1);
const COMPRESSION: Compression = Compression::Zstd;
}
impl FileFormat for Prover {
const FORMAT: [u8; 8] = *b"PrvKitPr";
const EXTENSION: &'static str = "pkp";
const VERSION: (u16, u16) = (1, 1);
const COMPRESSION: Compression = Compression::Xz;
}
impl FileFormat for Verifier {
const FORMAT: [u8; 8] = *b"PrvKitVr";
const EXTENSION: &'static str = "pkv";
const VERSION: (u16, u16) = (1, 2);
const COMPRESSION: Compression = Compression::Zstd;
}
impl FileFormat for NoirProof {
const FORMAT: [u8; 8] = *b"NPSProof";
const EXTENSION: &'static str = "np";
const VERSION: (u16, u16) = (1, 0);
const COMPRESSION: Compression = Compression::Zstd;
}
#[instrument(skip(value))]
pub fn write<T: FileFormat>(value: &T, path: &Path) -> Result<()> {
match path.extension().and_then(OsStr::to_str) {
Some("json") => write_json(value, path),
Some(ext) if ext == T::EXTENSION => {
write_bin(value, path, T::FORMAT, T::VERSION, T::COMPRESSION)
}
_ => Err(anyhow::anyhow!(
"Unsupported file extension, please specify .{} or .json",
T::EXTENSION
)),
}
}
#[instrument()]
pub fn read<T: FileFormat>(path: &Path) -> Result<T> {
match path.extension().and_then(OsStr::to_str) {
Some("json") => read_json(path),
Some(ext) if ext == T::EXTENSION => read_bin(path, T::FORMAT, T::VERSION),
_ => Err(anyhow::anyhow!(
"Unsupported file extension, please specify .{} or .json",
T::EXTENSION
)),
}
}
pub fn serialize<T: FileFormat>(value: &T) -> Result<Vec<u8>> {
serialize_to_bytes(value, T::FORMAT, T::VERSION, T::COMPRESSION)
}
pub fn deserialize<T: FileFormat>(data: &[u8]) -> Result<T> {
deserialize_from_bytes(data, T::FORMAT, T::VERSION)
}