Giter VIP home page Giter VIP logo

dusk-zerocaf's Introduction

Dusk-Zerocaf Build Status codecov GitHub closed issues Crates.io

WARNING: WIP Repo.

Fast, efficient and bulletproof-friendly cryptographic operations.

This repository contains an implementation of the Sonny curve over the Ristretto Scalar field: a pure Rust implementation designed by Dusk team.

Special thanks to Isis Agora Lovecruft and Henry de Valence for their implementation of Curve25519-dalek library, which has been so useful in order to get some of the basic arithmetic ops and the structure of our library.

Ristretto curve

Ristretto is a technique for constructing prime order elliptic curve groups with non-malleable encodings.

The Ristretto protocol arose as an extension of Mike Hamburg's Decaf approach to cofactor elimination, which is applicable to curves of cofactor 4, whereas the Ristretto is designed for non-prime-order curves of cofactor 8 or 4. Ristretto was designed by the dalek-cryprography team, specifically, Henry de Valence and Isis Agora Lovecruft to whom we greatly appreciate their work and dedication.

Ristretto Scalar Field And Bulletproofs.

Originally designed to abstract non-prime-order curves into prime-order scalar fields, the Ristretto abstraction would have been far too inefficient to implement for Bulletproofs zero-knowledge proof. Therefore the Ristretto scalar field is used to solve all negative impacts of using cofactors equalling 8 on the Ristretto curve.. The strategy is to use a Ristretto embedded curve (also called Sonny Curve), as the initial operations within zerocaf are performed therein. zerocaf opens up new opportunities for the use cases of zero-knowledge proofs inside the Dusk Network protocol as well as making a Bulletproof-integrated ring signature substitute possible, with orders of magnitude performance improvements compared to the fastest ringsig implementation.

Within this library, the implementation of the Ristretto to construct the curve with desired properties is made possible by defining the curve over the scalar field, using only a thin abstraction layer, which in turn allows for systems that use signatures to be safely extended with zero-knowledge protocols. These zero-knowledge protocols are utilised with no additional cryptographic assumptions and minimal changes in the code. The Ristretto scalar field is Bulletproof friendly, which makes it possible to use both cryptographic protocols in tandem with one another, as they are centric to contemporary applications of elliptic curve operations.

Details

Curve parameters:

Variable Value Explanation
Equation Edwards -x²+y²=1-$\frac{126296}{126297}$x²y² -
a -1 -
d $-\frac{126296}{126297}$ -
B $\frac{3}{5}$ Edwards Basepoint Y-coordinate With X > 0

Montgomery y²=x³+505186*x²+x
u(P) 4
A 505186

Weierstrass y²=x³+ax+b
a 7237005577332262213973186563042994240857116359379907606001950828033483786813
b 445582015604702849664
Variable Value Explanation
G 2²⁵² + 115924404605461509904689566245241897752 Curve order
p 2²⁵² + 27742317777372353535851937790883648493 Prime of the field
r 2²⁴⁹ + 15114490550575682688738086195780655237219 Prime of the Sub-Group

Encoding / Decoding tools

In order to work with our points along the curve, or any non trivial computuaions, for example those with tough notations - there has been a set of tools and examples which have been created to make facilitate the Encoding/Decoding processes. These can be found at: tools/src/main.rs

Examples

num_from_bytes_le(&[76, 250, 187, 243, 105, 92, 117, 70, 234, 124, 126, 180, 87, 149, 62, 249, 16, 149, 138, 56, 26, 87, 14, 76, 251, 39, 168, 74, 176, 202, 26, 84]);
// Prints: 38041616210253564751207933125345413214423929536328854382158537130491690875468
    
let res = to_field_elem_51(&"1201935917638644956968126114584555454358623906841733991436515590915937358637");
println!("{:?}", res);
// Gives us: [939392471225133, 1174884015108736, 2226020409917912, 1948943783348399, 46747909865470]

hex_bytes_le("120193591763864495696812611458455545435862390684173399143651559091593735863735685683568356835683");
// Prints: Encoding result -> [63, 41, b7, c, b, 79, 94, 7b, 21, d2, fe, 7b, c8, 89, c9, 7f, 76, c8, 9b, a3, 58, 18, 39, a, f2, d2, 7c, 17, ed, 7f, 6, c4, 9d, 44, f3, 7c, 85, c2, 67, e]
// Put the 0x by yourseleves and if there's any value alone like `c` padd it with a 0 on the left like: `0x0c`

