/ constantine / math / config / curves_parser_curve.nim
curves_parser_curve.nim
  1  # Copyright (c) 2018-2019    Status Research & Development GmbH
  2  # Copyright (c) 2020-Present Mamy André-Ratsimbazafy
  3  # Licensed and distributed under either of
  4  #   * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT).
  5  #   * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0).
  6  # at your option. This file may not be copied, modified, or distributed except according to those terms.
  7  
  8  import
  9    # Standard library
 10    std/macros,
 11    # Internal
 12    ./type_bigint, ./type_ff,
 13    ../io/[io_bigints, io_fields],
 14    ./curves_declaration, ./curves_parser_field
 15  
 16  export CurveFamily, Curve, SexticTwist
 17  
 18  # ############################################################
 19  #
 20  #                   Curve properties generator
 21  #
 22  # ############################################################
 23  
 24  template getCoef(c: CurveCoef, curveName: untyped): untyped {.dirty.}=
 25    case c.kind
 26    of NoCoef:
 27      error "Unreachable"
 28      nnkDiscardStmt.newTree(newLit "Dummy")
 29    of Small:
 30      newLit c.coef
 31    of Large:
 32      newCall(
 33        bindSym"fromHex",
 34        nnkBracketExpr.newTree(bindSym"Fp", curveName),
 35        newLit c.coefHex
 36      )
 37  
 38  proc genCurveConstants(defs: seq[CurveParams]): NimNode =
 39    ## Generate curves main constants
 40  
 41    # MapCurveBitWidth & MapCurveOrderBitWidth
 42    # are workaround for https://github.com/nim-lang/Nim/issues/16774
 43  
 44    var MapCurveFamily = nnkBracket.newTree()
 45    var curveEllipticStmts = newStmtList()
 46  
 47    for curveDef in defs:
 48      curveDef.name.expectKind(nnkIdent)
 49      curveDef.bitWidth.expectKind(nnkIntLit)
 50      curveDef.modulus.expectKind(nnkStrLit)
 51  
 52      let curve = curveDef.name
 53      let family = curveDef.family
 54  
 55      MapCurveFamily.add nnkExprColonExpr.newTree(
 56          curve, newLit(family)
 57      )
 58  
 59      # Curve equation
 60      # -----------------------------------------------
 61      curveEllipticStmts.add newConstStmt(
 62        exported($curve & "_equation_form"),
 63        newLit curveDef.eq_form
 64      )
 65  
 66      if curveDef.eq_form == ShortWeierstrass and
 67           curveDef.coef_A.kind != NoCoef and curveDef.coef_B.kind != NoCoef:
 68        curveEllipticStmts.add newConstStmt(
 69          exported($curve & "_coef_A"),
 70          curveDef.coef_A.getCoef(curve)
 71        )
 72        curveEllipticStmts.add newConstStmt(
 73          exported($curve & "_coef_B"),
 74          curveDef.coef_B.getCoef(curve)
 75        )
 76  
 77        # Towering
 78        # -----------------------------------------------
 79        curveEllipticStmts.add newConstStmt(
 80          exported($curve & "_nonresidue_fp"),
 81          curveDef.nonresidue_fp
 82        )
 83        curveEllipticStmts.add newConstStmt(
 84          exported($curve & "_nonresidue_fp2"),
 85          curveDef.nonresidue_fp2
 86        )
 87  
 88        # Pairing
 89        # -----------------------------------------------
 90        curveEllipticStmts.add newConstStmt(
 91          exported($curve & "_embedding_degree"),
 92          newLit curveDef.embedding_degree
 93        )
 94        curveEllipticStmts.add newConstStmt(
 95          exported($curve & "_sexticTwist"),
 96          newLit curveDef.sexticTwist
 97        )
 98  
 99      if curveDef.eq_form == TwistedEdwards and
100           curveDef.coef_A.kind != NoCoef and curveDef.coef_D.kind != NoCoef:
101        curveEllipticStmts.add newConstStmt(
102          exported($curve & "_coef_A"),
103          curveDef.coef_A.getCoef(curve)
104        )
105        curveEllipticStmts.add newConstStmt(
106          exported($curve & "_coef_D"),
107          curveDef.coef_D.getCoef(curve)
108        )
109  
110    # end for ---------------------------------------------------
111  
112    result = newStmtList()
113  
114    # const CurveFamily: array[Curve, CurveFamily] = ...
115    result.add newConstStmt(
116      exported("CurveFamilies"), MapCurveFamily
117    )
118  
119    result.add curveEllipticStmts
120  
121  macro setupCurves(): untyped =
122    result = genCurveConstants(curvesDefinitions)
123  
124  setupCurves()