Integrated bulletproofs into Grin with optional build parameter (enabled by default) (#711)

This commit is contained in:
Yeastplume 2018-02-16 20:34:54 +00:00 committed by GitHub
parent 5572fa075e
commit c63aa70a0b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 100 additions and 13 deletions

View file

@ -1059,9 +1059,13 @@ mod test {
let b = new_block(vec![], &keychain);
let mut vec = Vec::new();
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!(
vec.len(),
5_708,
target_len,
);
}
@ -1072,9 +1076,13 @@ mod test {
let b = new_block(vec![&tx1], &keychain);
let mut vec = Vec::new();
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!(
vec.len(),
16_256,
target_len,
);
}
@ -1084,9 +1092,13 @@ mod test {
let b = new_block(vec![], &keychain);
let mut vec = Vec::new();
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!(
vec.len(),
5_716,
target_len,
);
}
@ -1097,9 +1109,13 @@ mod test {
let b = new_block(vec![&tx1], &keychain);
let mut vec = Vec::new();
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!(
vec.len(),
5_722,
target_len,
);
}
@ -1119,9 +1135,13 @@ mod test {
);
let mut vec = Vec::new();
ser::serialize(&mut vec, &b).expect("serialization failed");
let target_len = match Keychain::is_using_bullet_proofs() {
true => 17696,
false => 111188,
};
assert_eq!(
vec.len(),
111_188,
target_len,
);
}
@ -1141,9 +1161,13 @@ mod test {
);
let mut vec = Vec::new();
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!(
vec.len(),
5_776,
target_len,
);
}

View file

@ -263,9 +263,13 @@ mod test {
let tx = tx2i1o();
let mut vec = Vec::new();
ser::serialize(&mut vec, &tx).expect("serialization failed");
let target_len = match Keychain::is_using_bullet_proofs() {
true => 986,
false => 5_438,
};
assert_eq!(
vec.len(),
5_438,
target_len,
);
}
@ -390,6 +394,12 @@ mod test {
let btx = tx2i1o();
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
let Output { proof, .. } = btx.outputs[0];

View file

@ -92,6 +92,8 @@ pub enum Error {
LockHeight(u64),
/// Error originating from an invalid switch commitment (coinbase lock_height related)
SwitchCommitment,
/// Range proof validation error
RangeProof,
}
impl From<secp::Error> for Error {
@ -749,8 +751,11 @@ impl Output {
pub fn verify_proof(&self) -> Result<(), secp::Error> {
let secp = static_secp_instance();
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
/// 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
let recovered_value = output.recover_value(&keychain, &key_id).unwrap();
assert_eq!(recovered_value, 1003);
let result = output.recover_value(&keychain, &key_id);
// 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
let key_id2 = keychain.derive_key_id(2).unwrap();

View file

@ -3,6 +3,12 @@ name = "grin_keychain"
version = "0.1.0"
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]
byteorder = "^1.0"
blake2-rfc = "~0.2.17"

View file

@ -28,12 +28,18 @@ use uuid::Uuid;
use blind::{BlindSum, BlindingFactor};
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)]
pub enum Error {
ExtendedKey(extkey::Error),
Secp(secp::Error),
KeyDerivation(String),
Transaction(String),
RangeProof(String),
}
impl From<secp::Error> for Error {
@ -220,6 +226,10 @@ impl Keychain {
Ok(child_key.switch_key)
}
pub fn is_using_bullet_proofs() -> bool {
USE_BULLET_PROOFS
}
pub fn range_proof(
&self,
amount: u64,
@ -228,10 +238,27 @@ impl Keychain {
msg: ProofMessage,
) -> Result<RangeProof, Error> {
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)
}
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(
&self,
key_id: &Identifier,
@ -239,6 +266,10 @@ impl Keychain {
proof: RangeProof,
) -> Result<ProofInfo, Error> {
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))
}
@ -527,6 +558,11 @@ mod test {
let commit = keychain.commit(5, &key_id).unwrap();
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_info = keychain.rewind_range_proof(&key_id, commit, proof).unwrap();

View file

@ -14,7 +14,7 @@ byteorder = "^1.0"
rand = "^0.3"
serde = "~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" }
walkdir = "^2.0.1"
zip = "^0.2.6"