from_radix_to_radix_10("1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab", 16u32);
// Prints: 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787

When performing operations with large values, such as: 2²⁵² - 121160309657751286123858757838224683208, it is recomended to compute them through SageMath, as the user interface adheres to these types of functions. From SageMath, they can be converted in a consistent format and easily compiled into Rust.

Roadmap:

Note: the refactoring relations are expressed as indentations

  • Build Scalar Arithmetics and Scalar Struct definition.
    • Find the proper radix value for FieldElement.
    • Add the required constants for computation.
      • Implement Addition.
      • implement Subtraction.
      • Implement Byte-encoding/decoding.
      • Implement From for uint native types.
      • Implement Ord, PartialOrd, Eq & PartialEq.
      • Implement Multiplication on u64-backend with u128 usage.
      • Implement Squaring.
      • Implement Half for even numbers.
      • Implement Modular Negation.
      • Implement Montgomery_reduction.
      • Define Montgomery_reduction algorithm.
  • Create FieldElement Struct and implement the basic operations we need on a u64 backend.
    • Find the proper radix value for FieldElement.
    • Add basic and needed constants.
    • Implement Reduce function to make the FieldElements fit on a 5 u64-bit limbs.
      • Implement Addition.
      • Implement Subtraction.
      • Implement Byte-encoding/decoding.
      • Implement From for uint native types.
      • Implement Ord, PartialOrd, Eq & PartialEq.
      • Implement Multiplication on u64-backend with u128 usage.
      • Implement Squaring.
      • Implement Half for even numbers
      • Implement Modular Negation.
      • Implement Montgomery_reduction.
      • Define Montgomery_reduction algorithm.
      • Implement Modular inversion.
      • Research about addition chains inversion methods.
    • Add proper tests for every function.
  • Implement Edwards Points
    • Implement Twisted Edwards Extended Coordiantes.
      • Implement Point Addition.
      • Implement Point Subtraction.
      • Implement Point Doubling.
      • Implement Scalar Mul.
      • Implement from_bytes conversions.
      • Implement to byte conversions.
      • Implement compressed Edwards point Y-coordinate.
    • Implement Twisted Edwards Projective Coordiates.
      • Implement Point Addition.
      • Implement Point Subtraction.
      • Implement Point Doubling.
      • Implement Scalar Mul.
      • Implement from_bytes conversions.
      • Implement to byte conversions.
      • Implement compressed Edwards point Y-coordinate.
    • Represent Edwards points as Ristretto points using wrapping type or struct.
    • Cargo doc testing and improvement.
    • Decide the best use cases of the various Edwards coordinate types (compressed, standard, extended, projective).
    • Benchmark different implementations and algorithms.
  • Implement Ristretto Mapping.
    • Implement 4coset debugging function.
    • Build and test torsion points.
    • Implement Ecoding & Decoding algorithms.
    • Implement Equalty testing.
    • Implement Elligator-ristretto-flavour.
    • Test all of the algorithms implemented.

dusk-zerocaf's People

Contributors

3for avatar autholykos avatar bellesmarta avatar cperezz avatar lukepearson1 avatar zer0 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

dusk-zerocaf's Issues

Implement ff traits on Scalar type

Describe what you want implemented
Implement https://github.com/zkcrypto/ff traits on Scalar type

Describe "Why" this is needed
A clear and concise description of why you need this to be implemented
We would like to use Sonny for circuits in https://github.com/microsoft/Spartan. Spartan requires scalars to implement the ff traits. If we implement the traits in Spartan then we need to create a wrapper type.

Describe alternatives you've considered
Implement Scalar wrapper that implements traits in Spartan.

Additional context
The source on github also seems to be out of sync with the crate with the same version number published to crates.io. Can we get a new release?

Thanks.

#ITEM 2 - ValidityCheck satisfied by 8L-order points

I implemented the ValidityCheck trait for RistrettoPoint as a "Debugging" tool more than any other thing, to allow us to check quickly if a point has order L and also satisfies the curve equation.

But after testing it, I noticed that something wrong is happening in 00f27d0.

For the point:

EdwardsPoint {
            X: FieldElement([3731501504646340, 2632059644919358, 1108201714444363, 744882977561776, 2025258919569]),
            Y: FieldElement([3013891596121777, 883213005096867, 3535650729451324, 1964766061767078, 17170538272920]),
            Z: FieldElement([1, 0, 0, 0, 0]),
            T: FieldElement([4309839181300502, 3141607060289509, 477484393435710, 4347613827760508, 5685771046887])
        };

