diff --git a/ergo-chain-types/src/ec_point.rs b/ergo-chain-types/src/ec_point.rs index 571873bae..cf793fa65 100644 --- a/ergo-chain-types/src/ec_point.rs +++ b/ergo-chain-types/src/ec_point.rs @@ -1,6 +1,7 @@ //! Elliptic curve point. use derive_more::{From, Into}; +use elliptic_curve::ops::MulByGenerator; use k256::elliptic_curve::group::prime::PrimeCurveAffine; use k256::elliptic_curve::sec1::ToEncodedPoint; use k256::{ProjectivePoint, PublicKey, Scalar}; @@ -116,6 +117,11 @@ pub fn exponentiate(base: &EcPoint, exponent: &Scalar) -> EcPoint { } } +/// Raise the generator g to the exponent. This is faster than exponentiate(&generator(), exponent) +pub fn exponentiate_gen(exponent: &Scalar) -> EcPoint { + ProjectivePoint::mul_by_generator(exponent).into() +} + impl ScorexSerializable for EcPoint { fn scorex_serialize(&self, w: &mut W) -> ScorexSerializeResult { let caff = self.0.to_affine(); diff --git a/ergotree-interpreter/src/sigma_protocol/dlog_protocol.rs b/ergotree-interpreter/src/sigma_protocol/dlog_protocol.rs index 106cb2355..2343d5689 100644 --- a/ergotree-interpreter/src/sigma_protocol/dlog_protocol.rs +++ b/ergotree-interpreter/src/sigma_protocol/dlog_protocol.rs @@ -44,6 +44,7 @@ pub mod interactive_prover { use crate::sigma_protocol::crypto_utils; use crate::sigma_protocol::wscalar::Wscalar; use crate::sigma_protocol::{private_input::DlogProverInput, Challenge}; + use ergo_chain_types::ec_point::exponentiate_gen; use ergo_chain_types::{ ec_point::{exponentiate, generator, inverse}, EcPoint, @@ -67,7 +68,7 @@ pub mod interactive_prover { let e: Scalar = challenge.clone().into(); let minus_e = e.negate(); let h_to_e = exponentiate(&public_input.h, &minus_e); - let g_to_z = exponentiate(&generator(), &z); + let g_to_z = exponentiate_gen(&z); let a = g_to_z * &h_to_e; ( FirstDlogProverMessage { a: a.into() }, @@ -80,8 +81,7 @@ pub mod interactive_prover { /// that leaf to compute the necessary randomness "r" and the commitment "a" pub fn first_message() -> (Wscalar, FirstDlogProverMessage) { let r = dlog_group::random_scalar_in_group_range(crypto_utils::secure_rng()); - let g = generator(); - let a = exponentiate(&g, &r); + let a = exponentiate_gen(&r); (r.into(), FirstDlogProverMessage { a: a.into() }) } @@ -115,7 +115,7 @@ pub mod interactive_prover { let g = generator(); let h = *proposition.h.clone(); let e: Scalar = challenge.clone().into(); - let g_z = exponentiate(&g, second_message.z.as_scalar_ref()); + let g_z = exponentiate_gen(second_message.z.as_scalar_ref()); let h_e = exponentiate(&h, &e); g_z * &inverse(&h_e) } diff --git a/ergotree-interpreter/src/sigma_protocol/private_input.rs b/ergotree-interpreter/src/sigma_protocol/private_input.rs index bf3930482..dc5a4b73d 100644 --- a/ergotree-interpreter/src/sigma_protocol/private_input.rs +++ b/ergotree-interpreter/src/sigma_protocol/private_input.rs @@ -2,7 +2,7 @@ use std::convert::TryInto; use std::fmt::Formatter; -use elliptic_curve::ops::MulByGenerator; +use ergo_chain_types::ec_point::exponentiate_gen; use ergo_chain_types::EcPoint; use ergotree_ir::serialization::SigmaSerializable; use ergotree_ir::sigma_protocol::dlog_group; @@ -14,7 +14,6 @@ use ergotree_ir::sigma_protocol::sigma_boolean::SigmaBoolean; extern crate derive_more; use derive_more::From; use k256::elliptic_curve::PrimeField; -use k256::ProjectivePoint; use num_bigint::BigUint; use num_traits::ToPrimitive; @@ -52,7 +51,7 @@ impl DlogProverInput { /// Create new DlogProverInput pub fn new(w: Wscalar) -> DlogProverInput { Self { - pk: EcPoint::from(ProjectivePoint::mul_by_generator(w.as_scalar_ref())), + pk: exponentiate_gen(w.as_scalar_ref()), w, } }