Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use precomputed tables #790

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from
Open
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
7 changes: 6 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -253,10 +253,15 @@ jobs:

android_tests:
name: Test JNI(Android) bindings
runs-on: macos-12
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v2
- name: Enable KVM
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm

- uses: actions-rs/toolchain@v1
with:
Expand Down
9 changes: 7 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ members = [
"bindings/ergo-lib-c",
"bindings/ergo-lib-jni",
]
resolver = "2"

[workspace.package]
repository = "https://github.com/ergoplatform/sigma-rust"
Expand All @@ -36,8 +37,12 @@ ergo-nipopow = { version = "^0.15", path = "./ergo-nipopow" }
ergo-merkle-tree = { version = "^0.15.0", path = "./ergo-merkle-tree" }
ergo-rest = { version = "^0.13.0", path = "./ergo-rest" }
ergo-lib = { version = "^0.28.0", path = "./ergo-lib" }
k256 = { version = "0.13.1", features = ["arithmetic", "ecdsa"] }
elliptic-curve = { version = "0.12", features = ["ff"] }
k256 = { version = "0.13.1", features = [
"arithmetic",
"ecdsa",
"precomputed-tables",
] }
elliptic-curve = { version = "0.13.8", features = ["ff"] }
thiserror = "1"
bounded-vec = { version = "^0.7.0" }
bitvec = { version = "1.0.1" }
Expand Down
2 changes: 1 addition & 1 deletion bindings/ergo-lib-wasm/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ impl UnsignedTransaction {

/// Returns distinct token id from output_candidates as array of byte arrays
pub fn distinct_token_ids(&self) -> Vec<Uint8Array> {
distinct_token_ids(self.0.output_candidates.clone())
distinct_token_ids(&self.0.output_candidates)
.iter()
.map(|id| Uint8Array::from(id.as_ref()))
.collect()
Expand Down
12 changes: 9 additions & 3 deletions ergo-chain-types/src/ec_point.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand All @@ -10,7 +11,7 @@ use std::convert::TryFrom;
use std::ops::{Add, Mul, Neg};

/// Elliptic curve point
#[derive(PartialEq, Clone, Default, From, Into)]
#[derive(PartialEq, Clone, Copy, Default, From, Into)]
#[cfg_attr(
feature = "json",
derive(serde::Serialize, serde::Deserialize),
Expand Down Expand Up @@ -103,7 +104,7 @@ pub fn is_identity(ge: &EcPoint) -> bool {

/// Calculates the inverse of the given group element
pub fn inverse(ec: &EcPoint) -> EcPoint {
-ec.clone()
-*ec
}

/// Raises the base GroupElement to the exponent. The result is another GroupElement.
Expand All @@ -112,10 +113,15 @@ pub fn exponentiate(base: &EcPoint, exponent: &Scalar) -> EcPoint {
// we treat EC as a multiplicative group, therefore, exponentiate point is multiply.
EcPoint(base.0 * exponent)
} else {
base.clone()
*base
}
}

/// 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<W: WriteSigmaVlqExt>(&self, w: &mut W) -> ScorexSerializeResult {
let caff = self.0.to_affine();
Expand Down
18 changes: 6 additions & 12 deletions ergo-lib/src/chain/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,20 +231,14 @@ pub enum TransactionSignatureVerificationError {
}

/// Returns distinct token ids from all given ErgoBoxCandidate's
pub fn distinct_token_ids<I>(output_candidates: I) -> IndexSet<TokenId>
pub fn distinct_token_ids<'a, I>(output_candidates: I) -> IndexSet<TokenId>
where
I: IntoIterator<Item = ErgoBoxCandidate>,
I: IntoIterator<Item = &'a ErgoBoxCandidate>,
{
let token_ids: Vec<TokenId> = output_candidates
let token_ids = output_candidates
.into_iter()
.flat_map(|b| {
b.tokens
.into_iter()
.flatten()
.map(|t| t.token_id)
.collect::<Vec<TokenId>>()
})
.collect();
.flat_map(|b| b.tokens.iter().flatten().map(|t| t.token_id));

IndexSet::<_>::from_iter(token_ids)
}

Expand All @@ -262,7 +256,7 @@ impl SigmaSerializable for Transaction {
}

// Serialize distinct ids of tokens in transaction outputs.
let distinct_token_ids = distinct_token_ids(self.output_candidates.clone());
let distinct_token_ids = distinct_token_ids(&self.output_candidates);

// Note that `self.output_candidates` is of type `TxIoVec` which has a max length of
// `u16::MAX`. Therefore the following unwrap is safe.
Expand Down
2 changes: 1 addition & 1 deletion ergo-lib/src/chain/transaction/unsigned.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ impl UnsignedTransaction {

/// Returns distinct token ids from all output_candidates
pub fn distinct_token_ids(&self) -> IndexSet<TokenId> {
distinct_token_ids(self.output_candidates.clone())
distinct_token_ids(&self.output_candidates)
}
}

Expand Down
3 changes: 2 additions & 1 deletion ergo-lib/src/wallet/ext_pub_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ type HmacSha512 = Hmac<Sha512>;
pub struct ExtPubKey {
/// Parsed public key (EcPoint)
pub public_key: EcPoint,
chain_code: ChainCode,
/// Chain code bytes
pub chain_code: ChainCode,
/// Derivation path for this extended public key
pub derivation_path: DerivationPath,
}
Expand Down
47 changes: 26 additions & 21 deletions ergo-lib/src/wallet/ext_secret_key.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
//! Extended private key operations according to BIP-32
use std::convert::TryInto;

use super::{
derivation_path::{ChildIndex, ChildIndexError, DerivationPath},
Expand Down Expand Up @@ -27,14 +26,23 @@ type HmacSha512 = Hmac<Sha512>;

/// Extended secret key
/// implemented according to BIP-32
#[derive(PartialEq, Eq, Debug, Clone)]
#[derive(PartialEq, Eq, Clone)]
pub struct ExtSecretKey {
/// The secret key
private_input: DlogProverInput,
private_input: Wscalar,
chain_code: ChainCode,
derivation_path: DerivationPath,
}

impl std::fmt::Debug for ExtSecretKey {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ExtSecretKey")
.field("private_input", &"*****") // disable debug output for secret key to prevent key leakage in logs
.field("chain_code", &self.chain_code)
.field("derivation_path", &self.derivation_path)
.finish()
}
}

/// Extended secret key errors
#[derive(Error, PartialEq, Eq, Debug, Clone)]
pub enum ExtSecretKeyError {
Expand Down Expand Up @@ -65,8 +73,8 @@ impl ExtSecretKey {
chain_code: ChainCode,
derivation_path: DerivationPath,
) -> Result<Self, ExtSecretKeyError> {
let private_input = DlogProverInput::from_bytes(&secret_key_bytes)
.ok_or(ExtSecretKeyError::ScalarEncodingError)?;
let private_input =
Wscalar::from_bytes(&secret_key_bytes).ok_or(ExtSecretKeyError::ScalarEncodingError)?;
Ok(Self {
private_input,
chain_code,
Expand All @@ -81,7 +89,7 @@ impl ExtSecretKey {

/// Returns secret key
pub fn secret_key(&self) -> SecretKey {
self.private_input.clone().into()
DlogProverInput::new(self.private_input.clone()).into()
}

/// Byte representation of the underlying scalar
Expand All @@ -91,7 +99,7 @@ impl ExtSecretKey {

/// Public image associated with the private input
pub fn public_image(&self) -> ProveDlog {
self.private_input.public_image()
DlogProverInput::new(self.private_input.clone()).public_image()
}

/// Public image bytes in SEC-1 encoded & compressed format
Expand All @@ -102,12 +110,11 @@ impl ExtSecretKey {
/// The extended public key associated with this secret key
pub fn public_key(&self) -> Result<ExtPubKey, ExtSecretKeyError> {
#[allow(clippy::unwrap_used)]
Ok(ExtPubKey::new(
// unwrap is safe as it is used on an Infallible result type
self.public_image_bytes()?.try_into().unwrap(),
self.chain_code,
self.derivation_path.clone(),
)?)
Ok(ExtPubKey {
public_key: *self.public_image().h,
chain_code: self.chain_code,
derivation_path: self.derivation_path.clone(),
})
}

/// Derive a child extended secret key using the provided index
Expand All @@ -126,16 +133,14 @@ impl ExtSecretKey {
let mac_bytes = mac.finalize().into_bytes();
let mut secret_key_bytes = [0; SecretKeyBytes::LEN];
secret_key_bytes.copy_from_slice(&mac_bytes[..32]);
if let Some(dlog_prover) = DlogProverInput::from_bytes(&secret_key_bytes) {
if let Some(wscalar) = Wscalar::from_bytes(&secret_key_bytes) {
// parse256(IL) + kpar (mod n).
// via https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#child-key-derivation-ckd-functions
let child_secret_key: DlogProverInput = Wscalar::from(
dlog_prover
.w
let child_secret_key = Wscalar::from(
wscalar
.as_scalar_ref()
.add(self.private_input.w.as_scalar_ref()),
)
.into();
.add(self.private_input.as_scalar_ref()),
);
if child_secret_key.is_zero() {
// ki == 0 case of:
// > In case parse256(IL) ≥ n or ki = 0, the resulting key is invalid, and one
Expand Down
2 changes: 1 addition & 1 deletion ergotree-interpreter/src/eval/create_provedlog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ impl Evaluable for CreateProveDlog {
let value_v = self.input.eval(env, ctx)?;
match value_v {
Value::GroupElement(ecpoint) => {
let prove_dlog = ProveDlog::new((*ecpoint).clone());
let prove_dlog = ProveDlog::new(*ecpoint);
Ok(prove_dlog.into())
}
_ => Err(EvalError::UnexpectedValue(format!(
Expand Down
4 changes: 2 additions & 2 deletions ergotree-interpreter/src/eval/multiply_group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ impl Evaluable for MultiplyGroup {

match (&left_v, &right_v) {
(Value::GroupElement(left), Value::GroupElement(right)) => {
Ok(((**left).clone() * right).into())
Ok(((**left) * right).into())
}
_ => Err(EvalError::UnexpectedValue(format!(
"Expected MultiplyGroup input to be GroupElement, got: {0:?}",
Expand Down Expand Up @@ -45,7 +45,7 @@ mod tests {
#[test]
fn eval_any(left in any::<EcPoint>(), right in any::<EcPoint>()) {

let expected_mul = left.clone() * &right;
let expected_mul = left * &right;

let expr: Expr = MultiplyGroup {
left: Box::new(Expr::Const(left.into())),
Expand Down
14 changes: 5 additions & 9 deletions ergotree-interpreter/src/eval/sgroup_elem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub(crate) static GET_ENCODED_EVAL_FN: EvalFn = |_mc, _env, _ctx, obj, _args| {

pub(crate) static NEGATE_EVAL_FN: EvalFn = |_mc, _env, _ctx, obj, _args| {
let negated: EcPoint = match obj {
Value::GroupElement(ec_point) => Ok(-(*ec_point).clone()),
Value::GroupElement(ec_point) => Ok(-(*ec_point)),
_ => Err(EvalError::UnexpectedValue(format!(
"expected obj to be Value::GroupElement, got: {0:?}",
obj
Expand All @@ -47,7 +47,7 @@ mod tests {
fn eval_get_encoded() {
let input = force_any_val::<EcPoint>();
let expr: Expr = MethodCall::new(
input.clone().into(),
input.into(),
sgroup_elem::GET_ENCODED_METHOD.clone(),
vec![],
)
Expand All @@ -64,13 +64,9 @@ mod tests {
#[test]
fn eval_negate() {
let input = force_any_val::<EcPoint>();
let expr: Expr = MethodCall::new(
input.clone().into(),
sgroup_elem::NEGATE_METHOD.clone(),
vec![],
)
.unwrap()
.into();
let expr: Expr = MethodCall::new(input.into(), sgroup_elem::NEGATE_METHOD.clone(), vec![])
.unwrap()
.into();
assert_eq!(-input, eval_out_wo_ctx::<EcPoint>(&expr))
}
}
6 changes: 3 additions & 3 deletions ergotree-interpreter/src/sigma_protocol/dht_protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ pub mod interactive_prover {
let z = dlog_group::random_scalar_in_group_range(crypto_utils::secure_rng());

// COMPUTE a = g^z*u^(-e) and b = h^z*v^{-e} (where -e here means -e mod q)
let e: Scalar = challenge.clone().into();
let e: Scalar = challenge.into();
let minus_e = e.negate();
let h_to_z = exponentiate(&public_input.h, &z);
let g_to_z = exponentiate(&public_input.g, &z);
Expand Down Expand Up @@ -106,7 +106,7 @@ pub mod interactive_prover {
rnd: &Wscalar,
challenge: &Challenge,
) -> SecondDhTupleProverMessage {
let e: Scalar = challenge.clone().into();
let e: Scalar = challenge.into();
// modulo multiplication, no need to explicit mod op
let ew = e.mul(private_input.w.as_scalar_ref());
// modulo addition, no need to explicit mod op
Expand All @@ -133,7 +133,7 @@ pub mod interactive_prover {

let z = second_message.z.clone();

let e: Scalar = challenge.clone().into();
let e: Scalar = challenge.into();

use ergo_chain_types::ec_point::{exponentiate, inverse};

Expand Down
Loading
Loading