Skip to content

Commit af69856

Browse files
committed
Precompute DlogProverInput.public_image
This avoids repeated multiplications by group element when signing
1 parent 250f065 commit af69856

File tree

4 files changed

+27
-15
lines changed

4 files changed

+27
-15
lines changed

Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ ergo-nipopow = { version = "^0.15", path = "./ergo-nipopow" }
3636
ergo-merkle-tree = { version = "^0.15.0", path = "./ergo-merkle-tree" }
3737
ergo-rest = { version = "^0.13.0", path = "./ergo-rest" }
3838
ergo-lib = { version = "^0.28.0", path = "./ergo-lib"}
39-
k256 = { version = "0.13.1", features = ["arithmetic", "ecdsa"] }
40-
elliptic-curve = { version = "0.12", features = ["ff"] }
39+
k256 = { version = "0.13.1", features = ["arithmetic", "ecdsa", "precomputed-tables"] }
40+
elliptic-curve = { version = "0.13.8", features = ["ff"] }
4141
thiserror = "1"
4242
bounded-vec = { version = "^0.7.0" }
4343
bitvec = { version = "1.0.1" }

ergo-chain-types/src/ec_point.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use std::convert::TryFrom;
1010
use std::ops::{Add, Mul, Neg};
1111

1212
/// Elliptic curve point
13-
#[derive(PartialEq, Clone, Default, From, Into)]
13+
#[derive(PartialEq, Clone, Copy, Default, From, Into)]
1414
#[cfg_attr(
1515
feature = "json",
1616
derive(serde::Serialize, serde::Deserialize),

ergotree-interpreter/src/sigma_protocol/dlog_protocol.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ pub mod interactive_prover {
105105
/// The function computes initial prover's commitment to randomness
106106
/// ("a" message of the sigma-protocol) based on the verifier's challenge ("e")
107107
/// and prover's response ("z")
108-
///
108+
///
109109
/// g^z = a*h^e => a = g^z/h^e
110110
pub fn compute_commitment(
111111
proposition: &ProveDlog,

ergotree-interpreter/src/sigma_protocol/private_input.rs

+23-11
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
use std::convert::TryInto;
33
use std::fmt::Formatter;
44

5+
use elliptic_curve::ops::MulByGenerator;
56
use ergo_chain_types::EcPoint;
67
use ergotree_ir::serialization::SigmaSerializable;
78
use ergotree_ir::sigma_protocol::dlog_group;
@@ -13,6 +14,7 @@ use ergotree_ir::sigma_protocol::sigma_boolean::SigmaBoolean;
1314
extern crate derive_more;
1415
use derive_more::From;
1516
use k256::elliptic_curve::PrimeField;
17+
use k256::ProjectivePoint;
1618
use num_bigint::BigUint;
1719
use num_traits::ToPrimitive;
1820

@@ -22,10 +24,12 @@ use super::wscalar::Wscalar;
2224
/// Secret key of discrete logarithm signature protocol
2325
#[cfg_attr(feature = "json", derive(serde::Serialize, serde::Deserialize))]
2426
#[cfg_attr(feature = "json", serde(transparent))]
25-
#[derive(PartialEq, Eq, Clone, derive_more::From)]
27+
#[derive(PartialEq, Eq, Clone)]
2628
pub struct DlogProverInput {
2729
/// secret key value
2830
pub w: Wscalar,
31+
#[serde(skip)]
32+
pk: EcPoint,
2933
}
3034

3135
impl std::fmt::Debug for DlogProverInput {
@@ -35,22 +39,35 @@ impl std::fmt::Debug for DlogProverInput {
3539
}
3640
}
3741

42+
impl From<Wscalar> for DlogProverInput {
43+
fn from(scalar: Wscalar) -> Self {
44+
DlogProverInput::new(scalar)
45+
}
46+
}
47+
3848
impl DlogProverInput {
3949
/// Scalar(secret key) size in bytes
4050
pub const SIZE_BYTES: usize = 32;
4151

52+
/// Create new DlogProverInput
53+
pub fn new(w: Wscalar) -> DlogProverInput {
54+
Self {
55+
pk: EcPoint::from(ProjectivePoint::mul_by_generator(w.as_scalar_ref())),
56+
w,
57+
}
58+
}
4259
/// generates random secret in the range [0, n), where n is DLog group order.
4360
pub fn random() -> DlogProverInput {
44-
DlogProverInput {
45-
w: dlog_group::random_scalar_in_group_range(crypto_utils::secure_rng()).into(),
46-
}
61+
DlogProverInput::new(
62+
dlog_group::random_scalar_in_group_range(crypto_utils::secure_rng()).into(),
63+
)
4764
}
4865

4966
/// Attempts to parse the given byte array as an SEC-1-encoded scalar(secret key).
5067
/// Returns None if the byte array does not contain a big-endian integer in the range [0, modulus).
5168
pub fn from_bytes(bytes: &[u8; DlogProverInput::SIZE_BYTES]) -> Option<DlogProverInput> {
5269
k256::Scalar::from_repr((*bytes).into())
53-
.map(|s| DlogProverInput::from(Wscalar::from(s)))
70+
.map(|s| DlogProverInput::new(Wscalar::from(s)))
5471
.into()
5572
}
5673

@@ -87,12 +104,7 @@ impl DlogProverInput {
87104

88105
/// public key of discrete logarithm signature protocol
89106
pub fn public_image(&self) -> ProveDlog {
90-
// test it, see https://github.com/ergoplatform/sigma-rust/issues/38
91-
let g = ergo_chain_types::ec_point::generator();
92-
ProveDlog::new(ergo_chain_types::ec_point::exponentiate(
93-
&g,
94-
self.w.as_scalar_ref(),
95-
))
107+
ProveDlog::new(self.pk)
96108
}
97109

98110
/// Return true if the secret is 0

0 commit comments

Comments
 (0)