Skip to content
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

Rewrite ec abstraction #17

Closed
wants to merge 46 commits into from
Closed

Rewrite ec abstraction #17

wants to merge 46 commits into from

Conversation

omershlo
Copy link
Contributor

@omershlo omershlo commented Aug 4, 2018

No description provided.

@omershlo omershlo requested a review from gbenattar August 4, 2018 18:23
@omershlo omershlo changed the title Rewrite ec abstract Rewrite ec abstract (wip) Aug 4, 2018
@omershlo
Copy link
Contributor Author

omershlo commented Aug 4, 2018

I made major changes to EC traits. currently implemented only for secp256k1. Unit tests are needed as well as implementation for curve25519.
The major milestone so far is the generic traits ECScalar and ECPoint and the EC specific implementation for Secp256k1Scalar and Secp256k1Point. Any discussion and feedback at this level are welcome

@omershlo omershlo changed the title Rewrite ec abstract (wip) Rewrite ec abstraction (wip) Aug 4, 2018
@omershlo
Copy link
Contributor Author

omershlo commented Aug 8, 2018

I changed the elliptic curves to be features. need to find a way to make the compilation of the crates optional such that we compile only the EC we need.

@romanz
Copy link
Contributor

romanz commented Aug 12, 2018

The build seems to be failing: https://travis-ci.com/KZen-networks/cryptography-utils/jobs/139499279#L694:

