Skip to content

Commit

Permalink
Development (#16)
Browse files Browse the repository at this point in the history
* Initial integration with elliptic curves without hashing and serialisation

* Restore hashing functionality

* Abstract Jacobian coordinates

* Attempt to integrate galois-field-0.4 and elliptic-curve-0.2

* Refactor all square roots and Y from X functions

* Relocate field and curve parameters and refactor conjugation and scalar multiplication

* Remove redundant tests and reorganise tests layout

* Remove redundant benchmarks and reorganise benchmarks layout

* Refactor Shallue-van de Woestijne encoding

* Update benchmarks

* Restore serialisation codebase

* Update change log and remove dependencies

* Update elliptic-curve version

* Remove redundant hashToG1 commented code

* Rename pairing module for refactoring

* Add pairing class

* Add Barreto-Naehrig class

* Prepend Math to modules

* Update Galois fields and elliptic curves

* Rename Math modules to Data

* Fix tests and benchmarks compatibility

* Restructure tests and benchmarks layout

* Replace data families with types

* Fix hash function

* Relocate BN254 curve

* Restructure library layout

* Fix failing test

* Relocate Pairing class

* Restore G2 to BN254T of elliptic-curve and GT to RootsOfUnity Fq12 of galois-field

* Improve performance of final exponentiation

* Remove redundant roots of unity

* Add BLS12381 skeleton

* Add tests and benchmarks for roots of unity

* Add Ate and Hash skeleton for BLS12381

* Update Galois fields

* Add BLS48581, BN254A, BN254B, BN462 curves

* Add optimal Ate pairings for BN254A and BN254B curves

* Add type families and instances

* Restructure tests and benchmarks layout

* Add preliminary implementation of general optimal ate pairing algorithm

* Refactor optimal ate pairing of Barreto Naehrig curves

* Relocate individual curves into families

* Add Barreto Lynn Scott pairings

* Add Barreto-Naehrig phantom type and remove BN254 unity module

* Remove undecidable instances

* Refactor BN254A, BN254B, and BN462 modules

* Rename curve families

* Relocate curve modules

* Remove base modules

* Fix tests compilation

* Add tests for Barreto-Naehrig curves and fix loop temporarily

* Fix BN254A parameters

* Optimise by removing line function

* Fix BN462 parameters

* Fix benchmarks compilation

* Fix BN254B parameters

* Remove field tests and benchmarks

* Fix BLS12381 parameters

* Remove bytes and serialisation temporarily

* Revert family refactoring

* Refactor complex conjugation

* Add BN254C and BN254D curves

* Refactor frobenius endomorphism

* Add IsList instances

* Add roots of unity function

* Remove field conversions

* Improve final exponentiation for Barreto-Naehrig curves

* Improve final exponentiation for Barreto-Lynn-Scott curves

* Add comments and improve layout

* Add supported curves

* Remove frobenius function

* Update poly version

* Update dependencies

* Implement final exp bls48 easy part

* Add hard part of final exponentiation for BLS48-581

* Relocate parameters to top level

* Remove semirings dependency

* Add polymorphic Shallue-van de Woestijne encoding hashing function to Barreto-Naehrig curves

* Add Shallue-van de Woestijne encoding hashing function to Barreto-Lynn-Scott curves TODO and hide BLS48-581 tests

* Remove BLS48-581 temporarily

* Refactor line function

* Refactor final step

* Update hash functions

* Improve Haddock documentation

* Add field and curve tests

* Update Galois fields

* Update elliptic curves

* Update change log, README, and documentation

* Remove unnecessary dependencies

* Update pairing example
  • Loading branch information
David Kurniadi Angdinata authored and sdiehl committed Sep 27, 2019
1 parent ff42eb0 commit 18b3dd5
Show file tree
Hide file tree
Showing 45 changed files with 2,328 additions and 1,409 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ pairing.cabal
*.hi
*.o
.ghc.environment.*
dist*/
dist*/
TAGS
28 changes: 21 additions & 7 deletions ChangeLog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
# Change log for pairing

## 0.5
## 1.0.0

* Refactor library structure from `Pairing.Pairing` to `Data.Pairing`.
* Rename `reducedPairing` to `pairing` and remove `atePairing`.
* Add major optimisations to `pairing` with detailed documentation.
* Add BN254, BN254A, BN254B, BN254C, BN254D, BN462, BLS12381 curves.
* Add polymorphism of `pairing` for BN curves and BLS12 curves.
* Add polymorphism of `swEncBN` to BN curves.
* Fix dependency issue with `galois-field` and `elliptic-curve`.

## 0.5.1

* Prepend `Math` to modules.

## 0.5.0

* Use `elliptic-curve` for BN254 elliptic curve group operations.
* Refactor Shallue-van de Woestijne encoding for efficiency.
Expand All @@ -15,21 +29,21 @@
* Add mclwasm compatible serialisation.
* Add efficient storage representation of an elliptic curve point over prime fields.

## 0.4
## 0.4.0

* Use `galois-field` for tower field underlying BN254 curve.

## 0.3.1

* Use `MonadRandom` typeclass constraints for curve hashing functions.

## 0.3
## 0.3.0

- Square root calculation on Fq2.
- Both square roots returned on Fq.
- Point serialisation for G1, G2 and GT.
* Square root calculation on Fq2.
* Both square roots returned on Fq.
* Point serialisation for G1, G2 and GT.

## 0.2
## 0.2.0

* Add Shallue-van de Woestijne encoding for curve hashing.

Expand Down
54 changes: 27 additions & 27 deletions Example.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,36 @@ module Main where

import Protolude

import Pairing.Group
import Pairing.Pairing
import Pairing.Point
import Pairing.Fq (Fq(..))
import Pairing.Fq2 (Fq2(..))
import Data.Group (pow)
import Data.Curve.Weierstrass (Point(A), mul')

e1 :: G1
e1 = Point
(Fq 1368015179489954701390400359078579693043519447331113978918064868415326638035)
(Fq 9918110051302171585080402603319702774565515993150576347155970296011118125764)
import Data.Pairing.BN254 (BN254, G1, G2, pairing)

p :: G1 BN254
p = A
1368015179489954701390400359078579693043519447331113978918064868415326638035
9918110051302171585080402603319702774565515993150576347155970296011118125764

e2 :: G2
e2 = Point
(Fq2
(Fq 2725019753478801796453339367788033689375851816420509565303521482350756874229)
(Fq 7273165102799931111715871471550377909735733521218303035754523677688038059653)
)
(Fq2
(Fq 2512659008974376214222774206987427162027254181373325676825515531566330959255)
(Fq 957874124722006818841961785324909313781880061366718538693995380805373202866)
)

q :: G2 BN254
q = A
[2725019753478801796453339367788033689375851816420509565303521482350756874229
,7273165102799931111715871471550377909735733521218303035754523677688038059653
]
[2512659008974376214222774206987427162027254181373325676825515531566330959255
,957874124722006818841961785324909313781880061366718538693995380805373202866
]

main :: IO ()
main = do
putText "Ate pairing:"
print (atePairing e1 e2)
let
lhs = reducedPairing (gMul e1 2) (gMul e2 3)
rhs = (reducedPairing e1 e2)^(2 * 3)
putText "Is bilinear:"
print (lhs == rhs)
main = do
putText "P:"
print $ p
putText "Q:"
print $ q
putText "e(P, Q):"
print $ pairing p q
putText "e(P, Q) is bilinear:"
print $ pairing (mul' p a) (mul' q b) == pow (pairing p q) (a * b)
where
a = 2 :: Int
b = 3 :: Int
91 changes: 42 additions & 49 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,39 +34,39 @@ A simple example of calculating the optimal ate pairing given two points in G<su
```haskell
import Protolude

import Pairing.Group
import Pairing.Pairing
import Pairing.Point
import Pairing.Fq (Fq(..))
import Pairing.Fq2 (Fq2(..))

e1 :: G1
e1 = Point
(Fq 1368015179489954701390400359078579693043519447331113978918064868415326638035)
(Fq 9918110051302171585080402603319702774565515993150576347155970296011118125764)


e2 :: G2
e2 = Point
(Fq2
(Fq 2725019753478801796453339367788033689375851816420509565303521482350756874229)
(Fq 7273165102799931111715871471550377909735733521218303035754523677688038059653)
)
(Fq2
(Fq 2512659008974376214222774206987427162027254181373325676825515531566330959255)
(Fq 957874124722006818841961785324909313781880061366718538693995380805373202866)
)
import Data.Group (pow)
import Data.Curve.Weierstrass (Point(A), mul')

import Data.Pairing.BN254 (BN254, G1, G2, pairing)

p :: G1 BN254
p = A
1368015179489954701390400359078579693043519447331113978918064868415326638035
9918110051302171585080402603319702774565515993150576347155970296011118125764


q :: G2 BN254
q = A
[2725019753478801796453339367788033689375851816420509565303521482350756874229
,7273165102799931111715871471550377909735733521218303035754523677688038059653
]
[2512659008974376214222774206987427162027254181373325676825515531566330959255
,957874124722006818841961785324909313781880061366718538693995380805373202866
]

main :: IO ()
main = do
putText "Ate pairing:"
print (atePairing e1 e2)
let
lhs = reducedPairing (gMul e1 2) (gMul e2 3)
rhs = (reducedPairing e1 e2)^(2 * 3)
putText "Is bilinear:"
print (lhs == rhs)
main = do
putText "P:"
print $ p
putText "Q:"
print $ q
putText "e(P, Q):"
print $ pairing p q
putText "e(P, Q) is bilinear:"
print $ pairing (mul' p a) (mul' q b) == pow (pairing p q) (a * b)
where
a = 2 :: Int
b = 3 :: Int
```

## Pairings in cryptography
Expand Down Expand Up @@ -120,27 +120,21 @@ at(Q,P) = f<sub>r,Q</sub>(P)<sup>(q<sup>k</sup> - 1) / r</sup>

## Implementation

We have implemented the optimal Ate pairing over the BN128 curve, i.e. we define `q` and `r` as

* q = 36t<sup>4</sup> + 36t<sup>3</sup> + 24t<sup>2</sup> + 6t + 1
* r = 36t<sup>4</sup> + 36t<sup>3</sup> + 18t<sup>2</sup> + 6t + 1
* t = 4965661367192848881
We have implemented a polymorphic optimal ate pairing over the following pairing-friendly elliptic curves:

The tower of finite fields we work with is defined as follows:
* Barreto-Lynn-Scott degree 12 curves
* [BLS12381](src/Data/Pairing/BLS12381.hs)
* Barreto-Naehrig curves
* [BN254](src/Data/Pairing/BN254.hs)
* [BN254A](src/Data/Pairing/BN254A.hs)
* [BN254B](src/Data/Pairing/BN254B.hs)
* [BN254C](src/Data/Pairing/BN254C.hs)
* [BN254D](src/Data/Pairing/BN254D.hs)
* [BN462](src/Data/Pairing/BN462.hs)

* F<sub>q</sub> is the prime field with characteristic `q`
* F<sub>q<sup>2</sup></sub> := F<sub>q</sub>[u]/u<sup>2</sup> + 1
* F<sub>q<sup>6</sup></sub> := F<sub>q<sup></sub>2</sup>[v]/v<sup>3</sup> - (9 + u)
* F<sub>q<sup>12</sup></sub> := F<sub>q<sup>6</sup></sub>[w]/w<sup>2</sup> - v
A more detailed documentation on their domain parameters can be found in our [elliptic curve library](https://github.com/adjoint-io/elliptic-curve).

The groups' definitions are:

* G<sub>1</sub> := E(F<sub>q</sub>), with equation y<sup>2</sup> = x<sup>3</sup> + 3
* G<sub>2</sub> := E'(F<sub>q<sup>2</sup></sub>), with equation y<sup>2</sup> = x<sup>3</sup> + 3 / (9 + u)
* G<sub>T</sub> := μ<sub>r</sub>, i.e. the `r`-th roots of unity subgroup of the multiplicative group of F<sub>q<sup>12</sup></sub>

License
-------
## License

```
Copyright (c) 2018-2019 Adjoint Inc.
Expand All @@ -163,4 +157,3 @@ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
OR OTHER DEALINGS IN THE SOFTWARE.
```

35 changes: 35 additions & 0 deletions bench/Bench/Hash.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
module Bench.Hash where

import Protolude

import Criterion.Main
import Data.Pairing
import qualified Data.Pairing.BLS12381 as BLS12381
import qualified Data.Pairing.BN254 as BN254
import qualified Data.Pairing.BN254A as BN254A
import qualified Data.Pairing.BN254B as BN254B
import qualified Data.Pairing.BN254C as BN254C
import qualified Data.Pairing.BN254D as BN254D
import qualified Data.Pairing.BN462 as BN462
import Data.Pairing.Hash

benchHash :: Benchmark
benchHash = bgroup "Shallue-van de Woestijne encoding hashing"
[ bench "BN254" $
nfIO (swEncBN test_hash :: IO (Maybe (G1 BN254.BN254)))
, bench "BN254A" $
nfIO (swEncBN test_hash :: IO (Maybe (G1 BN254A.BN254A)))
, bench "BN254B" $
nfIO (swEncBN test_hash :: IO (Maybe (G1 BN254B.BN254B)))
, bench "BN254C" $
nfIO (swEncBN test_hash :: IO (Maybe (G1 BN254C.BN254C)))
, bench "BN254D" $
nfIO (swEncBN test_hash :: IO (Maybe (G1 BN254D.BN254D)))
, bench "BN462" $
nfIO (swEncBN test_hash :: IO (Maybe (G1 BN462.BN462)))
, bench "BLS12381" $
nfIO (swEncBN test_hash :: IO (Maybe (G1 BLS12381.BLS12381)))
]

test_hash :: ByteString
test_hash = "TyqIPUBYojDVOnDPacfMGrGOzpaQDWD3KZCpqzLhpE4A3kRUCQFUx040Ok139J8WDVV2C99Sfge3G20Q8MEgu23giWmqRxqOc8pH"
53 changes: 53 additions & 0 deletions bench/Bench/Pairing.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
module Bench.Pairing where

import Protolude

import Criterion.Main
import Data.Curve
import Data.Pairing
import qualified Data.Pairing.BLS12381 as BLS12381
import qualified Data.Pairing.BN254 as BN254
import qualified Data.Pairing.BN254A as BN254A
import qualified Data.Pairing.BN254B as BN254B
import qualified Data.Pairing.BN254C as BN254C
import qualified Data.Pairing.BN254D as BN254D
import qualified Data.Pairing.BN462 as BN462

benchPairing :: Benchmark
benchPairing = bgroup "Optimal ate pairing"
[ bench "BLS12381" $
nf (uncurry pairing) bls12381
, bench "BN254" $
nf (uncurry pairing) bn254
, bench "BN254A" $
nf (uncurry pairing) bn254a
, bench "BN254B" $
nf (uncurry pairing) bn254b
, bench "BN254C" $
nf (uncurry pairing) bn254c
, bench "BN254D" $
nf (uncurry pairing) bn254d
, bench "BN462" $
nf (uncurry pairing) bn462
]

bls12381 :: (G1 BLS12381.BLS12381, G2 BLS12381.BLS12381)
bls12381 = (gen, gen)

bn254 :: (G1 BN254.BN254, G2 BN254.BN254)
bn254 = (gen, gen)

bn254a :: (G1 BN254A.BN254A, G2 BN254A.BN254A)
bn254a = (gen, gen)

bn254b :: (G1 BN254B.BN254B, G2 BN254B.BN254B)
bn254b = (gen, gen)

bn254c :: (G1 BN254C.BN254C, G2 BN254C.BN254C)
bn254c = (gen, gen)

bn254d :: (G1 BN254D.BN254D, G2 BN254D.BN254D)
bn254d = (gen, gen)

bn462 :: (G1 BN462.BN462, G2 BN462.BN462)
bn462 = (gen, gen)
6 changes: 3 additions & 3 deletions benchmarks/Main.hs → bench/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import Protolude

import Criterion.Main

import HashBenchmarks
import PairingBenchmarks
import Bench.Hash
import Bench.Pairing

main :: IO ()
main = defaultMain
[benchmarkHash, benchmarkPairing]
[benchHash, benchPairing]
17 changes: 0 additions & 17 deletions benchmarks/HashBenchmarks.hs

This file was deleted.

34 changes: 0 additions & 34 deletions benchmarks/PairingBenchmarks.hs

This file was deleted.

Loading

0 comments on commit 18b3dd5

Please sign in to comment.