risc0_groth16/
seal_to_json.rs1use std::io::{Read, Write};
16
17use anyhow::{Context, Result};
18use num_bigint::BigUint;
19use num_traits::Num;
20use risc0_core::field::baby_bear::BabyBearElem;
21use risc0_zkp::core::{
22 digest::{Digest, DIGEST_WORDS},
23 hash::poseidon_254::digest_to_fr,
24};
25
26use crate::seal_format::{IopType, K_SEAL_ELEMS, K_SEAL_TYPES, K_SEAL_WORDS};
27
28pub fn to_json<R: Read, W: Write>(mut reader: R, mut writer: W) -> Result<()> {
31 let mut iop = vec![0u32; K_SEAL_WORDS];
32 reader.read_exact(bytemuck::cast_slice_mut(&mut iop))?;
33
34 writeln!(writer, "{{\n \"iop\" : [")?;
35
36 let mut pos = 0;
37 for seal_type in K_SEAL_TYPES.iter().take(K_SEAL_ELEMS) {
38 if pos != 0 {
39 writeln!(writer, ",")?;
40 }
41 match seal_type {
42 IopType::Fp => {
43 let value = BabyBearElem::new_raw(iop[pos]).as_u32();
44 pos += 1;
45 writeln!(writer, " \"{value}\"")?;
46 }
47 _ => {
48 let digest = Digest::try_from(&iop[pos..pos + DIGEST_WORDS])?;
49 let value = digest_to_decimal(&digest)?;
50 pos += 8;
51 writeln!(writer, " \"{value}\"")?;
52 }
53 }
54 }
55 write!(writer, " ]\n}}")?;
56
57 Ok(())
58}
59
60fn digest_to_decimal(digest: &Digest) -> Result<String> {
61 to_decimal(&format!("{:?}", digest_to_fr(digest))).context("digest_to_decimal failed")
62}
63
64fn to_decimal(s: &str) -> Option<String> {
65 s.strip_prefix("Fr(0x")
66 .and_then(|s| s.strip_suffix(')'))
67 .and_then(|stripped| BigUint::from_str_radix(stripped, 16).ok())
68 .map(|n| n.to_str_radix(10))
69}