Rename Fq -> Fp

This commit is contained in:
Mamy André-Ratsimbazafy 2020-02-24 17:10:09 +01:00
parent 3bd70991d4
commit 6b05c69652
No known key found for this signature in database
GPG Key ID: 7B88AD1FE79492E1
7 changed files with 94 additions and 90 deletions

View File

@ -8,17 +8,21 @@
# ############################################################ # ############################################################
# #
# Fq: Finite Field arithmetic over Q # Fp: Finite Field arithmetic with prime field modulus P
# #
# ############################################################ # ############################################################
# We assume that q is known at compile-time # Constraints:
# We assume that q is not even: # - We assume that p is known at compile-time
# - Operations are done in the Montgomery domain # - We assume that p is not even:
# - The Montgomery domain introduce a Montgomery constant that must be coprime # - Operations are done in the Montgomery domain
# with the field modulus. # - The Montgomery domain introduce a Montgomery constant that must be coprime
# - The constant is chosen a power of 2 # with the field modulus.
# => to be coprime with a power of 2, q must be odd # - The constant is chosen a power of 2
# => to be coprime with a power of 2, p must be odd
# - We assume that p is a prime
# - Modular inversion uses the Fermat's little theorem
# which requires a prime
import import
../primitives/constant_time, ../primitives/constant_time,
@ -28,21 +32,21 @@ import
from ../io/io_bigints import exportRawUint # for "pow" from ../io/io_bigints import exportRawUint # for "pow"
# type # type
# `Fq`*[C: static Curve] = object # `Fp`*[C: static Curve] = object
# ## All operations on a field are modulo P # ## All operations on a field are modulo P
# ## P being the prime modulus of the Curve C # ## P being the prime modulus of the Curve C
# ## Internally, data is stored in Montgomery n-residue form # ## 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) # ## with the magic constant chosen for convenient division (a power of 2 depending on P bitsize)
# mres*: matchingBigInt(C) # mres*: matchingBigInt(C)
export Fq # defined in ../config/curves to avoid recursive module dependencies export Fp # defined in ../config/curves to avoid recursive module dependencies
debug: debug:
func `==`*(a, b: Fq): CTBool[Word] = func `==`*(a, b: Fp): CTBool[Word] =
## Returns true if 2 big ints are equal ## Returns true if 2 big ints are equal
a.mres == b.mres a.mres == b.mres
func `$`*[C: static Curve](a: Fq[C]): string = func `$`*[C: static Curve](a: Fp[C]): string =
result = "Fq[" & $C result = "Fp[" & $C
result.add "](" result.add "]("
result.add $a.mres result.add $a.mres
result.add ')' result.add ')'
@ -57,18 +61,18 @@ debug:
# #
# ############################################################ # ############################################################
func fromBig*[C: static Curve](T: type Fq[C], src: BigInt): Fq[C] {.noInit.} = func fromBig*[C: static Curve](T: type Fp[C], src: BigInt): Fp[C] {.noInit.} =
## Convert a BigInt to its Montgomery form ## Convert a BigInt to its Montgomery form
result.mres.montyResidue(src, C.Mod.mres, C.getR2modP(), C.getNegInvModWord()) result.mres.montyResidue(src, C.Mod.mres, C.getR2modP(), C.getNegInvModWord())
func fromBig*[C: static Curve](dst: var Fq[C], src: BigInt) {.noInit.} = func fromBig*[C: static Curve](dst: var Fp[C], src: BigInt) {.noInit.} =
## Convert a BigInt to its Montgomery form ## Convert a BigInt to its Montgomery form
dst.mres.montyResidue(src, C.Mod.mres, C.getR2modP(), C.getNegInvModWord()) dst.mres.montyResidue(src, C.Mod.mres, C.getR2modP(), C.getNegInvModWord())
func toBig*(src: Fq): auto {.noInit.} = func toBig*(src: Fp): auto {.noInit.} =
## Convert a finite-field element to a BigInt in natral representation ## Convert a finite-field element to a BigInt in natral representation
var r {.noInit.}: typeof(src.mres) var r {.noInit.}: typeof(src.mres)
r.redc(src.mres, Fq.C.Mod.mres, Fq.C.getNegInvModWord()) r.redc(src.mres, Fp.C.Mod.mres, Fp.C.getNegInvModWord())
return r return r
# ############################################################ # ############################################################
@ -77,7 +81,7 @@ func toBig*(src: Fq): auto {.noInit.} =
# #
# ############################################################ # ############################################################
template add(a: var Fq, b: Fq, ctl: CTBool[Word]): CTBool[Word] = template add(a: var Fp, b: Fp, ctl: CTBool[Word]): CTBool[Word] =
## Constant-time big integer in-place optional addition ## Constant-time big integer in-place optional addition
## The addition is only performed if ctl is "true" ## The addition is only performed if ctl is "true"
## The result carry is always computed. ## The result carry is always computed.
@ -86,7 +90,7 @@ template add(a: var Fq, b: Fq, ctl: CTBool[Word]): CTBool[Word] =
## a and b MUST have the same announced bitlength (i.e. `bits` static parameters) ## a and b MUST have the same announced bitlength (i.e. `bits` static parameters)
add(a.mres, b.mres, ctl) add(a.mres, b.mres, ctl)
template sub(a: var Fq, b: Fq, ctl: CTBool[Word]): CTBool[Word] = template sub(a: var Fp, b: Fp, ctl: CTBool[Word]): CTBool[Word] =
## Constant-time big integer in-place optional substraction ## Constant-time big integer in-place optional substraction
## The substraction is only performed if ctl is "true" ## The substraction is only performed if ctl is "true"
## The result carry is always computed. ## The result carry is always computed.
@ -109,46 +113,46 @@ template sub(a: var Fq, b: Fq, ctl: CTBool[Word]): CTBool[Word] =
# - Golden Primes (φ^2 - φ - 1 with φ = 2^k for example Ed448-Goldilocks: 2^448 - 2^224 - 1) # - Golden Primes (φ^2 - φ - 1 with φ = 2^k for example Ed448-Goldilocks: 2^448 - 2^224 - 1)
# exist and can be implemented with compile-time specialization. # exist and can be implemented with compile-time specialization.
func `+=`*(a: var Fq, b: Fq) = func `+=`*(a: var Fp, b: Fp) =
## Addition over Fq ## Addition over Fp
var ctl = add(a, b, CtTrue) var ctl = add(a, b, CtTrue)
ctl = ctl or not sub(a, Fq.C.Mod, CtFalse) ctl = ctl or not sub(a, Fp.C.Mod, CtFalse)
discard sub(a, Fq.C.Mod, ctl) discard sub(a, Fp.C.Mod, ctl)
func `-=`*(a: var Fq, b: Fq) = func `-=`*(a: var Fp, b: Fp) =
## Substraction over Fq ## Substraction over Fp
let ctl = sub(a, b, CtTrue) let ctl = sub(a, b, CtTrue)
discard add(a, Fq.C.Mod, ctl) discard add(a, Fp.C.Mod, ctl)
func `*`*(a, b: Fq): Fq {.noInit.} = func `*`*(a, b: Fp): Fp {.noInit.} =
## Multiplication over Fq ## Multiplication over Fp
## ##
## It is recommended to assign with {.noInit.} ## It is recommended to assign with {.noInit.}
## as Fq elements are usually large and this ## as Fp elements are usually large and this
## routine will zero init internally the result. ## routine will zero init internally the result.
result.mres.montyMul(a.mres, b.mres, Fq.C.Mod.mres, Fq.C.getNegInvModWord()) result.mres.montyMul(a.mres, b.mres, Fp.C.Mod.mres, Fp.C.getNegInvModWord())
func square*(a: Fq): Fq {.noInit.} = func square*(a: Fp): Fp {.noInit.} =
## Squaring over Fq ## Squaring over Fp
## ##
## It is recommended to assign with {.noInit.} ## It is recommended to assign with {.noInit.}
## as Fq elements are usually large and this ## as Fp elements are usually large and this
## routine will zero init internally the result. ## routine will zero init internally the result.
result.mres.montySquare(a.mres, Fq.C.Mod.mres, Fq.C.getNegInvModWord()) result.mres.montySquare(a.mres, Fp.C.Mod.mres, Fp.C.getNegInvModWord())
func pow*(a: var Fq, exponent: BigInt) = func pow*(a: var Fp, exponent: BigInt) =
## Exponentiation over Fq ## Exponentiation over Fp
## ``a``: a field element to be exponentiated ## ``a``: a field element to be exponentiated
## ``exponent``: a big integer ## ``exponent``: a big integer
const windowSize = 5 # TODO: find best window size for each curves const windowSize = 5 # TODO: find best window size for each curves
a.mres.montyPow( a.mres.montyPow(
exponent, exponent,
Fq.C.Mod.mres, Fq.C.getMontyOne(), Fp.C.Mod.mres, Fp.C.getMontyOne(),
Fq.C.getNegInvModWord(), windowSize Fp.C.getNegInvModWord(), windowSize
) )
func powUnsafeExponent*(a: var Fq, exponent: BigInt) = func powUnsafeExponent*(a: var Fp, exponent: BigInt) =
## Exponentiation over Fq ## Exponentiation over Fp
## ``a``: a field element to be exponentiated ## ``a``: a field element to be exponentiated
## ``exponent``: a big integer ## ``exponent``: a big integer
## ##
@ -161,17 +165,17 @@ func powUnsafeExponent*(a: var Fq, exponent: BigInt) =
const windowSize = 5 # TODO: find best window size for each curves const windowSize = 5 # TODO: find best window size for each curves
a.mres.montyPowUnsafeExponent( a.mres.montyPowUnsafeExponent(
exponent, exponent,
Fq.C.Mod.mres, Fq.C.getMontyOne(), Fp.C.Mod.mres, Fp.C.getMontyOne(),
Fq.C.getNegInvModWord(), windowSize Fp.C.getNegInvModWord(), windowSize
) )
func inv*(a: var Fq) = func inv*(a: var Fp) =
## Modular inversion ## Modular inversion
## Warning ⚠️ : ## Warning ⚠️ :
## - This assumes that `Fq` is a prime field ## - This assumes that `Fp` is a prime field
const windowSize = 5 # TODO: find best window size for each curves const windowSize = 5 # TODO: find best window size for each curves
a.mres.montyPowUnsafeExponent( a.mres.montyPowUnsafeExponent(
Fq.C.getInvModExponent(), Fp.C.getInvModExponent(),
Fq.C.Mod.mres, Fq.C.getMontyOne(), Fp.C.Mod.mres, Fp.C.getMontyOne(),
Fq.C.getNegInvModWord(), windowSize Fp.C.getNegInvModWord(), windowSize
) )

