diff --git a/constantine/arithmetic/finite_fields.nim b/constantine/arithmetic/finite_fields.nim index 04be32d8..e81a6fad 100644 --- a/constantine/arithmetic/finite_fields.nim +++ b/constantine/arithmetic/finite_fields.nim @@ -26,7 +26,7 @@ import ../primitives, - ../config/[common, type_fp, curves], + ../config/[common, type_fp, type_fr, curves], ./bigints, ./limbs_montgomery when UseASM_X86_64: @@ -37,7 +37,7 @@ when nimvm: else: discard -export Fp +export Fp, Fr # No exceptions allowed {.push raises: [].} diff --git a/constantine/config/curves.nim b/constantine/config/curves.nim index 3bd5894f..89778593 100644 --- a/constantine/config/curves.nim +++ b/constantine/config/curves.nim @@ -32,6 +32,7 @@ template getCurveBitwidth*(C: Curve): int = CurveBitWidth[C] template matchingBigInt*(C: static Curve): untyped = + # Workaround: https://github.com/nim-lang/Nim/issues/16774 BigInt[CurveBitWidth[C]] template family*(C: Curve): CurveFamily = @@ -60,6 +61,10 @@ macro getCurveOrderBitwidth*(C: static Curve): untyped = ident"bits" ) +template matchingOrderBigInt*(C: static Curve): untyped = + # Workaround: https://github.com/nim-lang/Nim/issues/16774 + BigInt[CurveOrderBitWidth[C]] + macro getEquationForm*(C: static Curve): untyped = ## Returns the equation form ## (ShortWeierstrass, Montgomery, Twisted Edwards, Weierstrass, ...) diff --git a/constantine/config/curves_parser.nim b/constantine/config/curves_parser.nim index 09846feb..e35a9628 100644 --- a/constantine/config/curves_parser.nim +++ b/constantine/config/curves_parser.nim @@ -237,8 +237,12 @@ template getCoef(c: CurveCoef, width: NimNode): untyped {.dirty.}= proc genMainConstants(defs: var seq[CurveParams]): NimNode = ## Generate curves and fields main constants + # MapCurveBitWidth & MapCurveOrderBitWidth + # are workaround for https://github.com/nim-lang/Nim/issues/16774 + var Curves: seq[NimNode] var MapCurveBitWidth = nnkBracket.newTree() + var MapCurveOrderBitWidth = nnkBracket.newTree() var MapCurveFamily = nnkBracket.newTree() var curveModStmts = newStmtList() var curveEllipticStmts = newStmtList() @@ -290,6 +294,14 @@ proc genMainConstants(defs: var seq[CurveParams]): NimNode = curveDef.order ) ) + MapCurveOrderBitWidth.add nnkExprColonExpr.newTree( + curve, curveDef.orderBitwidth + ) + else: # Dummy + MapCurveOrderBitWidth.add nnkExprColonExpr.newTree( + curve, newLit 0 + ) + if curveDef.coef_A.kind != NoCoef and curveDef.coef_B.kind != NoCoef: curveEllipticStmts.add newConstStmt( exported($curve & "_coef_A"), @@ -347,6 +359,10 @@ proc genMainConstants(defs: var seq[CurveParams]): NimNode = result.add newConstStmt( exported("CurveFamilies"), MapCurveFamily ) + # const CurveOrderBitSize: array[Curve, int] = ... + result.add newConstStmt( + exported("CurveOrderBitWidth"), MapCurveOrderBitWidth + ) result.add curveModStmts result.add curveEllipticStmts diff --git a/constantine/config/type_fp.nim b/constantine/config/type_fp.nim index a206021c..fc191511 100644 --- a/constantine/config/type_fp.nim +++ b/constantine/config/type_fp.nim @@ -12,7 +12,7 @@ import type Fp*[C: static Curve] = object - ## All operations on a field are modulo P + ## All operations on a Fp field are modulo P ## P being the prime modulus of the Curve C ## Internally, data is stored in Montgomery n-residue form ## with the magic constant chosen for convenient division (a power of 2 depending on P bitsize) diff --git a/constantine/config/type_fr.nim b/constantine/config/type_fr.nim new file mode 100644 index 00000000..6da9d3d9 --- /dev/null +++ b/constantine/config/type_fr.nim @@ -0,0 +1,28 @@ +# Constantine +# Copyright (c) 2018-2019 Status Research & Development GmbH +# Copyright (c) 2020-Present Mamy André-Ratsimbazafy +# Licensed and distributed under either of +# * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT). +# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0). +# at your option. This file may not be copied, modified, or distributed except according to those terms. + +import + ./common, + ./curves_declaration + +type + Fr*[C: static Curve] = object + ## All operations on a field are modulo `r` + ## `r` being the prime curve order or subgroup order + ## Internally, data is stored in Montgomery n-residue form + ## with the magic constant chosen for convenient division (a power of 2 depending on P bitsize) + mres: matchingOrderBigInt(C) + +debug: + import ./type_bigint + + func `$`*[C: static Curve](a: Fr[C]): string = + result = "Fr[" & $C + result.add "](" + result.add $a.mres + result.add ')' diff --git a/tests/t_fr.nim b/tests/t_fr.nim new file mode 100644 index 00000000..8b5c0e30 --- /dev/null +++ b/tests/t_fr.nim @@ -0,0 +1,14 @@ +# Constantine +# Copyright (c) 2018-2019 Status Research & Development GmbH +# Copyright (c) 2020-Present Mamy André-Ratsimbazafy +# Licensed and distributed under either of +# * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT). +# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0). +# at your option. This file may not be copied, modified, or distributed except according to those terms. + +import std/unittest, + ../constantine/arithmetic, + ../constantine/io/io_fields, + ../constantine/config/curves + +var x: Fr[BLS12_381]