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()