Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ impl Fr {
format!("0x{}", hex::encode(self.to_bytes()))
}

pub fn inverse(&self) -> Self {
Fr(self.0.inverse().unwrap())
pub fn inverse(&self) -> Option<Self> {
self.0.inverse().map(Fr)
}

pub fn zero() -> Self {
Expand All @@ -85,8 +85,8 @@ impl Fr {
self.0.is_zero()
}

pub fn div(&self, rhs: &Fr) -> Self {
Fr(self.0 * rhs.0.inverse().unwrap())
pub fn div(&self, rhs: &Fr) -> Option<Self> {
rhs.inverse().map(|inv| *self * inv)
}
}

Expand Down
31 changes: 22 additions & 9 deletions src/shplemini.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,14 @@ use crate::ec::{g1_msm, pairing_check};
use crate::field::Fr;
use crate::trace;
use crate::types::{G1Point, Proof, Transcript, VerificationKey, CONST_PROOF_SIZE_LOG_N};
#[cfg(not(feature = "std"))]
use alloc::format;
use ark_bn254::{Fq, G1Affine, G1Projective};
use ark_ec::{CurveGroup, PrimeGroup};
#[cfg(feature = "trace")]
use ark_ff::BigInteger;
use ark_ff::{One, PrimeField, Zero};

#[cfg(not(feature = "std"))]
use alloc::{string::String, vec, vec::Vec};
use alloc::{format, string::String, vec, vec::Vec};

pub const NUMBER_UNSHIFTED: usize = 35; // = 40 – 5
pub const NUMBER_SHIFTED: usize = 5; // Final 5 are shifted
Expand Down Expand Up @@ -63,10 +61,18 @@ pub fn verify_shplemini(
];

// 3) compute shplonk weights
let pos0 = (tx.shplonk_z - r_pows[0]).inverse();
let neg0 = (tx.shplonk_z + r_pows[0]).inverse();
let pos0 = (tx.shplonk_z - r_pows[0])
.inverse()
.ok_or_else(|| String::from("shplonk denominator (z - r^0) is zero"))?;
let neg0 = (tx.shplonk_z + r_pows[0])
.inverse()
.ok_or_else(|| String::from("shplonk denominator (z + r^0) is zero"))?;
let unshifted = pos0 + tx.shplonk_nu * neg0;
let shifted = tx.gemini_r.inverse() * (pos0 - tx.shplonk_nu * neg0);
let gemini_r_inv = tx
.gemini_r
.inverse()
.ok_or_else(|| String::from("gemini_r challenge is zero"))?;
let shifted = gemini_r_inv * (pos0 - tx.shplonk_nu * neg0);
#[cfg(feature = "trace")]
{
dbg_fr("pos0", &pos0);
Expand Down Expand Up @@ -180,7 +186,10 @@ pub fn verify_shplemini(
let num = r2 * cur * Fr::from_u64(2)
- proof.gemini_a_evaluations[j - 1] * (r2 * (Fr::one() - u) - u);
let den = r2 * (Fr::one() - u) + u;
cur = num * den.inverse();
let den_inv = den
.inverse()
.ok_or_else(|| format!("fold round {} denominator is zero", j))?;
cur = num * den_inv;
fold_pos[j - 1] = cur;
}
#[cfg(feature = "trace")]
Expand All @@ -207,8 +216,12 @@ pub fn verify_shplemini(
dbg_fr("v_pow (before)", &v_pow);
}

let pos_inv = (tx.shplonk_z - r_pows[j]).inverse();
let neg_inv = (tx.shplonk_z + r_pows[j]).inverse();
let pos_inv = (tx.shplonk_z - r_pows[j])
.inverse()
.ok_or_else(|| format!("shplonk denominator (z - r^{}) is zero", j))?;
let neg_inv = (tx.shplonk_z + r_pows[j])
.inverse()
.ok_or_else(|| format!("shplonk denominator (z + r^{}) is zero", j))?;
let sp = v_pow * pos_inv;
let sn = v_pow * tx.shplonk_nu * neg_inv;

Expand Down
11 changes: 7 additions & 4 deletions src/sumcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ fn check_round_sum(u: &[Fr], target: Fr) -> bool {

/// Calculate next target value for the sum-check
#[inline(always)]
fn next_target(u: &[Fr], chi: Fr) -> Fr {
fn next_target(u: &[Fr], chi: Fr) -> Result<Fr, String> {
// B(χ) = ∏ (χ - i)
let mut b = Fr::one();
for i in 0..8 {
Expand All @@ -73,11 +73,14 @@ fn next_target(u: &[Fr], chi: Fr) -> Fr {
#[cfg(not(feature = "std"))]
let bary_val = get_bary()[i];

let inv = (bary_val * (chi - Fr::from_u64(i as u64))).inverse();
let denom = bary_val * (chi - Fr::from_u64(i as u64));
let inv = denom
.inverse()
.ok_or_else(|| format!("sum-check denominator is zero at i={}", i))?;
acc = acc + (u[i] * inv);
}

b * acc
Ok(b * acc)
}

#[inline(always)]
Expand Down Expand Up @@ -112,7 +115,7 @@ pub fn verify_sumcheck(
let chi = tx.sumcheck_u_challenges[r];
dbg_fr("chi", &chi);

target = next_target(uni, chi);
target = next_target(uni, chi)?;
pow_par = update_pow(pow_par, tx.gate_challenges[r], chi);

dbg_fr("target_after", &target);
Expand Down
12 changes: 9 additions & 3 deletions src/verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use alloc::{format, string::String, vec::Vec};
/// 검증 실패의 원인을 구체적으로 나타내는 오류 타입입니다.
#[derive(Debug)]
pub enum VerifyError {
InvalidInput(String),
SumcheckFailed(String),
ShplonkFailed(String),
}
Expand All @@ -24,6 +25,7 @@ pub enum VerifyError {
impl From<VerifyError> for String {
fn from(err: VerifyError) -> String {
match err {
VerifyError::InvalidInput(s) => format!("Invalid input: {}", s),
VerifyError::SumcheckFailed(s) => format!("Sum-check failed: {}", s),
VerifyError::ShplonkFailed(s) => format!("Shplonk failed: {}", s),
}
Expand Down Expand Up @@ -89,7 +91,8 @@ impl UltraHonkVerifier {
tx.rel_params.gamma,
pub_offset,
self.vk.circuit_size,
);
)
.map_err(VerifyError::InvalidInput)?;

// 5) Sum-check: 실패 시 SumcheckFailed 오류를 반환합니다.
verify_sumcheck(&proof, &tx, &self.vk).map_err(VerifyError::SumcheckFailed)?;
Expand All @@ -107,7 +110,7 @@ impl UltraHonkVerifier {
gamma: Fr,
offset: u64,
n: u64,
) -> Fr {
) -> Result<Fr, String> {
let mut num = Fr::one();
let mut den = Fr::one();

Expand All @@ -127,6 +130,9 @@ impl UltraHonkVerifier {
num_acc = num_acc + beta;
den_acc = den_acc - beta;
}
num * den.inverse()
let den_inv = den
.inverse()
.ok_or_else(|| String::from("public inputs delta denominator is zero"))?;
Ok(num * den_inv)
}
}