We know that it has order 8L. This can be seen by running this test:

 #[test]
    fn point_order() {
        let p = EdwardsPoint {
            X: FieldElement([3731501504646340, 2632059644919358, 1108201714444363, 744882977561776, 2025258919569]),
            Y: FieldElement([3013891596121777, 883213005096867, 3535650729451324, 1964766061767078, 17170538272920]),
            Z: FieldElement([1, 0, 0, 0, 0]),
            T: FieldElement([4309839181300502, 3141607060289509, 477484393435710, 4347613827760508, 5685771046887])
        };

        println!("P: {:?}", p);
        println!("2P: {:?}", p * Scalar::from(&2u8));
        println!("4P: {:?}", p * Scalar::from(&4u8));
        println!("8P: {:?}", p * Scalar::from(&8u8));
        println!("LP: {:?}", p * constants::L);
        println!("8LP: {:?}", p * (Scalar::from(&8u8) * constants::L));
    }

We got this output:

P: 
        EdwardsPoint {
            X: FieldElement([3731501504646340, 2632059644919358, 1108201714444363, 744882977561776, 2025258919569]),
            Y: FieldElement([3013891596121777, 883213005096867, 3535650729451324, 1964766061767078, 17170538272920]),
            Z: FieldElement([1, 0, 0, 0, 0]),
            T: FieldElement([4309839181300502, 3141607060289509, 477484393435710, 4347613827760508, 5685771046887])
        };
2P: 
        EdwardsPoint {
            X: FieldElement([1581903538332981, 3897322517161954, 739470916735812, 3933839205066363, 14319678237084]),
            Y: FieldElement([3802412528702858, 4230217016052064, 21335598471067, 2125185184181581, 7058138582956]),
            Z: FieldElement([4291582830127351, 3139935631023128, 1765943667821979, 2750084873741768, 15359893862222]),
            T: FieldElement([880350716218136, 1157074269980283, 2545042651358370, 4347268629240480, 6169177924914])
        };
4P: 
        EdwardsPoint {
            X: FieldElement([3095863263405017, 3946080980994928, 582881671569195, 2584928177605537, 6953811421157]),
            Y: FieldElement([1252588343291005, 2688635240358084, 1739953009646032, 260082537088771, 14602768550509]),
            Z: FieldElement([4469763732334176, 83200972471014, 1580302563144246, 2231320620854224, 11798485432966]),
            T: FieldElement([3683428567497520, 1158112628503060, 56744773491027, 2635388843238068, 14036323062787])
        };
8P: 
        EdwardsPoint {
            X: FieldElement([4073812832481156, 32819470661162, 3868018734021392, 3904292247112958, 12699018628058]),
            Y: FieldElement([1917210661050587, 2207154946670874, 4296178259787701, 860290928123544, 9409911222067]),
            Z: FieldElement([2616222906903401, 1338241646821956, 3351746580267457, 344484677790574, 2765353590567]),
            T: FieldElement([4164579757689625, 1872627432887735, 1444893267671336, 4105352397272432, 6113706583096])
        };
LP: 
        EdwardsPoint {
            X: FieldElement([2343102587906502, 2760519207737545, 3330700626258293, 2681846281196326, 9383246181605]),
            Y: FieldElement([0, 0, 0, 0, 0]),
            Z: FieldElement([1606294061858997, 3766769899330158, 599503231942171, 2176372674299479, 16277867246398]),
            T: FieldElement([0, 0, 0, 0, 0])
        };
8LP: 
        EdwardsPoint {
            X: FieldElement([0, 0, 0, 0, 0]),
            Y: FieldElement([1, 0, 0, 0, 0]),
            Z: FieldElement([1, 0, 0, 0, 0]),
            T: FieldElement([0, 0, 0, 0, 0])
        };

So it's clear that the point has order 8L not L. But for some reason, the assertion:

assert!(RistrettoPoint(point_8L).is_valid().unwrap_u8() == 0u8);
fails.

Montgomery reduction on Scalar arithmetics.

Since we need a fast way to compute arithmetic operations on our Scalar field:

Scalar Field with modulo: r = 2^249 - 15145038707218910765482344729778085401

We will need to use the Montgomery reduction algorithm to perform operations as fast as possible. We need to figure out which values will be needed and the proper way of merging them with the implementation we are doing.

