-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add extended ristretto commitment factory and pedersen generators #99
feat: add extended ristretto commitment factory and pedersen generators #99
Conversation
Add extended commitment factory Added extended ristretto commitment factory for Pedersen commitments making use of the extended Pedersen generators in the Tari Bulletproofs+ library.
src/ristretto/constants.rs
Outdated
let mut data = b"TARI CRYPTO - ".to_vec(); | ||
data.append(&mut i.to_le_bytes().to_vec()); | ||
data.append(&mut val.to_vec()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a particular reason to bind the base point to these generators? They're still NUMS if you simply use an indexed hash. I also recommend using a more descriptive domain separator that makes the intent of the generators more clear.
Depending on efficiency, you could also use Blake2b
, which has specific safe functionality for domain separation (the persona
parameter) and index-type functionality (the salt
parameter, or simply passing the index as fixed-encoding input).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated as suggested, although I did not change the hash function as hashing performance is not an issue for the test case that generates the test vector for the NUMS constants.
fn zero(&self) -> PedersenCommitment { | ||
let extension_degree = self.0.extension_degree as usize; | ||
let zero = vec![Scalar::zero(); extension_degree + 1]; | ||
let mut points = Vec::with_capacity(extension_degree + 1); | ||
points.push(self.0.h_base); | ||
points.append(&mut self.0.g_base_vec.clone()); | ||
let c = RistrettoPoint::multiscalar_mul(&zero, &self.0.g_base_vec); | ||
HomomorphicCommitment(RistrettoPublicKey::new_from_pk(c)) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This must always return the group identity, so there's no need to compute this multiscalar multiplication.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated and added a specific test case for it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It may be useful to add a test that asserts the NUMS points are unique and all non-zero, to catch the case where the hashing implementation has failed catastrophically. This isn't sufficient to guarantee the generators are sufficiently independent, but the failure of such a test would immediately imply commitments are trivially non-binding.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a partial overview review.
Everything is reviewed except extended_commitment_factory.rs
which requires a deeper dive, so I'll focus on that in a 2nd pass.
Everything else is fine, except some semantic and nit-picky stuff. See comments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed extended_commitment_factory.rs
.
No major issues; the copies in commit
are likely detrimental to performance, but I didn't run any benches to determine the extent of it.
…ent_factory-patch fix: use a slice directly in the extended_commitment_factory
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like most of it, but the abstraction is not 100% correct.
impl ExtendedPedersenCommitmentFactory { | ||
/// Create a new Extended Pedersen Ristretto Commitment factory for the required extension degree using | ||
/// pre-calculated compressed constants - we only hold references to the static generator points. | ||
pub fn new_with_extension_degree(extension_degree: ExtensionDegree) -> Result<Self, CommitmentError> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not too fond of the use of ExtensionDegree here. The type is in the bulletproofs_plus
crate, meaning that you can't use this crate without Bulletproofs, for example, if it were hidden behind a feature flag. PedersonGens
is perhaps in the wrong crate, or perhaps we should use a field in the ExtendedPedersonCommitmentFactory
gens: Vec<RistrettoPoint>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As we are dependent on
use bulletproofs_plus::{generators::pedersen_gens::ExtensionDegree, PedersenGens};
here and if we need to remove the dependency I think the most elegant solution would be to completely move generators
out of bulletproofs_plus
into its own crate.
If that solution is acceptable I propose we deal with that as a separate series of PRs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. Would it be better to rewrite ExtensionDegree
as a newtype around u64 rather than an enum, since the code in bp+ always converts it to an int anyway.
You could then add an adapter type in tari_crypto to resolve the dependency issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Added extended ristretto commitment factory for Pedersen commitments making use of the extended Pedersen generators in the Tari Bulletproofs+ library.
Notes:
RISTRETTO_NUMS_POINTS
have been updated by sequentially hashing the domain separated Ristretto255 generator point instead of sequentially hashing the generator point only. Domain separated hashing is less likely to result in unintended collisions or reuse elsewhere.ExtendedHomomorphicCommitmentFactory
trait has been addedristretto/pedersen
has been changed into a module that definespedersen/commitment_factory
andpedersen/extended_commitment_factory
PedersenCommitmentFactory
andExtendedPedersenCommitmentFactory
use the same baseG
andH
generator points so that each factory produces the same commitments for their default implementation.ExtendedPedersenCommitmentFactory
:ExtensionDegree::Zero
'Ord' and 'PartialOrd' are undefined for extended commitments other thanExtensionDegree::Zero
HomomorphicCommitmentFactory
has also been implemented forExtendedPedersenCommitmentFactory
so that its default invocation is compatible with all methods ofPedersenCommitmentFactory
.The next PR will include the
ExtendedRangeProofService
trait andBulletProofsPlusService
.