mirror of
https://github.com/mimblewimble/grin.git
synced 2025-02-08 04:11:08 +03:00
Integrated bulletproofs into Grin with optional build parameter (enabled by default) (#711)
This commit is contained in:
parent
5572fa075e
commit
c63aa70a0b
6 changed files with 100 additions and 13 deletions
|
@ -1059,9 +1059,13 @@ mod test {
|
||||||
let b = new_block(vec![], &keychain);
|
let b = new_block(vec![], &keychain);
|
||||||
let mut vec = Vec::new();
|
let mut vec = Vec::new();
|
||||||
ser::serialize(&mut vec, &b).expect("serialization failed");
|
ser::serialize(&mut vec, &b).expect("serialization failed");
|
||||||
|
let target_len = match Keychain::is_using_bullet_proofs() {
|
||||||
|
true => 1_256,
|
||||||
|
false => 5_708,
|
||||||
|
};
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
vec.len(),
|
vec.len(),
|
||||||
5_708,
|
target_len,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1072,9 +1076,13 @@ mod test {
|
||||||
let b = new_block(vec![&tx1], &keychain);
|
let b = new_block(vec![&tx1], &keychain);
|
||||||
let mut vec = Vec::new();
|
let mut vec = Vec::new();
|
||||||
ser::serialize(&mut vec, &b).expect("serialization failed");
|
ser::serialize(&mut vec, &b).expect("serialization failed");
|
||||||
|
let target_len = match Keychain::is_using_bullet_proofs() {
|
||||||
|
true => 2_900,
|
||||||
|
false => 16_256,
|
||||||
|
};
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
vec.len(),
|
vec.len(),
|
||||||
16_256,
|
target_len,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1084,9 +1092,13 @@ mod test {
|
||||||
let b = new_block(vec![], &keychain);
|
let b = new_block(vec![], &keychain);
|
||||||
let mut vec = Vec::new();
|
let mut vec = Vec::new();
|
||||||
ser::serialize(&mut vec, &b.as_compact_block()).expect("serialization failed");
|
ser::serialize(&mut vec, &b.as_compact_block()).expect("serialization failed");
|
||||||
|
let target_len = match Keychain::is_using_bullet_proofs() {
|
||||||
|
true => 1_264,
|
||||||
|
false => 5_716,
|
||||||
|
};
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
vec.len(),
|
vec.len(),
|
||||||
5_716,
|
target_len,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1097,9 +1109,13 @@ mod test {
|
||||||
let b = new_block(vec![&tx1], &keychain);
|
let b = new_block(vec![&tx1], &keychain);
|
||||||
let mut vec = Vec::new();
|
let mut vec = Vec::new();
|
||||||
ser::serialize(&mut vec, &b.as_compact_block()).expect("serialization failed");
|
ser::serialize(&mut vec, &b.as_compact_block()).expect("serialization failed");
|
||||||
|
let target_len = match Keychain::is_using_bullet_proofs() {
|
||||||
|
true => 1_270,
|
||||||
|
false => 5_722,
|
||||||
|
};
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
vec.len(),
|
vec.len(),
|
||||||
5_722,
|
target_len,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1119,9 +1135,13 @@ mod test {
|
||||||
);
|
);
|
||||||
let mut vec = Vec::new();
|
let mut vec = Vec::new();
|
||||||
ser::serialize(&mut vec, &b).expect("serialization failed");
|
ser::serialize(&mut vec, &b).expect("serialization failed");
|
||||||
|
let target_len = match Keychain::is_using_bullet_proofs() {
|
||||||
|
true => 17696,
|
||||||
|
false => 111188,
|
||||||
|
};
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
vec.len(),
|
vec.len(),
|
||||||
111_188,
|
target_len,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1141,9 +1161,13 @@ mod test {
|
||||||
);
|
);
|
||||||
let mut vec = Vec::new();
|
let mut vec = Vec::new();
|
||||||
ser::serialize(&mut vec, &b.as_compact_block()).expect("serialization failed");
|
ser::serialize(&mut vec, &b.as_compact_block()).expect("serialization failed");
|
||||||
|
let target_len = match Keychain::is_using_bullet_proofs() {
|
||||||
|
true => 1_324,
|
||||||
|
false => 5_776,
|
||||||
|
};
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
vec.len(),
|
vec.len(),
|
||||||
5_776,
|
target_len,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -263,9 +263,13 @@ mod test {
|
||||||
let tx = tx2i1o();
|
let tx = tx2i1o();
|
||||||
let mut vec = Vec::new();
|
let mut vec = Vec::new();
|
||||||
ser::serialize(&mut vec, &tx).expect("serialization failed");
|
ser::serialize(&mut vec, &tx).expect("serialization failed");
|
||||||
|
let target_len = match Keychain::is_using_bullet_proofs() {
|
||||||
|
true => 986,
|
||||||
|
false => 5_438,
|
||||||
|
};
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
vec.len(),
|
vec.len(),
|
||||||
5_438,
|
target_len,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -390,6 +394,12 @@ mod test {
|
||||||
let btx = tx2i1o();
|
let btx = tx2i1o();
|
||||||
assert!(btx.validate().is_ok());
|
assert!(btx.validate().is_ok());
|
||||||
|
|
||||||
|
// Ignored for bullet proofs, info doesn't exist yet and calling range_proof_info
|
||||||
|
// with a bullet proof causes painful errors
|
||||||
|
if Keychain::is_using_bullet_proofs() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// checks that the range proof on our blind output is sufficiently hiding
|
// checks that the range proof on our blind output is sufficiently hiding
|
||||||
let Output { proof, .. } = btx.outputs[0];
|
let Output { proof, .. } = btx.outputs[0];
|
||||||
|
|
||||||
|
|
|
@ -92,6 +92,8 @@ pub enum Error {
|
||||||
LockHeight(u64),
|
LockHeight(u64),
|
||||||
/// Error originating from an invalid switch commitment (coinbase lock_height related)
|
/// Error originating from an invalid switch commitment (coinbase lock_height related)
|
||||||
SwitchCommitment,
|
SwitchCommitment,
|
||||||
|
/// Range proof validation error
|
||||||
|
RangeProof,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<secp::Error> for Error {
|
impl From<secp::Error> for Error {
|
||||||
|
@ -749,8 +751,11 @@ impl Output {
|
||||||
pub fn verify_proof(&self) -> Result<(), secp::Error> {
|
pub fn verify_proof(&self) -> Result<(), secp::Error> {
|
||||||
let secp = static_secp_instance();
|
let secp = static_secp_instance();
|
||||||
let secp = secp.lock().unwrap();
|
let secp = secp.lock().unwrap();
|
||||||
secp.verify_range_proof(self.commit, self.proof).map(|_| ())
|
match Keychain::verify_range_proof(&secp, self.commit, self.proof){
|
||||||
}
|
Ok(_) => Ok(()),
|
||||||
|
Err(e) => Err(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Given the original blinding factor we can recover the
|
/// Given the original blinding factor we can recover the
|
||||||
/// value from the range proof and the commitment
|
/// value from the range proof and the commitment
|
||||||
|
@ -1089,8 +1094,14 @@ mod test {
|
||||||
};
|
};
|
||||||
|
|
||||||
// check we can successfully recover the value with the original blinding factor
|
// check we can successfully recover the value with the original blinding factor
|
||||||
let recovered_value = output.recover_value(&keychain, &key_id).unwrap();
|
let result = output.recover_value(&keychain, &key_id);
|
||||||
assert_eq!(recovered_value, 1003);
|
// TODO: Remove this check once value recovery is supported within bullet proofs
|
||||||
|
if let Some(v) = result {
|
||||||
|
assert_eq!(v, 1003);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// check we cannot recover the value without the original blinding factor
|
// check we cannot recover the value without the original blinding factor
|
||||||
let key_id2 = keychain.derive_key_id(2).unwrap();
|
let key_id2 = keychain.derive_key_id(2).unwrap();
|
||||||
|
|
|
@ -3,6 +3,12 @@ name = "grin_keychain"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["Antioch Peverell"]
|
authors = ["Antioch Peverell"]
|
||||||
|
|
||||||
|
[features]
|
||||||
|
#remove this feature to use older-style rangeproofs
|
||||||
|
#(this flag will disappear in future releases)
|
||||||
|
default = ["use-bullet-proofs"]
|
||||||
|
use-bullet-proofs = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
byteorder = "^1.0"
|
byteorder = "^1.0"
|
||||||
blake2-rfc = "~0.2.17"
|
blake2-rfc = "~0.2.17"
|
||||||
|
|
|
@ -28,12 +28,18 @@ use uuid::Uuid;
|
||||||
use blind::{BlindSum, BlindingFactor};
|
use blind::{BlindSum, BlindingFactor};
|
||||||
use extkey::{self, Identifier};
|
use extkey::{self, Identifier};
|
||||||
|
|
||||||
|
#[cfg(feature = "use-bullet-proofs")]
|
||||||
|
const USE_BULLET_PROOFS:bool = true;
|
||||||
|
#[cfg(not(feature = "use-bullet-proofs"))]
|
||||||
|
const USE_BULLET_PROOFS:bool = false;
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
#[derive(PartialEq, Eq, Clone, Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
ExtendedKey(extkey::Error),
|
ExtendedKey(extkey::Error),
|
||||||
Secp(secp::Error),
|
Secp(secp::Error),
|
||||||
KeyDerivation(String),
|
KeyDerivation(String),
|
||||||
Transaction(String),
|
Transaction(String),
|
||||||
|
RangeProof(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<secp::Error> for Error {
|
impl From<secp::Error> for Error {
|
||||||
|
@ -220,6 +226,10 @@ impl Keychain {
|
||||||
Ok(child_key.switch_key)
|
Ok(child_key.switch_key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_using_bullet_proofs() -> bool {
|
||||||
|
USE_BULLET_PROOFS
|
||||||
|
}
|
||||||
|
|
||||||
pub fn range_proof(
|
pub fn range_proof(
|
||||||
&self,
|
&self,
|
||||||
amount: u64,
|
amount: u64,
|
||||||
|
@ -228,10 +238,27 @@ impl Keychain {
|
||||||
msg: ProofMessage,
|
msg: ProofMessage,
|
||||||
) -> Result<RangeProof, Error> {
|
) -> Result<RangeProof, Error> {
|
||||||
let skey = self.derived_key(key_id)?;
|
let skey = self.derived_key(key_id)?;
|
||||||
let range_proof = self.secp.range_proof(0, amount, skey, commit, msg);
|
let range_proof = match USE_BULLET_PROOFS {
|
||||||
|
true => self.secp.bullet_proof(amount, skey),
|
||||||
|
false => self.secp.range_proof(0, amount, skey, commit, msg),
|
||||||
|
};
|
||||||
Ok(range_proof)
|
Ok(range_proof)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn verify_range_proof(
|
||||||
|
secp: &Secp256k1,
|
||||||
|
commit: Commitment,
|
||||||
|
proof: RangeProof) -> Result<(), secp::Error> {
|
||||||
|
let result = match USE_BULLET_PROOFS {
|
||||||
|
true => secp.verify_bullet_proof(commit, proof),
|
||||||
|
false => secp.verify_range_proof(commit, proof),
|
||||||
|
};
|
||||||
|
match result {
|
||||||
|
Ok(_) => Ok(()),
|
||||||
|
Err(e) => Err(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn rewind_range_proof(
|
pub fn rewind_range_proof(
|
||||||
&self,
|
&self,
|
||||||
key_id: &Identifier,
|
key_id: &Identifier,
|
||||||
|
@ -239,6 +266,10 @@ impl Keychain {
|
||||||
proof: RangeProof,
|
proof: RangeProof,
|
||||||
) -> Result<ProofInfo, Error> {
|
) -> Result<ProofInfo, Error> {
|
||||||
let nonce = self.derived_key(key_id)?;
|
let nonce = self.derived_key(key_id)?;
|
||||||
|
if USE_BULLET_PROOFS {
|
||||||
|
error!(LOGGER, "Rewinding Bullet proofs not yet supported");
|
||||||
|
return Err(Error::RangeProof("Rewinding Bullet proofs not yet supported".to_string()));
|
||||||
|
}
|
||||||
Ok(self.secp.rewind_range_proof(commit, proof, nonce))
|
Ok(self.secp.rewind_range_proof(commit, proof, nonce))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -527,6 +558,11 @@ mod test {
|
||||||
let commit = keychain.commit(5, &key_id).unwrap();
|
let commit = keychain.commit(5, &key_id).unwrap();
|
||||||
let msg = ProofMessage::empty();
|
let msg = ProofMessage::empty();
|
||||||
|
|
||||||
|
//TODO: Remove this check when bullet proofs can be rewound
|
||||||
|
if Keychain::is_using_bullet_proofs(){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let proof = keychain.range_proof(5, &key_id, commit, msg).unwrap();
|
let proof = keychain.range_proof(5, &key_id, commit, msg).unwrap();
|
||||||
let proof_info = keychain.rewind_range_proof(&key_id, commit, proof).unwrap();
|
let proof_info = keychain.rewind_range_proof(&key_id, commit, proof).unwrap();
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ byteorder = "^1.0"
|
||||||
rand = "^0.3"
|
rand = "^0.3"
|
||||||
serde = "~1.0.8"
|
serde = "~1.0.8"
|
||||||
serde_derive = "~1.0.8"
|
serde_derive = "~1.0.8"
|
||||||
secp256k1zkp = { git = "https://github.com/mimblewimble/rust-secp256k1-zkp", tag="grin_integration_7" }
|
secp256k1zkp = { git = "https://github.com/mimblewimble/rust-secp256k1-zkp", tag="grin_integration_8" }
|
||||||
#secp256k1zkp = { path = "../../rust-secp256k1-zkp" }
|
#secp256k1zkp = { path = "../../rust-secp256k1-zkp" }
|
||||||
walkdir = "^2.0.1"
|
walkdir = "^2.0.1"
|
||||||
zip = "^0.2.6"
|
zip = "^0.2.6"
|
||||||
|
|
Loading…
Reference in a new issue