Rename Fq -> Fp
This commit is contained in:
parent
3bd70991d4
commit
6b05c69652
|
@ -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
|
||||
# We assume that q is not even:
|
||||
# - Operations are done in the Montgomery domain
|
||||
# - The Montgomery domain introduce a Montgomery constant that must be coprime
|
||||
# with the field modulus.
|
||||
# - The constant is chosen a power of 2
|
||||
# => to be coprime with a power of 2, q must be odd
|
||||
# Constraints:
|
||||
# - We assume that p is known at compile-time
|
||||
# - We assume that p is not even:
|
||||
# - Operations are done in the Montgomery domain
|
||||
# - The Montgomery domain introduce a Montgomery constant that must be coprime
|
||||
# with the field modulus.
|
||||
# - 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
|
||||
../primitives/constant_time,
|
||||
|
@ -28,21 +32,21 @@ import
|
|||
from ../io/io_bigints import exportRawUint # for "pow"
|
||||
|
||||
# type
|
||||
# `Fq`*[C: static Curve] = object
|
||||
# `Fp`*[C: static Curve] = object
|
||||
# ## All operations on a field are modulo P
|
||||
# ## P being the prime modulus of the Curve C
|
||||
# ## 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)
|
||||
# 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:
|
||||
func `==`*(a, b: Fq): CTBool[Word] =
|
||||
func `==`*(a, b: Fp): CTBool[Word] =
|
||||
## Returns true if 2 big ints are equal
|
||||
a.mres == b.mres
|
||||
|
||||
func `$`*[C: static Curve](a: Fq[C]): string =
|
||||
result = "Fq[" & $C
|
||||
func `$`*[C: static Curve](a: Fp[C]): string =
|
||||
result = "Fp[" & $C
|
||||
result.add "]("
|
||||
result.add $a.mres
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
|
||||
# ############################################################
|
||||
|
@ -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
|
||||
## The addition is only performed if ctl is "true"
|
||||
## 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)
|
||||
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
|
||||
## The substraction is only performed if ctl is "true"
|
||||
## 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)
|
||||
# exist and can be implemented with compile-time specialization.
|
||||
|
||||
func `+=`*(a: var Fq, b: Fq) =
|
||||
## Addition over Fq
|
||||
func `+=`*(a: var Fp, b: Fp) =
|
||||
## Addition over Fp
|
||||
var ctl = add(a, b, CtTrue)
|
||||
ctl = ctl or not sub(a, Fq.C.Mod, CtFalse)
|
||||
discard sub(a, Fq.C.Mod, ctl)
|
||||
ctl = ctl or not sub(a, Fp.C.Mod, CtFalse)
|
||||
discard sub(a, Fp.C.Mod, ctl)
|
||||
|
||||
func `-=`*(a: var Fq, b: Fq) =
|
||||
## Substraction over Fq
|
||||
func `-=`*(a: var Fp, b: Fp) =
|
||||
## Substraction over Fp
|
||||
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.} =
|
||||
## Multiplication over Fq
|
||||
func `*`*(a, b: Fp): Fp {.noInit.} =
|
||||
## Multiplication over Fp
|
||||
##
|
||||
## 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.
|
||||
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.} =
|
||||
## Squaring over Fq
|
||||
func square*(a: Fp): Fp {.noInit.} =
|
||||
## Squaring over Fp
|
||||
##
|
||||
## 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.
|
||||
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) =
|
||||
## Exponentiation over Fq
|
||||
func pow*(a: var Fp, exponent: BigInt) =
|
||||
## Exponentiation over Fp
|
||||
## ``a``: a field element to be exponentiated
|
||||
## ``exponent``: a big integer
|
||||
const windowSize = 5 # TODO: find best window size for each curves
|
||||
a.mres.montyPow(
|
||||
exponent,
|
||||
Fq.C.Mod.mres, Fq.C.getMontyOne(),
|
||||
Fq.C.getNegInvModWord(), windowSize
|
||||
Fp.C.Mod.mres, Fp.C.getMontyOne(),
|
||||
Fp.C.getNegInvModWord(), windowSize
|
||||
)
|
||||
|
||||
func powUnsafeExponent*(a: var Fq, exponent: BigInt) =
|
||||
## Exponentiation over Fq
|
||||
func powUnsafeExponent*(a: var Fp, exponent: BigInt) =
|
||||
## Exponentiation over Fp
|
||||
## ``a``: a field element to be exponentiated
|
||||
## ``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
|
||||
a.mres.montyPowUnsafeExponent(
|
||||
exponent,
|
||||
Fq.C.Mod.mres, Fq.C.getMontyOne(),
|
||||
Fq.C.getNegInvModWord(), windowSize
|
||||
Fp.C.Mod.mres, Fp.C.getMontyOne(),
|
||||
Fp.C.getNegInvModWord(), windowSize
|
||||
)
|
||||
|
||||
func inv*(a: var Fq) =
|
||||
func inv*(a: var Fp) =
|
||||
## Modular inversion
|
||||
## 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
|
||||
a.mres.montyPowUnsafeExponent(
|
||||
Fq.C.getInvModExponent(),
|
||||
Fq.C.Mod.mres, Fq.C.getMontyOne(),
|
||||
Fq.C.getNegInvModWord(), windowSize
|
||||
Fp.C.getInvModExponent(),
|
||||
Fp.C.Mod.mres, Fp.C.getMontyOne(),
|
||||
Fp.C.getNegInvModWord(), windowSize
|
||||
)
|
||||
|
|
|
@ -59,7 +59,7 @@ macro declareCurves*(curves: untyped): untyped =
|
|||
var CurveBitSize = nnKBracket.newTree()
|
||||
var curveModStmts = newStmtList()
|
||||
|
||||
let Fq = ident"Fq"
|
||||
let Fp = ident"Fp"
|
||||
|
||||
for curveDesc in curves:
|
||||
curveDesc.expectKind(nnkCommand)
|
||||
|
@ -87,12 +87,12 @@ macro declareCurves*(curves: untyped): untyped =
|
|||
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")
|
||||
curveModStmts.add newConstStmt(
|
||||
modulusID,
|
||||
nnkObjConstr.newTree(
|
||||
nnkBracketExpr.newTree(Fq, curve),
|
||||
nnkBracketExpr.newTree(Fp, curve),
|
||||
nnkExprColonExpr.newTree(
|
||||
ident"mres",
|
||||
newCall(
|
||||
|
@ -136,7 +136,7 @@ macro declareCurves*(curves: untyped): untyped =
|
|||
)
|
||||
|
||||
# type
|
||||
# `Fq`*[C: static Curve] = object
|
||||
# `Fp`*[C: static Curve] = object
|
||||
# ## All operations on a field are modulo P
|
||||
# ## P being the prime modulus of the Curve C
|
||||
# ## Internally, data is stored in Montgomery n-residue form
|
||||
|
@ -144,7 +144,7 @@ macro declareCurves*(curves: untyped): untyped =
|
|||
# mres*: matchingBigInt(C)
|
||||
result.add nnkTypeSection.newTree(
|
||||
nnkTypeDef.newTree(
|
||||
nnkPostfix.newTree(ident"*", Fq),
|
||||
nnkPostfix.newTree(ident"*", Fp),
|
||||
nnkGenericParams.newTree(newIdentDefs(
|
||||
C, nnkStaticTy.newTree(Curve), newEmptyNode()
|
||||
)),
|
||||
|
|
|
@ -21,7 +21,7 @@ import
|
|||
#
|
||||
# ############################################################
|
||||
|
||||
func fromUint*(dst: var Fq,
|
||||
func fromUint*(dst: var Fp,
|
||||
src: SomeUnsignedInt) =
|
||||
## Parse a regular unsigned integer
|
||||
## and store it into a BigInt of size `bits`
|
||||
|
@ -29,7 +29,7 @@ func fromUint*(dst: var Fq,
|
|||
dst.fromBig(raw)
|
||||
|
||||
func exportRawUint*(dst: var openarray[byte],
|
||||
src: Fq,
|
||||
src: Fp,
|
||||
dstEndianness: static Endianness) =
|
||||
## Serialize a finite field element to its canonical big-endian or little-endian
|
||||
## representation
|
||||
|
@ -42,7 +42,7 @@ func exportRawUint*(dst: var openarray[byte],
|
|||
## I.e least significant bit is aligned to buffer boundary
|
||||
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.
|
||||
## Note. Leading zeros are not removed.
|
||||
## Result is prefixed with 0x
|
||||
|
@ -53,7 +53,7 @@ func toHex*(f: Fq, order: static Endianness = bigEndian): string =
|
|||
## - no leaks
|
||||
result = f.toBig().toHex(order)
|
||||
|
||||
func fromHex*(dst: var Fq, s: string) {.raises: [ValueError].}=
|
||||
## Convert a hex string to a element of Fq
|
||||
func fromHex*(dst: var Fp, s: string) {.raises: [ValueError].}=
|
||||
## Convert a hex string to a element of Fp
|
||||
let raw {.noinit.} = fromHex(dst.mres.typeof, s)
|
||||
dst.fromBig(raw)
|
||||
|
|
|
@ -19,7 +19,7 @@ proc main() =
|
|||
suite "Basic arithmetic over finite fields":
|
||||
test "Addition mod 101":
|
||||
block:
|
||||
var x, y, z: Fq[Fake101]
|
||||
var x, y, z: Fp[Fake101]
|
||||
|
||||
x.fromUint(80'u32)
|
||||
y.fromUint(10'u32)
|
||||
|
@ -37,7 +37,7 @@ proc main() =
|
|||
90'u64 == cast[uint64](x_bytes)
|
||||
|
||||
block:
|
||||
var x, y, z: Fq[Fake101]
|
||||
var x, y, z: Fp[Fake101]
|
||||
|
||||
x.fromUint(80'u32)
|
||||
y.fromUint(21'u32)
|
||||
|
@ -55,7 +55,7 @@ proc main() =
|
|||
0'u64 == cast[uint64](x_bytes)
|
||||
|
||||
block:
|
||||
var x, y, z: Fq[Fake101]
|
||||
var x, y, z: Fp[Fake101]
|
||||
|
||||
x.fromUint(80'u32)
|
||||
y.fromUint(22'u32)
|
||||
|
@ -74,7 +74,7 @@ proc main() =
|
|||
|
||||
test "Substraction mod 101":
|
||||
block:
|
||||
var x, y, z: Fq[Fake101]
|
||||
var x, y, z: Fp[Fake101]
|
||||
|
||||
x.fromUint(80'u32)
|
||||
y.fromUint(10'u32)
|
||||
|
@ -92,7 +92,7 @@ proc main() =
|
|||
70'u64 == cast[uint64](x_bytes)
|
||||
|
||||
block:
|
||||
var x, y, z: Fq[Fake101]
|
||||
var x, y, z: Fp[Fake101]
|
||||
|
||||
x.fromUint(80'u32)
|
||||
y.fromUint(80'u32)
|
||||
|
@ -110,7 +110,7 @@ proc main() =
|
|||
0'u64 == cast[uint64](x_bytes)
|
||||
|
||||
block:
|
||||
var x, y, z: Fq[Fake101]
|
||||
var x, y, z: Fp[Fake101]
|
||||
|
||||
x.fromUint(80'u32)
|
||||
y.fromUint(81'u32)
|
||||
|
@ -129,7 +129,7 @@ proc main() =
|
|||
|
||||
test "Multiplication mod 101":
|
||||
block:
|
||||
var x, y, z: Fq[Fake101]
|
||||
var x, y, z: Fp[Fake101]
|
||||
|
||||
x.fromUint(10'u32)
|
||||
y.fromUint(10'u32)
|
||||
|
@ -147,7 +147,7 @@ proc main() =
|
|||
100'u64 == cast[uint64](r_bytes)
|
||||
|
||||
block:
|
||||
var x, y, z: Fq[Fake101]
|
||||
var x, y, z: Fp[Fake101]
|
||||
|
||||
x.fromUint(10'u32)
|
||||
y.fromUint(11'u32)
|
||||
|
@ -166,7 +166,7 @@ proc main() =
|
|||
|
||||
test "Addition mod 2^61 - 1":
|
||||
block:
|
||||
var x, y, z: Fq[Mersenne61]
|
||||
var x, y, z: Fp[Mersenne61]
|
||||
|
||||
x.fromUint(80'u64)
|
||||
y.fromUint(10'u64)
|
||||
|
@ -185,7 +185,7 @@ proc main() =
|
|||
new_x == 90'u64
|
||||
|
||||
block:
|
||||
var x, y, z: Fq[Mersenne61]
|
||||
var x, y, z: Fp[Mersenne61]
|
||||
|
||||
x.fromUint(1'u64 shl 61 - 2)
|
||||
y.fromUint(1'u32)
|
||||
|
@ -204,7 +204,7 @@ proc main() =
|
|||
new_x == 0'u64
|
||||
|
||||
block:
|
||||
var x, y, z: Fq[Mersenne61]
|
||||
var x, y, z: Fp[Mersenne61]
|
||||
|
||||
x.fromUint(1'u64 shl 61 - 2)
|
||||
y.fromUint(2'u64)
|
||||
|
@ -224,7 +224,7 @@ proc main() =
|
|||
|
||||
test "Substraction mod 2^61 - 1":
|
||||
block:
|
||||
var x, y, z: Fq[Mersenne61]
|
||||
var x, y, z: Fp[Mersenne61]
|
||||
|
||||
x.fromUint(80'u64)
|
||||
y.fromUint(10'u64)
|
||||
|
@ -243,7 +243,7 @@ proc main() =
|
|||
new_x == 70'u64
|
||||
|
||||
block:
|
||||
var x, y, z: Fq[Mersenne61]
|
||||
var x, y, z: Fp[Mersenne61]
|
||||
|
||||
x.fromUint(0'u64)
|
||||
y.fromUint(1'u64)
|
||||
|
@ -263,7 +263,7 @@ proc main() =
|
|||
|
||||
test "Multiplication mod 2^61 - 1":
|
||||
block:
|
||||
var x, y, z: Fq[Mersenne61]
|
||||
var x, y, z: Fp[Mersenne61]
|
||||
|
||||
x.fromUint(10'u32)
|
||||
y.fromUint(10'u32)
|
||||
|
@ -282,7 +282,7 @@ proc main() =
|
|||
cast[uint64](r_bytes) == 100'u64
|
||||
|
||||
block:
|
||||
var x, y, z: Fq[Mersenne61]
|
||||
var x, y, z: Fp[Mersenne61]
|
||||
|
||||
x.fromUint(1'u32 shl 31)
|
||||
y.fromUint(1'u32 shl 31)
|
||||
|
|
|
@ -21,7 +21,7 @@ proc main() =
|
|||
let exponent = BigInt[64].fromUint(2'u64)
|
||||
|
||||
block: # 1^2 mod 101
|
||||
var n, expected: Fq[Fake101]
|
||||
var n, expected: Fp[Fake101]
|
||||
|
||||
n.fromUint(1'u32)
|
||||
expected = n
|
||||
|
@ -39,7 +39,7 @@ proc main() =
|
|||
1'u64 == r
|
||||
|
||||
block: # 2^2 mod 101
|
||||
var n, expected: Fq[Fake101]
|
||||
var n, expected: Fp[Fake101]
|
||||
|
||||
n.fromUint(2'u32)
|
||||
expected.fromUint(4'u32)
|
||||
|
@ -57,7 +57,7 @@ proc main() =
|
|||
4'u64 == r
|
||||
|
||||
block: # 10^2 mod 101
|
||||
var n, expected: Fq[Fake101]
|
||||
var n, expected: Fp[Fake101]
|
||||
|
||||
n.fromUint(10'u32)
|
||||
expected.fromUint(100'u32)
|
||||
|
@ -75,7 +75,7 @@ proc main() =
|
|||
100'u64 == r
|
||||
|
||||
block: # 11^2 mod 101
|
||||
var n, expected: Fq[Fake101]
|
||||
var n, expected: Fp[Fake101]
|
||||
|
||||
n.fromUint(11'u32)
|
||||
expected.fromUint(20'u32)
|
||||
|
@ -94,7 +94,7 @@ proc main() =
|
|||
|
||||
test "x^(p-2) mod p (modular inversion if p prime)":
|
||||
block:
|
||||
var x: Fq[BLS12_381]
|
||||
var x: Fp[BLS12_381]
|
||||
|
||||
# BN254 field modulus
|
||||
x.fromHex("0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47")
|
||||
|
@ -110,7 +110,7 @@ proc main() =
|
|||
computed == expected
|
||||
|
||||
block:
|
||||
var x: Fq[BLS12_381]
|
||||
var x: Fp[BLS12_381]
|
||||
|
||||
# BN254 field modulus
|
||||
x.fromHex("0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47")
|
||||
|
@ -127,7 +127,7 @@ proc main() =
|
|||
|
||||
suite "Modular inversion over prime fields":
|
||||
test "x^(-1) mod p":
|
||||
var x: Fq[BLS12_381]
|
||||
var x: Fp[BLS12_381]
|
||||
|
||||
# BN254 field modulus
|
||||
x.fromHex("0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47")
|
||||
|
|
|
@ -94,8 +94,8 @@ proc mainMul() =
|
|||
doAssert len >= bW, "Expected at most " & $len & " bytes but wrote " & $bW & " for " & toHex(bBuf) & " (little-endian)"
|
||||
|
||||
# Build the bigint - TODO more fields codecs
|
||||
let aTest = Fq[curve].fromBig BigInt[bits].fromRawUint(aBuf, littleEndian)
|
||||
let bTest = Fq[curve].fromBig BigInt[bits].fromRawUint(bBuf, littleEndian)
|
||||
let aTest = Fp[curve].fromBig BigInt[bits].fromRawUint(aBuf, littleEndian)
|
||||
let bTest = Fp[curve].fromBig BigInt[bits].fromRawUint(bBuf, littleEndian)
|
||||
|
||||
#########################################################
|
||||
# Modular multiplication
|
||||
|
@ -169,7 +169,7 @@ proc mainInv() =
|
|||
doAssert len >= aW, "Expected at most " & $len & " bytes but wrote " & $aW & " for " & toHex(aBuf) & " (little-endian)"
|
||||
|
||||
# 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
|
||||
|
|
|
@ -22,7 +22,7 @@ proc main() =
|
|||
# "Little-endian" - 0
|
||||
let x = 0'u64
|
||||
let x_bytes = cast[array[8, byte]](x)
|
||||
var f: Fq[Mersenne61]
|
||||
var f: Fp[Mersenne61]
|
||||
f.fromUint(x)
|
||||
|
||||
var r_bytes: array[8, byte]
|
||||
|
@ -33,7 +33,7 @@ proc main() =
|
|||
# "Little-endian" - 1
|
||||
let x = 1'u64
|
||||
let x_bytes = cast[array[8, byte]](x)
|
||||
var f: Fq[Mersenne61]
|
||||
var f: Fp[Mersenne61]
|
||||
f.fromUint(x)
|
||||
|
||||
var r_bytes: array[8, byte]
|
||||
|
@ -44,7 +44,7 @@ proc main() =
|
|||
# "Little-endian" - 2^31
|
||||
let x = 1'u64 shl 31
|
||||
let x_bytes = cast[array[8, byte]](x)
|
||||
var f: Fq[Mersenne61]
|
||||
var f: Fp[Mersenne61]
|
||||
f.fromUint(x)
|
||||
|
||||
var r_bytes: array[8, byte]
|
||||
|
@ -55,7 +55,7 @@ proc main() =
|
|||
# "Little-endian" - 2^32
|
||||
let x = 1'u64 shl 32
|
||||
let x_bytes = cast[array[8, byte]](x)
|
||||
var f: Fq[Mersenne61]
|
||||
var f: Fp[Mersenne61]
|
||||
f.fromUint(x)
|
||||
|
||||
var r_bytes: array[8, byte]
|
||||
|
@ -67,7 +67,7 @@ proc main() =
|
|||
# "Little-endian" - 2^63
|
||||
let x = 1'u64 shl 63
|
||||
let x_bytes = cast[array[8, byte]](x)
|
||||
var f: Fq[Mersenne127]
|
||||
var f: Fp[Mersenne127]
|
||||
f.fromUint(x)
|
||||
|
||||
var r_bytes: array[16, byte]
|
||||
|
@ -77,7 +77,7 @@ proc main() =
|
|||
block: # "Little-endian" - single random
|
||||
let x = uint64 rand(0..high(int))
|
||||
let x_bytes = cast[array[8, byte]](x)
|
||||
var f: Fq[Mersenne127]
|
||||
var f: Fp[Mersenne127]
|
||||
f.fromUint(x)
|
||||
|
||||
var r_bytes: array[16, byte]
|
||||
|
@ -88,7 +88,7 @@ proc main() =
|
|||
for _ in 0 ..< 10:
|
||||
let x = uint64 rand(0..high(int))
|
||||
let x_bytes = cast[array[8, byte]](x)
|
||||
var f: Fq[Mersenne127]
|
||||
var f: Fp[Mersenne127]
|
||||
f.fromUint(x)
|
||||
|
||||
var r_bytes: array[16, byte]
|
||||
|
@ -98,7 +98,7 @@ proc main() =
|
|||
test "Round trip on large constant":
|
||||
block: # 2^126
|
||||
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)
|
||||
|
||||
check: p == hex
|
||||
|
|
Loading…
Reference in New Issue