Hey,
I was wondering if I want to print the values in enum, how does one do that?
Hey,
I was wondering if I want to print the values in enum, how does one do that?
A simple way to do it is #[derive(Debug)]
. For example:
#[derive(Debug)]
enum Message {
Text(String),
Number(i32),
}
fn main() {
let msg = Message::Number(5);
println!("{:?}", msg);
}
For more information, see the std::fmt documentation.
Note that the output generated from this is unstable, so shouldn't be relied on for anything other than programmer-facing output.
If you need user-facing output you will typically implement Display
for your enum, which unlike Debug
must be implemented manually, for example:
use std::fmt::{self, Display, Formatter};
enum Priority {
Low,
Medium,
High { reason: String },
}
impl Display for Priority {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
Self::Low => write!(f, "Low priority"),
Self::Medium => write!(f, "Medium priority"),
Self::High { reason } => write!(f, "High priority: {}", reason),
}
}
}
let priority = Priority::High { reason: "xyz".to_owned() };
assert_eq!(priority.to_string(), "High priority: xyz");
Another way of generating stable, customizable output automatically is to use serde
and #[derive(Serialize)]
.
Ah alright. Actually for me,
let proof = groth16::create_random_proof(c, ¶ms, &mut OsRng).unwrap();
I have this line of code I kind of want to see the elements of proof, upon googling I understand that the function create random proof outputs an enum, but it is important for me to obtain the proof as an output as I want to make changes to the proof and then check further if it still gets verified.
My entire code is,
use bellman::{gadgets::{boolean::{AllocatedBit, Boolean},multipack,sha256::sha256,},groth16, Circuit, ConstraintSystem, SynthesisError};
use bls12_381::Bls12;//field used
use ff::PrimeField;
//use pairing::Engine;
use rand::rngs::OsRng;
use sha2::{Digest, Sha256};
//use bitvec::prelude::*;
use std::time::{Duration,Instant};
const LEN: usize = 160;
struct MyCircuit {
/// The input to SHA-256d we are proving that we know. Set to `None` when we
/// are verifying a proof (and do not have the witness data).
preimage: Option<[u8; LEN]>,
}
fn main(){
// Create parameters for our circuit. In a production deployment these would
// be generated securely using a multiparty computation.
println!("Parameter Generation...");
let mut time_param = Duration::new(0,0);
let mut time_prove = Duration::new(0,0);
let mut time_verify = Duration::new(0,0);
let start = Instant::now();
let params = {
let c = MyCircuit { preimage: None };
groth16::generate_random_parameters::<Bls12, _, _>(c, &mut OsRng).unwrap()
};
//time accounting
time_param += start.elapsed();
let time_param_f =
time_param.subsec_nanos() as f64 / 1_000_000_000f64 + (time_param.as_secs() as f64);
println!("Parameter generation time: {:?}",time_param_f);
// Prepare the verification key (for proof verification).
let pvk = groth16::prepare_verifying_key(¶ms.vk);
// Pick a preimage and compute its hash.
//samples a u8 array of lenght LEN with initial value 42
let preimage = [42; LEN];
//for i in 1..LEN{
// println!("{}",preimage[i]);
//}
//digest is from built in function for verifier
let hash = Sha256::digest(&preimage);
//let hash = Sha256::digest(&preimage);
// Create an instance of our circuit (with the preimage as a witness).
let c = MyCircuit {
preimage: Some(preimage),
};
println!("Generating Proof...");
// Create a Groth16 proof with our parameters.
let proof = groth16::create_random_proof(c, ¶ms, &mut OsRng).unwrap();
//println!("Proof: {:?}", proof);
time_prove += start.elapsed();
let time_prove_f =
time_prove.subsec_nanos() as f64 / 1_000_000_000f64 + (time_prove.as_secs() as f64);
println!("Time after proof generation: {:?}",time_prove_f - time_param_f);
// Pack the hash as inputs for proof verification.
let hash_bits = multipack::bytes_to_bits_le(&hash);
let inputs = multipack::compute_multipacking(&hash_bits);
println!("Verification time...");
// Check the proof!
assert!(groth16::verify_proof(&pvk, &proof, &inputs).is_ok());
time_verify += start.elapsed();
let time_verify_f =
time_verify.subsec_nanos() as f64 / 1_000_000_000f64 + (time_verify.as_secs() as f64);
println!("Time after verification: {:?}",time_verify_f - time_prove_f);
}
//===================================================================================
/// Our own SHA-256d gadget. Input and output are in little-endian bit order.
// Now this is sha256 gadget and only takes hash once
fn sha256d<Scalar: PrimeField, CS: ConstraintSystem<Scalar>>(
mut cs: CS,
data: &[Boolean],
) -> Result<Vec<Boolean>, SynthesisError> {
// Flip endianness of each input byte
let input: Vec<_> = data
.chunks(8)
.map(|c| c.iter().rev())
.flatten()
.cloned()
.collect();
let mid = sha256(cs.namespace(|| "SHA-256(input)"), &input)?;
//let res = sha256(cs.namespace(|| "SHA-256(mid)"), &mid)?;
// Flip endianness of each output byte
//Ok(res
Ok(mid
.chunks(8)
.map(|c| c.iter().rev())
.flatten()
.cloned()
.collect())
}
//====================================================================================
// SHA256 circuit
impl<Scalar: PrimeField> Circuit<Scalar> for MyCircuit {
fn synthesize<CS: ConstraintSystem<Scalar>>(self, cs: &mut CS) -> Result<(), SynthesisError> {
// Compute the values for the bits of the preimage. If we are verifying a proof,
// we still need to create the same constraints, so we return an equivalent-size
// Vec of None (indicating that the value of each bit is unknown).
let bit_values = if let Some(preimage) = self.preimage {
preimage.iter().map(|byte| (0..8).map(move |i| (byte >> i) & 1u8 == 1u8)).flatten().map(|b| Some(b)).collect()
} else {
vec![None; LEN * 8]
};
assert_eq!(bit_values.len(), LEN * 8);
// Witness the bits of the preimage.
// Allocate each bit.
let preimage_bits = bit_values.into_iter().enumerate().map(|(i, b)| {AllocatedBit::alloc(cs.namespace(|| format!("preimage bit {}", i)), b)
})
// Convert the AllocatedBits into Booleans (required for the sha256 gadget).
.map(|b| b.map(Boolean::from))
.collect::<Result<Vec<_>, _>>()?;
// Compute hash = SHA-256d(preimage).
let hash = sha256d(cs.namespace(|| "SHA-256d(preimage)"), &preimage_bits)?;
// Expose the vector of 32 boolean variables as compact public inputs.
multipack::pack_into_inputs(cs.namespace(|| "pack hash"), &hash)
}
}
So it looks like your question is how to print a bellman::groth16::Proof<bls12_381::Bls12>
.
The Proof<E>
type does not implement the Debug
trait or provide any other way to get human-readable output, but it does expose all of its fields, which have type E::G1Affine
.
For your program, this type is bls12_381::G1Affine
, which does implement Debug
. So you can print the fields like this:
println!("Proof: a = {:?}, b = {:?}, c = {:?}", proof.a, proof.b, proof.c);
Oh okay, I will give it a go, thanks !!!
So can I assume that all the standard libraries in rust do have debug implemented? Like, here I can print directly the elements. So, when do I know such a situation works. I just wanna know if I do face similar condition again. I don't understand why it is not sort of standard way to print an enum value?
The standard way to print any value for logging/debugging is the Debug
trait. You can look in the documentation to see which types implement Debug
or Display
. For example, it's listed in the bls12_381
docs here.
It's generally a good practice for library authors to implement Debug
for all of their public types, but not all library authors follow this practice. If a library doesn't provide some way to inspect a type, you could always submit a bug report or patch to fix this. For example, you could ask the author of the bellman
crate to implement Debug
for Proof<E>
.
(Also, just a note: Proof<E>
and G1Affine
are structs, not enums.)
Oh alright. I am sorry, I am not sure why I called it an enum.
Thanks !!!
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.