Prepare for bindings generation

This commit is contained in:
Mamy Ratsimbazafy 2022-07-16 13:34:27 +02:00
parent e29e529f18
commit 7d29cb947a
No known key found for this signature in database
GPG Key ID: 6227262F49BE273A
10 changed files with 252 additions and 45 deletions

View File

@ -0,0 +1,211 @@
# 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
./platforms/abstractions,
./math/config/[curves, type_ff],
./math/[
ec_shortweierstrass,
extension_fields,
arithmetic,
curves/zoo_subgroups,
curves/zoo_generators
],
./math/io/[io_bigints, io_ec],
./math/isogenies/frobenius,
./math/pairings,
./math/pairing/[
cyclotomic_subgroup,
lines_eval
],
./math/curves/zoo_pairings,
./hash_to_curve/hash_to_curve
# ############################################################
#
# Generator for low-level primitives API
#
# ############################################################
{.push raises: [].} # No exceptions allowed in core cryptographic operations
{.push inline.}
# Base types
# ------------------------------------------------------------
export
abstractions.SecretBool,
curves.Curve
# Scalar field Fr and Prime Field Fp
# ------------------------------------------------------------
export
type_ff.Fp,
type_ff.Fr,
type_ff.FF
func unmarshalBE*(dst: var FF, src: openarray[byte]) =
var raw {.noInit.}: typeof dst.mres
raw.unmarshal(src, bigEndian)
dst.fromBig(raw)
func marshalBE*(dst: var openarray[byte], src: FF) =
var raw {.noInit.}: typeof src.mres
raw.fromField(src)
dst.marshal(src, bigEndian)
export arithmetic.`==`
export arithmetic.isZero
export arithmetic.isOne
export arithmetic.isMinusOne
export arithmetic.setZero
export arithmetic.setOne
export arithmetic.setMinusOne
export arithmetic.neg
export arithmetic.sum
export arithmetic.`+=`
export arithmetic.diff
export arithmetic.`-=`
export arithmetic.double
export arithmetic.prod
export arithmetic.`*=`
export arithmetic.square
export arithmetic.square_repeated
export arithmetic.csetZero
export arithmetic.csetOne
export arithmetic.cneg
export arithmetic.cadd
export arithmetic.csub
export arithmetic.div2
export arithmetic.inv
export arithmetic.isSquare
export arithmetic.invsqrt
export arithmetic.sqrt
export arithmetic.sqrt_invsqrt
export arithmetic.sqrt_invsqrt_if_square
export arithmetic.sqrt_if_square
export arithmetic.invsqrt_if_square
export arithmetic.sqrt_ratio_if_square
# Elliptic curve
# ------------------------------------------------------------
export
ec_shortweierstrass.Subgroup,
ec_shortweierstrass.ECP_ShortW_Aff,
ec_shortweierstrass.ECP_ShortW_Jac,
ec_shortweierstrass.ECP_ShortW_Prj,
ec_shortweierstrass.ECP_ShortW
export ec_shortweierstrass.`==`
export ec_shortweierstrass.isInf
export ec_shortweierstrass.setInf
export ec_shortweierstrass.ccopy
export ec_shortweierstrass.isOnCurve
export ec_shortweierstrass.neg
export ec_shortweierstrass.cneg
export ec_shortweierstrass.affine
export ec_shortweierstrass.fromAffine
export ec_shortweierstrass.batchAffine
export ec_shortweierstrass.sum
export ec_shortweierstrass.double
export ec_shortweierstrass.diff
# export ec_shortweierstrass.madd
export ec_shortweierstrass.scalarMul
export zoo_generators.getGenerator
export zoo_subgroups.clearCofactor
export zoo_subgroups.isInSubgroup
export frobenius.frobenius_psi
# Extension fields
# ------------------------------------------------------------
export
extension_fields.Fp2
# TODO: deal with Fp2->Fp6 vs Fp3->Fp6 and Fp2->Fp6->Fp12 vs Fp2->Fp4->Fp12
# extension_fields.Fp4,
# extension_fields.Fp6,
# extension_fields.Fp12
export extension_fields.setZero
export extension_fields.setOne
export extension_fields.`==`
export extension_fields.isZero
export extension_fields.isOne
export extension_fields.isMinusOne
export extension_fields.ccopy
export extension_fields.neg
export extension_fields.`+=`
export extension_fields.`-=`
export extension_fields.double
export extension_fields.div2
export extension_fields.sum
export extension_fields.diff
export extension_fields.conj
export extension_fields.conjneg
export extension_fields.csetZero
export extension_fields.csetOne
export extension_fields.cneg
export extension_fields.csub
export extension_fields.cadd
export extension_fields.`*=`
export extension_fields.prod
export extension_fields.inv
export extension_fields.isSquare
export extension_fields.sqrt_if_square
export extension_fields.sqrt
export frobenius.frobenius_map
# Pairings
# ------------------------------------------------------------
export
lines_eval.Line
export lines_eval.line_double
export lines_eval.line_add
export lines_eval.mul_by_line
export lines_eval.mul_by_2_lines
export cyclotomic_subgroup.finalExpEasy
export cyclotomic_subgroup.cyclotomic_inv
export cyclotomic_subgroup.cyclotomic_square
export cyclotomic_subgroup.cycl_sqr_repeated
export cyclotomic_subgroup.cyclotomic_exp
export cyclotomic_subgroup.isInCyclotomicSubgroup
export zoo_pairings.cycl_exp_by_curve_param
export zoo_pairings.cycl_exp_by_curve_param_div2
export zoo_pairings.millerLoopAddchain
export zoo_pairings.isInPairingSubgroup
export pairings.pairing
# Hashing to Elliptic Curve
# ------------------------------------------------------------
export hash_to_curve.hash_to_curve

