Skip to content
This repository has been archived by the owner on Nov 9, 2023. It is now read-only.

Last doc updates & benches for bumping to v0.2.0 #72

Merged
merged 6 commits into from
Jul 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions benchmarks/dusk_benchmarks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ mod scalar_benches {
mod edwards_benches {

use super::*;
use zerocaf::edwards::{EdwardsPoint, ProjectivePoint};
use zerocaf::edwards::{EdwardsPoint, ProjectivePoint, CompressedEdwardsY};
use zerocaf::scalar::Scalar;
use zerocaf::field::FieldElement;
use subtle::Choice;
Expand Down Expand Up @@ -159,6 +159,12 @@ mod edwards_benches {
/// `A = 182687704666362864775460604089535377456991567872`.
pub static A: Scalar = Scalar([0, 0, 0, 2, 0]);

/// `P1_EXTENDED on `CompressedEdwardsY` format.
pub(self) static P1_COMPRESSED: CompressedEdwardsY = CompressedEdwardsY([216, 221, 167, 21, 54, 234, 101, 84, 47,
55, 89, 137, 7, 175, 226, 87, 240, 1, 227,
18, 81, 168, 46, 95, 65, 36, 110, 118, 217,
246, 20, 140]);

pub fn bench_extended_point_ops(c: &mut Criterion) {
c.bench(
"Extended Coordinates Point Addition",
Expand Down Expand Up @@ -213,13 +219,28 @@ mod edwards_benches {
Choice::from(1u8))))
);
}

pub fn bench_point_compression_decompression(c: &mut Criterion) {
c.bench(
"Compress/Decompress",
Benchmark::new("Point compression.",
|b| b.iter(|| P1_EXTENDED.compress()))
);

c.bench(
"Compress/Decompress",
Benchmark::new("Point decompression.",
|b| b.iter(|| P1_COMPRESSED.decompress().unwrap()))
);
}
}

criterion_group!(benchmarks,
field_benches::bench_field_element_ops,
field_benches::bench_modular_inverse,
scalar_benches::bench_scalar_element_ops,
edwards_benches::bench_extended_point_ops,
edwards_benches::bench_projective_point_ops);
edwards_benches::bench_projective_point_ops,
edwards_benches::bench_point_compression_decompression);
//criterion_group!(benchmarks, field_benches::bench_modular_inverse);
LukePearson1 marked this conversation as resolved.
Show resolved Hide resolved
criterion_main!(benchmarks);
15 changes: 12 additions & 3 deletions src/backend/u64/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,6 @@ impl Mul<FieldElement> for FieldElement {
}
}


impl<'a,'b> Div<&'a FieldElement> for &'b FieldElement {
type Output = FieldElement;
/// Performs the op: `x / y (mod l)`.
Expand Down Expand Up @@ -309,7 +308,6 @@ impl Div<FieldElement> for FieldElement {
}
}


