From aa377698db64de763f9d3979e3ffb4d725ffa18f Mon Sep 17 00:00:00 2001 From: Kamal Ahmad Date: Sun, 7 Jul 2024 06:38:21 +0500 Subject: [PATCH] Allow negative exponents for GroupElement.exp This fixes validation for transaction 307696f33cc8b03ac731616f025cb33555f854ddb3ab58cfd8af884c59225cd1 and chaincash schnorr signature verification --- ergotree-interpreter/src/eval/exponentiate.rs | 10 ++++++++-- ergotree-ir/src/sigma_protocol/dlog_group.rs | 6 ++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/ergotree-interpreter/src/eval/exponentiate.rs b/ergotree-interpreter/src/eval/exponentiate.rs index b7698d510..0256cb571 100644 --- a/ergotree-interpreter/src/eval/exponentiate.rs +++ b/ergotree-interpreter/src/eval/exponentiate.rs @@ -40,7 +40,7 @@ impl Evaluable for Exponentiate { mod tests { use super::*; use crate::eval::context::Context; - use crate::eval::tests::{eval_out, try_eval_out}; + use crate::eval::tests::eval_out; use crate::sigma_protocol::private_input::DlogProverInput; use ergo_chain_types::EcPoint; @@ -79,6 +79,12 @@ mod tests { fn eval_exponent_negative() { let left = force_any_val::(); let right = BigInt256::from_str_radix("-1", 10).unwrap(); + + let expected_exp = ergo_chain_types::ec_point::exponentiate( + &left, + &dlog_group::bigint256_to_scalar(right.clone()).unwrap(), + ); + let expr: Expr = Exponentiate { left: Box::new(Expr::Const(left.into())), right: Box::new(Expr::Const(right.into())), @@ -86,6 +92,6 @@ mod tests { .into(); let ctx = force_any_val::(); - assert!(try_eval_out::(&expr, &ctx).is_err()); + assert_eq!(eval_out::(&expr, &ctx), expected_exp); } } diff --git a/ergotree-ir/src/sigma_protocol/dlog_group.rs b/ergotree-ir/src/sigma_protocol/dlog_group.rs index b7616ffe9..9b92ccc45 100644 --- a/ergotree-ir/src/sigma_protocol/dlog_group.rs +++ b/ergotree-ir/src/sigma_protocol/dlog_group.rs @@ -73,10 +73,12 @@ fn biguint_to_bytes(x: &BigUint) -> [u8; 32] { } /// Attempts to create Scalar from BigInt256 -/// Returns None if not in the range [0, modulus). pub fn bigint256_to_scalar(bi: BigInt256) -> Option { + // To convert BigInt bi to Scalar calculate (bi mod order) + let order = order(); + let mut bi = &**bi % ℴ if Sign::Minus == bi.sign() { - return None; + bi += order; } #[allow(clippy::unwrap_used)] // since it's 256-bit BigInt it should always fit into BigUint let bu = bi.to_biguint().unwrap();