View File

@ -82,7 +82,7 @@ func ccopy*(a: var FF, b: FF, ctl: SecretBool) {.meter.} =
## Time and memory accesses are the same whether a copy occurs or not ## Time and memory accesses are the same whether a copy occurs or not
ccopy(a.mres, b.mres, ctl) ccopy(a.mres, b.mres, ctl)
func cswap*(a, b: var FF, ctl: CTBool) {.meter.} = func cswap*(a, b: var FF, ctl: SecretBool) {.meter.} =
## Swap ``a`` and ``b`` if ``ctl`` is true ## Swap ``a`` and ``b`` if ``ctl`` is true
## ##
## Constant-time: ## Constant-time:

View File

@ -9,7 +9,6 @@ import
# Standard library # Standard library
std/macros, std/macros,
# Internal # Internal
./type_bigint,
./curves_declaration, ./curves_parser_curve ./curves_declaration, ./curves_parser_curve
export CurveFamily, Curve, SexticTwist export CurveFamily, Curve, SexticTwist
@ -22,6 +21,10 @@ export CurveFamily, Curve, SexticTwist
{.experimental: "dynamicBindSym".} {.experimental: "dynamicBindSym".}
template getCurveBitwidth*(C: Curve): int =
## Returns the number of bits taken by the curve modulus
CurveBitWidth[C]
macro getCurveOrder*(C: static Curve): untyped = macro getCurveOrder*(C: static Curve): untyped =
## Get the curve order `r` ## Get the curve order `r`
## i.e. the number of points on the elliptic curve ## i.e. the number of points on the elliptic curve
@ -35,10 +38,6 @@ macro getCurveOrderBitwidth*(C: static Curve): untyped =
ident"bits" ident"bits"
) )
template matchingOrderBigInt*(C: static Curve): untyped =
# Workaround: https://github.com/nim-lang/Nim/issues/16774
BigInt[CurveOrderBitWidth[C]]
template family*(C: Curve): CurveFamily = template family*(C: Curve): CurveFamily =
CurveFamilies[C] CurveFamilies[C]

View File

@ -27,16 +27,18 @@ macro Mod*(C: static Curve): untyped =
## Get the Modulus associated to a curve ## Get the Modulus associated to a curve
result = bindSym($C & "_Modulus") result = bindSym($C & "_Modulus")
template getCurveBitwidth*(C: Curve): int =
## Returns the number of bits taken by the curve modulus
CurveBitWidth[C]
template matchingBigInt*(C: static Curve): untyped = template matchingBigInt*(C: static Curve): untyped =
## BigInt type necessary to store the prime field Fp
# Workaround: https://github.com/nim-lang/Nim/issues/16774 # Workaround: https://github.com/nim-lang/Nim/issues/16774
BigInt[CurveBitWidth[C]] BigInt[CurveBitWidth[C]]
template matchingOrderBigInt*(C: static Curve): untyped =
## BigInt type necessary to store the scalar field Fr
# Workaround: https://github.com/nim-lang/Nim/issues/16774
BigInt[CurveOrderBitWidth[C]]
template matchingLimbs2x*(C: Curve): untyped = template matchingLimbs2x*(C: Curve): untyped =
const N2 = wordsRequired(getCurveBitwidth(C)) * 2 # TODO upstream, not precomputing N2 breaks semcheck const N2 = wordsRequired(CurveBitWidth[C]) * 2 # TODO upstream, not precomputing N2 breaks semcheck
array[N2, SecretWord] # TODO upstream, using Limbs[N2] breaks semcheck array[N2, SecretWord] # TODO upstream, using Limbs[N2] breaks semcheck
func has_P_3mod4_primeModulus*(C: static Curve): static bool = func has_P_3mod4_primeModulus*(C: static Curve): static bool =

