Skip to content

Commit

Permalink
Replace BigInt256 internals with bnum
Browse files Browse the repository at this point in the history
num256 has no no_std support and uses BigInt internally, so it'll be less efficient for fixed-size ops compared to bnum
  • Loading branch information
SethDusek committed Nov 14, 2024
1 parent 250f065 commit 3a71272
Show file tree
Hide file tree
Showing 20 changed files with 277 additions and 325 deletions.
16 changes: 13 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,26 @@ ergotree-interpreter = { version = "^0.28.0", path = "./ergotree-interpreter" }
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"}
ergo-lib = { version = "^0.28.0", path = "./ergo-lib" }
k256 = { version = "0.13.1", features = ["arithmetic", "ecdsa"] }
elliptic-curve = { version = "0.12", features = ["ff"] }
thiserror = "1"
bounded-vec = { version = "^0.7.0" }
bitvec = { version = "1.0.1" }
derive_more = "0.99"
derive_more = { version = "0.99", features = [
"add",
"add_assign",
"mul",
"not",
"from",
"into",
"try_into",
"from_str",
"display",
] }
blake2 = "0.10"
sha2 = "0.10"
num-derive = "0.3.3"
num-derive = "0.4.2"
num-traits = "0.2.14"
num-integer = "0.1.44"
num-bigint = "0.4.0"
Expand Down
5 changes: 4 additions & 1 deletion bindings/ergo-lib-wasm/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,10 @@ impl Constant {
/// Create BigInt constant from byte array (signed bytes bit-endian)
pub fn from_bigint_signed_bytes_be(num: &[u8]) -> Result<Constant, JsValue> {
Ok(Constant(
ergo_lib::ergotree_ir::mir::constant::Constant::from(BigInt256::try_from(num)?),
ergo_lib::ergotree_ir::mir::constant::Constant::from(
BigInt256::from_be_slice(num)
.ok_or_else(|| String::from("BigInt256: out of bounds"))?,
),
))
}

Expand Down
8 changes: 4 additions & 4 deletions ergo-chain-generation/src/chain_generation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use ergo_lib::{
transaction::{prover_result::ProverResult, Input, Transaction, TxIoVec},
},
ergo_chain_types::{BlockId, Digest32},
ergotree_ir::sigma_protocol::dlog_group::order_bigint,
};
use ergo_lib::{
ergo_chain_types::ADDigest,
Expand All @@ -21,7 +22,6 @@ use ergo_lib::{
chain::ergo_box::{box_value::BoxValue, BoxId},
ergo_tree::ErgoTree,
serialization::{sigma_byte_writer::SigmaByteWriter, SigmaSerializable},
sigma_protocol::dlog_group::order,
},
};
use ergo_merkle_tree::{MerkleNode, MerkleTree};
Expand Down Expand Up @@ -196,7 +196,7 @@ fn prove_block(
.0
.to_vec();
// Order of the secp256k1 elliptic curve
let order = order();
let order = order_bigint();
let target_b = order.clone() / ergo_nipopow::decode_compact_bits(header.n_bits);

let x = DlogProverInput::random();
Expand Down Expand Up @@ -293,8 +293,8 @@ fn generate_element(
concat.extend(pk);
concat.extend(msg);
concat.extend(w);
let valid_range = (BigInt::from(2_u8).pow(256) / order()) * order();
numeric_hash(&concat, valid_range, order())
let valid_range = (BigInt::from(2_u8).pow(256) / order_bigint()) * order_bigint();
numeric_hash(&concat, valid_range, order_bigint())
} else {
// Autolykos v. 2: H(j|h|M) (line 5 from the Algo 2 of the spec)
let mut concat = vec![];
Expand Down
7 changes: 3 additions & 4 deletions ergo-chain-generation/src/fake_pow_scheme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,12 @@
#[cfg(test)]
mod tests {
use ergo_lib::ergo_chain_types::{blake2b256_hash, ADDigest, BlockId, Digest32};
use ergo_lib::ergotree_ir::sigma_protocol::dlog_group::order_bigint;
use ergo_nipopow::{NipopowAlgos, NipopowProof};

use ergo_chain_types::{AutolykosSolution, Header, Votes};
use ergo_lib::ergotree_interpreter::sigma_protocol::private_input::DlogProverInput;
use ergo_lib::ergotree_ir::{
serialization::sigma_byte_writer::SigmaByteWriter, sigma_protocol::dlog_group::order,
};
use ergo_lib::ergotree_ir::serialization::sigma_byte_writer::SigmaByteWriter;
use ergo_nipopow::PoPowHeader;
use num_bigint::BigInt;
use rand::{thread_rng, Rng};
Expand Down Expand Up @@ -149,7 +148,7 @@ mod tests {

let (sk, _) = default_miner_secret();
let nonce: Vec<u8> = std::iter::repeat(0_u8).take(8).collect();
let d = order() / (height + 1);
let d = order_bigint() / (height + 1);
let autolykos_solution = AutolykosSolution {
miner_pk: sk.public_key().unwrap().public_key.into(),
pow_onetime_pk: Some(x.public_image().h),
Expand Down
8 changes: 4 additions & 4 deletions ergo-nipopow/src/autolykos_pow_scheme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ pub enum AutolykosPowSchemeError {
#[allow(clippy::unwrap_used)]
#[cfg(test)]
mod tests {
use ergotree_ir::{serialization::SigmaSerializable, sigma_protocol::dlog_group::order};
use ergotree_ir::{serialization::SigmaSerializable, sigma_protocol::dlog_group::order_bigint};

use crate::nipopow_algos::decode_compact_bits;

Expand Down Expand Up @@ -256,7 +256,7 @@ mod tests {
"adProofsId" : "dec129290a763f4de41f04e87e2b661dd59758af6bdd00dd51f5d97c3a8cb9b5",
"transactionsId" : "eba1dd82cf51147232e09c1f72b37c554c30f63274d5093bff36849a83472a42",
"parentId" : "ac2101807f0000ca01ff0119db227f202201007f62000177a080005d440896d0"
}
}
"#;

let header: Header = serde_json::from_str(json).unwrap();
Expand Down Expand Up @@ -285,7 +285,7 @@ mod tests {
let decoded = decode_compact_bits(header.n_bits);

// Target `b` from encoded difficulty `nBits`
let target_b = order() / decoded;
let target_b = order_bigint() / decoded;
assert_eq!(
target_b,
BigInt::parse_bytes(
Expand Down Expand Up @@ -324,7 +324,7 @@ mod tests {
let decoded = decode_compact_bits(header.n_bits);

// Target `b` from encoded difficulty `nBits`
let target_b = order() / decoded;
let target_b = order_bigint() / decoded;
let hit = pow.pow_hit(&header).unwrap();

assert!(hit >= target_b);
Expand Down
4 changes: 2 additions & 2 deletions ergo-nipopow/src/nipopow_algos.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use ergo_chain_types::Header;
use ergotree_ir::sigma_protocol::dlog_group::order;
use ergotree_ir::sigma_protocol::dlog_group::order_bigint;
use num_bigint::BigInt;
use num_traits::ToPrimitive;
use std::convert::TryInto;
Expand Down Expand Up @@ -93,7 +93,7 @@ impl NipopowAlgos {
let genesis_header = header.height == 1;
if !genesis_header {
// Order of the secp256k1 elliptic curve
let order = order();
let order = order_bigint();
#[allow(clippy::unwrap_used)]
let required_target = (order / decode_compact_bits(header.n_bits))
.to_f64()
Expand Down
36 changes: 18 additions & 18 deletions ergotree-interpreter/src/eval/bin_op.rs
Original file line number Diff line number Diff line change
Expand Up @@ -627,24 +627,24 @@ mod tests {
fn test_num_bigint(l_long in any::<i64>(), r_long in any::<i64>()) {
let l = BigInt256::from(l_long);
let r = BigInt256::from(r_long);
prop_assert_eq!(eval_arith_op(ArithOp::Plus, l.clone(), r.clone()).ok(), l.checked_add(&r));
prop_assert_eq!(eval_arith_op(ArithOp::Minus, l.clone(), r.clone()).ok(), l.checked_sub(&r));
prop_assert_eq!(eval_arith_op(ArithOp::Multiply, l.clone(), r.clone()).ok(), l.checked_mul(&r));
prop_assert_eq!(eval_arith_op(ArithOp::Divide, l.clone(), r.clone()).ok(), l.checked_div(&r));
prop_assert_eq!(eval_arith_op(ArithOp::Modulo, l.clone(), r.clone()).ok(), l.checked_rem(&r));
prop_assert_eq!(eval_arith_op::<BigInt256>(ArithOp::Max, l.clone(),
r.clone()).unwrap(), l.clone().max(r.clone()));
prop_assert_eq!(eval_arith_op::<BigInt256>(ArithOp::Min, l.clone(),
r.clone()).unwrap(), l.clone().min(r.clone()));

prop_assert_eq!(eval_bit_op(BitOp::BitAnd, l.clone(), r.clone()), Ok(&l & &r));
prop_assert_eq!(eval_bit_op(BitOp::BitOr, l.clone(), r.clone()), Ok(&l | &r));
prop_assert_eq!(eval_bit_op(BitOp::BitXor, l.clone(), r.clone()), Ok(&l ^ &r));

prop_assert_eq!(eval_relation_op(RelationOp::Gt, l.clone(), r.clone()), l > r);
prop_assert_eq!(eval_relation_op(RelationOp::Lt, l.clone(), r.clone()), l < r);
prop_assert_eq!(eval_relation_op(RelationOp::Ge, l.clone(), r.clone()), l >= r);
prop_assert_eq!(eval_relation_op(RelationOp::Le, l.clone(), r.clone()), l <= r);
prop_assert_eq!(eval_arith_op(ArithOp::Plus, l, r).ok(), l.checked_add(&r));
prop_assert_eq!(eval_arith_op(ArithOp::Minus, l, r).ok(), l.checked_sub(&r));
prop_assert_eq!(eval_arith_op(ArithOp::Multiply, l, r).ok(), l.checked_mul(&r));
prop_assert_eq!(eval_arith_op(ArithOp::Divide, l, r).ok(), l.checked_div(&r));
prop_assert_eq!(eval_arith_op(ArithOp::Modulo, l, r).ok(), l.checked_rem(&r));
prop_assert_eq!(eval_arith_op::<BigInt256>(ArithOp::Max, l,
r).unwrap(), l.max(r));
prop_assert_eq!(eval_arith_op::<BigInt256>(ArithOp::Min, l,
r).unwrap(), l.min(r));

prop_assert_eq!(eval_bit_op(BitOp::BitAnd, l, r), Ok(l & r));
prop_assert_eq!(eval_bit_op(BitOp::BitOr, l, r), Ok(l | r));
prop_assert_eq!(eval_bit_op(BitOp::BitXor, l, r), Ok(l ^ r));

prop_assert_eq!(eval_relation_op(RelationOp::Gt, l, r), l > r);
prop_assert_eq!(eval_relation_op(RelationOp::Lt, l, r), l < r);
prop_assert_eq!(eval_relation_op(RelationOp::Ge, l, r), l >= r);
prop_assert_eq!(eval_relation_op(RelationOp::Le, l, r), l <= r);
}

#[test]
Expand Down
9 changes: 5 additions & 4 deletions ergotree-interpreter/src/eval/byte_array_to_bigint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use ergotree_ir::bigint256::BigInt256;
use ergotree_ir::mir::byte_array_to_bigint::ByteArrayToBigInt;
use ergotree_ir::mir::constant::TryExtractInto;
use ergotree_ir::mir::value::Value;
use std::convert::TryFrom;

use crate::eval::env::Env;
use crate::eval::Context;
Expand All @@ -23,9 +22,11 @@ impl Evaluable for ByteArrayToBigInt {
"ByteArrayToBigInt: byte array is empty".into(),
));
}
match BigInt256::try_from(&input[..]) {
Ok(n) => Ok(Value::BigInt(n)),
Err(e) => Err(UnexpectedValue(e)),
match BigInt256::from_be_slice(&input[..]) {
Some(n) => Ok(Value::BigInt(n)),
None => Err(UnexpectedValue(
"ByteArrayToBigInt: input array out of bounds".into(),
)),
}
}
}
Expand Down
18 changes: 9 additions & 9 deletions ergotree-interpreter/src/eval/downcast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,12 +214,12 @@ mod tests {
);
let ctx = force_any_val::<Context>();
(0..ErgoTreeVersion::V6_SOFT_FORK_VERSION)
.for_each(|version| assert!(try_eval_out_with_version::<BigInt256>(&downcast(v_bigint.clone(), SType::SBigInt), &ctx, version).is_err()));
.for_each(|version| assert!(try_eval_out_with_version::<BigInt256>(&downcast(v_bigint, SType::SBigInt), &ctx, version).is_err()));
(ErgoTreeVersion::V6_SOFT_FORK_VERSION..=ErgoTreeVersion::MAX_SCRIPT_VERSION).for_each(
|version| {
assert_eq!(
try_eval_out_with_version::<BigInt256>(
&downcast(v_bigint.clone(), SType::SBigInt),
&downcast(v_bigint, SType::SBigInt),
&ctx,
version
).unwrap(),
Expand All @@ -234,7 +234,7 @@ mod tests {
let c_short: Constant = v_short.into();
let c_int: Constant = v_int.into();
let c_long: Constant = v_long.into();
let c_bigint: Constant = v_bigint.clone().into();
let c_bigint: Constant = v_bigint.into();

assert_eq!(
eval_out_wo_ctx::<i64>(&downcast(c_byte, SType::SLong)),
Expand Down Expand Up @@ -307,11 +307,11 @@ mod tests {
.is_err());
let ctx = force_any_val::<Context>();
(0..ErgoTreeVersion::V6_SOFT_FORK_VERSION)
.for_each(|version| assert!(try_eval_out_with_version::<i32>(&downcast(v_bigint.clone(), SType::SInt), &ctx, version).is_err()));
.for_each(|version| assert!(try_eval_out_with_version::<i32>(&downcast(v_bigint, SType::SInt), &ctx, version).is_err()));
(ErgoTreeVersion::V6_SOFT_FORK_VERSION..=ErgoTreeVersion::MAX_SCRIPT_VERSION).for_each(
|version| {
let res = try_eval_out_with_version::<i32>(
&downcast(v_bigint.clone(), SType::SInt),
&downcast(v_bigint, SType::SInt),
&ctx,
version
);
Expand Down Expand Up @@ -361,11 +361,11 @@ mod tests {
assert!(try_eval_out_wo_ctx::<i16>(&downcast(c_long_oob, SType::SShort)).is_err());
let ctx = force_any_val::<Context>();
(0..ErgoTreeVersion::V6_SOFT_FORK_VERSION)
.for_each(|version| assert!(try_eval_out_with_version::<i16>(&downcast(v_bigint.clone(), SType::SShort), &ctx, version).is_err()));
.for_each(|version| assert!(try_eval_out_with_version::<i16>(&downcast(v_bigint, SType::SShort), &ctx, version).is_err()));
(ErgoTreeVersion::V6_SOFT_FORK_VERSION..=ErgoTreeVersion::MAX_SCRIPT_VERSION).for_each(
|version| {
let res = try_eval_out_with_version::<i16>(
&downcast(v_bigint.clone(), SType::SShort),
&downcast(v_bigint, SType::SShort),
&ctx,
version
);
Expand Down Expand Up @@ -426,11 +426,11 @@ mod tests {
assert!(try_eval_out_wo_ctx::<i8>(&downcast(c_long_oob, SType::SByte)).is_err());
let ctx = force_any_val::<Context>();
(0..ErgoTreeVersion::V6_SOFT_FORK_VERSION)
.for_each(|version| assert!(try_eval_out_with_version::<i8>(&downcast(v_bigint.clone(), SType::SByte), &ctx, version).is_err()));
.for_each(|version| assert!(try_eval_out_with_version::<i8>(&downcast(v_bigint, SType::SByte), &ctx, version).is_err()));
(ErgoTreeVersion::V6_SOFT_FORK_VERSION..=ErgoTreeVersion::MAX_SCRIPT_VERSION).for_each(
|version| {
let res = try_eval_out_with_version::<i8>(
&downcast(v_bigint.clone(), SType::SByte),
&downcast(v_bigint, SType::SByte),
&ctx,
version
);
Expand Down
4 changes: 2 additions & 2 deletions ergotree-interpreter/src/eval/exponentiate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ mod tests {

let expected_exp = ergo_chain_types::ec_point::exponentiate(
&left,
&dlog_group::bigint256_to_scalar(right.clone()).unwrap()
&dlog_group::bigint256_to_scalar(right).unwrap()
);

let expr: Expr = Exponentiate {
Expand All @@ -82,7 +82,7 @@ mod tests {

let expected_exp = ergo_chain_types::ec_point::exponentiate(
&left,
&dlog_group::bigint256_to_scalar(right.clone()).unwrap(),
&dlog_group::bigint256_to_scalar(right).unwrap(),
);

let expr: Expr = Exponentiate {
Expand Down
2 changes: 1 addition & 1 deletion ergotree-interpreter/src/eval/upcast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ mod tests {

#[test]
fn from_bigint(v in any::<BigInt256>()) {
let c: Constant = v.clone().into();
let c: Constant = v.into();
let ctx = force_any_val::<Context>();
(0..ErgoTreeVersion::V6_SOFT_FORK_VERSION).for_each(|version| {
assert!(try_eval_out_with_version::<BigInt256>(&Upcast::new(c.clone().into(), SType::SBigInt).unwrap().into(), &ctx, version).is_err());
Expand Down
2 changes: 1 addition & 1 deletion ergotree-ir/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ indexmap = { workspace = true }
serde = { workspace = true, optional = true }
serde_json = { workspace = true, optional = true }
serde_with = { workspace = true, optional = true }
num256 = "0.3.1"
bnum = { version = "0.12.0", features = ["numtraits"] }
impl-trait-for-tuples = "0.2.0"
strum = "0.21"
strum_macros = "0.21"
Expand Down
Loading

0 comments on commit 3a71272

Please sign in to comment.