View File

@ -59,7 +59,7 @@ macro declareCurves*(curves: untyped): untyped =
var CurveBitSize = nnKBracket.newTree() var CurveBitSize = nnKBracket.newTree()
var curveModStmts = newStmtList() var curveModStmts = newStmtList()
let Fq = ident"Fq" let Fp = ident"Fp"
for curveDesc in curves: for curveDesc in curves:
curveDesc.expectKind(nnkCommand) curveDesc.expectKind(nnkCommand)
@ -87,12 +87,12 @@ macro declareCurves*(curves: untyped): untyped =
curve, bitSize curve, bitSize
) )
# const BN254_Modulus = Fq[BN254](value: fromHex(BigInt[254], "0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47")) # const BN254_Modulus = Fp[BN254](value: fromHex(BigInt[254], "0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47"))
let modulusID = ident($curve & "_Modulus") let modulusID = ident($curve & "_Modulus")
curveModStmts.add newConstStmt( curveModStmts.add newConstStmt(
modulusID, modulusID,
nnkObjConstr.newTree( nnkObjConstr.newTree(
nnkBracketExpr.newTree(Fq, curve), nnkBracketExpr.newTree(Fp, curve),
nnkExprColonExpr.newTree( nnkExprColonExpr.newTree(
ident"mres", ident"mres",
newCall( newCall(
@ -136,7 +136,7 @@ macro declareCurves*(curves: untyped): untyped =
) )
# type # type
# `Fq`*[C: static Curve] = object # `Fp`*[C: static Curve] = object
# ## All operations on a field are modulo P # ## All operations on a field are modulo P
# ## P being the prime modulus of the Curve C # ## P being the prime modulus of the Curve C
# ## Internally, data is stored in Montgomery n-residue form # ## Internally, data is stored in Montgomery n-residue form
@ -144,7 +144,7 @@ macro declareCurves*(curves: untyped): untyped =
# mres*: matchingBigInt(C) # mres*: matchingBigInt(C)
result.add nnkTypeSection.newTree( result.add nnkTypeSection.newTree(
nnkTypeDef.newTree( nnkTypeDef.newTree(
nnkPostfix.newTree(ident"*", Fq), nnkPostfix.newTree(ident"*", Fp),
nnkGenericParams.newTree(newIdentDefs( nnkGenericParams.newTree(newIdentDefs(
C, nnkStaticTy.newTree(Curve), newEmptyNode() C, nnkStaticTy.newTree(Curve), newEmptyNode()
)), )),

View File

@ -21,7 +21,7 @@ import
# #
# ############################################################ # ############################################################
func fromUint*(dst: var Fq, func fromUint*(dst: var Fp,
src: SomeUnsignedInt) = src: SomeUnsignedInt) =
## Parse a regular unsigned integer ## Parse a regular unsigned integer
## and store it into a BigInt of size `bits` ## and store it into a BigInt of size `bits`
@ -29,7 +29,7 @@ func fromUint*(dst: var Fq,
dst.fromBig(raw) dst.fromBig(raw)
func exportRawUint*(dst: var openarray[byte], func exportRawUint*(dst: var openarray[byte],
src: Fq, src: Fp,
dstEndianness: static Endianness) = dstEndianness: static Endianness) =
## Serialize a finite field element to its canonical big-endian or little-endian ## Serialize a finite field element to its canonical big-endian or little-endian
## representation ## representation
@ -42,7 +42,7 @@ func exportRawUint*(dst: var openarray[byte],
## I.e least significant bit is aligned to buffer boundary ## I.e least significant bit is aligned to buffer boundary
exportRawUint(dst, src.toBig(), dstEndianness) exportRawUint(dst, src.toBig(), dstEndianness)
func toHex*(f: Fq, order: static Endianness = bigEndian): string = func toHex*(f: Fp, order: static Endianness = bigEndian): string =
## Stringify a finite field element to hex. ## Stringify a finite field element to hex.
## Note. Leading zeros are not removed. ## Note. Leading zeros are not removed.
## Result is prefixed with 0x ## Result is prefixed with 0x
@ -53,7 +53,7 @@ func toHex*(f: Fq, order: static Endianness = bigEndian): string =
## - no leaks ## - no leaks
result = f.toBig().toHex(order) result = f.toBig().toHex(order)
func fromHex*(dst: var Fq, s: string) {.raises: [ValueError].}= func fromHex*(dst: var Fp, s: string) {.raises: [ValueError].}=
## Convert a hex string to a element of Fq ## Convert a hex string to a element of Fp
let raw {.noinit.} = fromHex(dst.mres.typeof, s) let raw {.noinit.} = fromHex(dst.mres.typeof, s)
dst.fromBig(raw) dst.fromBig(raw)

View File

@ -19,7 +19,7 @@ proc main() =
suite "Basic arithmetic over finite fields": suite "Basic arithmetic over finite fields":
test "Addition mod 101": test "Addition mod 101":
block: block:
var x, y, z: Fq[Fake101] var x, y, z: Fp[Fake101]
x.fromUint(80'u32) x.fromUint(80'u32)
y.fromUint(10'u32) y.fromUint(10'u32)
@ -37,7 +37,7 @@ proc main() =
90'u64 == cast[uint64](x_bytes) 90'u64 == cast[uint64](x_bytes)
block: block:
var x, y, z: Fq[Fake101] var x, y, z: Fp[Fake101]
x.fromUint(80'u32) x.fromUint(80'u32)
y.fromUint(21'u32) y.fromUint(21'u32)
@ -55,7 +55,7 @@ proc main() =
0'u64 == cast[uint64](x_bytes) 0'u64 == cast[uint64](x_bytes)
block: block:
var x, y, z: Fq[Fake101] var x, y, z: Fp[Fake101]
x.fromUint(80'u32) x.fromUint(80'u32)
y.fromUint(22'u32) y.fromUint(22'u32)
@ -74,7 +74,7 @@ proc main() =
test "Substraction mod 101": test "Substraction mod 101":
block: block:
var x, y, z: Fq[Fake101] var x, y, z: Fp[Fake101]
x.fromUint(80'u32) x.fromUint(80'u32)
y.fromUint(10'u32) y.fromUint(10'u32)
@ -92,7 +92,7 @@ proc main() =
70'u64 == cast[uint64](x_bytes) 70'u64 == cast[uint64](x_bytes)
block: block:
var x, y, z: Fq[Fake101] var x, y, z: Fp[Fake101]
x.fromUint(80'u32) x.fromUint(80'u32)
y.fromUint(80'u32) y.fromUint(80'u32)
@ -110,7 +110,7 @@ proc main() =
0'u64 == cast[uint64](x_bytes) 0'u64 == cast[uint64](x_bytes)
block: block:
var x, y, z: Fq[Fake101] var x, y, z: Fp[Fake101]
x.fromUint(80'u32) x.fromUint(80'u32)
y.fromUint(81'u32) y.fromUint(81'u32)
@ -129,7 +129,7 @@ proc main() =
test "Multiplication mod 101": test "Multiplication mod 101":
block: block:
var x, y, z: Fq[Fake101] var x, y, z: Fp[Fake101]
x.fromUint(10'u32) x.fromUint(10'u32)
y.fromUint(10'u32) y.fromUint(10'u32)
@ -147,7 +147,7 @@ proc main() =
100'u64 == cast[uint64](r_bytes) 100'u64 == cast[uint64](r_bytes)
block: block:
var x, y, z: Fq[Fake101] var x, y, z: Fp[Fake101]
x.fromUint(10'u32) x.fromUint(10'u32)
y.fromUint(11'u32) y.fromUint(11'u32)
@ -166,7 +166,7 @@ proc main() =
test "Addition mod 2^61 - 1": test "Addition mod 2^61 - 1":
block: block:
var x, y, z: Fq[Mersenne61] var x, y, z: Fp[Mersenne61]
x.fromUint(80'u64) x.fromUint(80'u64)
y.fromUint(10'u64) y.fromUint(10'u64)
@ -185,7 +185,7 @@ proc main() =
new_x == 90'u64 new_x == 90'u64
block: block:
var x, y, z: Fq[Mersenne61] var x, y, z: Fp[Mersenne61]
x.fromUint(1'u64 shl 61 - 2) x.fromUint(1'u64 shl 61 - 2)
y.fromUint(1'u32) y.fromUint(1'u32)
@ -204,7 +204,7 @@ proc main() =
new_x == 0'u64 new_x == 0'u64
block: block:
var x, y, z: Fq[Mersenne61] var x, y, z: Fp[Mersenne61]
x.fromUint(1'u64 shl 61 - 2) x.fromUint(1'u64 shl 61 - 2)
y.fromUint(2'u64) y.fromUint(2'u64)
@ -224,7 +224,7 @@ proc main() =
test "Substraction mod 2^61 - 1": test "Substraction mod 2^61 - 1":
block: block:
var x, y, z: Fq[Mersenne61] var x, y, z: Fp[Mersenne61]
x.fromUint(80'u64) x.fromUint(80'u64)
y.fromUint(10'u64) y.fromUint(10'u64)
@ -243,7 +243,7 @@ proc main() =
new_x == 70'u64 new_x == 70'u64
block: block:
var x, y, z: Fq[Mersenne61] var x, y, z: Fp[Mersenne61]
x.fromUint(0'u64) x.fromUint(0'u64)
y.fromUint(1'u64) y.fromUint(1'u64)
@ -263,7 +263,7 @@ proc main() =
test "Multiplication mod 2^61 - 1": test "Multiplication mod 2^61 - 1":
block: block:
var x, y, z: Fq[Mersenne61] var x, y, z: Fp[Mersenne61]
x.fromUint(10'u32) x.fromUint(10'u32)
y.fromUint(10'u32) y.fromUint(10'u32)
@ -282,7 +282,7 @@ proc main() =
cast[uint64](r_bytes) == 100'u64 cast[uint64](r_bytes) == 100'u64
block: block:
var x, y, z: Fq[Mersenne61] var x, y, z: Fp[Mersenne61]
x.fromUint(1'u32 shl 31) x.fromUint(1'u32 shl 31)
y.fromUint(1'u32 shl 31) y.fromUint(1'u32 shl 31)

View File

@ -21,7 +21,7 @@ proc main() =
let exponent = BigInt[64].fromUint(2'u64) let exponent = BigInt[64].fromUint(2'u64)
block: # 1^2 mod 101 block: # 1^2 mod 101
var n, expected: Fq[Fake101] var n, expected: Fp[Fake101]
n.fromUint(1'u32) n.fromUint(1'u32)
expected = n expected = n
@ -39,7 +39,7 @@ proc main() =
1'u64 == r 1'u64 == r
block: # 2^2 mod 101 block: # 2^2 mod 101
var n, expected: Fq[Fake101] var n, expected: Fp[Fake101]
n.fromUint(2'u32) n.fromUint(2'u32)
expected.fromUint(4'u32) expected.fromUint(4'u32)
@ -57,7 +57,7 @@ proc main() =
4'u64 == r 4'u64 == r
block: # 10^2 mod 101 block: # 10^2 mod 101
var n, expected: Fq[Fake101] var n, expected: Fp[Fake101]
n.fromUint(10'u32) n.fromUint(10'u32)
expected.fromUint(100'u32) expected.fromUint(100'u32)
@ -75,7 +75,7 @@ proc main() =
100'u64 == r 100'u64 == r
block: # 11^2 mod 101 block: # 11^2 mod 101
var n, expected: Fq[Fake101] var n, expected: Fp[Fake101]
n.fromUint(11'u32) n.fromUint(11'u32)
expected.fromUint(20'u32) expected.fromUint(20'u32)
@ -94,7 +94,7 @@ proc main() =
test "x^(p-2) mod p (modular inversion if p prime)": test "x^(p-2) mod p (modular inversion if p prime)":
block: block:
var x: Fq[BLS12_381] var x: Fp[BLS12_381]
# BN254 field modulus # BN254 field modulus
x.fromHex("0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47") x.fromHex("0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47")
@ -110,7 +110,7 @@ proc main() =
computed == expected computed == expected
block: block:
var x: Fq[BLS12_381] var x: Fp[BLS12_381]
# BN254 field modulus # BN254 field modulus
x.fromHex("0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47") x.fromHex("0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47")
@ -127,7 +127,7 @@ proc main() =
suite "Modular inversion over prime fields": suite "Modular inversion over prime fields":
test "x^(-1) mod p": test "x^(-1) mod p":
var x: Fq[BLS12_381] var x: Fp[BLS12_381]
# BN254 field modulus # BN254 field modulus
x.fromHex("0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47") x.fromHex("0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47")

View File

@ -94,8 +94,8 @@ proc mainMul() =
doAssert len >= bW, "Expected at most " & $len & " bytes but wrote " & $bW & " for " & toHex(bBuf) & " (little-endian)" doAssert len >= bW, "Expected at most " & $len & " bytes but wrote " & $bW & " for " & toHex(bBuf) & " (little-endian)"
# Build the bigint - TODO more fields codecs # Build the bigint - TODO more fields codecs
let aTest = Fq[curve].fromBig BigInt[bits].fromRawUint(aBuf, littleEndian) let aTest = Fp[curve].fromBig BigInt[bits].fromRawUint(aBuf, littleEndian)
let bTest = Fq[curve].fromBig BigInt[bits].fromRawUint(bBuf, littleEndian) let bTest = Fp[curve].fromBig BigInt[bits].fromRawUint(bBuf, littleEndian)
######################################################### #########################################################
# Modular multiplication # Modular multiplication
@ -169,7 +169,7 @@ proc mainInv() =
doAssert len >= aW, "Expected at most " & $len & " bytes but wrote " & $aW & " for " & toHex(aBuf) & " (little-endian)" doAssert len >= aW, "Expected at most " & $len & " bytes but wrote " & $aW & " for " & toHex(aBuf) & " (little-endian)"
# Build the bigint - TODO more fields codecs # Build the bigint - TODO more fields codecs
let aTest = Fq[curve].fromBig BigInt[bits].fromRawUint(aBuf[0 ..< aW], bigEndian) let aTest = Fp[curve].fromBig BigInt[bits].fromRawUint(aBuf[0 ..< aW], bigEndian)
######################################################### #########################################################
# Modular inversion # Modular inversion

View File

@ -22,7 +22,7 @@ proc main() =
# "Little-endian" - 0 # "Little-endian" - 0
let x = 0'u64 let x = 0'u64
let x_bytes = cast[array[8, byte]](x) let x_bytes = cast[array[8, byte]](x)
var f: Fq[Mersenne61] var f: Fp[Mersenne61]
f.fromUint(x) f.fromUint(x)
var r_bytes: array[8, byte] var r_bytes: array[8, byte]
@ -33,7 +33,7 @@ proc main() =
# "Little-endian" - 1 # "Little-endian" - 1
let x = 1'u64 let x = 1'u64
let x_bytes = cast[array[8, byte]](x) let x_bytes = cast[array[8, byte]](x)
var f: Fq[Mersenne61] var f: Fp[Mersenne61]
f.fromUint(x) f.fromUint(x)
var r_bytes: array[8, byte] var r_bytes: array[8, byte]
@ -44,7 +44,7 @@ proc main() =
# "Little-endian" - 2^31 # "Little-endian" - 2^31
let x = 1'u64 shl 31 let x = 1'u64 shl 31
let x_bytes = cast[array[8, byte]](x) let x_bytes = cast[array[8, byte]](x)
var f: Fq[Mersenne61] var f: Fp[Mersenne61]
f.fromUint(x) f.fromUint(x)
var r_bytes: array[8, byte] var r_bytes: array[8, byte]
@ -55,7 +55,7 @@ proc main() =
# "Little-endian" - 2^32 # "Little-endian" - 2^32
let x = 1'u64 shl 32 let x = 1'u64 shl 32
let x_bytes = cast[array[8, byte]](x) let x_bytes = cast[array[8, byte]](x)
var f: Fq[Mersenne61] var f: Fp[Mersenne61]
f.fromUint(x) f.fromUint(x)
var r_bytes: array[8, byte] var r_bytes: array[8, byte]
@ -67,7 +67,7 @@ proc main() =
# "Little-endian" - 2^63 # "Little-endian" - 2^63
let x = 1'u64 shl 63 let x = 1'u64 shl 63
let x_bytes = cast[array[8, byte]](x) let x_bytes = cast[array[8, byte]](x)
var f: Fq[Mersenne127] var f: Fp[Mersenne127]
f.fromUint(x) f.fromUint(x)
var r_bytes: array[16, byte] var r_bytes: array[16, byte]
@ -77,7 +77,7 @@ proc main() =
block: # "Little-endian" - single random block: # "Little-endian" - single random
let x = uint64 rand(0..high(int)) let x = uint64 rand(0..high(int))
let x_bytes = cast[array[8, byte]](x) let x_bytes = cast[array[8, byte]](x)
var f: Fq[Mersenne127] var f: Fp[Mersenne127]
f.fromUint(x) f.fromUint(x)
var r_bytes: array[16, byte] var r_bytes: array[16, byte]
@ -88,7 +88,7 @@ proc main() =
for _ in 0 ..< 10: for _ in 0 ..< 10:
let x = uint64 rand(0..high(int)) let x = uint64 rand(0..high(int))
let x_bytes = cast[array[8, byte]](x) let x_bytes = cast[array[8, byte]](x)
var f: Fq[Mersenne127] var f: Fp[Mersenne127]
f.fromUint(x) f.fromUint(x)
var r_bytes: array[16, byte] var r_bytes: array[16, byte]
@ -98,7 +98,7 @@ proc main() =
test "Round trip on large constant": test "Round trip on large constant":
block: # 2^126 block: # 2^126
const p = "0x40000000000000000000000000000000" const p = "0x40000000000000000000000000000000"
let x = Fq[Mersenne127].fromBig BigInt[127].fromHex(p) let x = Fp[Mersenne127].fromBig BigInt[127].fromHex(p)
let hex = x.toHex(bigEndian) let hex = x.toHex(bigEndian)
check: p == hex check: p == hex