From a76336549b089ba477470c73cf3be60a02667bdf Mon Sep 17 00:00:00 2001 From: cheatfate Date: Thu, 4 Oct 2018 21:54:21 +0300 Subject: [PATCH] Added AffinePoint[G1,G2] initalization procedures. Added more tests from Paritytech fork. Removed Coeff[T] type. --- bncurve/arith.nim | 3 ++- bncurve/fp.nim | 2 ++ bncurve/fq12.nim | 2 ++ bncurve/fq2.nim | 2 ++ bncurve/fq6.nim | 2 ++ bncurve/groups.nim | 38 +++++++++++++++++++++++++++----------- tests/tpairing.nim | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 83 insertions(+), 12 deletions(-) diff --git a/bncurve/arith.nim b/bncurve/arith.nim index 2fe78ea..71d35d8 100644 --- a/bncurve/arith.nim +++ b/bncurve/arith.nim @@ -8,9 +8,10 @@ # those terms. import options, endians import nimcrypto/[utils, sysrand] - export options +{.deadCodeElim: on.} + type BNU256* = array[4, uint64] BNU512* = array[8, uint64] diff --git a/bncurve/fp.nim b/bncurve/fp.nim index 4aa635b..7b43726 100644 --- a/bncurve/fp.nim +++ b/bncurve/fp.nim @@ -8,6 +8,8 @@ # those terms. import arith, options +{.deadCodeElim: on.} + template fieldImplementation(finame, fimodulus, firsquared, fircubed, fionep, fiinv: untyped): untyped {.dirty.} = type finame* = distinct BNU256 diff --git a/bncurve/fq12.nim b/bncurve/fq12.nim index 4fad0c8..523a926 100644 --- a/bncurve/fq12.nim +++ b/bncurve/fq12.nim @@ -9,6 +9,8 @@ import options import fq6, fq2, fp, arith +{.deadCodeElim: on.} + const frobeniusCoeffsC1: array[4, FQ2] = [ FQ2.one(), FQ2( diff --git a/bncurve/fq2.nim b/bncurve/fq2.nim index 2e6c85e..4472881 100644 --- a/bncurve/fq2.nim +++ b/bncurve/fq2.nim @@ -9,6 +9,8 @@ import options import fp, arith +{.deadCodeElim: on.} + type FQ2* = object c0*: FQ diff --git a/bncurve/fq6.nim b/bncurve/fq6.nim index 30be2e7..3beda84 100644 --- a/bncurve/fq6.nim +++ b/bncurve/fq6.nim @@ -9,6 +9,8 @@ import options import fq2, fp, arith +{.deadCodeElim: on.} + const frobeniusCoeffsC1: array[4, FQ2] = [ FQ2.one(), FQ2( diff --git a/bncurve/groups.nim b/bncurve/groups.nim index 2fed26b..879de8f 100644 --- a/bncurve/groups.nim +++ b/bncurve/groups.nim @@ -10,6 +10,8 @@ import fields, arith, options export fields, arith, options import nimcrypto/utils +{.deadCodeElim: on.} + type G1* = object G2* = object @@ -26,12 +28,6 @@ type else: x*, y*: FQ2 - Coeff*[T: G1|G2] = object - when T is G1: - b*: FQ - else: - b*: FQ2 - EllCoeffs* = object ell_0*: FQ2 ell_vw*: FQ2 @@ -124,11 +120,11 @@ proc name*[T: G1|G2](t: typedesc[T]): string {.inline, noinit.} = else: result = "G2" -proc coeff*[T: G1|G2](t: typedesc[T]): Coeff[T] {.inline, noinit.} = - when T is G1: - result = G1B - else: - result = G2B +proc coeff*(t: typedesc[G1]): FQ {.inline, noinit.} = + result = G1B + +proc coeff*(t: typedesc[G2]): FQ2 {.inline, noinit.} = + result = G2B proc zero*[T: G1|G2](t: typedesc[T]): Point[T] {.inline, noinit.} = when T is G1: @@ -377,6 +373,26 @@ proc pairing*(p: Point[G1], q: Point[G2]): FQ12 {.noinit, inline.} = if ores.isSome(): result = ores.get() +proc init*(p: var AffinePoint[G1], x: FQ, y: FQ): bool {.inline.} = + ## Initializes AffinePoint[G1] with coordinates ``x`` and ``y``. + ## Returns ``true`` if (x, y) is on curve and in the subgroup. + if y.squared() == (x.squared() * x) + G1B: + var point = Point[G1](x: x, y: y, z: FQ.one()) + if (point * (-FR.one())) + point == G1.zero(): + p.x = x + p.y = y + result = true + +proc init*(p: var AffinePoint[G2], x: FQ2, y: FQ2): bool {.inline.} = + ## Initializes AffinePoint[G2] with coordinates ``x`` and ``y``. + ## Returns ``true`` if (x, y) is on curve and in the subgroup. + if y.squared() == (x.squared() * x) + G2B: + var point = Point[G2](x: x, y: y, z: FQ2.one()) + if (point * (-FR.one())) + point == G2.zero(): + p.x = x + p.y = y + result = true + proc toBytes*[T: G1|G2](p: AffinePoint[T], dst: var openarray[byte]): bool = ## Encode affine point coordinates (x, y) to big-endian bytes representation ## ``dst``. diff --git a/tests/tpairing.nim b/tests/tpairing.nim index 2bdfdcf..0a911a6 100644 --- a/tests/tpairing.nim +++ b/tests/tpairing.nim @@ -224,6 +224,44 @@ proc testJoux(): bool = result = (alice_ss == bob_ss and bob_ss == carol_ss) +proc testPredefinedPair(): bool = + let fq2x = FQ2( + c0: FQ.fromString("10857046999023057135944570762232829481370756359578518086990519993285655852781"), + c1: FQ.fromString("11559732032986387107991004021392285783925812861821192530917403151452391805634") + ) + let fq2y = FQ2( + c0: FQ.fromString("8495653923123431417604973247489272438418190587263600148770280649306958101930"), + c1: FQ.fromString("4082367875863433681332203403145435568316851327593401208105741076214120093531") + ) + var g1a: AffinePoint[G1] + var g2a: AffinePoint[G2] + if g1a.init(FQ.fromString("1"), FQ.fromString("2")): + var g1 = g1a.toJacobian() + if g2a.init(fq2x, fq2y): + var g2 = g2a.toJacobian() + let p = pairing(g1, g2) + if not p.isZero(): + result = true + +proc testInternals(): bool = + let p = G1.one() + let val = p + let affineOpt = val.toAffine() + if isSome(affineOpt): + let affine = affineOpt.get() + if affine.x == FQ.one(): + result = true + +proc testAffineFail1(): bool = + var ap: AffinePoint[G1] + if not ap.init(FQ.one(), FQ.one()): + result = true + +proc testAffineFail2(): bool = + var ap: AffinePoint[G1] + if not ap.init(FQ.one(), G1.coeff()): + result = true + when isMainModule: suite "Pairing test suite": test "Prepared G2 test": @@ -238,3 +276,11 @@ when isMainModule: check testDH() == true test "Joux test": check testJoux() == true + test "[Paritytech] Predefined pair test": + check testPredefinedPair() == true + test "[Paritytech] Internals test": + check testInternals() == true + test "[Paritytech] Affine FAIL#1 test": + check testAffineFail1() == true + test "[Paritytech] Affine FAIL#2 test": + check testAffineFail2() == true