impl<'a> Square for &'a FieldElement {
type Output = FieldElement;
/// Compute `a^2 (mod l)`.
Expand Down Expand Up @@ -490,7 +488,10 @@ impl FieldElement {

/// Evaluate if a `FieldElement` is even or not.
pub fn is_even(self) -> bool {
self.0[0].is_even()
// Compare the last bit of the first limb to check evenness.
// 0b0 -> true
// 0b1 -> false
CPerezz marked this conversation as resolved.
Show resolved Hide resolved
self.0[0] & 0b01 == 0u64
}

pub fn generate_random() -> FieldElement {
Expand Down Expand Up @@ -1519,4 +1520,12 @@ pub mod tests {
assert!(res[i] == INV_MOD_C[i]);
}
}

#[test]
fn evenness() {
// Even number should return true.
assert!(A.is_even());
// Odd number should return false.
assert!(!B.is_even());
}
}
68 changes: 66 additions & 2 deletions src/edwards.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,70 @@
//! Edwards Point operation implementations and definitions.
//! Encoding/decoding processes implementations
//! and support for all kind of interactions with them.
//!
//! # Examples
//! ```rust
//! use zerocaf::edwards::*;
//! use zerocaf::traits::ops::*;
//! use zerocaf::traits::Identity;
//! use zerocaf::field::FieldElement;
//! use zerocaf::scalar::Scalar;
//!
//! use subtle::Choice;
//! use core::ops::{Add, Sub, Mul};
//!
//! // You can work in different point coordinates like
//! // Affine, Projective and Extended ones.
//! //
//! // It's highly recommended to work over Extended ones
//! // since are the fastest. And the ones you can compress
//! // directly.
//!
//! // In order to get a Point over the Doppio curve,
//! // you can do the following:
//!
//! // From a y-coordinate of a point:
//! let y = FieldElement([1799957170131195, 4493955741554471, 4409493758224495, 3389415867291423, 16342693473584]);
//! // The `Choice` specifies the symbol that we want to get as a result
//! // for the `x-coordinate`.
//! let ex_point = EdwardsPoint::new_from_y_coord(&y, Choice::from(0u8)).unwrap();
//!
//! // Create a random point.
//! let rngp = EdwardsPoint::new_random_point();
//!
//! // Get it from an AffinePoint or a ProjectivePoint:
//! let exampl = EdwardsPoint::from(&ProjectivePoint::identity());
//!
//! // The same examples work for the ProjectivePoint struct.
//!
//! // You can perform the following operations with an EdwardsPoint
//! // or a ProjectivePoint:
//!
//! // Point addition:
//! let p1 = &ex_point + &rngp;
//! // Point subtraction (which is a point negation and a sum):
//! let p2 = &ex_point - &rngp;
//! // Point doubling:
//! let p3 = &ex_point.double();
//! // Scalar mul:
//! let p4 = double_and_add(&ex_point, &Scalar::from(&8u8));
//!
//! // You can also multiply by the co-factor directly:
//! assert!(p4 == mul_by_cofactor(&ex_point));
//!
//! // In order to send points saving space, you can use
//! // compressed points, repressented as: `CompressedEwdardsY`.
CPerezz marked this conversation as resolved.
Show resolved Hide resolved
//!
//! // The only ways of getting a `CompressedEdwardsY` are:
//! // By compressing an `EdwardsPoint`:
//! let cp_point = rngp.compress();
//! // Note that you can get your EdwardsPoint back just by doing:
//! let decompr_point = &cp_point.decompress().unwrap();
//!
//! // You can also get a compressed point by copying it from a
//! // slice of bytes (as if it came from a socket or similar situations).
//! let cpedw = CompressedEdwardsY::from_slice(&cp_point.to_bytes());
//! ```

use crate::field::FieldElement;
use crate::scalar::Scalar;
Expand All @@ -11,7 +75,7 @@ use crate::traits::Identity;
use crate::traits::ops::*;


use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};
use subtle::{Choice, ConstantTimeEq};

use rand::{Rng, thread_rng};

Expand Down Expand Up @@ -171,7 +235,7 @@ impl CompressedEdwardsY {
/// # Note:
/// This function should only be used to get a
/// `CompressedEdwardsY` compressed point from
/// a [u8; 31] that we know that is already a
/// a [u8; 32] that we know that is already a
/// compressed point.
///
/// If this function is used with y-coordinates
Expand Down
9 changes: 9 additions & 0 deletions src/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
//! use zerocaf::field::FieldElement;
//! use zerocaf::traits::ops::*;
//! use zerocaf::constants::EDWARDS_D;
//! use subtle::Choice;
//!
//! // You can create a FieldElement from a byte-array as follows:
//! let a = FieldElement::from_bytes(&[0u8;32]);
Expand All @@ -20,6 +21,9 @@
//! let b = FieldElement::from(&86649u128);
//! let c = FieldElement::from(&86650u64);
//!
//! // You can create random FieldElements by calling:
//! let rand = FieldElement::generate_random();
//!
//! // The last way of creating a FieldElement it by calling the
//! // constructor. THIS IS NOT RECOMMENDED since NO checks about
//! // the correctness of the input will be done at all.
Expand All @@ -34,6 +38,11 @@
//! res = a * b; // Performs a * b (mod l).
//! res = a.square(); // Performs a^2 (mod l).
//! res = -&a; // Performs Negation over the modulo l.
//! res = a.pow(&b); // Performs Modular exponentiation.
//! res = a.mod_sqrt(Choice::from(1u8)).unwrap(); //Performs
CPerezz marked this conversation as resolved.
Show resolved Hide resolved
//! // modular sqrt.
//! // Returs `None` if the input is not a QR on the field.
//! // Returns Some(result) if everything is correct.
//!
//! // Division has been also implemented. Remember that when we write
//! // a/b (mod l), we are indeed performing a * inverse_mod(b, l) (mod l).
Expand Down
2 changes: 1 addition & 1 deletion src/scalar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
//! res = a.square(); // Performs a^2 (mod l).
//! res = -&a; // Performs Negation over the modulo l.
//!
//! // Dividing by two even Scalars is recommended through the `Half`
//! // Dividing even Scalars by two is recommended through the `Half`
//! // trait implmementation since it's much faster.
CPerezz marked this conversation as resolved.
Show resolved Hide resolved
//! if a.is_even() {
//! let half_c = c.half(); // This will panic if a isn't even.
Expand Down