Due to upstream bug https://github.com/nim-lang/Nim/issues/9679 and another hard-to reproduce one for static Word, the use of compile-time property of the modulus requires lots of workarounds.
Bug 2 gives the following errors:
========================================================================================
Running tests/test_io_fields
========================================================================================
/home/beta/Programming/Nim/constantine/tests/test_io_fields.nim(19, 9) template/generic instantiation of `suite` from here
/home/beta/Programming/Nim/constantine/tests/test_io_fields.nim(20, 10) template/generic instantiation of `test` from here
/home/beta/Programming/Nim/constantine/tests/test_io_fields.nim(26, 10) template/generic instantiation of `fromUint` from here
/home/beta/Programming/Nim/constantine/constantine/io/io_fields.nim(29, 6) template/generic instantiation of `fromBig` from here
/home/beta/Programming/Nim/constantine/constantine/arithmetic/finite_fields.nim(64, 11) Error: type mismatch: got <BigInt[61], BigInt[61], BigInt[61], BigInt[61], static[Word](2305843009213693953)>
but expected one of:
func montyResidue(mres: var BigInt; a, N, r2modN: BigInt; negInvModWord: static Word)
first type mismatch at position: 5
required type for negInvModWord: static[Word]
but expression '2305843009213693953' is of type: static[Word](2305843009213693953)
Trying to reduce it to a minimal example makes it disappear ...
import macros
type Word = distinct uint64
const WordBitSize = 63
func wordsRequired*(bits: int): int {.compileTime.} =
(bits + WordBitSize - 1) div WordBitSize
type
BigInt*[bits: static int] = object
bitLength: uint32
limbs: array[bits.wordsRequired, Word]
Curve = enum
BN254
BLS12_381
const CurveBitSize = [
BN254: 254,
BLS12_381: 381
]
template matchingBigInt(C: static Curve): untyped =
# Need template indirection to avoid a sigmatch bug
BigInt[CurveBitSize[C]]
type
FiniteField*[C: static enum] = object
big: matchingBigInt(C)
const BN254_Modulus = BigInt[254]()
const BN254_NegInvModWord = Word(2305843009213693953)
{.experimental: "dynamicBindSym".}
macro getModulus(C: static Curve): untyped =
result = bindSym($C & "_Modulus")
macro getNegInvModWord(C: static Curve): untyped =
result = bindSym($C & "_NegInvModWord")
func foo(mres: var BigInt, a, N: BigInt, negInvModWord: static Word) =
discard
func bar(r: var FiniteField, a: FiniteField) =
foo(r.big, a.big, a.C.getModulus(), a.C.getNegInvModWord())
var r: FiniteField[BN254]
let a = FiniteField[BN254]()
bar(r, a)
Due to upstream bug https://github.com/nim-lang/Nim/issues/9679 and another hard-to reproduce one for static Word, the use of compile-time property of the modulus requires lots of workarounds.
Bug 2 gives the following errors:
Trying to reduce it to a minimal example makes it disappear ...