This is affecting the implementation of Scalar arithmetic functions like:

  • Scalar::mul()
  • Scalar::to_montgomery()
  • Scalar::from_montgomery()
  • Scalar::montgomery_reduce()

If at some point we want to enable 512-bit Scalar usage, this issue will also affect to the function:

  • Scalar::from_bytes_wide()

We have to explore between the development of the classical Montgomery reduction algorithm or move to something more optimized for our parameters.

ITEM 2 - Implement tests for Twisted Edwards Projective Point operation implementations.

This issue lives under the item: https://gitlab.dusk.network/dusk-org/tech/issues/2

After #48 is closed, it'll be necessary to have implemented all of the tests that we need to cover the implementations done for ProjectivePoint type.

We will need to research for new points and the results that the implemented operations should provide for them and then test them.

We can also get the Extended Coodinates points implemented in f90c86d and remove and remove the T coordinate, as was done on 3a4aabf.

Figure out the reduction of 277.... to make it fit on FieldElement u64 limbs.

Since we are working on a field with p = 2^252 + 27742317777372353535851937790883648493 we know that we can assume:

2^252 (mod p) = - 27742317777372353535851937790883648493

The problem is that we are working with FieldElement structs which are defined as:

pub struct FieldElement(pub(crate) [u64;5] );

And the elements defined into them are expressed in Radix-51 as the curve25519 paper suggests to improve the performance and enable easier implementations of the field arithmetics.

So we find troubles while implementing functions like:

reduce(foo: &FieldElement) -> FieldElement

Since 27742317777372353535851937790883648493 is bigger than the u64 MAX value we need to find a workaround.

Ideas:

  • Use Montgomery reduction and figure out how will it fit into our current implementation.
  • Find other ways of reducing the value or an alternative way of reducing it.

This problem is affecting the development of other functions that need this value which at the moment are:

  • FieldElement Subtraction implementation.
  • FieldElement Multiplication implementation.
  • FieldElement to_bytes() conversion.

Implement Random Point generation.

Since it will be a good idea to provide Random point generation for Twisted Edwards points, and we have the methods and codes (in python) needed to implement it, It would be nice to implement this at some point.

