mirror of
https://github.com/mimblewimble/grin.git
synced 2025-01-20 19:11:08 +03:00
Use updated bulletproof API (#1194)
This commit is contained in:
parent
dc827ebe93
commit
38a7936521
11 changed files with 43 additions and 266 deletions
6
Cargo.lock
generated
6
Cargo.lock
generated
|
@ -749,7 +749,7 @@ dependencies = [
|
|||
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"secp256k1zkp 0.7.1 (git+https://github.com/mimblewimble/rust-secp256k1-zkp?tag=grin_integration_19)",
|
||||
"secp256k1zkp 0.7.1 (git+https://github.com/mimblewimble/rust-secp256k1-zkp?branch=testnet3)",
|
||||
"serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"slog 2.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -1617,7 +1617,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
[[package]]
|
||||
name = "secp256k1zkp"
|
||||
version = "0.7.1"
|
||||
source = "git+https://github.com/mimblewimble/rust-secp256k1-zkp?tag=grin_integration_19#800e9b3ea4a8b2df7b999980ae78b224a6ad07ce"
|
||||
source = "git+https://github.com/mimblewimble/rust-secp256k1-zkp?branch=testnet3#748296c61341461e46e7b2c05db494d60f96ac44"
|
||||
dependencies = [
|
||||
"arrayvec 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -2429,7 +2429,7 @@ dependencies = [
|
|||
"checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637"
|
||||
"checksum scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28"
|
||||
"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
|
||||
"checksum secp256k1zkp 0.7.1 (git+https://github.com/mimblewimble/rust-secp256k1-zkp?tag=grin_integration_19)" = "<none>"
|
||||
"checksum secp256k1zkp 0.7.1 (git+https://github.com/mimblewimble/rust-secp256k1-zkp?branch=testnet3)" = "<none>"
|
||||
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
"checksum sequence_trie 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c915714ca833b1d4d6b8f6a9d72a3ff632fe45b40a8d184ef79c81bec6327eed"
|
||||
|
|
|
@ -917,114 +917,6 @@ impl Readable for OutputIdentifier {
|
|||
}
|
||||
}
|
||||
|
||||
/// A structure which contains fields that are to be committed to within
|
||||
/// an Output's range (bullet) proof.
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||
pub struct ProofMessageElements {
|
||||
/// The amount, stored to allow for wallet reconstruction as
|
||||
/// rewinding isn't supported in bulletproofs just yet
|
||||
/// This is going to be written 3 times, to facilitate checking
|
||||
/// values on rewind
|
||||
/// Note that rewinding with only the nonce will give you back
|
||||
/// the first 32 bytes of the message. To get the second
|
||||
/// 32 bytes, you need to provide the correct blinding factor as well
|
||||
value: u64,
|
||||
/// another copy of the value, to check on rewind
|
||||
value_copy_1: u64,
|
||||
/// another copy of the value
|
||||
value_copy_2: u64,
|
||||
/// the first 8 bytes of the blinding factor, used to avoid having to grind
|
||||
/// through a proof each time you want to check against key possibilities
|
||||
bf_first_8: Vec<u8>,
|
||||
/// unused portion of message, used to test whether we have both nonce
|
||||
/// and blinding correct
|
||||
zeroes: Vec<u8>,
|
||||
}
|
||||
|
||||
impl Writeable for ProofMessageElements {
|
||||
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ser::Error> {
|
||||
writer.write_u64(self.value)?;
|
||||
writer.write_u64(self.value_copy_1)?;
|
||||
writer.write_u64(self.value_copy_2)?;
|
||||
writer.write_fixed_bytes(&self.bf_first_8)?;
|
||||
for i in 0..32 {
|
||||
let _ = writer.write_u8(self.zeroes[i]);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Readable for ProofMessageElements {
|
||||
fn read(reader: &mut Reader) -> Result<ProofMessageElements, ser::Error> {
|
||||
// if the value isn't repeated 3 times, it's most likely not the value,
|
||||
// so reject
|
||||
Ok(ProofMessageElements {
|
||||
value: reader.read_u64()?,
|
||||
value_copy_1: reader.read_u64()?,
|
||||
value_copy_2: reader.read_u64()?,
|
||||
bf_first_8: reader.read_fixed_bytes(8)?,
|
||||
zeroes: reader.read_fixed_bytes(32)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ProofMessageElements {
|
||||
/// Create a new proof message
|
||||
pub fn new(value: u64, blinding: &keychain::Identifier) -> ProofMessageElements {
|
||||
ProofMessageElements {
|
||||
value: value,
|
||||
value_copy_1: value,
|
||||
value_copy_2: value,
|
||||
bf_first_8: blinding.to_bytes()[0..8].to_vec(),
|
||||
zeroes: [0u8; 32].to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the value if it's valid, an error otherwise
|
||||
pub fn value(&self) -> Result<u64, Error> {
|
||||
if self.value == self.value_copy_1 && self.value == self.value_copy_2 {
|
||||
Ok(self.value)
|
||||
} else {
|
||||
Err(Error::InvalidProofMessage)
|
||||
}
|
||||
}
|
||||
|
||||
/// Compare given identifier with first 8 bytes of what's stored
|
||||
pub fn compare_bf_first_8(&self, in_id: &keychain::Identifier) -> bool {
|
||||
let in_id_vec = in_id.to_bytes()[0..8].to_vec();
|
||||
for i in 0..8 {
|
||||
if in_id_vec[i] != self.bf_first_8[i] {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
/// Whether our remainder is zero (as it should be if the BF and nonce used
|
||||
/// to unwind are correct
|
||||
pub fn zeroes_correct(&self) -> bool {
|
||||
for i in 0..self.zeroes.len() {
|
||||
if self.zeroes[i] != 0 {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
/// Serialize and return a ProofMessage
|
||||
pub fn to_proof_message(&self) -> ProofMessage {
|
||||
ProofMessage::from_bytes(&ser_vec(self).unwrap())
|
||||
}
|
||||
|
||||
/// Deserialize and return the message elements
|
||||
pub fn from_proof_message(
|
||||
proof_message: &ProofMessage,
|
||||
) -> Result<ProofMessageElements, ser::Error> {
|
||||
let mut c = Cursor::new(proof_message.as_bytes());
|
||||
ser::deserialize::<ProofMessageElements>(&mut c)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
|
|
@ -233,7 +233,7 @@ fn empty_block_serialized_size() {
|
|||
let b = new_block(vec![], &keychain, &prev, &key_id);
|
||||
let mut vec = Vec::new();
|
||||
ser::serialize(&mut vec, &b).expect("serialization failed");
|
||||
let target_len = 1_265;
|
||||
let target_len = 1_266;
|
||||
assert_eq!(vec.len(), target_len,);
|
||||
}
|
||||
|
||||
|
@ -246,7 +246,7 @@ fn block_single_tx_serialized_size() {
|
|||
let b = new_block(vec![&tx1], &keychain, &prev, &key_id);
|
||||
let mut vec = Vec::new();
|
||||
ser::serialize(&mut vec, &b).expect("serialization failed");
|
||||
let target_len = 2_845;
|
||||
let target_len = 2_848;
|
||||
assert_eq!(vec.len(), target_len);
|
||||
}
|
||||
|
||||
|
@ -258,7 +258,7 @@ fn empty_compact_block_serialized_size() {
|
|||
let b = new_block(vec![], &keychain, &prev, &key_id);
|
||||
let mut vec = Vec::new();
|
||||
ser::serialize(&mut vec, &b.as_compact_block()).expect("serialization failed");
|
||||
let target_len = 1_273;
|
||||
let target_len = 1_274;
|
||||
assert_eq!(vec.len(), target_len,);
|
||||
}
|
||||
|
||||
|
@ -271,7 +271,7 @@ fn compact_block_single_tx_serialized_size() {
|
|||
let b = new_block(vec![&tx1], &keychain, &prev, &key_id);
|
||||
let mut vec = Vec::new();
|
||||
ser::serialize(&mut vec, &b.as_compact_block()).expect("serialization failed");
|
||||
let target_len = 1_279;
|
||||
let target_len = 1_280;
|
||||
assert_eq!(vec.len(), target_len,);
|
||||
}
|
||||
|
||||
|
@ -290,7 +290,7 @@ fn block_10_tx_serialized_size() {
|
|||
let b = new_block(txs.iter().collect(), &keychain, &prev, &key_id);
|
||||
let mut vec = Vec::new();
|
||||
ser::serialize(&mut vec, &b).expect("serialization failed");
|
||||
let target_len = 17_065;
|
||||
let target_len = 17_086;
|
||||
assert_eq!(vec.len(), target_len,);
|
||||
}
|
||||
|
||||
|
@ -308,7 +308,7 @@ fn compact_block_10_tx_serialized_size() {
|
|||
let b = new_block(txs.iter().collect(), &keychain, &prev, &key_id);
|
||||
let mut vec = Vec::new();
|
||||
ser::serialize(&mut vec, &b.as_compact_block()).expect("serialization failed");
|
||||
let target_len = 1_333;
|
||||
let target_len = 1_334;
|
||||
assert_eq!(vec.len(), target_len,);
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ fn simple_tx_ser() {
|
|||
let tx = tx2i1o();
|
||||
let mut vec = Vec::new();
|
||||
ser::serialize(&mut vec, &tx).expect("serialization failed");
|
||||
let target_len = 954;
|
||||
let target_len = 955;
|
||||
assert_eq!(vec.len(), target_len,);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@ pub mod common;
|
|||
use grin_core::core::{Output, OutputFeatures};
|
||||
use grin_core::ser;
|
||||
use keychain::{ExtKeychain, Keychain};
|
||||
use util::secp;
|
||||
use wallet::libtx::proof;
|
||||
|
||||
#[test]
|
||||
|
@ -31,8 +30,7 @@ fn test_output_ser_deser() {
|
|||
let keychain = ExtKeychain::from_random_seed().unwrap();
|
||||
let key_id = keychain.derive_key_id(1).unwrap();
|
||||
let commit = keychain.commit(5, &key_id).unwrap();
|
||||
let msg = secp::pedersen::ProofMessage::empty();
|
||||
let proof = proof::create(&keychain, 5, &key_id, commit, None, msg).unwrap();
|
||||
let proof = proof::create(&keychain, 5, &key_id, commit, None).unwrap();
|
||||
|
||||
let out = Output {
|
||||
features: OutputFeatures::DEFAULT_OUTPUT,
|
||||
|
|
|
@ -20,6 +20,6 @@ zip = "0.4"
|
|||
|
||||
[dependencies.secp256k1zkp]
|
||||
git = "https://github.com/mimblewimble/rust-secp256k1-zkp"
|
||||
tag = "grin_integration_19"
|
||||
branch = "testnet3"
|
||||
#path = "../../rust-secp256k1-zkp"
|
||||
features = ["bullet-proof-sizing"]
|
||||
|
|
|
@ -29,7 +29,7 @@ use util::{kernel_sig_msg, secp};
|
|||
|
||||
use core::core::hash::Hash;
|
||||
use core::core::merkle_proof::MerkleProof;
|
||||
use core::core::{Input, Output, OutputFeatures, ProofMessageElements, Transaction, TxKernel};
|
||||
use core::core::{Input, Output, OutputFeatures, Transaction, TxKernel};
|
||||
use keychain::{self, BlindSum, BlindingFactor, Identifier, Keychain};
|
||||
use libtx::{aggsig, proof};
|
||||
use util::LOGGER;
|
||||
|
@ -118,15 +118,12 @@ where
|
|||
let commit = build.keychain.commit(value, &key_id).unwrap();
|
||||
trace!(LOGGER, "Builder - Pedersen Commit is: {:?}", commit,);
|
||||
|
||||
let msg = ProofMessageElements::new(value, &key_id);
|
||||
|
||||
let rproof = proof::create(
|
||||
build.keychain,
|
||||
value,
|
||||
&key_id,
|
||||
commit,
|
||||
None,
|
||||
msg.to_proof_message(),
|
||||
).unwrap();
|
||||
|
||||
(
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
use blake2;
|
||||
use keychain::{Identifier, Keychain};
|
||||
use libtx::error::{Error, ErrorKind};
|
||||
use util::logger::LOGGER;
|
||||
use util::secp::key::SecretKey;
|
||||
use util::secp::pedersen::{Commitment, ProofInfo, ProofMessage, RangeProof};
|
||||
use util::secp::{self, Secp256k1};
|
||||
|
@ -42,16 +41,13 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// So we want this to take an opaque structure that can be called
|
||||
/// back to get the sensitive data
|
||||
|
||||
/// Create a bulletproof
|
||||
pub fn create<K>(
|
||||
k: &K,
|
||||
amount: u64,
|
||||
key_id: &Identifier,
|
||||
_commit: Commitment,
|
||||
extra_data: Option<Vec<u8>>,
|
||||
msg: ProofMessage,
|
||||
) -> Result<RangeProof, Error>
|
||||
where
|
||||
K: Keychain,
|
||||
|
@ -59,18 +55,7 @@ where
|
|||
let commit = k.commit(amount, key_id)?;
|
||||
let skey = k.derived_key(key_id)?;
|
||||
let nonce = create_nonce(k, &commit)?;
|
||||
if msg.len() == 0 {
|
||||
return Ok(k.secp().bullet_proof(amount, skey, nonce, extra_data, None));
|
||||
} else {
|
||||
if msg.len() != 64 {
|
||||
error!(LOGGER, "Bullet proof message must be 64 bytes.");
|
||||
return Err(ErrorKind::RangeProof(
|
||||
"Bullet proof message must be 64 bytes".to_string(),
|
||||
))?;
|
||||
}
|
||||
}
|
||||
return Ok(k.secp()
|
||||
.bullet_proof(amount, skey, nonce, extra_data, Some(msg)));
|
||||
Ok(k.secp().bullet_proof(amount, skey, nonce, extra_data))
|
||||
}
|
||||
|
||||
/// Verify a proof
|
||||
|
@ -90,7 +75,6 @@ pub fn verify(
|
|||
/// Rewind a rangeproof to retrieve the amount
|
||||
pub fn rewind<K>(
|
||||
k: &K,
|
||||
key_id: &Identifier,
|
||||
commit: Commitment,
|
||||
extra_data: Option<Vec<u8>>,
|
||||
proof: RangeProof,
|
||||
|
@ -98,25 +82,16 @@ pub fn rewind<K>(
|
|||
where
|
||||
K: Keychain,
|
||||
{
|
||||
let skey = k.derived_key(key_id)?;
|
||||
let nonce = create_nonce(k, &commit)?;
|
||||
let proof_message = k.secp()
|
||||
.unwind_bullet_proof(commit, skey, nonce, extra_data, proof);
|
||||
.rewind_bullet_proof(commit, nonce, extra_data, proof);
|
||||
let proof_info = match proof_message {
|
||||
Ok(p) => ProofInfo {
|
||||
success: true,
|
||||
value: 0,
|
||||
message: p,
|
||||
mlen: 0,
|
||||
min: 0,
|
||||
max: 0,
|
||||
exp: 0,
|
||||
mantissa: 0,
|
||||
},
|
||||
Ok(p) => p,
|
||||
Err(_) => ProofInfo {
|
||||
success: false,
|
||||
value: 0,
|
||||
message: ProofMessage::empty(),
|
||||
blinding: SecretKey([0; secp::constants::SECRET_KEY_SIZE]),
|
||||
mlen: 0,
|
||||
min: 0,
|
||||
max: 0,
|
||||
|
|
|
@ -18,7 +18,7 @@ use keychain::{Identifier, Keychain};
|
|||
|
||||
use core::consensus::reward;
|
||||
use core::core::KernelFeatures;
|
||||
use core::core::{Output, OutputFeatures, ProofMessageElements, TxKernel};
|
||||
use core::core::{Output, OutputFeatures, TxKernel};
|
||||
use libtx::error::Error;
|
||||
use libtx::{aggsig, proof};
|
||||
use util::{kernel_sig_msg, secp, static_secp_instance, LOGGER};
|
||||
|
@ -35,7 +35,6 @@ where
|
|||
{
|
||||
let value = reward(fees);
|
||||
let commit = keychain.commit(value, key_id)?;
|
||||
let msg = ProofMessageElements::new(value, key_id);
|
||||
|
||||
trace!(LOGGER, "Block reward - Pedersen Commit is: {:?}", commit,);
|
||||
|
||||
|
@ -45,7 +44,6 @@ where
|
|||
key_id,
|
||||
commit,
|
||||
None,
|
||||
msg.to_proof_message(),
|
||||
)?;
|
||||
|
||||
let output = Output {
|
||||
|
|
|
@ -16,10 +16,9 @@
|
|||
/// TODO: Remove api
|
||||
use api;
|
||||
use byteorder::{BigEndian, ByteOrder};
|
||||
use core::core::transaction::ProofMessageElements;
|
||||
use core::global;
|
||||
use error::{Error, ErrorKind};
|
||||
use failure::{Fail, ResultExt};
|
||||
use failure::Fail;
|
||||
use keychain::{Identifier, Keychain};
|
||||
use libtx::proof;
|
||||
use libwallet::types::*;
|
||||
|
@ -77,8 +76,7 @@ where
|
|||
// TODO - wrap the many return values in a struct
|
||||
fn find_outputs_with_key<T, K>(
|
||||
wallet: &mut T,
|
||||
outputs: Vec<api::OutputPrintable>,
|
||||
found_key_index: &mut Vec<u32>,
|
||||
outputs: Vec<api::OutputPrintable>
|
||||
) -> Vec<(
|
||||
pedersen::Commitment,
|
||||
Identifier,
|
||||
|
@ -109,76 +107,41 @@ where
|
|||
info!(LOGGER, "Scanning {} outputs", outputs.len(),);
|
||||
let current_chain_height = wallet.get_chain_height(wallet.node_url()).unwrap();
|
||||
|
||||
// skey doesn't matter in this case
|
||||
let skey = wallet.keychain().derive_key_id(1).unwrap();
|
||||
for output in outputs.iter().filter(|x| !x.spent) {
|
||||
// attempt to unwind message from the RP and get a value.. note
|
||||
// this will only return okay if the value is included in the
|
||||
// message 3 times, indicating a strong match. Also, sec_key provided
|
||||
// to unwind in this case will be meaningless. With only the nonce known
|
||||
// only the first 32 bytes of the recovered message will be accurate
|
||||
// attempt to unwind message from the RP and get a value
|
||||
// will fail if it's not ours
|
||||
let info = proof::rewind(
|
||||
wallet.keychain(),
|
||||
&skey,
|
||||
output.commit,
|
||||
None,
|
||||
output.range_proof().unwrap(),
|
||||
).unwrap();
|
||||
let message = ProofMessageElements::from_proof_message(&info.message).unwrap();
|
||||
let value = message.value();
|
||||
if value.is_err() {
|
||||
|
||||
if !info.success {
|
||||
continue;
|
||||
}
|
||||
// we have a match, now check through our key iterations to find a partial match
|
||||
let mut found = false;
|
||||
|
||||
// we have a match, now check through our key iterations to find out which one it was
|
||||
let mut found = false;
|
||||
let mut start_index = 1;
|
||||
|
||||
// TODO: This assumption only holds with current wallet software assuming
|
||||
// wallet doesn't go back and re-use gaps in its key index, ie. every
|
||||
// new key index produced is always greater than the previous max key index
|
||||
if let Some(m) = found_key_index.iter().max() {
|
||||
start_index = *m as usize + 1;
|
||||
}
|
||||
|
||||
for i in start_index..max_derivations {
|
||||
// much faster than calling EC functions for each found key
|
||||
// Shouldn't be needed if assumption about wallet key 'gaps' above
|
||||
// holds.. otherwise this is a good optimization.. perhaps
|
||||
// provide a command line switch
|
||||
/*if found_key_index.contains(&(i as u32)) {
|
||||
continue;
|
||||
}*/
|
||||
let key_id = &wallet.keychain().derive_key_id(i as u32).unwrap();
|
||||
if !message.compare_bf_first_8(key_id) {
|
||||
let b = wallet.keychain().derived_key(key_id).unwrap();
|
||||
if info.blinding != b {
|
||||
continue;
|
||||
}
|
||||
found = true;
|
||||
// we have a partial match, let's just confirm
|
||||
let info = proof::rewind(
|
||||
wallet.keychain(),
|
||||
key_id,
|
||||
output.commit,
|
||||
None,
|
||||
output.range_proof().unwrap(),
|
||||
).unwrap();
|
||||
let message = ProofMessageElements::from_proof_message(&info.message).unwrap();
|
||||
let value = message.value();
|
||||
if value.is_err() || !message.zeroes_correct() {
|
||||
continue;
|
||||
}
|
||||
let value = value.unwrap();
|
||||
info!(
|
||||
LOGGER,
|
||||
"Output found: {:?}, key_index: {:?}", output.commit, i,
|
||||
);
|
||||
found_key_index.push(i as u32);
|
||||
// add it to result set here
|
||||
let commit_id = output.commit.0;
|
||||
|
||||
let is_coinbase = coinbase_status(output);
|
||||
|
||||
info!(LOGGER, "Amount: {}", value);
|
||||
info!(LOGGER, "Amount: {}", info.value);
|
||||
|
||||
let commit = wallet
|
||||
.keychain()
|
||||
|
@ -204,7 +167,7 @@ where
|
|||
commit,
|
||||
key_id.clone(),
|
||||
i as u32,
|
||||
value,
|
||||
info.value,
|
||||
height,
|
||||
lock_height,
|
||||
is_coinbase,
|
||||
|
@ -218,7 +181,7 @@ where
|
|||
LOGGER,
|
||||
"Very probable matching output found with amount: {} \
|
||||
but didn't match key child key up to {}",
|
||||
message.value().unwrap(),
|
||||
info.value,
|
||||
max_derivations,
|
||||
);
|
||||
}
|
||||
|
@ -248,9 +211,6 @@ where
|
|||
|
||||
let batch_size = 1000;
|
||||
let mut start_index = 1;
|
||||
// Keep a set of keys we've already claimed (cause it's far faster than
|
||||
// deriving a key for each one)
|
||||
let mut found_key_index: Vec<u32> = vec![];
|
||||
// this will start here, then lower as outputs are found, moving backwards on
|
||||
// the chain
|
||||
loop {
|
||||
|
@ -265,10 +225,10 @@ where
|
|||
|
||||
let root_key_id = wallet.keychain().root_key_id();
|
||||
let result_vec =
|
||||
find_outputs_with_key(wallet, output_listing.outputs.clone(), &mut found_key_index);
|
||||
find_outputs_with_key(wallet, output_listing.outputs.clone());
|
||||
let mut batch = wallet.batch()?;
|
||||
for output in result_vec {
|
||||
batch.save(OutputData {
|
||||
let _ = batch.save(OutputData {
|
||||
root_key_id: root_key_id.clone(),
|
||||
key_id: output.1.clone(),
|
||||
n_child: output.2,
|
||||
|
|
|
@ -22,7 +22,6 @@ extern crate uuid;
|
|||
|
||||
use keychain::{BlindSum, BlindingFactor, ExtKeychain, Keychain};
|
||||
use util::secp::key::{PublicKey, SecretKey};
|
||||
use util::secp::pedersen::ProofMessage;
|
||||
use util::{kernel_sig_msg, secp};
|
||||
use wallet::libtx::{aggsig, proof};
|
||||
use wallet::libwallet::internal::sigcontext;
|
||||
|
@ -408,8 +407,8 @@ fn aggsig_sender_receiver_interaction_offset() {
|
|||
fn test_rewind_range_proof() {
|
||||
let keychain = ExtKeychain::from_random_seed().unwrap();
|
||||
let key_id = keychain.derive_key_id(1).unwrap();
|
||||
let key_id2 = keychain.derive_key_id(2).unwrap();
|
||||
let commit = keychain.commit(5, &key_id).unwrap();
|
||||
let msg = ProofMessage::from_bytes(&[0u8; 64]);
|
||||
let extra_data = [99u8; 64];
|
||||
|
||||
let proof = proof::create(
|
||||
|
@ -418,65 +417,24 @@ fn test_rewind_range_proof() {
|
|||
&key_id,
|
||||
commit,
|
||||
Some(extra_data.to_vec().clone()),
|
||||
msg,
|
||||
).unwrap();
|
||||
let proof_info = proof::rewind(
|
||||
&keychain,
|
||||
&key_id,
|
||||
commit,
|
||||
Some(extra_data.to_vec().clone()),
|
||||
proof,
|
||||
).unwrap();
|
||||
let proof_info =
|
||||
proof::rewind(&keychain, commit, Some(extra_data.to_vec().clone()), proof).unwrap();
|
||||
|
||||
assert_eq!(proof_info.success, true);
|
||||
assert_eq!(proof_info.value, 5);
|
||||
|
||||
// now check the recovered message is "empty" (but not truncated) i.e. all
|
||||
// zeroes
|
||||
//Value is in the message in this case
|
||||
assert_eq!(
|
||||
proof_info.message,
|
||||
secp::pedersen::ProofMessage::from_bytes(&[0; secp::constants::BULLET_PROOF_MSG_SIZE])
|
||||
);
|
||||
|
||||
let key_id2 = keychain.derive_key_id(2).unwrap();
|
||||
|
||||
// cannot rewind with a different nonce
|
||||
let proof_info = proof::rewind(
|
||||
&keychain,
|
||||
&key_id2,
|
||||
commit,
|
||||
Some(extra_data.to_vec().clone()),
|
||||
proof,
|
||||
).unwrap();
|
||||
// With bullet proofs, if you provide the wrong nonce you'll get gibberish back
|
||||
// as opposed to a failure to recover the message
|
||||
assert_ne!(
|
||||
proof_info.message,
|
||||
secp::pedersen::ProofMessage::from_bytes(&[0; secp::constants::BULLET_PROOF_MSG_SIZE])
|
||||
);
|
||||
assert_eq!(proof_info.value, 0);
|
||||
|
||||
// cannot rewind with a commitment to the same value using a different key
|
||||
// cannot rewind with a different commit
|
||||
let commit2 = keychain.commit(5, &key_id2).unwrap();
|
||||
let proof_info = proof::rewind(
|
||||
&keychain,
|
||||
&key_id,
|
||||
commit2,
|
||||
Some(extra_data.to_vec().clone()),
|
||||
proof,
|
||||
).unwrap();
|
||||
let proof_info =
|
||||
proof::rewind(&keychain, commit2, Some(extra_data.to_vec().clone()), proof).unwrap();
|
||||
assert_eq!(proof_info.success, false);
|
||||
assert_eq!(proof_info.value, 0);
|
||||
|
||||
// cannot rewind with a commitment to a different value
|
||||
let commit3 = keychain.commit(4, &key_id).unwrap();
|
||||
let proof_info = proof::rewind(
|
||||
&keychain,
|
||||
&key_id,
|
||||
commit3,
|
||||
Some(extra_data.to_vec().clone()),
|
||||
proof,
|
||||
).unwrap();
|
||||
let proof_info =
|
||||
proof::rewind(&keychain, commit3, Some(extra_data.to_vec().clone()), proof).unwrap();
|
||||
assert_eq!(proof_info.success, false);
|
||||
assert_eq!(proof_info.value, 0);
|
||||
|
||||
|
@ -485,7 +443,6 @@ fn test_rewind_range_proof() {
|
|||
let wrong_extra_data = [98u8; 64];
|
||||
let _should_err = proof::rewind(
|
||||
&keychain,
|
||||
&key_id,
|
||||
commit3,
|
||||
Some(wrong_extra_data.to_vec().clone()),
|
||||
proof,
|
||||
|
|
Loading…
Reference in a new issue