$ cargo +nightly check --all
    Checking cryptography-utils v0.1.0 (file:///home/roman/Code/KZen/cryptography-utils)                                                                                                                                                                                        
error[E0432]: unresolved import `FE`
  --> src/cryptographic_primitives/proofs/dlog_zk_protocol.rs:34:5
   |
34 | use FE;
   |     ^^ no `FE` in the root

error[E0432]: unresolved import `GE`
  --> src/cryptographic_primitives/proofs/dlog_zk_protocol.rs:35:5
   |
35 | use GE;
   |     ^^ no `GE` in the root

error[E0432]: unresolved import `PK`
  --> src/cryptographic_primitives/proofs/dlog_zk_protocol.rs:36:5
   |
36 | use PK;
   |     ^^ no `PK` in the root

error[E0432]: unresolved import `SK`
  --> src/cryptographic_primitives/proofs/dlog_zk_protocol.rs:37:5
   |
37 | use SK;
   |     ^^ no `SK` in the root

@omershlo
Copy link
Contributor Author

@romanz this is because you must choose an elliptic curve feature for the build to be successful.

@romanz
Copy link
Contributor

romanz commented Aug 12, 2018

@omershlo Thanks! It should be fixed by a9d78ef.

Copy link
Contributor

@romanz romanz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly style and naming-related comments; didn't review the cryptography-related changes.

Cargo.toml Outdated
@@ -8,9 +8,14 @@ authors = [
[lib]
crate-type = ["lib"]

[features]
#default = ["curve25519"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove the commented line - or set the default explicitly.


for value in big_ints {
let bytes: Vec<u8> = value.borrow().into();
digest.update(&bytes);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be written as digest.update(&value.to_vec())?

If so - please change hash_sha256.rs as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed it. thanks!

//#[cfg(feature="curvesecp256k1")]
//use secp256k1instance::{SK,PK,GE,FE};
//#[cfg(feature="curve25519-dalek")]
//use curve25519instance::{SK,PK,GE,FE};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please delete the commented code blocks (above and in the rest of the changed code).

// Secp256k1 elliptic curve utility functions (se: https://en.bitcoin.it/wiki/Secp256k1).
//
// In Cryptography utilities, we need to manipulate low level elliptic curve members as Point
// in order to perform operation on them. As the library secp256k1 expose only SecretKey and
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

secp256k1 -> curve25519


fn sub(&self, other: &SK) -> Curve25519Scalar {
Curve25519Scalar {
purpose: "mul",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mul -> sub


// TODO: add a fn is_point
pub trait ECPoint<PK, SK> {
fn new() -> Self;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider naming it generator() (instead of new()).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done. good idea!!

src/lib.rs Outdated
#[cfg(feature = "curvesecp256k1")]
mod secp256k1instance {

pub use elliptic::curves::secp256_k1::EC;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider removing the line (as "curve25519" doesn't export an EC type).

Copy link
Contributor

@mortendahl mortendahl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some comments, but didn't look too closely at the crypto parts -- is that a review priority as well? anything that's worth focusing specifically on?


pub struct PedersenCommitment;

impl Commitment<Secp256k1Point> for PedersenCommitment {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

won't this fail when not using feature curvesecp256k1? maybe find a way to use conditional compilation to leave this code out in those cases

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, the reason was that not every elliptic curve that is used for signing can be used for Pedersen commitment as well so when new elliptic curves are introduced we would add pedersen commitment based on them. But your point is solid. @gbenattar @romanz do you know of a way to support Pederesen with fixed elliptic curve while condition compilation on all other elliptic curve related stuff? this might come in useful in the future?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

out of curiosity, what determines whether a curve can be used for commitment or not?

for conditional compilation you can simply annotate the impl with #[cfg(feature = "...")]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the curve is prime order group or not. For example curve25519 is not.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I sprayed #[cfg(feature = "curvesecp256k1")] all over the place. It appears that we are using pedersen commitments in many places. @romanz @mortendahl @gbenattar maybe one of you have an idea on how to do this exclusion more elegant or at least how to minimize the times I use #[cfg(feature = "curvesecp256k1")]?

pub struct HashCommitment;

//TODO: using the function with BigInt's as input instead of string's makes it impossible to commit to empty message or use empty randomness
impl Commitment for HashCommitment {
impl Commitment<BigInt> for HashCommitment {
fn create_commitment_with_user_defined_randomness(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

create_commitment_with_user_defined_randomness and create_commitment share almost the same code; let one use the other?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done. good catch.

mg.add_point(&rh.get_element())
}

fn create_commitment(message: &BigInt) -> (Secp256k1Point, BigInt) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

both methods again share almost the same code; let one use the other?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

[features]
default = ["curvesecp256k1"]
curvesecp256k1 = []
curve25519 = []
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

couldn't get it to compile with this curve (blocked on serde errors)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gbenattar probably some backward compatibility issue from your work on serialization?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default one? Just to make sure, do a cargo update and also do a rustup update, they changed nightly recently.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gbenattar not the default one, the build is failing for curve25519 because serde is not implemented for this.

*/
use BigInt;

use super::ring::{digest, hmac};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the extern crate ring is in the wrong place if super is needed here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

completely right, moved it to lib.rs

&generator_x,
&pk.get_x_coor_as_big_int(),
]);
let challenge_fe: FE = ECScalar::from_big_int(&challenge);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some methods perhaps seem a bit more explicit in naming than typical rust code, eg from_big_int instead of simply from, get_element instead of element, and get_x_coor_as_big_int instead of x_coor

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed the interface. my only problem is with get_element - I need to differentiate it from set_element so I cannot just change it to element


let base_point: GE = ECPoint::new();
//let sk_challenge_response : FE = ECScalar::from_big_int(&proof.challenge_response);
let sk_challenge_response: FE = proof.challenge_response.clone();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to clone

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great!

use cryptographic_primitives::commitments::pedersen_commitment::PedersenCommitment;
use cryptographic_primitives::commitments::traits::Commitment;

use elliptic::curves::secp256_k1::Secp256k1Point;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

conditional compilation to only be included when this curve is used?

let lhs = z1g.add_point(&z2h.get_element());
let rhs = proof.a1.add_point(&proof.a2.get_element());
let com_clone = proof.com.clone();
let ecom = com_clone.scalar_mul(&e.get_element());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is something slightly unpleasant about scalar_mul taking mut self while other operations don't. perhaps a Borrow could work and still get the same reuse optimisation when needed? in any case the extra clones could be move into that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I follow. scalar_mul takes self with the intention to consume self.
This was done to limit the interface. Is this a problem?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not a problem, only saying that the clone could be hidden if desired

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you give an example please?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"hidden" as in moved into the function by letting the function take eg a Cow instead. does that make sense?

use cryptographic_primitives::twoparty::dh_key_exchange::*;

#[test]
fn test_full_key_gen() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if the interface could be changed to avoid this picking of fields, which might cause some confusion or worse down the line. What if eg verify_commitments_and_dlog_proof simply took party_one_first_message and party_one_second_message as arguments?

@omershlo omershlo changed the title Rewrite ec abstraction (wip) Rewrite ec abstraction Sep 4, 2018
gbenattar pushed a commit that referenced this pull request Sep 12, 2018
* ECScalar and ECPoint and the EC specific implementation for Secp256k1Scalar and Secp256k1Point
* Commitments: Pedersen, Sigma valid Pedersen blind, Two party coin toss, Key exchange
PR: #17
Legacy branch created: https://github.com/KZen-networks/cryptography-utils/tree/two-party-v0
@omershlo omershlo closed this Jan 15, 2019
xmas7 pushed a commit to RubyOnWorld/curv that referenced this pull request Sep 6, 2022
* ECScalar and ECPoint and the EC specific implementation for Secp256k1Scalar and Secp256k1Point
* Commitments: Pedersen, Sigma valid Pedersen blind, Two party coin toss, Key exchange
PR: ZenGo-X/curv#17
Legacy branch created: https://github.com/KZen-networks/cryptography-utils/tree/two-party-v0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants