#![allow(clippy::missing_safety_doc)]
#[cfg(all(not(feature = "hints"), not(zisk_guest)))]
use super::sw_impl::{
blake2, bls12 as bls12_sw, bn254 as bn254_sw, modexp as modexp_sw, ripemd160 as ripemd160_sw,
secp256k1 as secp256k1_sw, sha256 as sha256_sw,
};
use super::{bls12_381, bn254};
use zisk_zkvm_interface::{
zkvm_blake2f_message, zkvm_blake2f_offset, zkvm_blake2f_state, zkvm_bls12_381_fp,
zkvm_bls12_381_fp2, zkvm_bls12_381_g1_msm_pair, zkvm_bls12_381_g1_point,
zkvm_bls12_381_g2_msm_pair, zkvm_bls12_381_g2_point, zkvm_bls12_381_pairing_pair,
zkvm_bn254_g1_point, zkvm_bn254_pairing_pair, zkvm_bn254_scalar, zkvm_keccak256_hash,
zkvm_kzg_commitment, zkvm_kzg_field_element, zkvm_kzg_proof, zkvm_ripemd160_hash,
zkvm_secp256k1_hash, zkvm_secp256k1_pubkey, zkvm_secp256k1_signature, zkvm_secp256r1_hash,
zkvm_secp256r1_pubkey, zkvm_secp256r1_signature, zkvm_sha256_hash, zkvm_status,
zkvm_status_ZKVM_EFAIL as ZKVM_EFAIL, zkvm_status_ZKVM_EOK as ZKVM_EOK,
};
#[cfg_attr(all(not(feature = "hints"), not(zisk_staticlib)), no_mangle)]
#[cfg_attr(feature = "hints", export_name = "hints_zkvm_keccak256")]
pub unsafe extern "C" fn zkvm_keccak256(
data: *const u8,
len: usize,
output: *mut zkvm_keccak256_hash,
#[cfg(feature = "hints")] hints: &mut Vec<u64>,
) -> zkvm_status {
super::keccak256_c(
data,
len,
(*output).data.as_mut_ptr(),
#[cfg(feature = "hints")]
hints,
);
ZKVM_EOK
}
#[cfg_attr(all(not(feature = "hints"), not(zisk_staticlib)), no_mangle)]
#[cfg_attr(feature = "hints", export_name = "hints_zkvm_sha256")]
pub unsafe extern "C" fn zkvm_sha256(
data: *const u8,
len: usize,
output: *mut zkvm_sha256_hash,
#[cfg(feature = "hints")] hints: &mut Vec<u64>,
) -> zkvm_status {
#[cfg(feature = "hints")]
{
super::sha256_c(data, len, (*output).data.as_mut_ptr(), hints);
ZKVM_EOK
}
#[cfg(not(feature = "hints"))]
{
#[cfg(any(zisk_guest, zisk_hints))]
{
#[cfg(zisk_hints)]
unsafe {
crate::hints::hint_sha256(data, len);
}
#[cfg(zisk_hints_debug)]
crate::hint_log(format!(
"hint_sha2 (input: {:x?})",
std::slice::from_raw_parts(data, len)
));
#[cfg(zisk_guest)]
{
super::sha256_c(data, len, (*output).data.as_mut_ptr());
return ZKVM_EOK;
}
}
#[cfg(not(zisk_guest))]
{
let result = sha256_sw::hash(std::slice::from_raw_parts(data, len));
std::ptr::copy_nonoverlapping(result.as_ptr(), output as *mut u8, 32);
ZKVM_EOK
}
}
}
#[cfg_attr(all(not(feature = "hints"), not(zisk_staticlib)), no_mangle)]
#[cfg_attr(feature = "hints", export_name = "hints_zkvm_ripemd160")]
pub unsafe extern "C" fn zkvm_ripemd160(
data: *const u8,
len: usize,
output: *mut zkvm_ripemd160_hash,
#[cfg(feature = "hints")] hints: &mut Vec<u64>,
) -> zkvm_status {
#[cfg(feature = "hints")]
{
super::ripemd160_c(data, len, (*output).data.as_mut_ptr(), hints);
ZKVM_EOK
}
#[cfg(not(feature = "hints"))]
{
#[cfg(any(zisk_guest, zisk_hints))]
{
#[cfg(zisk_hints)]
unsafe {
crate::hints::hint_ripemd160(data, len);
}
#[cfg(zisk_hints_debug)]
crate::hint_log(format!("hint_ripemd160 (input len: {})", len));
#[cfg(zisk_guest)]
{
super::ripemd160_c(data, len, (*output).data.as_mut_ptr());
return ZKVM_EOK;
}
}
#[cfg(not(zisk_guest))]
{
(*output).data = ripemd160_sw::hash(std::slice::from_raw_parts(data, len));
ZKVM_EOK
}
}
}
#[cfg_attr(all(not(feature = "hints"), not(zisk_staticlib)), no_mangle)]
#[cfg_attr(feature = "hints", export_name = "hints_zkvm_modexp")]
pub unsafe extern "C" fn zkvm_modexp(
base: *const u8,
base_len: usize,
exp: *const u8,
exp_len: usize,
modulus: *const u8,
mod_len: usize,
output: *mut u8,
#[cfg(feature = "hints")] hints: &mut Vec<u64>,
) -> zkvm_status {
#[cfg(feature = "hints")]
{
super::modexp_bytes_c(base, base_len, exp, exp_len, modulus, mod_len, output, hints);
ZKVM_EOK
}
#[cfg(not(feature = "hints"))]
{
#[cfg(any(zisk_guest, zisk_hints))]
{
#[cfg(zisk_hints)]
unsafe {
crate::hints::hint_modexp_bytes(base, base_len, exp, exp_len, modulus, mod_len);
}
#[cfg(zisk_hints_debug)]
crate::hint_log(format!(
"hint_modexp_bytes (base_len: {}, exp_len: {}, mod_len: {})",
base_len, exp_len, mod_len
));
#[cfg(zisk_guest)]
{
super::modexp_bytes_c(base, base_len, exp, exp_len, modulus, mod_len, output);
return ZKVM_EOK;
}
}
#[cfg(not(zisk_guest))]
{
let result = modexp_sw::modexp(
std::slice::from_raw_parts(base, base_len),
std::slice::from_raw_parts(exp, exp_len),
std::slice::from_raw_parts(modulus, mod_len),
);
let offset = mod_len - result.len();
std::ptr::copy_nonoverlapping(result.as_ptr(), output.add(offset), result.len());
ZKVM_EOK
}
}
}
#[cfg_attr(all(not(feature = "hints"), not(zisk_staticlib)), no_mangle)]
#[cfg_attr(feature = "hints", export_name = "hints_zkvm_bn254_g1_add")]
pub unsafe extern "C" fn zkvm_bn254_g1_add(
p1: *const zkvm_bn254_g1_point,
p2: *const zkvm_bn254_g1_point,
result: *mut zkvm_bn254_g1_point,
#[cfg(feature = "hints")] hints: &mut Vec<u64>,
) -> zkvm_status {
#[cfg(feature = "hints")]
{
let ret = super::add_safe_bn254_c(
(*p1).data.as_ptr(),
(*p2).data.as_ptr(),
(*result).data.as_mut_ptr(),
hints,
);
if matches!(ret, bn254::G1_ADD_SUCCESS | bn254::G1_ADD_SUCCESS_INFINITY) {
ZKVM_EOK
} else {
ZKVM_EFAIL
}
}
#[cfg(not(feature = "hints"))]
{
#[cfg(any(zisk_guest, zisk_hints))]
{
#[cfg(zisk_hints)]
unsafe {
crate::hints::hint_bn254_g1_add(
std::ptr::addr_of!((*p1).data).cast::<u8>(),
std::ptr::addr_of!((*p2).data).cast::<u8>(),
);
}
#[cfg(zisk_hints_debug)]
crate::hint_log(format!(
"hint_bn254_g1_add (p1: {:x?}, p2: {:x?})",
&std::ptr::read_unaligned(std::ptr::addr_of!((*p1).data)),
&std::ptr::read_unaligned(std::ptr::addr_of!((*p2).data)),
));
#[cfg(zisk_guest)]
{
let ret = super::add_safe_bn254_c(
(*p1).data.as_ptr(),
(*p2).data.as_ptr(),
(*result).data.as_mut_ptr(),
);
return if matches!(ret, bn254::G1_ADD_SUCCESS | bn254::G1_ADD_SUCCESS_INFINITY) {
ZKVM_EOK
} else {
ZKVM_EFAIL
};
}
}
#[cfg(not(zisk_guest))]
{
match bn254_sw::g1_add(
&std::ptr::read_unaligned(std::ptr::addr_of!((*p1).data)),
&std::ptr::read_unaligned(std::ptr::addr_of!((*p2).data)),
) {
Some(res) => {
(*result).data = res;
ZKVM_EOK
}
None => ZKVM_EFAIL,
}
}
}
}
#[cfg_attr(all(not(feature = "hints"), not(zisk_staticlib)), no_mangle)]
#[cfg_attr(feature = "hints", export_name = "hints_zkvm_bn254_g1_mul")]
pub unsafe extern "C" fn zkvm_bn254_g1_mul(
point: *const zkvm_bn254_g1_point,
scalar: *const zkvm_bn254_scalar,
result: *mut zkvm_bn254_g1_point,
#[cfg(feature = "hints")] hints: &mut Vec<u64>,
) -> zkvm_status {
#[cfg(feature = "hints")]
{
let ret = super::scalar_mul_safe_bn254_c(
(*point).data.as_ptr(),
(*scalar).data.as_ptr(),
(*result).data.as_mut_ptr(),
hints,
);
if matches!(ret, bn254::G1_MUL_SUCCESS | bn254::G1_MUL_SUCCESS_INFINITY) {
ZKVM_EOK
} else {
ZKVM_EFAIL
}
}
#[cfg(not(feature = "hints"))]
{
#[cfg(any(zisk_guest, zisk_hints))]
{
#[cfg(zisk_hints)]
unsafe {
crate::hints::hint_bn254_g1_mul(
std::ptr::addr_of!((*point).data).cast::<u8>(),
std::ptr::addr_of!((*scalar).data).cast::<u8>(),
);
}
#[cfg(zisk_hints_debug)]
crate::hint_log(format!(
"hint_bn254_g1_mul (point: {:x?}, scalar: {:x?})",
&std::ptr::read_unaligned(std::ptr::addr_of!((*point).data)),
&std::ptr::read_unaligned(std::ptr::addr_of!((*scalar).data)),
));
#[cfg(zisk_guest)]
{
let ret = super::scalar_mul_safe_bn254_c(
(*point).data.as_ptr(),
(*scalar).data.as_ptr(),
(*result).data.as_mut_ptr(),
);
return if matches!(ret, bn254::G1_MUL_SUCCESS | bn254::G1_MUL_SUCCESS_INFINITY) {
ZKVM_EOK
} else {
ZKVM_EFAIL
};
}
}
#[cfg(not(zisk_guest))]
{
match bn254_sw::g1_mul(
&std::ptr::read_unaligned(std::ptr::addr_of!((*point).data)),
&std::ptr::read_unaligned(std::ptr::addr_of!((*scalar).data)),
) {
Some(res) => {
(*result).data = res;
ZKVM_EOK
}
None => ZKVM_EFAIL,
}
}
}
}
#[cfg_attr(all(not(feature = "hints"), not(zisk_staticlib)), no_mangle)]
#[cfg_attr(feature = "hints", export_name = "hints_zkvm_bn254_pairing")]
pub unsafe extern "C" fn zkvm_bn254_pairing(
pairs: *const zkvm_bn254_pairing_pair,
num_pairs: usize,
verified: *mut bool,
#[cfg(feature = "hints")] hints: &mut Vec<u64>,
) -> zkvm_status {
#[cfg(feature = "hints")]
{
let ret = super::pairing_check_safe_bn254_c(pairs as *const u8, num_pairs, hints);
match ret {
bn254::PAIRING_CHECK_SUCCESS => {
*verified = true;
ZKVM_EOK
}
bn254::PAIRING_CHECK_FAILED => {
*verified = false;
ZKVM_EOK
}
_ => ZKVM_EFAIL,
}
}
#[cfg(not(feature = "hints"))]
{
#[cfg(any(zisk_guest, zisk_hints))]
{
#[cfg(zisk_hints)]
unsafe {
crate::hints::hint_bn254_pairing_check(pairs as *const u8, num_pairs);
}
#[cfg(zisk_hints_debug)]
crate::hint_log(format!("hint_bn254_pairing_check num_pairs: {}", num_pairs));
#[cfg(zisk_guest)]
{
let ret = super::pairing_check_safe_bn254_c(pairs as *const u8, num_pairs);
return match ret {
bn254::PAIRING_CHECK_SUCCESS => {
*verified = true;
ZKVM_EOK
}
bn254::PAIRING_CHECK_FAILED => {
*verified = false;
ZKVM_EOK
}
_ => ZKVM_EFAIL,
};
}
}
#[cfg(not(zisk_guest))]
{
match bn254_sw::pairing_check(core::slice::from_raw_parts(
pairs as *const [u8; 192],
num_pairs,
)) {
Some(result) => {
*verified = result;
ZKVM_EOK
}
None => ZKVM_EFAIL,
}
}
}
}
#[cfg_attr(all(not(feature = "hints"), not(zisk_staticlib)), no_mangle)]
#[cfg_attr(feature = "hints", export_name = "hints_zkvm_blake2f")]
pub unsafe extern "C" fn zkvm_blake2f(
rounds: u32,
h: *mut zkvm_blake2f_state,
m: *const zkvm_blake2f_message,
t: *const zkvm_blake2f_offset,
f: u8,
#[cfg(feature = "hints")] hints: &mut Vec<u64>,
) -> zkvm_status {
#[cfg(feature = "hints")]
{
super::blake2b_compress_c(
rounds,
(*h).data.as_mut_ptr() as *mut u64,
(*m).data.as_ptr() as *const u64,
(*t).data.as_ptr() as *const u64,
f,
hints,
);
ZKVM_EOK
}
#[cfg(not(feature = "hints"))]
{
#[cfg(any(zisk_guest, zisk_hints))]
{
#[cfg(zisk_hints)]
unsafe {
crate::hints::hint_blake2b_compress(
rounds,
(*h).data.as_mut_ptr() as *mut u64,
(*m).data.as_ptr() as *const u64,
(*t).data.as_ptr() as *const u64,
f,
);
}
#[cfg(zisk_hints_debug)]
crate::hint_log(format!("hint_blake2b_compress (rounds: {})", rounds));
#[cfg(zisk_guest)]
{
super::blake2b_compress_c(
rounds,
(*h).data.as_mut_ptr() as *mut u64,
(*m).data.as_ptr() as *const u64,
(*t).data.as_ptr() as *const u64,
f,
);
return ZKVM_EOK;
}
}
#[cfg(not(zisk_guest))]
{
let h_arr: &mut [u64; 8] = &mut *((*h).data.as_mut_ptr() as *mut [u64; 8]);
let m_arr: [u64; 16] = *((*m).data.as_ptr() as *const [u64; 16]);
let t_arr: [u64; 2] = *((*t).data.as_ptr() as *const [u64; 2]);
blake2::compress(rounds, h_arr, m_arr, t_arr, f != 0);
ZKVM_EOK
}
}
}
#[cfg_attr(all(not(feature = "hints"), not(zisk_staticlib)), no_mangle)]
#[cfg_attr(feature = "hints", export_name = "hints_zkvm_kzg_point_eval")]
pub unsafe extern "C" fn zkvm_kzg_point_eval(
commitment: *const zkvm_kzg_commitment,
z: *const zkvm_kzg_field_element,
y: *const zkvm_kzg_field_element,
proof: *const zkvm_kzg_proof,
verified: *mut bool,
#[cfg(feature = "hints")] hints: &mut Vec<u64>,
) -> zkvm_status {
#[cfg(feature = "hints")]
{
*verified = super::verify_kzg_proof_c(
(*z).data.as_ptr(),
(*y).data.as_ptr(),
(*commitment).data.as_ptr(),
(*proof).data.as_ptr(),
hints,
);
ZKVM_EOK
}
#[cfg(not(feature = "hints"))]
{
#[cfg(any(zisk_guest, zisk_hints))]
{
#[cfg(zisk_hints)]
unsafe {
crate::hints::hint_verify_kzg_proof(
std::ptr::addr_of!((*z).data).cast::<u8>(),
std::ptr::addr_of!((*y).data).cast::<u8>(),
std::ptr::addr_of!((*commitment).data).cast::<u8>(),
std::ptr::addr_of!((*proof).data).cast::<u8>(),
);
}
#[cfg(zisk_hints_debug)]
crate::hint_log(format!(
"hint_verify_kzg_proof (z: {:x?}, y: {:x?})",
&std::ptr::read_unaligned(std::ptr::addr_of!((*z).data)),
&std::ptr::read_unaligned(std::ptr::addr_of!((*y).data)),
));
#[cfg(zisk_guest)]
{
*verified = super::verify_kzg_proof_c(
(*z).data.as_ptr(),
(*y).data.as_ptr(),
(*commitment).data.as_ptr(),
(*proof).data.as_ptr(),
);
return ZKVM_EOK;
}
}
#[cfg(not(zisk_guest))]
{
*verified = bls12_sw::verify_kzg_proof(
&std::ptr::read_unaligned(std::ptr::addr_of!((*z).data)),
&std::ptr::read_unaligned(std::ptr::addr_of!((*y).data)),
&std::ptr::read_unaligned(std::ptr::addr_of!((*commitment).data)),
&std::ptr::read_unaligned(std::ptr::addr_of!((*proof).data)),
);
ZKVM_EOK
}
}
}
#[cfg_attr(all(not(feature = "hints"), not(zisk_staticlib)), no_mangle)]
#[cfg_attr(feature = "hints", export_name = "hints_zkvm_bls12_g1_add")]
pub unsafe extern "C" fn zkvm_bls12_g1_add(
p1: *const zkvm_bls12_381_g1_point,
p2: *const zkvm_bls12_381_g1_point,
result: *mut zkvm_bls12_381_g1_point,
#[cfg(feature = "hints")] hints: &mut Vec<u64>,
) -> zkvm_status {
#[cfg(feature = "hints")]
{
let ret = super::add_safe_bls12_381_c(
(*result).data.as_mut_ptr(),
(*p1).data.as_ptr(),
(*p2).data.as_ptr(),
hints,
);
if matches!(ret, bls12_381::G1_ADD_SUCCESS | bls12_381::G1_ADD_SUCCESS_INFINITY) {
ZKVM_EOK
} else {
ZKVM_EFAIL
}
}
#[cfg(not(feature = "hints"))]
{
#[cfg(any(zisk_guest, zisk_hints))]
{
#[cfg(zisk_hints)]
unsafe {
crate::hints::hint_bls12_381_g1_add(
std::ptr::addr_of!((*p1).data).cast::<u8>(),
std::ptr::addr_of!((*p2).data).cast::<u8>(),
);
}
#[cfg(zisk_hints_debug)]
crate::hint_log(format!(
"hint_bls12_381_g1_add (p1: {:x?}, p2: {:x?})",
&std::ptr::read_unaligned(std::ptr::addr_of!((*p1).data)),
&std::ptr::read_unaligned(std::ptr::addr_of!((*p2).data)),
));
#[cfg(zisk_guest)]
{
let ret = super::add_safe_bls12_381_c(
(*result).data.as_mut_ptr(),
(*p1).data.as_ptr(),
(*p2).data.as_ptr(),
);
return if matches!(
ret,
bls12_381::G1_ADD_SUCCESS | bls12_381::G1_ADD_SUCCESS_INFINITY
) {
ZKVM_EOK
} else {
ZKVM_EFAIL
};
}
}
#[cfg(not(zisk_guest))]
{
match bls12_sw::g1_add(
&std::ptr::read_unaligned(std::ptr::addr_of!((*p1).data)),
&std::ptr::read_unaligned(std::ptr::addr_of!((*p2).data)),
) {
Some(res) => {
(*result).data = res;
ZKVM_EOK
}
None => ZKVM_EFAIL,
}
}
}
}
#[cfg_attr(all(not(feature = "hints"), not(zisk_staticlib)), no_mangle)]
#[cfg_attr(feature = "hints", export_name = "hints_zkvm_bls12_g1_msm")]
pub unsafe extern "C" fn zkvm_bls12_g1_msm(
pairs: *const zkvm_bls12_381_g1_msm_pair,
num_pairs: usize,
result: *mut zkvm_bls12_381_g1_point,
#[cfg(feature = "hints")] hints: &mut Vec<u64>,
) -> zkvm_status {
if num_pairs == 0 {
return ZKVM_EFAIL;
}
#[cfg(feature = "hints")]
{
let ret = super::msm_safe_bls12_381_c(
(*result).data.as_mut_ptr(),
pairs as *const u8,
num_pairs,
hints,
);
if matches!(ret, bls12_381::G1_MSM_SUCCESS | bls12_381::G1_MSM_SUCCESS_INFINITY) {
ZKVM_EOK
} else {
ZKVM_EFAIL
}
}
#[cfg(not(feature = "hints"))]
{
#[cfg(any(zisk_guest, zisk_hints))]
{
#[cfg(zisk_hints)]
unsafe {
crate::hints::hint_bls12_381_g1_msm(pairs as *const u8, num_pairs);
}
#[cfg(zisk_hints_debug)]
crate::hint_log(format!("hint_bls12_381_g1_msm (num_pairs: {})", num_pairs));
#[cfg(zisk_guest)]
{
let ret = super::msm_safe_bls12_381_c(
(*result).data.as_mut_ptr(),
pairs as *const u8,
num_pairs,
);
return if matches!(
ret,
bls12_381::G1_MSM_SUCCESS | bls12_381::G1_MSM_SUCCESS_INFINITY
) {
ZKVM_EOK
} else {
ZKVM_EFAIL
};
}
}
#[cfg(not(zisk_guest))]
{
match bls12_sw::g1_msm(core::slice::from_raw_parts(
pairs as *const [u8; 128],
num_pairs,
)) {
Some(res) => {
(*result).data = res;
ZKVM_EOK
}
None => ZKVM_EFAIL,
}
}
}
}
#[cfg_attr(all(not(feature = "hints"), not(zisk_staticlib)), no_mangle)]
#[cfg_attr(feature = "hints", export_name = "hints_zkvm_bls12_g2_add")]
pub unsafe extern "C" fn zkvm_bls12_g2_add(
p1: *const zkvm_bls12_381_g2_point,
p2: *const zkvm_bls12_381_g2_point,
result: *mut zkvm_bls12_381_g2_point,
#[cfg(feature = "hints")] hints: &mut Vec<u64>,
) -> zkvm_status {
#[cfg(feature = "hints")]
{
let ret = super::add_safe_twist_bls12_381_c(
(*result).data.as_mut_ptr(),
(*p1).data.as_ptr(),
(*p2).data.as_ptr(),
hints,
);
if matches!(ret, bls12_381::G2_ADD_SUCCESS | bls12_381::G2_ADD_SUCCESS_INFINITY) {
ZKVM_EOK
} else {
ZKVM_EFAIL
}
}
#[cfg(not(feature = "hints"))]
{
#[cfg(any(zisk_guest, zisk_hints))]
{
#[cfg(zisk_hints)]
unsafe {
crate::hints::hint_bls12_381_g2_add(
std::ptr::addr_of!((*p1).data).cast::<u8>(),
std::ptr::addr_of!((*p2).data).cast::<u8>(),
);
}
#[cfg(zisk_hints_debug)]
crate::hint_log(format!(
"hint_bls12_381_g2_add (p1: {:x?}, p2: {:x?})",
&std::ptr::read_unaligned(std::ptr::addr_of!((*p1).data)),
&std::ptr::read_unaligned(std::ptr::addr_of!((*p2).data)),
));
#[cfg(zisk_guest)]
{
let ret = super::add_safe_twist_bls12_381_c(
(*result).data.as_mut_ptr(),
(*p1).data.as_ptr(),
(*p2).data.as_ptr(),
);
return if matches!(
ret,
bls12_381::G2_ADD_SUCCESS | bls12_381::G2_ADD_SUCCESS_INFINITY
) {
ZKVM_EOK
} else {
ZKVM_EFAIL
};
}
}
#[cfg(not(zisk_guest))]
{
match bls12_sw::g2_add(
&std::ptr::read_unaligned(std::ptr::addr_of!((*p1).data)),
&std::ptr::read_unaligned(std::ptr::addr_of!((*p2).data)),
) {
Some(res) => {
(*result).data = res;
ZKVM_EOK
}
None => ZKVM_EFAIL,
}
}
}
}
#[cfg_attr(all(not(feature = "hints"), not(zisk_staticlib)), no_mangle)]
#[cfg_attr(feature = "hints", export_name = "hints_zkvm_bls12_g2_msm")]
pub unsafe extern "C" fn zkvm_bls12_g2_msm(
pairs: *const zkvm_bls12_381_g2_msm_pair,
num_pairs: usize,
result: *mut zkvm_bls12_381_g2_point,
#[cfg(feature = "hints")] hints: &mut Vec<u64>,
) -> zkvm_status {
if num_pairs == 0 {
return ZKVM_EFAIL;
}
#[cfg(feature = "hints")]
{
let ret = super::msm_safe_twist_bls12_381_c(
(*result).data.as_mut_ptr(),
pairs as *const u8,
num_pairs,
hints,
);
if matches!(ret, bls12_381::G2_MSM_SUCCESS | bls12_381::G2_MSM_SUCCESS_INFINITY) {
ZKVM_EOK
} else {
ZKVM_EFAIL
}
}
#[cfg(not(feature = "hints"))]
{
#[cfg(any(zisk_guest, zisk_hints))]
{
#[cfg(zisk_hints)]
unsafe {
crate::hints::hint_bls12_381_g2_msm(pairs as *const u8, num_pairs);
}
#[cfg(zisk_hints_debug)]
crate::hint_log(format!("hint_bls12_381_g2_msm (num_pairs: {})", num_pairs));
#[cfg(zisk_guest)]
{
let ret = super::msm_safe_twist_bls12_381_c(
(*result).data.as_mut_ptr(),
pairs as *const u8,
num_pairs,
);
return if matches!(
ret,
bls12_381::G2_MSM_SUCCESS | bls12_381::G2_MSM_SUCCESS_INFINITY
) {
ZKVM_EOK
} else {
ZKVM_EFAIL
};
}
}
#[cfg(not(zisk_guest))]
{
match bls12_sw::g2_msm(core::slice::from_raw_parts(
pairs as *const [u8; 224],
num_pairs,
)) {
Some(res) => {
(*result).data = res;
ZKVM_EOK
}
None => ZKVM_EFAIL,
}
}
}
}
#[cfg_attr(all(not(feature = "hints"), not(zisk_staticlib)), no_mangle)]
#[cfg_attr(feature = "hints", export_name = "hints_zkvm_bls12_pairing")]
pub unsafe extern "C" fn zkvm_bls12_pairing(
pairs: *const zkvm_bls12_381_pairing_pair,
num_pairs: usize,
verified: *mut bool,
#[cfg(feature = "hints")] hints: &mut Vec<u64>,
) -> zkvm_status {
if num_pairs == 0 {
return ZKVM_EFAIL;
}
#[cfg(feature = "hints")]
{
let ret = super::pairing_check_safe_bls12_381_c(pairs as *const u8, num_pairs, hints);
match ret {
bls12_381::PAIRING_CHECK_SUCCESS => {
*verified = true;
ZKVM_EOK
}
bls12_381::PAIRING_CHECK_FAILED => {
*verified = false;
ZKVM_EOK
}
_ => ZKVM_EFAIL,
}
}
#[cfg(not(feature = "hints"))]
{
#[cfg(any(zisk_guest, zisk_hints))]
{
#[cfg(zisk_hints)]
unsafe {
crate::hints::hint_bls12_381_pairing_check(pairs as *const u8, num_pairs);
}
#[cfg(zisk_hints_debug)]
crate::hint_log(format!("hint_bls12_381_pairing_check (num_pairs: {})", num_pairs));
#[cfg(zisk_guest)]
{
let ret = super::pairing_check_safe_bls12_381_c(pairs as *const u8, num_pairs);
return match ret {
bls12_381::PAIRING_CHECK_SUCCESS => {
*verified = true;
ZKVM_EOK
}
bls12_381::PAIRING_CHECK_FAILED => {
*verified = false;
ZKVM_EOK
}
_ => ZKVM_EFAIL,
};
}
}
#[cfg(not(zisk_guest))]
{
match bls12_sw::pairing_check(core::slice::from_raw_parts(
pairs as *const [u8; 288],
num_pairs,
)) {
Some(result) => {
*verified = result;
ZKVM_EOK
}
None => ZKVM_EFAIL,
}
}
}
}
#[cfg_attr(all(not(feature = "hints"), not(zisk_staticlib)), no_mangle)]
#[cfg_attr(feature = "hints", export_name = "hints_zkvm_bls12_map_fp_to_g1")]
pub unsafe extern "C" fn zkvm_bls12_map_fp_to_g1(
field_element: *const zkvm_bls12_381_fp,
result: *mut zkvm_bls12_381_g1_point,
#[cfg(feature = "hints")] hints: &mut Vec<u64>,
) -> zkvm_status {
#[cfg(feature = "hints")]
{
let ret = super::bls12_381_fp_to_g1_c(
(*result).data.as_mut_ptr(),
(*field_element).data.as_ptr(),
hints,
);
if ret == bls12_381::FP_TO_G1_SUCCESS {
ZKVM_EOK
} else {
ZKVM_EFAIL
}
}
#[cfg(not(feature = "hints"))]
{
#[cfg(any(zisk_guest, zisk_hints))]
{
#[cfg(zisk_hints)]
unsafe {
crate::hints::hint_bls12_381_fp_to_g1(
std::ptr::addr_of!((*field_element).data).cast::<u8>(),
);
}
#[cfg(zisk_hints_debug)]
crate::hint_log(format!(
"hint_bls12_381_fp_to_g1 (fp: {:x?})",
&std::ptr::read_unaligned(std::ptr::addr_of!((*field_element).data))
));
#[cfg(zisk_guest)]
{
let ret = super::bls12_381_fp_to_g1_c(
(*result).data.as_mut_ptr(),
(*field_element).data.as_ptr(),
);
return if ret == bls12_381::FP_TO_G1_SUCCESS { ZKVM_EOK } else { ZKVM_EFAIL };
}
}
#[cfg(not(zisk_guest))]
{
match bls12_sw::map_fp_to_g1(&std::ptr::read_unaligned(std::ptr::addr_of!(
(*field_element).data
))) {
Some(res) => {
(*result).data = res;
ZKVM_EOK
}
None => ZKVM_EFAIL,
}
}
}
}
#[cfg_attr(all(not(feature = "hints"), not(zisk_staticlib)), no_mangle)]
#[cfg_attr(feature = "hints", export_name = "hints_zkvm_bls12_map_fp2_to_g2")]
pub unsafe extern "C" fn zkvm_bls12_map_fp2_to_g2(
field_element: *const zkvm_bls12_381_fp2,
result: *mut zkvm_bls12_381_g2_point,
#[cfg(feature = "hints")] hints: &mut Vec<u64>,
) -> zkvm_status {
#[cfg(feature = "hints")]
{
let ret = super::bls12_381_fp2_to_g2_c(
(*result).data.as_mut_ptr(),
(*field_element).data.as_ptr(),
hints,
);
if ret == bls12_381::FP2_TO_G2_SUCCESS {
ZKVM_EOK
} else {
ZKVM_EFAIL
}
}
#[cfg(not(feature = "hints"))]
{
#[cfg(any(zisk_guest, zisk_hints))]
{
#[cfg(zisk_hints)]
unsafe {
crate::hints::hint_bls12_381_fp2_to_g2(
std::ptr::addr_of!((*field_element).data).cast::<u8>(),
);
}
#[cfg(zisk_hints_debug)]
crate::hint_log(format!(
"hint_bls12_381_fp2_to_g2 (fp2: {:x?})",
&std::ptr::read_unaligned(std::ptr::addr_of!((*field_element).data)),
));
#[cfg(zisk_guest)]
{
let ret = super::bls12_381_fp2_to_g2_c(
(*result).data.as_mut_ptr(),
(*field_element).data.as_ptr(),
);
return if ret == bls12_381::FP2_TO_G2_SUCCESS { ZKVM_EOK } else { ZKVM_EFAIL };
}
}
#[cfg(not(zisk_guest))]
{
match bls12_sw::map_fp2_to_g2(&std::ptr::read_unaligned(std::ptr::addr_of!(
(*field_element).data
))) {
Some(res) => {
(*result).data = res;
ZKVM_EOK
}
None => ZKVM_EFAIL,
}
}
}
}
#[cfg_attr(all(not(feature = "hints"), not(zisk_staticlib)), no_mangle)]
#[cfg_attr(feature = "hints", export_name = "hints_zkvm_secp256r1_verify")]
pub unsafe extern "C" fn zkvm_secp256r1_verify(
msg: *const zkvm_secp256r1_hash,
sig: *const zkvm_secp256r1_signature,
pubkey: *const zkvm_secp256r1_pubkey,
verified: *mut bool,
#[cfg(feature = "hints")] hints: &mut Vec<u64>,
) -> zkvm_status {
#[cfg(feature = "hints")]
{
*verified = super::secp256r1_ecdsa_verify_c(
(*msg).data.as_ptr(),
(*sig).data.as_ptr(),
(*pubkey).data.as_ptr(),
hints,
);
ZKVM_EOK
}
#[cfg(not(feature = "hints"))]
{
#[cfg(any(zisk_guest, zisk_hints))]
{
#[cfg(zisk_hints)]
unsafe {
crate::hints::hint_secp256r1_ecdsa_verify(
std::ptr::addr_of!((*msg).data).cast::<u8>(),
std::ptr::addr_of!((*sig).data).cast::<u8>(),
std::ptr::addr_of!((*pubkey).data).cast::<u8>(),
);
}
#[cfg(zisk_hints_debug)]
crate::hint_log(format!(
"hint_secp256r1_ecdsa_verify (msg: {:x?}, sig: {:x?}, pk: {:x?})",
std::ptr::read_unaligned(std::ptr::addr_of!((*msg).data)),
std::ptr::read_unaligned(std::ptr::addr_of!((*sig).data)),
std::ptr::read_unaligned(std::ptr::addr_of!((*pubkey).data)),
));
#[cfg(zisk_guest)]
{
*verified = super::secp256r1_ecdsa_verify_c(
(*msg).data.as_ptr(),
(*sig).data.as_ptr(),
(*pubkey).data.as_ptr(),
);
return ZKVM_EOK;
}
}
#[cfg(not(zisk_guest))]
{
*verified = super::secp256r1_ecdsa_verify_c(
std::ptr::addr_of!((*msg).data).cast::<u8>(),
std::ptr::addr_of!((*sig).data).cast::<u8>(),
std::ptr::addr_of!((*pubkey).data).cast::<u8>(),
);
ZKVM_EOK
}
}
}
#[cfg_attr(all(not(feature = "hints"), not(zisk_staticlib)), no_mangle)]
#[cfg_attr(feature = "hints", export_name = "hints_zkvm_secp256k1_verify")]
pub unsafe extern "C" fn zkvm_secp256k1_verify(
msg: *const zkvm_secp256k1_hash,
sig: *const zkvm_secp256k1_signature,
pubkey: *const zkvm_secp256k1_pubkey,
verified: *mut bool,
#[cfg(feature = "hints")] hints: &mut Vec<u64>,
) -> zkvm_status {
#[cfg(feature = "hints")]
{
*verified = super::secp256k1_ecdsa_verify_c(
sig as *const u8,
msg as *const u8,
pubkey as *const u8,
hints,
);
ZKVM_EOK
}
#[cfg(not(feature = "hints"))]
{
#[cfg(any(zisk_guest, zisk_hints))]
{
#[cfg(zisk_hints)]
unsafe {
crate::hints::hint_secp256k1_ecdsa_verify(
sig as *const u8,
msg as *const u8,
pubkey as *const u8,
);
}
#[cfg(zisk_hints_debug)]
crate::hint_log(format!(
"hint_secp256k1_ecdsa_verify (sig: {:x?}, msg: {:x?}, pk: {:x?})",
std::ptr::read_unaligned(std::ptr::addr_of!((*sig).data)),
std::ptr::read_unaligned(std::ptr::addr_of!((*msg).data)),
std::ptr::read_unaligned(std::ptr::addr_of!((*pubkey).data)),
));
#[cfg(zisk_guest)]
{
*verified = super::secp256k1_ecdsa_verify_c(
sig as *const u8,
msg as *const u8,
pubkey as *const u8,
);
return ZKVM_EOK;
}
}
#[cfg(not(zisk_guest))]
{
*verified = secp256k1_sw::verify(
&std::ptr::read_unaligned(std::ptr::addr_of!((*sig).data)),
std::ptr::read_unaligned(std::ptr::addr_of!((*msg).data)),
&std::ptr::read_unaligned(std::ptr::addr_of!((*pubkey).data)),
);
ZKVM_EOK
}
}
}
#[cfg_attr(all(not(feature = "hints"), not(zisk_staticlib)), no_mangle)]
#[cfg_attr(feature = "hints", export_name = "hints_zkvm_secp256k1_ecrecover")]
pub unsafe extern "C" fn zkvm_secp256k1_ecrecover(
msg: *const zkvm_secp256k1_hash,
sig: *const zkvm_secp256k1_signature,
recid: u8,
output: *mut zkvm_secp256k1_pubkey,
#[cfg(feature = "hints")] hints: &mut Vec<u64>,
) -> zkvm_status {
#[cfg(feature = "hints")]
{
let ret = super::secp256k1_ecdsa_recover_c(
sig as *const u8,
recid,
msg as *const u8,
output as *mut u8,
hints,
);
if ret == super::ECDSA_RECOVER_SUCCESS {
ZKVM_EOK
} else {
ZKVM_EFAIL
}
}
#[cfg(not(feature = "hints"))]
{
#[cfg(any(zisk_guest, zisk_hints))]
{
#[cfg(zisk_hints)]
unsafe {
let recid_bytes = (recid as u64).to_le_bytes();
crate::hints::hint_secp256k1_ecrecover(
sig as *const u8,
recid_bytes.as_ptr(),
msg as *const u8,
);
}
#[cfg(zisk_hints_debug)]
{
let recid_bytes = (recid as u64).to_le_bytes();
crate::hint_log(format!(
"hint_secp256k1_ecrecover (sig: {:x?}, recid: {:x?}, msg: {:x?})",
std::ptr::read_unaligned(std::ptr::addr_of!((*sig).data)),
recid_bytes,
std::ptr::read_unaligned(std::ptr::addr_of!((*msg).data)),
));
}
#[cfg(zisk_guest)]
{
let ret = super::secp256k1_ecdsa_recover_c(
sig as *const u8,
recid,
msg as *const u8,
output as *mut u8,
);
return if ret == super::ECDSA_RECOVER_SUCCESS { ZKVM_EOK } else { ZKVM_EFAIL };
}
}
#[cfg(not(zisk_guest))]
{
match secp256k1_sw::ecrecover(
&std::ptr::read_unaligned(std::ptr::addr_of!((*sig).data)),
recid,
std::ptr::read_unaligned(std::ptr::addr_of!((*msg).data)),
) {
Some(pk) => {
(*output).data = pk;
ZKVM_EOK
}
None => ZKVM_EFAIL,
}
}
}
}
#[cfg(not(feature = "hints"))]
#[allow(dead_code)]
mod _interface_type_checks {
use super::*;
use zisk_zkvm_interface as bindings;
fn _check() {
let _ = [bindings::zkvm_keccak256, super::zkvm_keccak256];
let _ = [bindings::zkvm_sha256, super::zkvm_sha256];
let _ = [bindings::zkvm_ripemd160, super::zkvm_ripemd160];
let _ = [bindings::zkvm_modexp, super::zkvm_modexp];
let _ = [bindings::zkvm_bn254_g1_add, super::zkvm_bn254_g1_add];
let _ = [bindings::zkvm_bn254_g1_mul, super::zkvm_bn254_g1_mul];
let _ = [bindings::zkvm_bn254_pairing, super::zkvm_bn254_pairing];
let _ = [bindings::zkvm_blake2f, super::zkvm_blake2f];
let _ = [bindings::zkvm_kzg_point_eval, super::zkvm_kzg_point_eval];
let _ = [bindings::zkvm_bls12_g1_add, super::zkvm_bls12_g1_add];
let _ = [bindings::zkvm_bls12_g1_msm, super::zkvm_bls12_g1_msm];
let _ = [bindings::zkvm_bls12_g2_add, super::zkvm_bls12_g2_add];
let _ = [bindings::zkvm_bls12_g2_msm, super::zkvm_bls12_g2_msm];
let _ = [bindings::zkvm_bls12_pairing, super::zkvm_bls12_pairing];
let _ = [bindings::zkvm_bls12_map_fp_to_g1, super::zkvm_bls12_map_fp_to_g1];
let _ = [bindings::zkvm_bls12_map_fp2_to_g2, super::zkvm_bls12_map_fp2_to_g2];
let _ = [bindings::zkvm_secp256r1_verify, super::zkvm_secp256r1_verify];
let _ = [bindings::zkvm_secp256k1_verify, super::zkvm_secp256k1_verify];
let _ = [bindings::zkvm_secp256k1_ecrecover, super::zkvm_secp256k1_ecrecover];
}
}