use std::{
fs::{self, File},
io::Read,
};
use p3_baby_bear::BabyBear;
use p3_bn254_fr::Bn254Fr;
use p3_field::AbstractField;
use p3_field::PrimeField32;
use sp1_core::{
air::Word,
io::SP1Stdin,
runtime::{Program, Runtime},
utils::SP1CoreOpts,
};
use crate::SP1CoreProofData;
impl SP1CoreProofData {
pub fn save(&self, path: &str) -> Result<(), std::io::Error> {
let data = serde_json::to_string(self).unwrap();
fs::write(path, data).unwrap();
Ok(())
}
}
pub fn get_cycles(elf: &[u8], stdin: &SP1Stdin) -> u64 {
let program = Program::from(elf);
let mut runtime = Runtime::new(program, SP1CoreOpts::default());
runtime.write_vecs(&stdin.buffer);
runtime.dry_run();
runtime.state.global_clk
}
pub fn load_elf(path: &str) -> Result<Vec<u8>, std::io::Error> {
let mut elf_code = Vec::new();
File::open(path)?.read_to_end(&mut elf_code)?;
Ok(elf_code)
}
pub fn words_to_bytes<T: Copy>(words: &[Word<T>]) -> Vec<T> {
return words.iter().flat_map(|word| word.0).collect();
}
pub fn babybears_to_bn254(digest: &[BabyBear; 8]) -> Bn254Fr {
let mut result = Bn254Fr::zero();
for word in digest.iter() {
result *= Bn254Fr::from_canonical_u64(1 << 31);
result += Bn254Fr::from_canonical_u32(word.as_canonical_u32());
}
result
}
pub fn babybear_bytes_to_bn254(bytes: &[BabyBear; 32]) -> Bn254Fr {
let mut result = Bn254Fr::zero();
for (i, byte) in bytes.iter().enumerate() {
debug_assert!(byte < &BabyBear::from_canonical_u32(256));
if i == 0 {
result = Bn254Fr::from_canonical_u32(byte.as_canonical_u32() & 0x1f);
} else {
result *= Bn254Fr::from_canonical_u32(256);
result += Bn254Fr::from_canonical_u32(byte.as_canonical_u32());
}
}
result
}
pub fn words_to_bytes_be(words: &[u32; 8]) -> [u8; 32] {
let mut bytes = [0u8; 32];
for i in 0..8 {
let word_bytes = words[i].to_be_bytes();
bytes[i * 4..(i + 1) * 4].copy_from_slice(&word_bytes);
}
bytes
}