mirror of
https://github.com/codex-storage/constantine.git
synced 2025-03-04 04:10:40 +00:00
Less magics, les macros, faster compile-times (or not, Fp6 starts to get really slow, like 5s) + some cleanups in curve families + test 𝔽p6 on 32-bit
This commit is contained in:
parent
c40bc1977d
commit
2d5b173a39
@ -72,8 +72,8 @@ task test, "Run all tests":
|
||||
test "-d:Constantine32", "tests/test_finite_fields_vs_gmp.nim"
|
||||
|
||||
# Towers of extension fields
|
||||
test "", "tests/test_fp2.nim"
|
||||
test "", "tests/test_fp6.nim"
|
||||
test "-d:Constantine32", "tests/test_fp2.nim"
|
||||
test "-d:Constantine32", "tests/test_fp6.nim"
|
||||
|
||||
task test_no_gmp, "Run tests that don't require GMP":
|
||||
# -d:testingCurves is configured in a *.nim.cfg for convenience
|
||||
@ -112,8 +112,8 @@ task test_no_gmp, "Run tests that don't require GMP":
|
||||
test "-d:Constantine32", "tests/test_finite_fields_powinv.nim"
|
||||
|
||||
# Towers of extension fields
|
||||
test "", "tests/test_fp2.nim"
|
||||
test "", "tests/test_fp6.nim"
|
||||
test "-d:Constantine32", "tests/test_fp2.nim"
|
||||
test "-d:Constantine32", "tests/test_fp6.nim"
|
||||
|
||||
proc runBench(benchName: string, compiler = "") =
|
||||
if not dirExists "build":
|
||||
|
@ -29,14 +29,13 @@ import
|
||||
../config/[common, curves],
|
||||
./bigints, ./limbs_montgomery
|
||||
|
||||
# type
|
||||
# `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 Fp # defined in ../config/curves to avoid recursive module dependencies
|
||||
type
|
||||
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)
|
||||
|
||||
debug:
|
||||
func `$`*[C: static Curve](a: Fp[C]): string =
|
||||
@ -57,16 +56,16 @@ debug:
|
||||
|
||||
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(), C.canUseNoCarryMontyMul())
|
||||
result.mres.montyResidue(src, C.Mod, C.getR2modP(), C.getNegInvModWord(), C.canUseNoCarryMontyMul())
|
||||
|
||||
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(), C.canUseNoCarryMontyMul())
|
||||
dst.mres.montyResidue(src, C.Mod, C.getR2modP(), C.getNegInvModWord(), C.canUseNoCarryMontyMul())
|
||||
|
||||
func toBig*(src: Fp): auto {.noInit.} =
|
||||
## Convert a finite-field element to a BigInt in natural representation
|
||||
var r {.noInit.}: typeof(src.mres)
|
||||
r.redc(src.mres, Fp.C.Mod.mres, Fp.C.getNegInvModWord(), Fp.C.canUseNoCarryMontyMul())
|
||||
r.redc(src.mres, Fp.C.Mod, Fp.C.getNegInvModWord(), Fp.C.canUseNoCarryMontyMul())
|
||||
return r
|
||||
|
||||
# ############################################################
|
||||
@ -84,7 +83,7 @@ func toBig*(src: Fp): auto {.noInit.} =
|
||||
# exist and can be implemented with compile-time specialization.
|
||||
|
||||
# Note: for `+=`, double, sum
|
||||
# not(a.mres < Fp.C.Mod.mres) is unnecessary if the prime has the form
|
||||
# not(a.mres < Fp.C.Mod) is unnecessary if the prime has the form
|
||||
# (2^64)^w - 1 (if using uint64 words).
|
||||
# In practice I'm not aware of such prime being using in elliptic curves.
|
||||
# 2^127 - 1 and 2^521 - 1 are used but 127 and 521 are not multiple of 32/64
|
||||
@ -107,52 +106,52 @@ func setOne*(a: var Fp) =
|
||||
func `+=`*(a: var Fp, b: Fp) =
|
||||
## In-place addition modulo p
|
||||
var overflowed = add(a.mres, b.mres)
|
||||
overflowed = overflowed or not(a.mres < Fp.C.Mod.mres)
|
||||
discard csub(a.mres, Fp.C.Mod.mres, overflowed)
|
||||
overflowed = overflowed or not(a.mres < Fp.C.Mod)
|
||||
discard csub(a.mres, Fp.C.Mod, overflowed)
|
||||
|
||||
func `-=`*(a: var Fp, b: Fp) =
|
||||
## In-place substraction modulo p
|
||||
let underflowed = sub(a.mres, b.mres)
|
||||
discard cadd(a.mres, Fp.C.Mod.mres, underflowed)
|
||||
discard cadd(a.mres, Fp.C.Mod, underflowed)
|
||||
|
||||
func double*(a: var Fp) =
|
||||
## Double ``a`` modulo p
|
||||
var overflowed = double(a.mres)
|
||||
overflowed = overflowed or not(a.mres < Fp.C.Mod.mres)
|
||||
discard csub(a.mres, Fp.C.Mod.mres, overflowed)
|
||||
overflowed = overflowed or not(a.mres < Fp.C.Mod)
|
||||
discard csub(a.mres, Fp.C.Mod, overflowed)
|
||||
|
||||
func sum*(r: var Fp, a, b: Fp) =
|
||||
## Sum ``a`` and ``b`` into ``r`` module p
|
||||
## r is initialized/overwritten
|
||||
var overflowed = r.mres.sum(a.mres, b.mres)
|
||||
overflowed = overflowed or not(r.mres < Fp.C.Mod.mres)
|
||||
discard csub(r.mres, Fp.C.Mod.mres, overflowed)
|
||||
overflowed = overflowed or not(r.mres < Fp.C.Mod)
|
||||
discard csub(r.mres, Fp.C.Mod, overflowed)
|
||||
|
||||
func diff*(r: var Fp, a, b: Fp) =
|
||||
## Substract `b` from `a` and store the result into `r`.
|
||||
## `r` is initialized/overwritten
|
||||
var underflowed = r.mres.diff(a.mres, b.mres)
|
||||
discard cadd(r.mres, Fp.C.Mod.mres, underflowed)
|
||||
discard cadd(r.mres, Fp.C.Mod, underflowed)
|
||||
|
||||
func double*(r: var Fp, a: Fp) =
|
||||
## Double ``a`` into ``r``
|
||||
## `r` is initialized/overwritten
|
||||
var overflowed = r.mres.double(a.mres)
|
||||
overflowed = overflowed or not(r.mres < Fp.C.Mod.mres)
|
||||
discard csub(r.mres, Fp.C.Mod.mres, overflowed)
|
||||
overflowed = overflowed or not(r.mres < Fp.C.Mod)
|
||||
discard csub(r.mres, Fp.C.Mod, overflowed)
|
||||
|
||||
func prod*(r: var Fp, a, b: Fp) =
|
||||
## Store the product of ``a`` by ``b`` modulo p into ``r``
|
||||
## ``r`` is initialized / overwritten
|
||||
r.mres.montyMul(a.mres, b.mres, Fp.C.Mod.mres, Fp.C.getNegInvModWord(), Fp.C.canUseNoCarryMontyMul())
|
||||
r.mres.montyMul(a.mres, b.mres, Fp.C.Mod, Fp.C.getNegInvModWord(), Fp.C.canUseNoCarryMontyMul())
|
||||
|
||||
func square*(r: var Fp, a: Fp) =
|
||||
## Squaring modulo p
|
||||
r.mres.montySquare(a.mres, Fp.C.Mod.mres, Fp.C.getNegInvModWord(), Fp.C.canUseNoCarryMontySquare())
|
||||
r.mres.montySquare(a.mres, Fp.C.Mod, Fp.C.getNegInvModWord(), Fp.C.canUseNoCarryMontySquare())
|
||||
|
||||
func neg*(r: var Fp, a: Fp) =
|
||||
## Negate modulo p
|
||||
discard r.mres.diff(Fp.C.Mod.mres, a.mres)
|
||||
discard r.mres.diff(Fp.C.Mod, a.mres)
|
||||
|
||||
# ############################################################
|
||||
#
|
||||
@ -169,7 +168,7 @@ func pow*(a: var Fp, exponent: BigInt) =
|
||||
const windowSize = 5 # TODO: find best window size for each curves
|
||||
a.mres.montyPow(
|
||||
exponent,
|
||||
Fp.C.Mod.mres, Fp.C.getMontyOne(),
|
||||
Fp.C.Mod, Fp.C.getMontyOne(),
|
||||
Fp.C.getNegInvModWord(), windowSize,
|
||||
Fp.C.canUseNoCarryMontyMul()
|
||||
)
|
||||
@ -188,7 +187,7 @@ func powUnsafeExponent*(a: var Fp, exponent: BigInt) =
|
||||
const windowSize = 5 # TODO: find best window size for each curves
|
||||
a.mres.montyPowUnsafeExponent(
|
||||
exponent,
|
||||
Fp.C.Mod.mres, Fp.C.getMontyOne(),
|
||||
Fp.C.Mod, Fp.C.getMontyOne(),
|
||||
Fp.C.getNegInvModWord(), windowSize,
|
||||
Fp.C.canUseNoCarryMontyMul()
|
||||
)
|
||||
@ -228,4 +227,4 @@ func `*=`*(a: var Fp, b: Fp) =
|
||||
|
||||
func square*(a: var Fp) =
|
||||
## Squaring modulo p
|
||||
a.mres.montySquare(a.mres, Fp.C.Mod.mres, Fp.C.getNegInvModWord(), Fp.C.canUseNoCarryMontySquare())
|
||||
a.mres.montySquare(a.mres, Fp.C.Mod, Fp.C.getNegInvModWord(), Fp.C.canUseNoCarryMontySquare())
|
||||
|
@ -131,4 +131,4 @@ func inv*(r: var Fp, a: Fp) =
|
||||
# For now we don't activate the addition chain.
|
||||
# Performance is equal to GCD and it does not pass test on 𝔽p2
|
||||
# We need faster squaring/multiplications
|
||||
r.mres.steinsGCD(a.mres, Fp.C.getR2modP(), Fp.C.Mod.mres, Fp.C.getPrimePlus1div2())
|
||||
r.mres.steinsGCD(a.mres, Fp.C.getR2modP(), Fp.C.Mod, Fp.C.getPrimePlus1div2())
|
||||
|
@ -131,62 +131,7 @@ declareCurves:
|
||||
|
||||
# ############################################################
|
||||
#
|
||||
# Curve Families
|
||||
#
|
||||
# ############################################################
|
||||
type CurveFamily = enum
|
||||
None
|
||||
BN # Barreto-Naehrig
|
||||
BLS # Barreto-Lynn-Scott
|
||||
|
||||
func family*(curve: Curve): CurveFamily =
|
||||
case curve
|
||||
of BN254:
|
||||
BN
|
||||
of BLS12_381:
|
||||
BLS
|
||||
else:
|
||||
None
|
||||
|
||||
# ############################################################
|
||||
#
|
||||
# Curve Specific Parameters
|
||||
#
|
||||
# ############################################################
|
||||
#
|
||||
# In the form CurveXXX_ParameterName where CurveXXX is the curve name + number of bits
|
||||
# of the field modulus
|
||||
|
||||
# BN Curves
|
||||
# ------------------------------------------------------------
|
||||
# See https://tools.ietf.org/id/draft-yonezawa-pairing-friendly-curves-00.html
|
||||
#
|
||||
# The prime p and order r are primes and of the form
|
||||
# p = 36u^4 + 36u^3 + 24u^2 + 6u + 1
|
||||
# r = 36u^4 + 36u^3 + 18u^2 + 6u + 1
|
||||
#
|
||||
# https://eprint.iacr.org/2010/429.pdf
|
||||
# https://eprint.iacr.org/2013/879.pdf
|
||||
# Usage: Zero-Knowledge Proofs / zkSNARKs in ZCash and Ethereum 1
|
||||
# https://eips.ethereum.org/EIPS/eip-196
|
||||
|
||||
# BLS Curves
|
||||
# ------------------------------------------------------------
|
||||
# See https://tools.ietf.org/id/draft-yonezawa-pairing-friendly-curves-00.html
|
||||
#
|
||||
# BLS12 curves
|
||||
# The prime p and order r are primes and of the form
|
||||
# p = (u - 1)^2 (u^4 - u^2 + 1)/3 + u
|
||||
# r = u^4 - u^2 + 1
|
||||
#
|
||||
# BLS48 curves
|
||||
# The prime p and order r are primes and of the form
|
||||
# p = (u - 1)^2 (u^16 - u^8 + 1)/3 + u
|
||||
# r = u^16 - u^8 + 1
|
||||
|
||||
# ############################################################
|
||||
#
|
||||
# Curve Modulus Accessor
|
||||
# Curve characteristics
|
||||
#
|
||||
# ############################################################
|
||||
|
||||
@ -196,6 +141,13 @@ macro Mod*(C: static Curve): untyped =
|
||||
## Get the Modulus associated to a curve
|
||||
result = bindSym($C & "_Modulus")
|
||||
|
||||
func getCurveBitSize*(C: static Curve): static int =
|
||||
## Returns the number of bits taken by the curve modulus
|
||||
result = static(CurveBitSize[C])
|
||||
|
||||
template matchingBigInt*(C: static Curve): untyped =
|
||||
BigInt[CurveBitSize[C]]
|
||||
|
||||
# ############################################################
|
||||
#
|
||||
# Autogeneration of precomputed Montgomery constants in ROM
|
||||
@ -220,10 +172,7 @@ macro genMontyMagics(T: typed): untyped =
|
||||
result.add newConstStmt(
|
||||
ident($curve & "_CanUseNoCarryMontyMul"), newCall(
|
||||
bindSym"useNoCarryMontyMul",
|
||||
nnkDotExpr.newTree(
|
||||
bindSym($curve & "_Modulus"),
|
||||
ident"mres"
|
||||
)
|
||||
bindSym($curve & "_Modulus")
|
||||
)
|
||||
)
|
||||
|
||||
@ -231,10 +180,7 @@ macro genMontyMagics(T: typed): untyped =
|
||||
result.add newConstStmt(
|
||||
ident($curve & "_CanUseNoCarryMontySquare"), newCall(
|
||||
bindSym"useNoCarryMontySquare",
|
||||
nnkDotExpr.newTree(
|
||||
bindSym($curve & "_Modulus"),
|
||||
ident"mres"
|
||||
)
|
||||
bindSym($curve & "_Modulus")
|
||||
)
|
||||
)
|
||||
|
||||
@ -242,10 +188,7 @@ macro genMontyMagics(T: typed): untyped =
|
||||
result.add newConstStmt(
|
||||
ident($curve & "_R2modP"), newCall(
|
||||
bindSym"r2mod",
|
||||
nnkDotExpr.newTree(
|
||||
bindSym($curve & "_Modulus"),
|
||||
ident"mres"
|
||||
)
|
||||
bindSym($curve & "_Modulus")
|
||||
)
|
||||
)
|
||||
|
||||
@ -253,40 +196,28 @@ macro genMontyMagics(T: typed): untyped =
|
||||
result.add newConstStmt(
|
||||
ident($curve & "_NegInvModWord"), newCall(
|
||||
bindSym"negInvModWord",
|
||||
nnkDotExpr.newTree(
|
||||
bindSym($curve & "_Modulus"),
|
||||
ident"mres"
|
||||
)
|
||||
bindSym($curve & "_Modulus")
|
||||
)
|
||||
)
|
||||
# const MyCurve_montyOne = montyOne(MyCurve_Modulus)
|
||||
result.add newConstStmt(
|
||||
ident($curve & "_MontyOne"), newCall(
|
||||
bindSym"montyOne",
|
||||
nnkDotExpr.newTree(
|
||||
bindSym($curve & "_Modulus"),
|
||||
ident"mres"
|
||||
)
|
||||
bindSym($curve & "_Modulus")
|
||||
)
|
||||
)
|
||||
# const MyCurve_InvModExponent = primeMinus2_BE(MyCurve_Modulus)
|
||||
result.add newConstStmt(
|
||||
ident($curve & "_InvModExponent"), newCall(
|
||||
bindSym"primeMinus2_BE",
|
||||
nnkDotExpr.newTree(
|
||||
bindSym($curve & "_Modulus"),
|
||||
ident"mres"
|
||||
)
|
||||
bindSym($curve & "_Modulus")
|
||||
)
|
||||
)
|
||||
# const MyCurve_PrimePlus1div2 = primePlus1div2(MyCurve_Modulus)
|
||||
result.add newConstStmt(
|
||||
ident($curve & "_PrimePlus1div2"), newCall(
|
||||
bindSym"primePlus1div2",
|
||||
nnkDotExpr.newTree(
|
||||
bindSym($curve & "_Modulus"),
|
||||
ident"mres"
|
||||
)
|
||||
bindSym($curve & "_Modulus")
|
||||
)
|
||||
)
|
||||
|
||||
@ -294,10 +225,6 @@ macro genMontyMagics(T: typed): untyped =
|
||||
|
||||
genMontyMagics(Curve)
|
||||
|
||||
func getCurveBitSize*(C: static Curve): static int =
|
||||
## Returns the number of bits taken by the curve modulus
|
||||
result = static(CurveBitSize[C])
|
||||
|
||||
macro canUseNoCarryMontyMul*(C: static Curve): untyped =
|
||||
## Returns true if the Modulus is compatible with a fast
|
||||
## Montgomery multiplication that avoids many carries
|
||||
|
@ -59,8 +59,6 @@ macro declareCurves*(curves: untyped): untyped =
|
||||
var CurveBitSize = nnKBracket.newTree()
|
||||
var curveModStmts = newStmtList()
|
||||
|
||||
let Fp = ident"Fp"
|
||||
|
||||
for curveDesc in curves:
|
||||
curveDesc.expectKind(nnkCommand)
|
||||
doAssert curveDesc[0].eqIdent"curve"
|
||||
@ -94,20 +92,14 @@ macro declareCurves*(curves: untyped): untyped =
|
||||
curve, bitSize
|
||||
)
|
||||
|
||||
# const BN254_Modulus = Fp[BN254](value: fromHex(BigInt[254], "0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47"))
|
||||
# const BN254_Modulus = fromHex(BigInt[254], "0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47")
|
||||
let modulusID = ident($curve & "_Modulus")
|
||||
curveModStmts.add newConstStmt(
|
||||
modulusID,
|
||||
nnkObjConstr.newTree(
|
||||
nnkBracketExpr.newTree(Fp, curve),
|
||||
nnkExprColonExpr.newTree(
|
||||
ident"mres",
|
||||
newCall(
|
||||
bindSym"fromHex",
|
||||
nnkBracketExpr.newTree(bindSym"BigInt", bitSize),
|
||||
modulus
|
||||
)
|
||||
)
|
||||
newCall(
|
||||
bindSym"fromHex",
|
||||
nnkBracketExpr.newTree(bindSym"BigInt", bitSize),
|
||||
modulus
|
||||
)
|
||||
)
|
||||
|
||||
@ -130,45 +122,6 @@ macro declareCurves*(curves: untyped): untyped =
|
||||
cbs, CurveBitSize
|
||||
)
|
||||
|
||||
# Need template indirection in the type section to avoid Nim sigmatch bug
|
||||
# template matchingBigInt(C: static Curve): untyped =
|
||||
# BigInt[CurveBitSize[C]]
|
||||
let C = ident"C"
|
||||
let matchingBigInt = genSym(nskTemplate, "matchingBigInt")
|
||||
result.add newProc(
|
||||
name = matchingBigInt,
|
||||
params = [ident"untyped", newIdentDefs(C, nnkStaticTy.newTree(Curve))],
|
||||
body = nnkBracketExpr.newTree(bindSym"BigInt", nnkBracketExpr.newTree(cbs, C)),
|
||||
procType = nnkTemplateDef
|
||||
)
|
||||
|
||||
# type
|
||||
# `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)
|
||||
result.add nnkTypeSection.newTree(
|
||||
nnkTypeDef.newTree(
|
||||
nnkPostfix.newTree(ident"*", Fp),
|
||||
nnkGenericParams.newTree(newIdentDefs(
|
||||
C, nnkStaticTy.newTree(Curve), newEmptyNode()
|
||||
)),
|
||||
# TODO: where should I put the nnkCommentStmt?
|
||||
nnkObjectTy.newTree(
|
||||
newEmptyNode(),
|
||||
newEmptyNode(),
|
||||
nnkRecList.newTree(
|
||||
newIdentDefs(
|
||||
nnkPostfix.newTree(ident"*", ident"mres"),
|
||||
newCall(matchingBigInt, C)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
result.add curveModStmts
|
||||
|
||||
# echo result.toStrLit()
|
||||
|
@ -90,8 +90,8 @@ func random[T](rng: var RngState, a: var T, C: static Curve) {.noInit.}=
|
||||
unreduced.limbs[i] = Word(rng.next())
|
||||
|
||||
# Note: a simple modulo will be biaised but it's simple and "fast"
|
||||
reduced.reduce(unreduced, C.Mod.mres)
|
||||
a.montyResidue(reduced, C.Mod.mres, C.getR2modP(), C.getNegInvModWord(), C.canUseNoCarryMontyMul())
|
||||
reduced.reduce(unreduced, C.Mod)
|
||||
a.montyResidue(reduced, C.Mod, C.getR2modP(), C.getNegInvModWord(), C.canUseNoCarryMontyMul())
|
||||
|
||||
else:
|
||||
for field in fields(a):
|
||||
|
@ -6,14 +6,35 @@
|
||||
# * 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.
|
||||
|
||||
# This script checks polynomial irreducibility
|
||||
#
|
||||
# Constructing Tower Extensions for the implementation of Pairing-Based Cryptography
|
||||
# Naomi Benger and Michael Scott, 2009
|
||||
# https://eprint.iacr.org/2009/556
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# ############################################################
|
||||
#
|
||||
# Quadratic and Cubic Non-Residue
|
||||
# Failed experiments of actually instantiating
|
||||
# the tower of extension fields
|
||||
#
|
||||
# ############################################################
|
||||
#
|
||||
# This script checks the compatibility of a field modulus
|
||||
# with given tower extensions
|
||||
|
||||
# ############################################################
|
||||
# 1st try
|
||||
@ -50,19 +71,20 @@
|
||||
# K.<xi, im, p> = NumberField([x^3 - I - 1, x^2 + 1, x - 1])
|
||||
|
||||
# ############################################################
|
||||
# Let's at least verify Fp6
|
||||
print('Verifying non-residues')
|
||||
# 4th try, just trying to verify Fp6
|
||||
# print('Verifying non-residues')
|
||||
|
||||
modulus = Integer('0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47')
|
||||
# modulus = Integer('0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47')
|
||||
|
||||
Fp.<p> = NumberField(x - 1)
|
||||
r1 = Fp(-1).residue_symbol(Fp.ideal(modulus),2)
|
||||
print('Fp² = Fp[sqrt(-1)]: ' + str(r1))
|
||||
# Fp.<p> = NumberField(x - 1)
|
||||
# r1 = Fp(-1).residue_symbol(Fp.ideal(modulus),2)
|
||||
# print('Fp² = Fp[sqrt(-1)]: ' + str(r1))
|
||||
|
||||
Fp2.<im> = Fp.extension(x^2 + 1)
|
||||
xi = Fp2(1+im)
|
||||
r2 = xi.residue_symbol(Fp2.ideal(modulus),3)
|
||||
# ValueError: The residue symbol to that power is not defined for the number field
|
||||
# ^ AFAIK that means that Fp2 doesn't contain the 3rd root of unity
|
||||
# so we are clear
|
||||
print('Fp6 = Fp²[cubicRoot(1+I)]: ' + str(r2))
|
||||
# Fp2.<im> = Fp.extension(x^2 + 1)
|
||||
|
||||
# xi = Fp2(1+im)
|
||||
# r2 = xi.residue_symbol(Fp2.ideal(modulus),3)
|
||||
# # ValueError: The residue symbol to that power is not defined for the number field
|
||||
# # ^ AFAIK that means that Fp2 doesn't contain the 3rd root of unity
|
||||
# # so we are clear
|
||||
# print('Fp6 = Fp²[cubicRoot(1+I)]: ' + str(r2))
|
||||
|
@ -61,7 +61,7 @@ proc binary_prologue[C: static Curve, N: static int](
|
||||
mpz_urandomb(a, gmpRng, uint bits)
|
||||
mpz_urandomb(b, gmpRng, uint bits)
|
||||
# Set modulus to curve modulus
|
||||
let err = mpz_set_str(p, Curve(C).Mod.mres.toHex(), 0)
|
||||
let err = mpz_set_str(p, Curve(C).Mod.toHex(), 0)
|
||||
doAssert err == 0, "Error on prime for curve " & $Curve(C)
|
||||
|
||||
#########################################################
|
||||
|
@ -40,12 +40,12 @@ suite "𝔽p2 = 𝔽p[𝑖] (irreducible polynomial x²+1)":
|
||||
O.setOne()
|
||||
O
|
||||
let oneBig = block:
|
||||
var O{.noInit.}: typeof(C.Mod.mres)
|
||||
var O{.noInit.}: typeof(C.Mod)
|
||||
O.setOne()
|
||||
O
|
||||
|
||||
var r: typeof(C.Mod.mres)
|
||||
r.redc(oneFp2.c0.mres, C.Mod.mres, C.getNegInvModWord(), canUseNoCarryMontyMul = false)
|
||||
var r: typeof(C.Mod)
|
||||
r.redc(oneFp2.c0.mres, C.Mod, C.getNegInvModWord(), canUseNoCarryMontyMul = false)
|
||||
|
||||
check:
|
||||
bool(r == oneBig)
|
||||
|
Loading…
x
Reference in New Issue
Block a user