#![cfg_attr(not(feature = "std"), no_std)]
#![deny(missing_docs)]
#![deny(rustdoc::broken_intra_doc_links)]
#![cfg_attr(docsrs, feature(doc_cfg))]
extern crate alloc;
#[cfg(feature = "prove")]
pub mod prove;
mod types;
mod verifier;
use alloc::vec::Vec;
use core::str::FromStr;
use anyhow::{anyhow, Error, Result};
use ark_bn254::{G1Affine, G2Affine};
use ark_serialize::CanonicalDeserialize;
use num_bigint::BigInt;
pub use types::{ProofJson, PublicInputsJson, Seal, VerifyingKeyJson};
pub use verifier::{verifying_key, Fr, Verifier, VerifyingKey};
pub(crate) fn g1_from_bytes(elem: &[Vec<u8>]) -> Result<G1Affine, Error> {
if elem.len() != 2 {
return Err(anyhow!("Malformed G1 field element"));
}
let g1_affine: Vec<u8> = elem[0]
.iter()
.rev()
.chain(elem[1].iter().rev())
.cloned()
.collect();
G1Affine::deserialize_uncompressed(&*g1_affine).map_err(|err| anyhow!(err))
}
pub(crate) fn g2_from_bytes(elem: &[Vec<Vec<u8>>]) -> Result<G2Affine, Error> {
if elem.len() != 2 || elem[0].len() != 2 || elem[1].len() != 2 {
return Err(anyhow!("Malformed G2 field element"));
}
let g2_affine: Vec<u8> = elem[0][1]
.iter()
.rev()
.chain(elem[0][0].iter().rev())
.chain(elem[1][1].iter().rev())
.chain(elem[1][0].iter().rev())
.cloned()
.collect();
G2Affine::deserialize_uncompressed(&*g2_affine).map_err(|err| anyhow!(err))
}
pub(crate) fn from_u256(value: &str) -> Result<Vec<u8>, Error> {
if let Some(stripped) = value.strip_prefix("0x") {
from_u256_hex(stripped)
} else {
Ok(to_fixed_array(
BigInt::from_str(value)
.map_err(|_| anyhow!("conversion from u256 failed"))?
.to_bytes_be()
.1,
)
.to_vec())
}
}
pub(crate) fn from_u256_hex(value: &str) -> Result<Vec<u8>, Error> {
Ok(
to_fixed_array(hex::decode(value).map_err(|_| anyhow!("conversion from u256 failed"))?)
.to_vec(),
)
}
fn to_fixed_array(input: Vec<u8>) -> [u8; 32] {
let mut fixed_array = [0u8; 32];
let start = core::cmp::max(32, input.len()) - core::cmp::min(32, input.len());
fixed_array[start..].copy_from_slice(&input[input.len().saturating_sub(32)..]);
fixed_array
}