Skip to content

Commit

Permalink
Upgrade curv interface (#120)
Browse files Browse the repository at this point in the history
* Impl From<u16> for BigInt

* Add Polynomial

* Add the proof

* Update travis config

* Bump version

* Rename coef0 to const_term + update docs

* Add sample_exact and sample_exact_with_fixed_const

* Rename LdeiProveError -> LdeiProofError

* Move polynomial into secret_sharing module

* LDEI prove takes witness and statement

* Comment out crypto primitives for a while

* Update traits, add wrappers, and upgrade secp256k1 implementation

* Update polynomial

* Do not access wrappers internal state directly, improve docs

* Add generator wrapper

* Add secp256k1 test

* Implement Serialize, Deserialize for Point(Z)

* Update feldman_vss

* Add {to,from}_bytes functions to PointZ

* Update hashing

* Change curve_name method with associated constant

* Deref stylistic fix

* Optimise generator multiplication

* Update docs

* Update commitments

* Update low_degree_exponent_interpolation

* Update sigma_correct_homomorphic_elgamal_enc

* Update sigma_correct_homomorphic_elgamal_encryption_of_dlog

* Wrappers: rename methods, implement PartialEq

* Update sigma_dlog

* Update sigma_ec_ddh

* Rename curve_order to group_order

* Restrict the points to be of group order

* Split a large wrappers module into several files

* Update sigma_valid_pedersen

* Update sigma_valid_pedersen_blind

* Fix derived Serialize/Deserialize traits

* Update coin_flip_optimal_rounds

* Update dh_key_exchange

* Update dh_key_exchange_variant_with_pok_comm

* Update diffie_hellman_key_exchange example

* Update pedersen_commitment

* Update proof_of_knowledge_of_dlog example

* Update verifiable_secret_sharing example

* Fix warning

* Fix clippy warnings

* Update doc

* Improve hashing

* Write doc

* Fix typos

* Update travis config

* Update P-256 curve implementation

* Add tests

* Update Ed25519 curve

* Update Ristretto curve

* Ristretto: x=hash(y)

* Add the first BLS curve

* Default implementation for ECPoint::is_zero method

* Add tests, fix ed25519 negation

* Uncomment proofs of base_point2 picked randomly

* Add the second BLS curve

* Write doc

* Add pairing, update docs

* Rename package

* Update readme

* Add changelog

* Merge Point&PointZ, Scalar&ScalarZ

* Serialize always succeeds

* Update doc

* Fix clippy warning

* VerifiableSS returns polynomial used to derive secret shares

* Fix documentation

* Optimize elliptic curves implementations

* Add serialize/deserialize to Scalars

* Use scalar/point `serialize` functions to implement serde serialization instead of bigint

* Add serde tests

* Add more EC serialize/deserialize tests

* Update examples

* Update Cargo.toml

* Update docs

* Update vss to use u16 instead of usize


fix

* Resolve TODO

* Fix doc

* Impl iter::{Sum, Product} for wrappers

* Ristretto: return x=None instead of x=hash(y)

* Add documentation for the rest of the curves

* Improve point serialization

* Improve scalar serialization

* Move serde-related stuff to dedicated module

* Improve serde tests

* Remove PointRef wrapper

* Move actual unsafe code to a single function

* Finalization

Co-authored-by: Elichai Turkel <elichai.turkel@gmail.com>
  • Loading branch information
Denis Varlakov and elichai authored Jul 27, 2021
1 parent b3b9c39 commit 795da47
Show file tree
Hide file tree
Showing 59 changed files with 6,005 additions and 4,839 deletions.
28 changes: 20 additions & 8 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
language: rust
cache: cargo
rust:
- stable
rust: stable
virt: lxd

before_script:
- rustup component add rustfmt-preview clippy
- cargo fmt --all -- --check
- cargo clippy -- -D clippy::all
env:
- BIGINT_BACKEND=rust-gmp-kzen
- BIGINT_BACKEND=num-bigint

before_install:
- rustup component add rustfmt clippy

script:
- cargo build --verbose
- cargo test --verbose
- cargo build --verbose --no-default-features --features $BIGINT_BACKEND
- cargo test --verbose --no-default-features --features $BIGINT_BACKEND
- if [[ "$BIGINT_BACKEND" = "rust-gmp-kzen" ]]; then cargo fmt --all -- --check; fi
- if [[ "$BIGINT_BACKEND" = "rust-gmp-kzen" ]]; then cargo clippy -- -D clippy::all; fi

deploy:
provider: cargo
token:
secure: "FE6A1XRyJtTK92rV3y5e0go+FDKn1HpJbYkHOacDqabTkUluXrCTw3ERFcQQ13QZdc9xkxoAs7roKp8ivl0Xg1IJCzI+yLb0ZR6YcYebKEqd06YFbBmejjvMsyyZHKPTQmroe+tBwcA1IqLLcAY8vmY5EGhJTsGUhovIomw1RvqM6gu9yUwII/sF0a5gqY761cJd4QoLlWTb1Er7DqZxoU9drhWAJQP7sLsspjLu6dOyWzb0A2mTmnek+iuVnt9mGPtjGk4FcNPGbEmNu3UPOVuXcyibFPIALEWrH0ouZB7E9k312g45LucSeKSimgQYQBNAzdsnkKyBwyTpGuaosGnMbI7mhoi3visV21RTbw61N05dmZTYb4VAMcx+93TslKMDv5nmIlUmKxULNRBSTPPtrg0/X7KuKaoHVstrxx0ohd8GFwGYQBB64mQaOxFBhoy//prpHjhFl+1cti4JHyaHFSV/PfaryvUfRg4q2Dlq1HP+ey5cPRPbwfpSO1RmXlIDWe21ncRnKSpgMHTPBzYNtil+gZyzHl5X4ZLvLCaHsZwZQPMFB+otlabFaS1caqkk1F1fHMrj8NMak/snb2IyUJqXgQivqzEn38G3k9/QHeQXhNVwyGDtdWV51P9XfXFpxrEuuWlXF56ABiWcF7bY7Y3DeCbnFNLkVkGZYvY="
on:
tags: true
condition: '"$TRAVIS_TAG" =~ ^v[0-9].+$ && "$BIGINT_BACKEND" = "rust-gmp-kzen"'
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Changelog

## v0.8.0-rc1
* Elliptic curve API has been significantly changed [#120]

In particular: ECPoint, ECScalar traits were redesigned. They remain,
but are not supposed to be used directly anymore. In replacement,
we introduce structures Point, Scalar representing elliptic point and
scalar. See curv::elliptic::curves module-level documentation to learn
more.
* Add low degree exponent interpolation proof [#119]

[#119]: https://github.com/ZenGo-X/curv/pull/119
[#120]: https://github.com/ZenGo-X/curv/pull/120
33 changes: 18 additions & 15 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,35 +1,39 @@
[package]
name = "curv"
version = "0.7.0"
name = "curv-kzen"
version = "0.8.0-rc1"
edition = "2018"
authors = ["Omer Shlomovits"]
authors = [
"Omer Shlomovits",
"Denis Varlakov",
]
license = "MIT"
description = "Curv contains an extremly simple interface to onboard new elliptic curves. Use this library for general purpose elliptic curve cryptography"
repository = "https://github.com/ZenGo-X/curv"

[lib]
name = "curv"
crate-type = ["lib"]

[dependencies]
blake2b_simd = "0.5.7"
cryptoxide = "0.1.2"
curve25519-dalek = "1.2.3"
derivative = "2.2"
curve25519-dalek = "3"
digest = "0.8.1"
ff-zeroize = "0.6.3"
funty = "=1.1.0"
generic-array = "0.14"
hex = "0.4"
hex = { version = "0.4", features = ["serde"] }
hmac = "0.7.1"
thiserror = "1"
merkle-sha3 = "^0.1"
lazy_static = "1.4.0"
lazy_static = "1.4"
num-traits = "0.2"
num-integer = "0.1"
pairing-plus = "0.19"
rand = "0.6"
rand = "0.7"
rand_legacy = { package = "rand", version = "0.6" }
ring-algorithm = "0.2.3"
rust-crypto = "^0.2"
serde = { version = "1.0", features = ["derive"] }
serde_bytes = "0.11"
serde_derive = "1.0"
sha2 = "0.8.0"
sha3 = "0.8.2"
Expand All @@ -40,15 +44,14 @@ num-bigint = { version = "0.4", features = ["serde"], optional = true }

[dependencies.secp256k1]
version = "0.20"
features = ["serde", "rand-std"]
features = ["serde", "rand-std", "global-context"]

[dependencies.p256]
version = "0.5"
features = ["ecdsa"]
version = "0.9"
features = ["ecdsa", "ecdsa-core", "zeroize"]

[dev-dependencies]
bincode = "1.1"
serde_json = "1.0"
serde_test = "1.0"
paste = "1.0.2"
proptest = "0.10"
proptest-derive = "0.2"
Expand Down
16 changes: 14 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,19 @@ The library has a built in support for some useful operations/primitives such as
schemes, zero knowledge proofs, and simple two party protocols such as ECDH and coin flip. The library comes with
serialize/deserialize support to be used in higher level code to implement networking.

### Usage

To use `curv` crate, add the following to your Cargo.toml:
```toml
[dependencies]
curv-kzen = "0.8"
```

The crate will be available under `curv` name, e.g.:
```rust
use curv::elliptic::curves::*;
```

### Currently Supported Elliptic Curves

| Curve | low level library | curve description |
Expand Down Expand Up @@ -44,8 +57,7 @@ You can choose any one which you prefer by specifying a feature:
* **num-bigint**, Rust's pure implementation of big integer. In order to use it, put in Cargo.toml:
```toml
[dependencies.curv]
git = "https://github.com/ZenGo-X/curv"
tag = "v0.6.0"
version = "0.8"
default-features = false
features = ["num-bigint"]
```
Expand Down
25 changes: 10 additions & 15 deletions examples/diffie_hellman_key_exchange.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
use std::fmt::Debug;

use curv::elliptic::curves::traits::ECPoint;
use curv::elliptic::curves::*;

/// Diffie Hellman Key Exchange:
/// TO RUN:
Expand All @@ -11,17 +9,13 @@ use curv::elliptic::curves::traits::ECPoint;
/// notice: this library includes also a more involved ECDH scheme. see
/// dh_key_exchange_variant_with_pok_comm.rs
pub fn ecdh<P>()
where
P: ECPoint + Clone + Debug,
P::Scalar: Clone,
{
pub fn ecdh<E: Curve>() {
use curv::cryptographic_primitives::twoparty::dh_key_exchange::{
compute_pubkey, Party1FirstMessage, Party2FirstMessage,
};

let (kg_party_one_first_message, kg_ec_key_pair_party1) = Party1FirstMessage::<P>::first();
let (kg_party_two_first_message, kg_ec_key_pair_party2) = Party2FirstMessage::<P>::first();
let (kg_party_one_first_message, kg_ec_key_pair_party1) = Party1FirstMessage::<E>::first();
let (kg_party_two_first_message, kg_ec_key_pair_party2) = Party2FirstMessage::<E>::first();

assert_eq!(
compute_pubkey(
Expand All @@ -38,11 +32,12 @@ where
fn main() {
let curve_name = std::env::args().nth(1);
match curve_name.as_deref() {
Some("secp256k1") => ecdh::<curv::elliptic::curves::secp256_k1::GE>(),
Some("ristretto") => ecdh::<curv::elliptic::curves::curve_ristretto::GE>(),
Some("ed25519") => ecdh::<curv::elliptic::curves::ed25519::GE>(),
Some("bls12_381") => ecdh::<curv::elliptic::curves::bls12_381::g1::GE>(),
Some("p256") => ecdh::<curv::elliptic::curves::p256::GE>(),
Some("secp256k1") => ecdh::<Secp256k1>(),
Some("ristretto") => ecdh::<Ristretto>(),
Some("ed25519") => ecdh::<Ed25519>(),
Some("bls12_381_1") => ecdh::<Bls12_381_1>(),
Some("bls12_381_2") => ecdh::<Bls12_381_2>(),
Some("p256") => ecdh::<Secp256r1>(),
Some(unknown_curve) => eprintln!("Unknown curve: {}", unknown_curve),
None => eprintln!("Missing curve name"),
}
Expand Down
29 changes: 12 additions & 17 deletions examples/pedersen_commitment.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
use curv::arithmetic::{traits::*, BigInt};
use curv::elliptic::curves::traits::ECPoint;
use curv::arithmetic::*;
use curv::elliptic::curves::*;

use std::fmt::Debug;

/// Pedesen Commitment:
/// Pedersen Commitment:
/// compute c = mG + rH
/// where m is the commited value, G is the group generator,
/// H is a random point and r is a blinding value.
Expand All @@ -14,16 +12,13 @@ use std::fmt::Debug;
///
/// notice: this library includes also hash based commitments
pub fn ped_com<P>(message: &BigInt)
where
P: ECPoint + Debug,
{
pub fn ped_com<E: Curve>(message: &BigInt) {
use curv::cryptographic_primitives::commitments::pedersen_commitment::PedersenCommitment;
use curv::cryptographic_primitives::commitments::traits::Commitment;

let security_bits = 256;
let blinding_factor = BigInt::sample(security_bits);
let com = PedersenCommitment::<P>::create_commitment_with_user_defined_randomness(
let com = PedersenCommitment::<E>::create_commitment_with_user_defined_randomness(
message,
&blinding_factor,
);
Expand All @@ -36,15 +31,15 @@ where

fn main() {
let message = "commit me!";
let message_bytes = message.as_bytes();
let _message_bn = BigInt::from_bytes(message_bytes);
let message_bn = BigInt::from_bytes(message.as_bytes());
let curve_name = std::env::args().nth(1);
match curve_name.as_deref() {
Some("secp256k1") => ped_com::<curv::elliptic::curves::secp256_k1::GE>(&_message_bn),
Some("ristretto") => ped_com::<curv::elliptic::curves::curve_ristretto::GE>(&_message_bn),
Some("ed25519") => ped_com::<curv::elliptic::curves::ed25519::GE>(&_message_bn),
Some("bls12_381") => ped_com::<curv::elliptic::curves::bls12_381::g1::GE>(&_message_bn),
Some("p256") => ped_com::<curv::elliptic::curves::p256::GE>(&_message_bn),
Some("secp256k1") => ped_com::<Secp256k1>(&message_bn),
Some("ristretto") => ped_com::<Ristretto>(&message_bn),
Some("ed25519") => ped_com::<Ed25519>(&message_bn),
Some("bls12_381_1") => ped_com::<Bls12_381_1>(&message_bn),
Some("bls12_381_2") => ped_com::<Bls12_381_2>(&message_bn),
Some("p256") => ped_com::<Secp256r1>(&message_bn),
Some(unknown_curve) => eprintln!("Unknown curve: {}", unknown_curve),
None => eprintln!("Missing curve name"),
}
Expand Down
25 changes: 10 additions & 15 deletions examples/proof_of_knowledge_of_dlog.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use curv::elliptic::curves::traits::ECPoint;
use zeroize::Zeroize;
use curv::elliptic::curves::*;

/// Sigma protocol for proof of knowledge of discrete log
/// TO RUN:
Expand All @@ -10,27 +9,23 @@ use zeroize::Zeroize;
/// notice: this library includes other more complex sigma protocol.
/// see proofs folder for more details
pub fn dlog_proof<P>()
where
P: ECPoint + Clone,
P::Scalar: Zeroize,
{
pub fn dlog_proof<E: Curve>() {
use curv::cryptographic_primitives::proofs::sigma_dlog::*;
use curv::elliptic::curves::traits::ECScalar;

let witness: P::Scalar = ECScalar::new_random();
let dlog_proof = DLogProof::<P>::prove(&witness);
let witness = Scalar::random();
let dlog_proof = DLogProof::<E>::prove(&witness);
assert!(DLogProof::verify(&dlog_proof).is_ok());
}

fn main() {
let curve_name = std::env::args().nth(1);
match curve_name.as_deref() {
Some("secp256k1") => dlog_proof::<curv::elliptic::curves::secp256_k1::GE>(),
Some("ristretto") => dlog_proof::<curv::elliptic::curves::curve_ristretto::GE>(),
Some("ed25519") => dlog_proof::<curv::elliptic::curves::ed25519::GE>(),
Some("bls12_381") => dlog_proof::<curv::elliptic::curves::bls12_381::g1::GE>(),
Some("p256") => dlog_proof::<curv::elliptic::curves::p256::GE>(),
Some("secp256k1") => dlog_proof::<Secp256k1>(),
Some("ristretto") => dlog_proof::<Ristretto>(),
Some("ed25519") => dlog_proof::<Ed25519>(),
Some("bls12_381_1") => dlog_proof::<Bls12_381_1>(),
Some("bls12_381_2") => dlog_proof::<Bls12_381_2>(),
Some("p256") => dlog_proof::<Secp256r1>(),
Some(unknown_curve) => eprintln!("Unknown curve: {}", unknown_curve),
None => eprintln!("Missing curve name"),
}
Expand Down
44 changes: 17 additions & 27 deletions examples/verifiable_secret_sharing.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
use std::fmt::Debug;

use curv::elliptic::curves::traits::ECPoint;
use curv::elliptic::curves::*;

/// secret_sharing_3_out_of_5
/// Feldman VSS, based on Paul Feldman. 1987. A practical scheme for non-interactive verifiable secret sharing.
Expand All @@ -13,17 +11,12 @@ use curv::elliptic::curves::traits::ECPoint;
/// CURVE_NAME is any of the supported curves: i.e.:
/// cargo run --example verifiable_secret_sharing -- ed25519
pub fn secret_sharing_3_out_of_5<P>()
where
P: ECPoint + Clone,
P::Scalar: PartialEq + Clone + Debug,
{
pub fn secret_sharing_3_out_of_5<E: Curve>() {
use curv::cryptographic_primitives::secret_sharing::feldman_vss::VerifiableSS;
use curv::elliptic::curves::traits::ECScalar;

let secret: P::Scalar = ECScalar::new_random();
let secret = Scalar::random();

let (vss_scheme, secret_shares) = VerifiableSS::<P>::share(3, 5, &secret);
let (vss_scheme, secret_shares) = VerifiableSS::<E>::share(3, 5, &secret);

let shares_vec = vec![
secret_shares[0].clone(),
Expand All @@ -42,18 +35,18 @@ where
assert!(valid3.is_ok());
assert!(valid1.is_ok());

let g: P = ECPoint::generator();
let share1_public = g * secret_shares[0].clone();
let g = Point::generator();
let share1_public = g * &secret_shares[0];
let valid1_public = vss_scheme.validate_share_public(&share1_public, 1);
assert!(valid1_public.is_ok());

// test map (t,n) - (t',t')
let s = &vec![0, 1, 2, 3, 4];
let l0 = VerifiableSS::<P>::map_share_to_new_params(&vss_scheme.parameters, 0, &s);
let l1 = VerifiableSS::<P>::map_share_to_new_params(&vss_scheme.parameters, 1, &s);
let l2 = VerifiableSS::<P>::map_share_to_new_params(&vss_scheme.parameters, 2, &s);
let l3 = VerifiableSS::<P>::map_share_to_new_params(&vss_scheme.parameters, 3, &s);
let l4 = VerifiableSS::<P>::map_share_to_new_params(&vss_scheme.parameters, 4, &s);
let l0 = VerifiableSS::<E>::map_share_to_new_params(&vss_scheme.parameters, 0, &s);
let l1 = VerifiableSS::<E>::map_share_to_new_params(&vss_scheme.parameters, 1, &s);
let l2 = VerifiableSS::<E>::map_share_to_new_params(&vss_scheme.parameters, 2, &s);
let l3 = VerifiableSS::<E>::map_share_to_new_params(&vss_scheme.parameters, 3, &s);
let l4 = VerifiableSS::<E>::map_share_to_new_params(&vss_scheme.parameters, 4, &s);

let w = l0 * secret_shares[0].clone()
+ l1 * secret_shares[1].clone()
Expand All @@ -66,15 +59,12 @@ where
fn main() {
let curve_name = std::env::args().nth(1);
match curve_name.as_deref() {
Some("secp256k1") => secret_sharing_3_out_of_5::<curv::elliptic::curves::secp256_k1::GE>(),
Some("ristretto") => {
secret_sharing_3_out_of_5::<curv::elliptic::curves::curve_ristretto::GE>()
}
Some("ed25519") => secret_sharing_3_out_of_5::<curv::elliptic::curves::ed25519::GE>(),
Some("bls12_381") => {
secret_sharing_3_out_of_5::<curv::elliptic::curves::bls12_381::g1::GE>()
}
Some("p256") => secret_sharing_3_out_of_5::<curv::elliptic::curves::p256::GE>(),
Some("secp256k1") => secret_sharing_3_out_of_5::<Secp256k1>(),
Some("ristretto") => secret_sharing_3_out_of_5::<Ristretto>(),
Some("ed25519") => secret_sharing_3_out_of_5::<Ed25519>(),
Some("bls12_381_1") => secret_sharing_3_out_of_5::<Bls12_381_1>(),
Some("bls12_381_2") => secret_sharing_3_out_of_5::<Bls12_381_2>(),
Some("p256") => secret_sharing_3_out_of_5::<Secp256r1>(),
Some(unknown_curve) => eprintln!("Unknown curve: {}", unknown_curve),
None => eprintln!("Missing curve name"),
}
Expand Down
6 changes: 6 additions & 0 deletions src/arithmetic/big_gmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,12 @@ impl ring_algorithm::RingNormalize for BigInt {

crate::__bigint_impl_from! { u32, i32, u64 }

impl From<u16> for BigInt {
fn from(n: u16) -> Self {
BigInt::from(u64::from(n))
}
}

/// Internal helper trait. Creates short-hand for wrapping Mpz into BigInt.
trait Wrap {
fn wrap(self) -> BigInt;
Expand Down
6 changes: 6 additions & 0 deletions src/arithmetic/big_native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@ impl num_traits::Num for BigInt {

crate::__bigint_impl_from! { u32, i32, u64 }

impl From<u16> for BigInt {
fn from(n: u16) -> Self {
BigInt::from(u64::from(n))
}
}

impl BasicOps for BigInt {
fn pow(&self, exponent: u32) -> Self {
self.num.pow(exponent).wrap()
Expand Down
Loading

0 comments on commit 795da47

Please sign in to comment.