Skip to content
Merged
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
19 changes: 4 additions & 15 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,9 @@ default = [ "bitcoin", "elements" ]
name = "simplicity"
path = "src/lib.rs"

[[bin]]
name = "main"
path = "src/main.rs"

[dependencies.bitcoin]
version = "0.23"
optional = true

[dependencies.elements]
version = "0.12"
optional = true

[dependencies]
bitcoin_hashes = "0.7"
bitcoin = { version = "0.28", optional = true }
bitcoin_hashes = "0.10"
byteorder = "1.3"
miniscript = "1.0.0"

elements = { version = "0.19", optional = true }
miniscript = "7.0"
2 changes: 1 addition & 1 deletion src/extension/bitcoin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ impl extension::Jet for BtcNode {
mac.write_u32(txenv.tx.lock_time);
}
BtcNode::Version => {
mac.write_u32(txenv.tx.version);
mac.write_u32(txenv.tx.version as u32);
}
ref b => unimplemented!("bitcoin {}", b),
}
Expand Down
94 changes: 39 additions & 55 deletions src/extension/elements/data_structures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,14 @@

use std::sync::Arc;

use super::jets::ElementsJetErr;
use crate::exec;
use crate::merkle::cmr::Cmr;
use bitcoin_hashes::{sha256, Hash, HashEngine};
use byteorder::{BigEndian, LittleEndian, WriteBytesExt};
use elements::confidential::{Asset, Nonce, Value};
use elements::{confidential, AssetIssuance};

use super::jets::ElementsJetErr;

/// Helper trait for writing various components of
/// Simplicity transactions (assets, values) into bit machine.
pub(in crate::extension::elements) trait SimplicityEncodable {
Expand All @@ -46,21 +45,17 @@ impl SimplicityEncodable for confidential::Asset {
fn simplicity_encode(self, mac: &mut exec::BitMachine) -> Result<(), ElementsJetErr> {
match self {
Asset::Null => return Err(ElementsJetErr::NullAssetEncoding),
Asset::Explicit(data) => {
Asset::Explicit(asset_id) => {
mac.write_bit(true);
mac.skip(1);
mac.write_bytes(&data);
mac.write_bytes(asset_id.into_inner().as_ref());
}
// consensus rules state that asset must be 0x0a or 0x0b
Asset::Confidential(prefix, comm) => {
if prefix != 0x0a || prefix != 0x0b {
unreachable!(
"No need to add an return error here. This will be fixed in elements 0.18"
)
}
Asset::Confidential(generator) => {
let bytes = generator.serialize();
mac.write_bit(false); //not explicit
mac.write_bit(prefix == 0x0b);
mac.write_bytes(&comm);
mac.write_bit(bytes[0] == 0x0b);
mac.write_bytes(&bytes[1..]);
}
}
Ok(())
Expand All @@ -82,14 +77,11 @@ impl SimplicityEncodable for confidential::Value {
mac.write_u64(data);
}
// consensus rules state that prefix value must be 0x08 or 0x09
Value::Confidential(prefix, comm) => {
if prefix != 0x08 || prefix != 0x09 {
panic!("This is fixed upstream in rust-elements 0.18. This panic would be removed later")
}
Value::Confidential(generator) => {
let bytes = generator.serialize();
mac.write_bit(false); //not explicit
mac.write_bit(prefix == 0x09);
debug_assert!(comm.len() == 32);
mac.write_bytes(&comm);
mac.write_bit(bytes[0] == 0x09);
mac.write_bytes(&bytes[1..]);
}
}
Ok(())
Expand All @@ -115,15 +107,12 @@ impl SimplicityEncodable for confidential::Nonce {
mac.write_bytes(&data);
}
// consensus rules state that prefix nocne must be 0x02 or 0x03
Nonce::Confidential(prefix, comm) => {
if prefix != 0x02 || prefix != 0x03 {
panic!("This is fixed upstream in rust-elements 0.18. This panic would be removed later")
}
Nonce::Confidential(generator) => {
let bytes = generator.serialize();
mac.write_bit(true); // not null
mac.write_bit(false); // not explicit
mac.write_bit(prefix == 0x03); // oddY
debug_assert!(comm.len() == 32);
mac.write_bytes(&comm);
mac.write_bit(bytes[0] == 0x03); // oddY
mac.write_bytes(&bytes[1..]);
}
}
Ok(())
Expand All @@ -144,14 +133,12 @@ impl SimplicityHash for confidential::Asset {
Asset::Null => {
eng.write_u8(0).unwrap();
}
Asset::Explicit(data) => {
Asset::Explicit(asset_id) => {
eng.write_u8(1).unwrap();
eng.input(&data);
eng.input(asset_id.into_inner().as_ref());
}
Asset::Confidential(prefix, data) => {
assert!(prefix == 0x0a || prefix == 0x0b);
eng.write_u8(prefix).unwrap();
eng.input(&data);
Asset::Confidential(generator) => {
eng.input(&generator.serialize());
}
}
}
Expand All @@ -167,10 +154,8 @@ impl SimplicityHash for confidential::Value {
eng.write_u8(1).unwrap();
eng.write_u64::<BigEndian>(data).unwrap();
}
Value::Confidential(prefix, data) => {
assert!(prefix == 0x08 || prefix == 0x09);
eng.write_u8(prefix).unwrap();
eng.input(&data);
Value::Confidential(comm) => {
eng.input(&comm.serialize());
}
}
}
Expand All @@ -186,16 +171,14 @@ impl SimplicityHash for confidential::Nonce {
eng.write_u8(1).unwrap();
eng.input(&data);
}
Nonce::Confidential(prefix, data) => {
assert!(prefix == 0x02 || prefix == 0x03);
eng.write_u8(prefix).unwrap();
eng.input(&data);
Nonce::Confidential(pubkey) => {
eng.input(&pubkey.serialize());
}
}
}
}

impl SimplicityHash for elements::bitcoin::Script {
impl SimplicityHash for elements::Script {
/// All scripts are first hashed to sha256 to get a scriptpubkey
/// equivalent and then added to current sha256 context.
fn simplicity_hash(&self, eng: &mut sha256::HashEngine) {
Expand All @@ -204,14 +187,14 @@ impl SimplicityHash for elements::bitcoin::Script {
}
}

// I think this should belong in rust-elements
// FIXME: I think this should belong in rust-elements
pub(super) fn is_asset_reissue(asset: &AssetIssuance) -> bool {
asset.asset_blinding_nonce != [0; 32]
asset.asset_blinding_nonce.as_ref() != &[0; 32]
}

// I think this should belong in rust-elements
// FIXME: I think this should belong in rust-elements
pub(super) fn is_asset_new_issue(asset: &AssetIssuance) -> bool {
asset.asset_blinding_nonce == [0; 32]
asset.asset_blinding_nonce.as_ref() == &[0; 32]
}

impl SimplicityHash for AssetIssuance {
Expand All @@ -220,17 +203,17 @@ impl SimplicityHash for AssetIssuance {
self.amount.simplicity_hash(eng);
self.inflation_keys.simplicity_hash(eng);
// asset blinding nonce here must be zero
eng.input(&self.asset_blinding_nonce);
eng.input(&self.asset_entropy);
eng.input(self.asset_blinding_nonce.as_ref());
eng.input(self.asset_entropy.as_ref());
} else {
debug_assert!(is_asset_reissue(self));
self.amount.simplicity_hash(eng);
// The inflation keys here must be zero
// Review this assertion
let null_amt = Value::Null;
null_amt.simplicity_hash(eng);
eng.input(&self.asset_blinding_nonce);
eng.input(&self.asset_entropy);
eng.input(self.asset_blinding_nonce.as_ref());
eng.input(self.asset_entropy.as_ref());
}
}
}
Expand Down Expand Up @@ -332,13 +315,14 @@ impl TxEnv {
tx.output.simplicity_hash(&mut output_eng);
let inputs_hash = sha256::Hash::from_engine(inp_eng);
let outputs_hash = sha256::Hash::from_engine(output_eng);

TxEnv {
tx: tx,
utxos: utxos,
ix: ix,
script_cmr: script_cmr,
inputs_hash: inputs_hash,
outputs_hash: outputs_hash,
tx,
utxos,
ix,
script_cmr,
inputs_hash,
outputs_hash,
}
}
}
45 changes: 24 additions & 21 deletions src/extension/elements/jets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -671,7 +671,7 @@ fn blinding_issuance(mac: &mut exec::BitMachine, issuance: &elements::AssetIssua
let is_reissue = is_asset_reissue(issuance);
mac.write_bit(is_reissue);
if is_reissue {
mac.write_bytes(&issuance.asset_blinding_nonce);
mac.write_bytes(issuance.asset_blinding_nonce.as_ref());
} else {
mac.skip(256);
}
Expand Down Expand Up @@ -763,10 +763,12 @@ mod tests {
};
use crate::merkle::cmr::Cmr;
use crate::merkle::common::MerkleRoot;
use bitcoin_hashes::sha256;
use elements::bitcoin::Script;
use bitcoin_hashes::sha256::Midstate;
use bitcoin_hashes::{sha256, Hash};
use elements::secp256k1_zkp::Tweak;
use elements::{
confidential, AssetIssuance, OutPoint, Transaction, TxIn, TxInWitness, TxOut, TxOutWitness,
confidential, AssetId, AssetIssuance, OutPoint, Transaction, TxIn, TxInWitness, TxOut,
TxOutWitness,
};

#[test]
Expand All @@ -780,6 +782,7 @@ mod tests {
assert_eq!(program.root_node().cmr.into_inner(), SIGHASH_ALL_CMR);
// TODO: check IMR
}

#[test]
#[ignore] // too expensive to run. Run with -- --ignored to run this
fn exec_sighash_all() {
Expand Down Expand Up @@ -824,32 +827,31 @@ mod tests {
0x33, 0x2f, 0xb7, 0x1d, 0xda, 0x90, 0xff, 0x4b, 0xef, 0x53, 0x70, 0xf2, 0x52, 0x26,
0xd3, 0xbc, 0x09, 0xfc,
];
use crate::bitcoin_hashes::Hash;
use bitcoin_hashes::sha256d;
let asset = confidential::Asset::Explicit(sha256d::Hash::from_inner(asset));

let asset = confidential::Asset::Explicit(AssetId::from_inner(Midstate::from_inner(asset)));
//create the txenv
let elements_tx = Transaction {
version: 2,
lock_time: 0,
input: vec![TxIn {
previous_output: OutPoint {
txid: elements::bitcoin::Txid::from_inner(tx_id),
txid: elements::Txid::from_inner(tx_id),
vout: 0,
},
sequence: 0xfffffffe,
is_pegin: false,
has_issuance: false,
// perhaps make this an option in elements upstream?
asset_issuance: AssetIssuance {
asset_blinding_nonce: [0; 32],
asset_blinding_nonce: Tweak::from_inner([0; 32]).expect("tweak from inner"),
asset_entropy: [0; 32],
amount: confidential::Value::Null,
inflation_keys: confidential::Value::Null,
},
script_sig: Script::new(),
script_sig: elements::Script::new(),
witness: TxInWitness {
amount_rangeproof: vec![],
inflation_keys_rangeproof: vec![],
amount_rangeproof: None,
inflation_keys_rangeproof: None,
script_witness: vec![],
pegin_witness: vec![],
},
Expand All @@ -863,25 +865,25 @@ mod tests {
&"1976a91448633e2c0ee9495dd3f9c43732c47f4702a362c888ac",
),
witness: TxOutWitness {
surjection_proof: vec![],
rangeproof: vec![],
surjection_proof: None,
rangeproof: None,
},
},
TxOut {
asset: asset.clone(),
value: confidential::Value::Explicit(0x0000000000000ce4),
nonce: confidential::Nonce::Null,
script_pubkey: Script::new(),
script_pubkey: elements::Script::new(),
witness: TxOutWitness {
surjection_proof: vec![],
rangeproof: vec![],
surjection_proof: None,
rangeproof: None,
},
},
],
};
let utxo = ElementsUtxo {
script_pubkey: sha256::Hash::from_inner([0; 32]),
asset: asset,
asset,
value: confidential::Value::Explicit(0x00000002540be400),
};

Expand All @@ -897,9 +899,10 @@ mod tests {
let mut mac = crate::exec::BitMachine::for_program(&program);
mac.exec(&program, &txenv).unwrap();
}

#[cfg(test)]
fn hex_script(s: &str) -> elements::bitcoin::Script {
let v: Vec<u8> = elements::bitcoin::hashes::hex::FromHex::from_hex(s).unwrap();
elements::bitcoin::Script::from(v)
fn hex_script(s: &str) -> elements::Script {
let v: Vec<u8> = bitcoin_hashes::hex::FromHex::from_hex(s).unwrap();
elements::Script::from(v)
}
}
Loading