View File

@ -11,7 +11,7 @@ import
./curves_declaration, ./curves_declaration,
./curves_prop_field_core ./curves_prop_field_core
export matchingBigInt export matchingBigInt, matchingOrderBigInt
type type
Fp*[C: static Curve] = object Fp*[C: static Curve] = object

View File

@ -53,7 +53,7 @@ func toHex*[EC: ECP_ShortW_Prj or ECP_ShortW_Jac or ECP_ShortW_Aff](P: EC, inden
result.appendHex(aff.y) result.appendHex(aff.y)
result &= "\n" & sp & ")" result &= "\n" & sp & ")"
func fromHex*(dst: var (ECP_ShortW_Prj or ECP_ShortW_Jac), x, y: string): bool {.raises: [ValueError].}= func fromHex*(dst: var (ECP_ShortW_Prj or ECP_ShortW_Jac), x, y: string): bool =
## Convert hex strings to a G1 curve point ## Convert hex strings to a G1 curve point
## Returns true if point exist or if input is the point at infinity (all 0) ## Returns true if point exist or if input is the point at infinity (all 0)
## Returns `false` if there is no point with coordinates (`x`, `y`) on the curve ## Returns `false` if there is no point with coordinates (`x`, `y`) on the curve
@ -66,7 +66,7 @@ func fromHex*(dst: var (ECP_ShortW_Prj or ECP_ShortW_Jac), x, y: string): bool {
dst.z.csetZero(isInf) dst.z.csetZero(isInf)
return bool(isOnCurve(dst.x, dst.y, dst.G) or isInf) return bool(isOnCurve(dst.x, dst.y, dst.G) or isInf)
func fromHex*(dst: var (ECP_ShortW_Prj or ECP_ShortW_Jac), x0, x1, y0, y1: string): bool {.raises: [ValueError].}= func fromHex*(dst: var (ECP_ShortW_Prj or ECP_ShortW_Jac), x0, x1, y0, y1: string): bool =
## Convert hex strings to a G2 curve point ## Convert hex strings to a G2 curve point
## Returns `false` ## Returns `false`
## if there is no point with coordinates (`x`, `y`) on the curve ## if there is no point with coordinates (`x`, `y`) on the curve
@ -79,7 +79,7 @@ func fromHex*(dst: var (ECP_ShortW_Prj or ECP_ShortW_Jac), x0, x1, y0, y1: strin
dst.z.csetZero(isInf) dst.z.csetZero(isInf)
return bool(isOnCurve(dst.x, dst.y, dst.G) or isInf) return bool(isOnCurve(dst.x, dst.y, dst.G) or isInf)
func fromHex*(dst: var ECP_ShortW_Aff, x, y: string): bool {.raises: [ValueError].}= func fromHex*(dst: var ECP_ShortW_Aff, x, y: string): bool =
## Convert hex strings to a G1 curve point ## Convert hex strings to a G1 curve point
## Returns true if point exist or if input is the point at infinity (all 0) ## Returns true if point exist or if input is the point at infinity (all 0)
## Returns `false` if there is no point with coordinates (`x`, `y`) on the curve ## Returns `false` if there is no point with coordinates (`x`, `y`) on the curve
@ -89,7 +89,7 @@ func fromHex*(dst: var ECP_ShortW_Aff, x, y: string): bool {.raises: [ValueError
dst.y.fromHex(y) dst.y.fromHex(y)
return bool(isOnCurve(dst.x, dst.y, dst.G) or dst.isInf()) return bool(isOnCurve(dst.x, dst.y, dst.G) or dst.isInf())
func fromHex*(dst: var ECP_ShortW_Aff, x0, x1, y0, y1: string): bool {.raises: [ValueError].}= func fromHex*(dst: var ECP_ShortW_Aff, x0, x1, y0, y1: string): bool =
## Convert hex strings to a G2 curve point ## Convert hex strings to a G2 curve point
## Returns true if point exist or if input is the point at infinity (all 0) ## Returns true if point exist or if input is the point at infinity (all 0)
## Returns `false` if there is no point with coordinates (`x`, `y`) on the curve ## Returns `false` if there is no point with coordinates (`x`, `y`) on the curve
@ -100,9 +100,9 @@ func fromHex*(dst: var ECP_ShortW_Aff, x0, x1, y0, y1: string): bool {.raises: [
return bool(isOnCurve(dst.x, dst.y, dst.G) or dst.isInf()) return bool(isOnCurve(dst.x, dst.y, dst.G) or dst.isInf())
func fromHex*[EC: ECP_ShortW_Prj or ECP_ShortW_Jac or ECP_ShortW_Aff]( func fromHex*[EC: ECP_ShortW_Prj or ECP_ShortW_Jac or ECP_ShortW_Aff](
_: type EC, x, y: string): EC {.raises: [ValueError].} = _: type EC, x, y: string): EC =
doAssert result.fromHex(x, y) doAssert result.fromHex(x, y)
func fromHex*[EC: ECP_ShortW_Prj or ECP_ShortW_Jac or ECP_ShortW_Aff]( func fromHex*[EC: ECP_ShortW_Prj or ECP_ShortW_Jac or ECP_ShortW_Aff](
_: type EC, x0, x1, y0, y1: string): EC {.raises: [ValueError].} = _: type EC, x0, x1, y0, y1: string): EC =
doAssert result.fromHex(x0, x1, y0, y1) doAssert result.fromHex(x0, x1, y0, y1)

View File

@ -57,34 +57,34 @@ func toHex*(f: Fp2 or Fp4 or Fp6 or Fp12, indent = 0, order: static Endianness =
## - no leaks ## - no leaks
result.appendHex(f, indent, order) result.appendHex(f, indent, order)
func fromHex*(dst: var Fp2, c0, c1: string) {.raises: [ValueError].}= func fromHex*(dst: var Fp2, c0, c1: string) =
## Convert 2 coordinates to an element of 𝔽p2 ## Convert 2 coordinates to an element of 𝔽p2
## with dst = c0 + β * c1 ## with dst = c0 + β * c1
## β is the quadratic non-residue chosen to construct 𝔽p2 ## β is the quadratic non-residue chosen to construct 𝔽p2
dst.c0.fromHex(c0) dst.c0.fromHex(c0)
dst.c1.fromHex(c1) dst.c1.fromHex(c1)
func fromHex*(T: typedesc[Fp2], c0, c1: string): T {.raises: [ValueError].}= func fromHex*(T: typedesc[Fp2], c0, c1: string): T =
## Convert 2 coordinates to an element of 𝔽p2 ## Convert 2 coordinates to an element of 𝔽p2
## with dst = c0 + β * c1 ## with dst = c0 + β * c1
## β is the quadratic non-residue chosen to construct 𝔽p2 ## β is the quadratic non-residue chosen to construct 𝔽p2
result.fromHex(c0, c1) result.fromHex(c0, c1)
func fromHex*(dst: var Fp4, func fromHex*(dst: var Fp4,
c0, c1, c2, c3: string) {.raises: [ValueError].}= c0, c1, c2, c3: string) =
## Convert 4 coordinates to an element of 𝔽p4 ## Convert 4 coordinates to an element of 𝔽p4
dst.c0.fromHex(c0, c1) dst.c0.fromHex(c0, c1)
dst.c1.fromHex(c2, c3) dst.c1.fromHex(c2, c3)
func fromHex*(T: typedesc[Fp4], func fromHex*(T: typedesc[Fp4],
c0, c1, c2: string, c0, c1, c2: string,
c3, c4, c5: string): T {.raises: [ValueError].}= c3, c4, c5: string): T =
## Convert 4 coordinates to an element of 𝔽p4 ## Convert 4 coordinates to an element of 𝔽p4
result.fromHex(c0, c1, c2, c3) result.fromHex(c0, c1, c2, c3)
func fromHex*(dst: var Fp6, func fromHex*(dst: var Fp6,
c0, c1, c2: string, c0, c1, c2: string,
c3, c4, c5: string) {.raises: [ValueError].}= c3, c4, c5: string) =
## Convert 6 coordinates to an element of 𝔽p6 ## Convert 6 coordinates to an element of 𝔽p6
dst.c0.fromHex(c0, c1) dst.c0.fromHex(c0, c1)
dst.c1.fromHex(c2, c3) dst.c1.fromHex(c2, c3)
@ -92,14 +92,14 @@ func fromHex*(dst: var Fp6,
func fromHex*(T: typedesc[Fp6], func fromHex*(T: typedesc[Fp6],
c0, c1, c2: string, c0, c1, c2: string,
c3, c4, c5: string): T {.raises: [ValueError].}= c3, c4, c5: string): T =
## Convert 6 coordinates to an element of 𝔽p6 ## Convert 6 coordinates to an element of 𝔽p6
result.fromHex(c0, c1, c2, c3, c4, c5) result.fromHex(c0, c1, c2, c3, c4, c5)
func fromHex*(dst: var Fp12, func fromHex*(dst: var Fp12,
c0, c1, c2, c3: string, c0, c1, c2, c3: string,
c4, c5, c6, c7: string, c4, c5, c6, c7: string,
c8, c9, c10, c11: string) {.raises: [ValueError].}= c8, c9, c10, c11: string) =
## Convert 12 coordinates to an element of 𝔽p12 ## Convert 12 coordinates to an element of 𝔽p12
when dst.c0 is Fp6: when dst.c0 is Fp6:
dst.c0.fromHex(c0, c1, c2, c3, c4, c5) dst.c0.fromHex(c0, c1, c2, c3, c4, c5)
@ -112,7 +112,7 @@ func fromHex*(dst: var Fp12,
func fromHex*(T: typedesc[Fp12], func fromHex*(T: typedesc[Fp12],
c0, c1, c2, c3: string, c0, c1, c2, c3: string,
c4, c5, c6, c7: string, c4, c5, c6, c7: string,
c8, c9, c10, c11: string): T {.raises: [ValueError].}= c8, c9, c10, c11: string): T =
## Convert 12 coordinates to an element of 𝔽p12 ## Convert 12 coordinates to an element of 𝔽p12
result.fromHex(c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11) result.fromHex(c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11)

View File

@ -82,7 +82,7 @@ func toHex*(f: FF, order: static Endianness = bigEndian): string =
## - no leaks ## - no leaks
result.appendHex(f, order) result.appendHex(f, order)
func fromHex*(dst: var FF, hexString: string) {.raises: [ValueError].}= func fromHex*(dst: var FF, hexString: string) =
## Convert a hex string to a element of Fp or Fr ## Convert a hex string to a element of Fp or Fr
## Warning: protocols might want a specific function that checks ## Warning: protocols might want a specific function that checks
## that the input is in [0, modulus) range ## that the input is in [0, modulus) range
@ -90,7 +90,7 @@ func fromHex*(dst: var FF, hexString: string) {.raises: [ValueError].}=
let raw {.noinit.} = fromHex(dst.mres.typeof, hexString) let raw {.noinit.} = fromHex(dst.mres.typeof, hexString)
dst.fromBig(raw) dst.fromBig(raw)
func fromHex*(T: type FF, hexString: string): T {.noInit, raises: [ValueError].}= func fromHex*(T: type FF, hexString: string): T {.noInit.}=
## Convert a hex string to a element of Fp ## Convert a hex string to a element of Fp
## Warning: protocols might want a specific function that checks ## Warning: protocols might want a specific function that checks
## that the input is in [0, modulus) range ## that the input is in [0, modulus) range
@ -106,7 +106,7 @@ func toDecimal*(f: FF): string =
# TODO constant-time # TODO constant-time
f.toBig().toDecimal() f.toBig().toDecimal()
func fromDecimal*(dst: var FF, decimalString: string) {.raises: [ValueError].}= func fromDecimal*(dst: var FF, decimalString: string) =
## Convert a decimal string. The input must be packed ## Convert a decimal string. The input must be packed
## with no spaces or underscores. ## with no spaces or underscores.
## This assumes that bits and decimal length are **public.** ## This assumes that bits and decimal length are **public.**
@ -126,7 +126,7 @@ func fromDecimal*(dst: var FF, decimalString: string) {.raises: [ValueError].}=
let raw {.noinit.} = fromDecimal(dst.mres.typeof, decimalString) let raw {.noinit.} = fromDecimal(dst.mres.typeof, decimalString)
dst.fromBig(raw) dst.fromBig(raw)
func fromDecimal*(T: type FF, hexString: string): T {.noInit, raises: [ValueError].}= func fromDecimal*(T: type FF, hexString: string): T {.noInit.}=
## Convert a decimal string. The input must be packed ## Convert a decimal string. The input must be packed
## with no spaces or underscores. ## with no spaces or underscores.
## This assumes that bits and decimal length are **public.** ## This assumes that bits and decimal length are **public.**

View File

@ -11,7 +11,7 @@ import
./pairing/[pairing_bn, pairing_bls12], ./pairing/[pairing_bn, pairing_bls12],
./extension_fields ./extension_fields
template pairing*[C](gt: var Fp12[C], P, Q: typed) = func pairing*[C](gt: var Fp12[C], P, Q: auto) {.inline.} =
when family(C) == BarretoNaehrig: when family(C) == BarretoNaehrig:
pairing_bn(gt, P, Q) pairing_bn(gt, P, Q)
elif family(C) == BarretoLynnScott: elif family(C) == BarretoLynnScott:

View File

@ -10,12 +10,7 @@ import
../../constantine/platforms/primitives, ../../constantine/platforms/primitives,
../../constantine/math/config/curves, ../../constantine/math/config/curves,
../../constantine/math/arithmetic, ../../constantine/math/arithmetic,
../../constantine/math/elliptic/[ ../../constantine/math/ec_shortweierstrass,
ec_scalar_mul,
ec_shortweierstrass_affine,
ec_shortweierstrass_projective,
ec_shortweierstrass_jacobian,
],
../../constantine/math/io/[io_fields, io_ec], ../../constantine/math/io/[io_fields, io_ec],
# Research # Research
./strided_views, ./strided_views,
@ -213,7 +208,7 @@ when isMainModule:
std/[times, monotimes, strformat], std/[times, monotimes, strformat],
../../helpers/prng_unsafe ../../helpers/prng_unsafe
type G1 = ECP_ShortW_Prj[Fp[BLS12_381], G1] type EC_G1 = ECP_ShortW_Prj[Fp[BLS12_381], G1]
var Generator1: ECP_ShortW_Aff[Fp[BLS12_381], G1] var Generator1: ECP_ShortW_Aff[Fp[BLS12_381], G1]
doAssert Generator1.fromHex( doAssert Generator1.fromHex(
"0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb", "0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb",
@ -221,18 +216,18 @@ when isMainModule:
) )
proc roundtrip() = proc roundtrip() =
let fftDesc = FFTDescriptor[G1].init(maxScale = 4) let fftDesc = FFTDescriptor[EC_G1].init(maxScale = 4)
var data = newSeq[G1](fftDesc.maxWidth) var data = newSeq[EC_G1](fftDesc.maxWidth)
data[0].fromAffine(Generator1) data[0].fromAffine(Generator1)
for i in 1 ..< fftDesc.maxWidth: for i in 1 ..< fftDesc.maxWidth:
data[i].madd(data[i-1], Generator1) data[i].madd(data[i-1], Generator1)
var coefs = newSeq[G1](data.len) var coefs = newSeq[EC_G1](data.len)
let fftOk = fft(fftDesc, coefs, data) let fftOk = fft(fftDesc, coefs, data)
doAssert fftOk == FFTS_Success doAssert fftOk == FFTS_Success
# display("coefs", 0, coefs) # display("coefs", 0, coefs)
var res = newSeq[G1](data.len) var res = newSeq[EC_G1](data.len)
let ifftOk = ifft(fftDesc, res, coefs) let ifftOk = ifft(fftDesc, res, coefs)
doAssert ifftOk == FFTS_Success doAssert ifftOk == FFTS_Success
# display("res", 0, coefs) # display("res", 0, coefs)
@ -272,13 +267,13 @@ when isMainModule:
for scale in 4 ..< 10: for scale in 4 ..< 10:
# Setup # Setup
let desc = FFTDescriptor[G1].init(uint8 scale) let desc = FFTDescriptor[EC_G1].init(uint8 scale)
var data = newSeq[G1](desc.maxWidth) var data = newSeq[EC_G1](desc.maxWidth)
data[0].fromAffine(Generator1) data[0].fromAffine(Generator1)
for i in 1 ..< desc.maxWidth: for i in 1 ..< desc.maxWidth:
data[i].madd(data[i-1], Generator1) data[i].madd(data[i-1], Generator1)
var coefsOut = newSeq[G1](data.len) var coefsOut = newSeq[EC_G1](data.len)
# Bench # Bench
let start = getMonotime() let start = getMonotime()