Skip to content

Commit

Permalink
Support new Bulletproof rewind scheme (#2848)
Browse files Browse the repository at this point in the history
* Update keychain with new rewind scheme

* Refactor: proof builder trait

* Update tests, cleanup

* rustfmt

* Move conversion of SwitchCommitmentType

* Add proof build trait to tx builders

* Cache hashes in proof builders

* Proof builder tests

* Add ViewKey struct

* Fix some warnings

* Zeroize proof builder secrets on drop
  • Loading branch information
jaspervdm authored and yeastplume committed Jun 12, 2019
1 parent 6429580 commit e3f3064
Show file tree
Hide file tree
Showing 30 changed files with 1,399 additions and 208 deletions.
10 changes: 6 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 10 additions & 2 deletions chain/tests/data_file_integrity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,14 @@ fn data_files() {
let prev = chain.head_header().unwrap();
let next_header_info = consensus::next_difficulty(1, chain.difficulty_iter().unwrap());
let pk = ExtKeychainPath::new(1, n as u32, 0, 0, 0).to_identifier();
let reward = libtx::reward::output(&keychain, &pk, 0, false).unwrap();
let reward = libtx::reward::output(
&keychain,
&libtx::ProofBuilder::new(&keychain),
&pk,
0,
false,
)
.unwrap();
let mut b =
core::core::Block::new(&prev, vec![], next_header_info.clone().difficulty, reward)
.unwrap();
Expand Down Expand Up @@ -154,7 +161,8 @@ fn _prepare_block_nosum(
let key_id = ExtKeychainPath::new(1, diff as u32, 0, 0, 0).to_identifier();

let fees = txs.iter().map(|tx| tx.fee()).sum();
let reward = libtx::reward::output(kc, &key_id, fees, false).unwrap();
let reward =
libtx::reward::output(kc, &libtx::ProofBuilder::new(kc), &key_id, fees, false).unwrap();
let mut b = match core::core::Block::new(
prev,
txs.into_iter().cloned().collect(),
Expand Down
30 changes: 25 additions & 5 deletions chain/tests/mine_simple_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use self::core::core::verifier_cache::LruVerifierCache;
use self::core::core::{Block, BlockHeader, OutputIdentifier, Transaction};
use self::core::genesis;
use self::core::global::ChainTypes;
use self::core::libtx::{self, build, reward};
use self::core::libtx::{self, build, reward, ProofBuilder};
use self::core::pow::Difficulty;
use self::core::{consensus, global, pow};
use self::keychain::{ExtKeychain, ExtKeychainPath, Keychain};
Expand Down Expand Up @@ -106,7 +106,14 @@ fn mine_genesis_reward_chain() {
let mut genesis = genesis::genesis_dev();
let keychain = keychain::ExtKeychain::from_random_seed(false).unwrap();
let key_id = keychain::ExtKeychain::derive_key_id(0, 1, 0, 0, 0);
let reward = reward::output(&keychain, &key_id, 0, false).unwrap();
let reward = reward::output(
&keychain,
&libtx::ProofBuilder::new(&keychain),
&key_id,
0,
false,
)
.unwrap();
genesis = genesis.with_reward(reward.0, reward.1);

let tmp_chain_dir = ".grin.tmp";
Expand Down Expand Up @@ -143,7 +150,9 @@ where
let prev = chain.head_header().unwrap();
let next_header_info = consensus::next_difficulty(1, chain.difficulty_iter().unwrap());
let pk = ExtKeychainPath::new(1, n as u32, 0, 0, 0).to_identifier();
let reward = libtx::reward::output(keychain, &pk, 0, false).unwrap();
let reward =
libtx::reward::output(keychain, &libtx::ProofBuilder::new(keychain), &pk, 0, false)
.unwrap();
let mut b =
core::core::Block::new(&prev, vec![], next_header_info.clone().difficulty, reward)
.unwrap();
Expand Down Expand Up @@ -401,6 +410,7 @@ fn spend_in_fork_and_compact() {
let chain = setup(".grin6", pow::mine_genesis_block().unwrap());
let prev = chain.head_header().unwrap();
let kc = ExtKeychain::from_random_seed(false).unwrap();
let pb = ProofBuilder::new(&kc);

let mut fork_head = prev;

Expand Down Expand Up @@ -434,6 +444,7 @@ fn spend_in_fork_and_compact() {
build::with_fee(20000),
],
&kc,
&pb,
)
.unwrap();

Expand All @@ -451,6 +462,7 @@ fn spend_in_fork_and_compact() {
build::with_fee(20000),
],
&kc,
&pb,
)
.unwrap();

Expand Down Expand Up @@ -540,7 +552,14 @@ fn output_header_mappings() {
let prev = chain.head_header().unwrap();
let next_header_info = consensus::next_difficulty(1, chain.difficulty_iter().unwrap());
let pk = ExtKeychainPath::new(1, n as u32, 0, 0, 0).to_identifier();
let reward = libtx::reward::output(&keychain, &pk, 0, false).unwrap();
let reward = libtx::reward::output(
&keychain,
&libtx::ProofBuilder::new(&keychain),
&pk,
0,
false,
)
.unwrap();
reward_outputs.push(reward.0.clone());
let mut b =
core::core::Block::new(&prev, vec![], next_header_info.clone().difficulty, reward)
Expand Down Expand Up @@ -643,7 +662,8 @@ where
let key_id = ExtKeychainPath::new(1, diff as u32, 0, 0, 0).to_identifier();

let fees = txs.iter().map(|tx| tx.fee()).sum();
let reward = libtx::reward::output(kc, &key_id, fees, false).unwrap();
let reward =
libtx::reward::output(kc, &libtx::ProofBuilder::new(kc), &key_id, fees, false).unwrap();
let mut b = match core::core::Block::new(
prev,
txs.into_iter().cloned().collect(),
Expand Down
9 changes: 8 additions & 1 deletion chain/tests/store_indices.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,14 @@ fn test_various_store_indices() {

setup_chain(&genesis, chain_store.clone()).unwrap();

let reward = libtx::reward::output(&keychain, &key_id, 0, false).unwrap();
let reward = libtx::reward::output(
&keychain,
&libtx::ProofBuilder::new(&keychain),
&key_id,
0,
false,
)
.unwrap();
let block = Block::new(&genesis.header, vec![], Difficulty::min(), reward).unwrap();
let block_hash = block.hash();

Expand Down
19 changes: 12 additions & 7 deletions chain/tests/test_coinbase_maturity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use self::chain::types::NoopAdapter;
use self::chain::ErrorKind;
use self::core::core::verifier_cache::LruVerifierCache;
use self::core::global::{self, ChainTypes};
use self::core::libtx::{self, build};
use self::core::libtx::{self, build, ProofBuilder};
use self::core::pow::Difficulty;
use self::core::{consensus, pow};
use self::keychain::{ExtKeychain, ExtKeychainPath, Keychain};
Expand Down Expand Up @@ -59,13 +59,14 @@ fn test_coinbase_maturity() {
let prev = chain.head_header().unwrap();

let keychain = ExtKeychain::from_random_seed(false).unwrap();
let builder = ProofBuilder::new(&keychain);
let key_id1 = ExtKeychainPath::new(1, 1, 0, 0, 0).to_identifier();
let key_id2 = ExtKeychainPath::new(1, 2, 0, 0, 0).to_identifier();
let key_id3 = ExtKeychainPath::new(1, 3, 0, 0, 0).to_identifier();
let key_id4 = ExtKeychainPath::new(1, 4, 0, 0, 0).to_identifier();

let next_header_info = consensus::next_difficulty(1, chain.difficulty_iter().unwrap());
let reward = libtx::reward::output(&keychain, &key_id1, 0, false).unwrap();
let reward = libtx::reward::output(&keychain, &builder, &key_id1, 0, false).unwrap();
let mut block = core::core::Block::new(&prev, vec![], Difficulty::min(), reward).unwrap();
block.header.timestamp = prev.timestamp + Duration::seconds(60);
block.header.pow.secondary_scaling = next_header_info.secondary_scaling;
Expand Down Expand Up @@ -104,12 +105,13 @@ fn test_coinbase_maturity() {
build::with_fee(2),
],
&keychain,
&builder,
)
.unwrap();

let txs = vec![coinbase_txn.clone()];
let fees = txs.iter().map(|tx| tx.fee()).sum();
let reward = libtx::reward::output(&keychain, &key_id3, fees, false).unwrap();
let reward = libtx::reward::output(&keychain, &builder, &key_id3, fees, false).unwrap();
let mut block = core::core::Block::new(&prev, txs, Difficulty::min(), reward).unwrap();
let next_header_info = consensus::next_difficulty(1, chain.difficulty_iter().unwrap());
block.header.timestamp = prev.timestamp + Duration::seconds(60);
Expand Down Expand Up @@ -141,10 +143,11 @@ fn test_coinbase_maturity() {
let prev = chain.head_header().unwrap();

let keychain = ExtKeychain::from_random_seed(false).unwrap();
let builder = ProofBuilder::new(&keychain);
let key_id1 = ExtKeychainPath::new(1, 1, 0, 0, 0).to_identifier();

let next_header_info = consensus::next_difficulty(1, chain.difficulty_iter().unwrap());
let reward = libtx::reward::output(&keychain, &key_id1, 0, false).unwrap();
let reward = libtx::reward::output(&keychain, &builder, &key_id1, 0, false).unwrap();
let mut block =
core::core::Block::new(&prev, vec![], Difficulty::min(), reward).unwrap();

Expand Down Expand Up @@ -185,12 +188,13 @@ fn test_coinbase_maturity() {
build::with_fee(2),
],
&keychain,
&builder,
)
.unwrap();

let txs = vec![coinbase_txn.clone()];
let fees = txs.iter().map(|tx| tx.fee()).sum();
let reward = libtx::reward::output(&keychain, &key_id3, fees, false).unwrap();
let reward = libtx::reward::output(&keychain, &builder, &key_id3, fees, false).unwrap();
let mut block = core::core::Block::new(&prev, txs, Difficulty::min(), reward).unwrap();
let next_header_info = consensus::next_difficulty(1, chain.difficulty_iter().unwrap());
block.header.timestamp = prev.timestamp + Duration::seconds(60);
Expand Down Expand Up @@ -222,9 +226,10 @@ fn test_coinbase_maturity() {
let prev = chain.head_header().unwrap();

let keychain = ExtKeychain::from_random_seed(false).unwrap();
let builder = ProofBuilder::new(&keychain);
let pk = ExtKeychainPath::new(1, 1, 0, 0, 0).to_identifier();

let reward = libtx::reward::output(&keychain, &pk, 0, false).unwrap();
let reward = libtx::reward::output(&keychain, &builder, &pk, 0, false).unwrap();
let mut block =
core::core::Block::new(&prev, vec![], Difficulty::min(), reward).unwrap();
let next_header_info =
Expand Down Expand Up @@ -254,7 +259,7 @@ fn test_coinbase_maturity() {
let txs = vec![coinbase_txn];
let fees = txs.iter().map(|tx| tx.fee()).sum();
let next_header_info = consensus::next_difficulty(1, chain.difficulty_iter().unwrap());
let reward = libtx::reward::output(&keychain, &key_id4, fees, false).unwrap();
let reward = libtx::reward::output(&keychain, &builder, &key_id4, fees, false).unwrap();
let mut block = core::core::Block::new(&prev, txs, Difficulty::min(), reward).unwrap();

block.header.timestamp = prev.timestamp + Duration::seconds(60);
Expand Down
1 change: 1 addition & 0 deletions core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ siphasher = "0.2"
uuid = { version = "0.6", features = ["serde", "v4"] }
log = "0.4"
chrono = { version = "0.4.4", features = ["serde"] }
zeroize = "0.8"

grin_keychain = { path = "../keychain", version = "2.0.0-beta.1" }
grin_util = { path = "../util", version = "2.0.0-beta.1" }
Expand Down
18 changes: 13 additions & 5 deletions core/src/core/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1499,14 +1499,16 @@ mod test {
use super::*;
use crate::core::hash::Hash;
use crate::core::id::{ShortId, ShortIdentifiable};
use crate::keychain::{ExtKeychain, Keychain};
use crate::keychain::{ExtKeychain, Keychain, SwitchCommitmentType};
use crate::util::secp;

#[test]
fn test_kernel_ser_deser() {
let keychain = ExtKeychain::from_random_seed(false).unwrap();
let key_id = ExtKeychain::derive_key_id(1, 1, 0, 0, 0);
let commit = keychain.commit(5, &key_id).unwrap();
let commit = keychain
.commit(5, &key_id, &SwitchCommitmentType::Regular)
.unwrap();

// just some bytes for testing ser/deser
let sig = secp::Signature::from_raw_data(&[0; 64]).unwrap();
Expand Down Expand Up @@ -1552,10 +1554,14 @@ mod test {
let keychain = ExtKeychain::from_seed(&[0; 32], false).unwrap();
let key_id = ExtKeychain::derive_key_id(1, 1, 0, 0, 0);

let commit = keychain.commit(1003, &key_id).unwrap();
let commit = keychain
.commit(1003, &key_id, &SwitchCommitmentType::Regular)
.unwrap();
let key_id = ExtKeychain::derive_key_id(1, 1, 0, 0, 0);

let commit_2 = keychain.commit(1003, &key_id).unwrap();
let commit_2 = keychain
.commit(1003, &key_id, &SwitchCommitmentType::Regular)
.unwrap();

assert!(commit == commit_2);
}
Expand All @@ -1564,7 +1570,9 @@ mod test {
fn input_short_id() {
let keychain = ExtKeychain::from_seed(&[0; 32], false).unwrap();
let key_id = ExtKeychain::derive_key_id(1, 1, 0, 0, 0);
let commit = keychain.commit(5, &key_id).unwrap();
let commit = keychain
.commit(5, &key_id, &SwitchCommitmentType::Regular)
.unwrap();

let input = Input {
features: OutputFeatures::Plain,
Expand Down
1 change: 1 addition & 0 deletions core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ extern crate log;
use failure;
#[macro_use]
extern crate failure_derive;
extern crate zeroize;
#[macro_use]
pub mod macros;

Expand Down
19 changes: 12 additions & 7 deletions core/src/libtx/aggsig.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use crate::libtx::error::{Error, ErrorKind};
use crate::util::secp::key::{PublicKey, SecretKey};
use crate::util::secp::pedersen::Commitment;
use crate::util::secp::{self, aggsig, Message, Secp256k1, Signature};
use grin_keychain::SwitchCommitmentType;

/// Creates a new secure nonce (as a SecretKey), guaranteed to be usable during
/// aggsig creation.
Expand Down Expand Up @@ -231,15 +232,17 @@ pub fn verify_partial_sig(
/// use core::libtx::{aggsig, proof};
/// use core::core::transaction::{kernel_sig_msg, KernelFeatures};
/// use core::core::{Output, OutputFeatures};
/// use keychain::{Keychain, ExtKeychain};
/// use keychain::{Keychain, ExtKeychain, SwitchCommitmentType};
///
/// let secp = Secp256k1::with_caps(ContextFlag::Commit);
/// let keychain = ExtKeychain::from_random_seed(false).unwrap();
/// let fees = 10_000;
/// let value = reward(fees);
/// let key_id = ExtKeychain::derive_key_id(1, 1, 0, 0, 0);
/// let commit = keychain.commit(value, &key_id).unwrap();
/// let rproof = proof::create(&keychain, value, &key_id, commit, None).unwrap();
/// let switch = &SwitchCommitmentType::Regular;
/// let commit = keychain.commit(value, &key_id, switch).unwrap();
/// let builder = proof::ProofBuilder::new(&keychain);
/// let rproof = proof::create(&keychain, &builder, value, &key_id, switch, commit, None).unwrap();
/// let output = Output {
/// features: OutputFeatures::Coinbase,
/// commit: commit,
Expand All @@ -266,7 +269,7 @@ pub fn sign_from_key_id<K>(
where
K: Keychain,
{
let skey = k.derive_key(value, key_id)?;
let skey = k.derive_key(value, key_id, &SwitchCommitmentType::Regular)?; // TODO: proper support for different switch commitment schemes
let sig = aggsig::sign_single(secp, &msg, &skey, s_nonce, None, None, blind_sum, None)?;
Ok(sig)
}
Expand Down Expand Up @@ -296,16 +299,18 @@ where
/// use util::secp::{ContextFlag, Secp256k1};
/// use core::core::transaction::{kernel_sig_msg, KernelFeatures};
/// use core::core::{Output, OutputFeatures};
/// use keychain::{Keychain, ExtKeychain};
/// use keychain::{Keychain, ExtKeychain, SwitchCommitmentType};
///
/// // Create signature
/// let secp = Secp256k1::with_caps(ContextFlag::Commit);
/// let keychain = ExtKeychain::from_random_seed(false).unwrap();
/// let fees = 10_000;
/// let value = reward(fees);
/// let key_id = ExtKeychain::derive_key_id(1, 1, 0, 0, 0);
/// let commit = keychain.commit(value, &key_id).unwrap();
/// let rproof = proof::create(&keychain, value, &key_id, commit, None).unwrap();
/// let switch = &SwitchCommitmentType::Regular;
/// let commit = keychain.commit(value, &key_id, switch).unwrap();
/// let builder = proof::ProofBuilder::new(&keychain);
/// let rproof = proof::create(&keychain, &builder, value, &key_id, switch, commit, None).unwrap();
/// let output = Output {
/// features: OutputFeatures::Coinbase,
/// commit: commit,
Expand Down
Loading

0 comments on commit e3f3064

Please sign in to comment.