This implementation will need some previous developments:

  • Random FieldElement generation.
  • Legendre Symbol algorithm implementation to prove Quadratic residue relationships. See:
    def legendre_symbol(a, p):
  • Tonelli-Shanks algorithm to perform modular sqrt operations (maybe there are more performant methods, so it'll be nice to research a little bit also). See:
    def prime_mod_sqrt(a, p):

Implement `2^k` for FieldElement

Since we are working on the implementation of McIvor, Corinne & Mcloone, Maire & Mccanny, J.V.. (2004). Improved Montgomery modular inverse algorithm. Electronics Letters. 40. 1110 - 1112. 10.1049/el:20045610.

We realized on #9 that we needed to implement the operation 2^k for FieldElement where k is a u64 on the range: 0 .. 253.

Once this is done, we will be able to conclude the implementation started on: 457ef6e

Refactor Ristretto Point operations.

Reviewing the Ristretto implementation, and working also on #78 and #76 at the same time, I realized that the implementation done for Ristretto Point ops was not correct because:

The operations are mapped to the underlying EdwardsPoint that the RistrettoPoint represents (A RistrettoPoint is a wrapper type over EdwardsPoint).

This is correct, if you're working with an a and d values that satisfy the Ristretto constraints/requirements (a-d) is Quadratic Residue.
But in our case, since we chose the @ebfull tweet parameters which do not satisfy the Ristretto req. we also use another d value for our RistrettoPoint which is different from the one used on EdwardsPoint formulas.

This causes:

  • Encoding/Decoding functions are mapped to RISTRETTO_D instead of EDWARDS_D. (That's how it is implemented).
  • Point op. functions have to be mapped. Since we are working with an isomorphic twist that already provides the same Scalar field, and Sub-group orders, we need to map the operations since the RistrettoPoint operations cannot rely on EdwardsPoint ones because they are already mapped to a different d.

That second thing was not considered at the beginning and so we need to refactor it.

Knowledge of a secret key

Create a code snippet that works as follows:

Given a Scalar a that, provided only a · G, you prove you know a without revealing a.

Preferably with bulletproofs

Add Point addition tests / Field Addition tests.

In order to have properly tested our Field Arithmetics, tests should be added in order to verify that the addition is being performed as expected.

  • First, find two points that rely on the curve, get the coordinates (one at least to have the Field Element) and see that the test returns the expected value.
  • Implement a fast way of checking equality of FieldElements (inline if possible and also in constant-time).
  • Check out https://github.com/dalek-cryptography/subtle to see ConstantTime verifications.

#ITEM 1 - Implement point addition for Doppio.

This issue lives under the item: https://gitlab.dusk.network/dusk-org/tech/issues/1 and it's one of it's main goals.

We need now to implement point addition operations over the Doppio Curve using Projective Twisted Edwards coordinates.

Found a paper with good performant algorithms to implement them:
Source: 2008 Hisil–Wong–Carter–Dawson, http://eprint.iacr.org/2008/522, Section 3.1..

The algorithm costs are:

  • Cost: 9M + 1*a + 7add.
  • Cost: 9M + 1*a + 6add dependent upon the first point.

@Bounce23 mentioned that there are more efficient algorithms but we need to review them. But to at least have something working, the implementation of the algorithm mentioned above has been started on b45abc5

#ITEM 2 - Random point generation from Elligator does not produce valid points.

As it was mentioned in 2683d3c.

This has been done like this instead of generating
random RistrettoPoints directly since it caused the
tests to fail, meaning that something was wrong on the
random point generation using the Elligator hash-to-group
function.

What this means is that generating random RistrettoPoints using the Elligator hash-to-group function is not working as expected since it does not produce valid RistretttoPoints.

It will be better, in my opinion, to implement the random RistrettoPoint generation following the double Elligator application to a [0; 64] random-bytes slice as it's done in the ristretto.rs implementation done in the curve25519-dalek library.

Why?
As mentioned there, following this path, we get a uniformly distributed entropy -> Uniformly distributed random RistrettoPoint generation. Which is better than the one obtained multiplying the unique_basepoint by a random Scalar.

So we should take a look at the whole random-generation path to spot the error (if there is any) or otherways review the docs again.

#ITEM 1 - Review Phase 1 of Kalinski's algorithm.

Since the algorithm implemented on #9 was passing the tests, we thought that Phase I was working correctly.

But while working on #14 we realized the function only works for the tested value surprisingly ..

So now it's time to find the bug that it's affecting Phase I of the Kalinski's algorithm.

Implement Scalar::from_bytes_wide

Describe what you want implemented
Scalar::from_bytes_wide.

Describe "Why" this is needed
A clear and concise description of why you need this to be implemented
We would like to use Sonny for circuits in https://github.com/microsoft/Spartan.

Describe alternatives you've considered
curve25519-dalek but that library is not ZK friendly.

Additional context
The source on github also seems to be out of sync with the crate with the same version number published to crates.io. Can we get a new release?

Thanks.

#ITEM 1 - Solve addition for FIELD_L on Phase II.

This issue is under the item: https://gitlab.dusk.network/dusk-org/tech/issues/1.

This issue comes from #15 solution while checking the correctness of #12 implementing the Savas & Koç algorithm in #14 .

An error has appeared on the Phase II algorithm while we performing the addition: rr + p since it should give an even number but gives an odd one.
Due to this, half() function does not do the job correctly since it's dividing odd numbers and the decimals should be rounded, not truncated.

Improve performance on modulo powers operations

Currently, the modulo exponentiation (or power modulo) in the library is documented under src/traits.rs, and is coded as:
` pub trait Pow {
type Output;

    #[must_use]
    /// Returns  `a^b (mod l)`. 
    fn pow(self, exp: T) -> Self::Output;`.

Exponentiation operations calculates the remainder when the integer a, is raised to the b'th power, and b is divided by the positive integer l. These operations are expensive for a CPU as when they become iterative each multiplication takes at least twice as long as the previous one. As they are not done to an order of (O(log b)).
As these operations are done continuously when representing Edwards points as Ristretto points then the optimisation of the process needs to be worked on. Examples and ideas will be marked below, then implemented and then benchmarked.

Implement CT evenness checking using subtle's Choice.

Since is_even() function calls inside the primitive type u64 is_even() function, it will be faster to take a workaround to enable even faster even numbers checking.ç

The workaround will be something similar to:

Let a be a Scalar or FieldElement which we don't know if it's even or not.

It'll be something similar to:

// Check even by applying an AND logical operator, to see if the last bit of `a` is set
// to `1` or `0`. 
pub fn is_even(&self) -> Choice {
   Choice::from((a[0] & 1u64) as u8)
}

Then, with the result, return a Choice which is a subtle type implemented by Isis Agora Lovecruft and Henry de Valence.

Highly performant inverse square root operations

The inverse square root operations is fundamental to the Ristretto operations. This is due to division. As division and exponentiation are expensive for a CPU to perform, inverse modular operations are used when any such operations need to be programmed.

For example taking 1/(√x), there is both a division and an exponentiation. For this, a modular inverse square root computes 1 multiplied by inverse mod of square root x.


There are multiple ways to compute the aforementioned calculation. This issue is opened to explore the various ways we can implement inverse square root. In general, the non-Euclidian methods provide shorter operation times but it doesn't necessarily mean this will be the case for us. This is a result of which sign choices we assign as well as which canonical endings we need to omit.


The issue will document which properties we seek from computed as well as benchmarks of various implemented inverse square root algorithms.

ITEM 2 - Provide support for Point Operations expressed in Projective Coordinates.

This issue lives under the item: https://gitlab.dusk.network/dusk-org/tech/issues/2

Following the notes on the paper: Source: 2008 Hisil–Wong–Carter–Dawson, we need to give support for all of the Twisted Edwards Point Operations.

The list will be:

  • Point Addition.
  • Point Subtraction.
  • Point Doubling.
  • Scalar Multiplication per Point.

It's also important to follow the guidelines explained in #47 to enable easier further implementations.

PR Sonny paper in ZeroCaf GH repo

The most recent version of the Sonny paper is on overleaf. The recent changes should be updated in the ZeroCaf GitHub repository.

Determine p-adicity

All of the safe curve criteria are documented in the docs. With the idea of using Zerocaf to run trustless setups, we would need to determine how large the polynomial roots are. This is derived directly with the adicity of the curve.

The adicity will determine the speed and expense of a trustless set up for creating public parameters.

#ITEM 2 - Ristretto Implementation over Sean's Doppio Curve

Since the curve that Sean provided in:

Here's an "embedded" curve over ristretto255's scalar field

-x^2 + y^2 = 1 - (86649/86650)x^2y^2

which is Ristretto-ready and birationally equivalent to

y^2 = x^3 + 346598x^2 + x (and it's twist secure)

Any other suggestions?

— Sean Bowe (@ebfull) January 22, 2019

Provides values for the Twisted Edwards form that aren't suitable for a Ristretto protocol implementation we have two options:

  • Find an isomorphic twist that allows us to mantain the same orders for the Finite Field and also the Sub group, and at the same time, gives a & d values that are suitable for a Ristretto implementation.

  • Choice a diferent curve. This will force us to:

    • Find the new order of the Sub group and refactor the Scalar implementation to work over the new order and implement Decaf or Ristretto depending on the co-factor that the new curve provides.

It seems that @Bounce23 found an isomorphic twist that can do the job. We will update here the discussions.

#ITEM 2 - Get testing values for Point Operations.

We need to get values to test the implementations done for:

  • Point Addition.
  • Point Subtraction.
  • Point Doubling.
  • Point Compression.
  • TwEdws -> Montgomery Conversion.

We should get the values and the expected results with sage in order to be able to test every operation.

Implement Montgomery arithmetics for Savas & Koç inversion algorithm.

This issue is derived from #9 .

Since we decided to implement The Montgomery Modular Inverse.
Implementation of McIvor, Corinne & Mcloone, Maire & Mccanny, J.V.. (2004).
Improved Montgomery modular inverse algorithm.
Electronics Letters. 40. 1110 - 1112. 10.1049/el:20045610.

References:
J Cryptogr Eng (2018) 8:201–210
SPECIAL ISSUE ON MONTGOMERY ARITHMETIC - Montgomery inversion
Erkay Sava ̧s · Çetin Kaya Koç

Was mentioned on the paper leaved avobe that to improve the performance of the Modular Montgomery Inverse Algorithm, the Montgomery Modulus should be changed for R^n where n = log2[P] = log2[ 2^252 + 27742317777372353535851937790883648493 ] = 235.

This statement forces us to implement again the following Montgomery Arithmetic functions for the new Montgomery Modulus:

  • to_montgomery().
  • from_montgomery().
  • montgomery_mul().
  • montgomery_reduce() -> This also makes us compute the new LFACTOR.

Implement Montgomery modular inverse algorithm

After continuous review of the possible algorithms, the decided algorithm will be the one implemented by 'E. Savas, C. K. Koc', :- 'http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.75.8377&rep=rep1&type=pdf'

The chosen Montgomery modular inverse algorithm divides the fore computation into two parts, Phase 1 & Phase 2.

Problems to address:

  • Outline values for both phases s.t. they multiply to 1 (mod p)
  • Determine whether the output values will be even or odd. Initial even values must be divided by 2 and then 2p is used for modulo

ITEM 2 - Implement Cipolla prime modular sqrt algorithm and benchmark against Tonelli-Shanks

This issue lives under the item: https://gitlab.dusk.network/dusk-org/tech/issues/2

Since the number of operations required for the algorithm is 4 m + 2 k − 4 multiplications and 4m-2 sums, where m is the number of digits in the binary representation of p and k is the number of ones in this representation.

This means that Cipolla's algorithm should be faster than Tonelli-Shanks, so we should implement it and benchmark both to get the most performant one.

ITEM 2 - Implement and test Add_and_Double for Point multiplication over Doppio.

This issue lives under the item: https://gitlab.dusk.network/dusk-org/tech/issues/2

The last operation to implement over the Doppio Curve is add and doubling which allows us to:

Given k and G compute P = kG.

In order to do it, we should design a table with pre-computed values [G, 2G, 4G, 8G, 16G .... ] So we can then pick just the ones we need seeing our Scalar in binary form.

I think this can reduce the amount of time we spend computing against adding a point to itself Scalar times.

For a better understanding, take a look at:
enter image description here

Maybe @decentralisedkev can help us discussing about the implementation possibilities.

Implement Into_Iter for EdwardsPoint and RistrettoPoint

It would be nice to have an implementation that returns an iterator over the 4 coordinates of a RistrettoPoint or an EdwardsPoint.

Ex:

use zerocaf::edwards::EdwardsPoint;
use zerocaf::traits::Identity();
let identity = EdwardsPoint::Identity();
identity.into_iter().map(|coordinate| do_something_with_cooord(coordinate)).collect();

Implement point generation tools.

Since the end-user will need to create/generate/import points into the corresponding coordinates encoding: EdwardsPoint or ProjectivePoint, we need to provide methods for it as:

  • new_random_point()
  • new_from_x_coord()

This can be done by implementing:

  • Legendre Symbol algorithm to check for quadratic residue properties.
  • Tonelli_Shanks algorithm to perform the modular sqrt operation over the finite field where the Doppio curve lives.

Both implementations should create a ProjectivePoint which can be easily converted to an EdwardsPoint by 3M + 1I

Any other suggestions about from where we can generate new points? @Bounce23

ITEM 2 - Implement all of `FieldElement` and `Scalar` operations for non-reference values

This issue lives under the item: https://gitlab.dusk.network/dusk-org/tech/issues/2

Some implementations have the issue called Eye of Sauron by Dalek guys team on it's Curve25519 RustConf talk, which consists of something that looks like:

let A = &(&(&(&(&self.X + &self.Y) * &(&other.X + &other.Y)) - &C) - &D);

As can be seen, it turns out much more complex and uncomfortable to write these kinds of operatios.

This problem comes from the implementation of the Add and other Traits, which are always implemented for &'a TRAIT. So in order to avoid this, we should implement all of the FieldElement, Scalar, EdwardsPoint and ProjectivePoint for non-reference items.

Finish Zerocaf paper

The Zerocaf paper is now centric around Fq arithmetic inside of Fq circuits. This is to be finished and put into Review prior to an IACR.

This Epic will have to include iterations of each of the sections and then their individual review.

#ITEM 2 - Finnish docs and examples for Ristretto release

Currently, we need to:

  • Add some docs about how Ristretto works and some code examples on the ristretto.rs file.
  • Review all of the library comments in order to make sure that they are correct.
  • Refactor the examples of the library and include a ECDH one.

#ITEM 2 - Document update for new curve constants.

Since we derived a new curve from a modified version of this @ebfull script:
https://github.com/zkcrypto/jubjub/blob/master/doc/derive/derive.sage

We got new constants and then the Curve order & the Sub-group order changed.

The scalar backend was refactored & documented again with the proper values, and constants modules too. See: 405f541 & e1a9249

But we need to:

  • Refactor Readme and library comments with the new curve name and constant values.
  • Refactor the doc-comments.
  • Refactor the Sage scripts that need it.

Implement 4-coset function for `RistrettoPoint`

Be able to print the 4-coset where a RistrettoPoint lives could be really helpful in order to debug lots of conversions and functions inside of this library.

The 4cosets where EdwardsPoints are aggregated in order to encode their values to the Ristretto Scalar Field, are defined here: https://ristretto.group/details/isogeny_encoding.html#torquing-points-to-lift-mathcal-e--mathcal-e4-to-mathcal-e--mathcal-e2-
and also on the Decaf paper Section 3.0.

I recently took them values and checked them against the curve25519-dalek library (they had a cyclic 8-torsion group defined where 4 of the points where the way for going to the 4-coset points of the given RistrettoPoint). See this section of their code.

The points obtained where:

// Ristretto EIGH TORSION curve25519-dalek
// (X, Y, Z, T) in descendent order format.
0
1
1
0


14399317868200118260347934320527232580618823971194345261214217575416788799818
55188659117513257062467267217118295137698188065244968500265048394206261417927
1
49249569669750663008941572433996126643240416652669157144375776867115012622209


38214883241950591754978413199355411911188925816896391856984770930832735035197 -sqrt(a) // 1/sqrt(a)
0
1
0


14399317868200118260347934320527232580618823971194345261214217575416788799818
2707385501144840649318225287225658788936804267575313519463743609750303402022
1
8646474948907434702843920070347827283394575680151124875353015136841552197740


0
57896044618658097711785492504343953926634992332820282019728792003956564819948  a
1
0


43496726750457979451437558183816721346016168361625936758514574428539776020131
2707385501144840649318225287225658788936804267575313519463743609750303402022
1
49249569669750663008941572433996126643240416652669157144375776867115012622209


19681161376707505956807079304988542015446066515923890162744021073123829784752 (sqrt(a))
0
1
0


43496726750457979451437558183816721346016168361625936758514574428539776020131
55188659117513257062467267217118295137698188065244968500265048394206261417927
1
8646474948907434702843920070347827283394575680151124875353015136841552197740

The ones we are interested in (which are already the easiest) are:

- The RistrettoPoint that we used as input (Which = P).

- `P + (-sqrt(a), 0, 1, 0)`.

- `P + (0, a, 1, 0)`.

- `P + (sqrt(a), 0, 1, 0)`.

Review Decaf's paper to figure out the Edwards points treatment & Compression.

In order to understand the Edwards points treatment and conversion into FieldElements and further conversions to Ristretto Scalars, read the Decaf Paper

With this, we will start the Edwards Point compression implementation and further conversions.
This may also give us some light about the whole process in order to avoid EC point operations for Ristretto Scalar's equivalent ones.

#ITEM 2 - Implement Affine Coordinates over Doppio.

This issue lives under the item: https://gitlab.dusk.network/dusk-org/tech/issues/2

Affine coordinates are the conventional way of expressing elliptic curve points, which uses 2 coordinates. The math is concise and easy to follow.

For a pair of constants a and b, an elliptic curve is defined by the set of all points (x,y) that satisfy the equation y2=x3+ax+b, plus a special “point at infinity” named O.

We should provide support for the point operations over this coordinates and also implement point Eq trait for them as all other Point implementations will rely on it.

The skeleton was started in 5d2928e and needs some work on it.
We will need to implement:

  • Point Addition
  • Point Doubling
  • Point Generation
  • Scalar Multiplication
  • Point Eq implementation and derive the others to this one
  • Point conversions

Ristretto Basepoint issues on Compression/Decompression process.

The standard behavior of the RistrettoPoint works like:

RistrettoPoint --> compression --> CompressedRistretto
CompressedRistretto --> decompression --> RistrettoPoint

Obviously, the expected behavior for a point compression followed by a point decompression is to obtain the same exact point in Twisted Edwards Extended Coordinates.
We should obtain the same RistrettoPoint we used as input.

Also, with the equality formulas that appear on:
https://ristretto.group/formulas/equality.html this statement mentioned above should happen always.

So after making some tests, I verified that:

 #[test]
 fn point_comp_decomp_equivalence() {
        // This should give the RISTRETTO_BASEPOINT. 
        assert!(constants::RISTRETTO_BASEPOINT.compress().decompress().unwrap() ==       constants::RISTRETTO_BASEPOINT);
    }

//This test does not pass and it should.

This happened on: e8066b5 and my ideas are:

  • The Basepoint is not the one on it's 4-coset that would be encoded as RistettoPoint.
  • The compression/decompression processes are not working as expected.
  • The point really pertains to the coset and current equalty does not catch it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.