mirror of
https://github.com/codex-storage/constantine.git
synced 2025-01-24 17:48:54 +00:00
Higher-power frobenius applications
This commit is contained in:
parent
d84edcd217
commit
406d999a9b
@ -44,7 +44,19 @@ func frobenius_map*(r: var Fp2, a: Fp2, k: static int = 1) {.inline.} =
|
||||
r = a
|
||||
|
||||
template mulCheckSparse[Fp2](a: var Fp2, b: Fp2) =
|
||||
when b.c0.isZero().bool:
|
||||
when b.c0.isOne().bool and b.c1.isZero().bool:
|
||||
discard
|
||||
elif b.c0.isZero().bool and b.c1.isOne().bool:
|
||||
var t {.noInit.}: type(b.c0)
|
||||
when fromComplexExtension(b.c0):
|
||||
t.neg(a.c1)
|
||||
a.c1 = a.c0
|
||||
a.c0 = t
|
||||
else:
|
||||
t = a.c1 * NonResidue
|
||||
a.c1 = a.c0
|
||||
a.c0 = t
|
||||
elif b.c0.isZero().bool:
|
||||
a.mul_sparse_by_0y(b)
|
||||
elif b.c1.isZero().bool:
|
||||
a.mul_sparse_by_x0(b)
|
||||
@ -54,24 +66,92 @@ template mulCheckSparse[Fp2](a: var Fp2, b: Fp2) =
|
||||
# Frobenius map - on extension fields
|
||||
# -----------------------------------------------------------------
|
||||
|
||||
{.experimental: "dynamicBindSym".}
|
||||
|
||||
macro frobMapConst(C: static Curve, coefpow, frobpow: static int): untyped =
|
||||
return bindSym("FrobMapConst_" & $C & "_coef" & $coefpow & "_pow" & $frobpow)
|
||||
|
||||
# SNR^((p-1)/6)^3
|
||||
const FrobMapConst_BLS12_381_coef3_pow1 = Fp2[BLS12_381].fromHex(
|
||||
# c = (SNR^((p-1)/6)^coef).
|
||||
# Then for frobenius(2): c * conjugate(c)
|
||||
# And for frobenius(2): c² * conjugate(c)
|
||||
const FrobMapConst_BLS12_381 = [
|
||||
# frobenius(1)
|
||||
[Fp2[BLS12_381].fromHex( # SNR^((p-1)/6)^0
|
||||
"0x1",
|
||||
"0x0"
|
||||
),
|
||||
Fp2[BLS12_381].fromHex( # SNR^((p-1)/6)^1
|
||||
"0x1904d3bf02bb0667c231beb4202c0d1f0fd603fd3cbd5f4f7b2443d784bab9c4f67ea53d63e7813d8d0775ed92235fb8",
|
||||
"0xfc3e2b36c4e03288e9e902231f9fb854a14787b6c7b36fec0c8ec971f63c5f282d5ac14d6c7ec22cf78a126ddc4af3"
|
||||
),
|
||||
Fp2[BLS12_381].fromHex(
|
||||
"0x0",
|
||||
"0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac"
|
||||
),
|
||||
Fp2[BLS12_381].fromHex(
|
||||
"0x6af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09",
|
||||
"0x6af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09"
|
||||
)
|
||||
),
|
||||
Fp2[BLS12_381].fromHex(
|
||||
"0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaad",
|
||||
"0x0"
|
||||
),
|
||||
Fp2[BLS12_381].fromHex(
|
||||
"0x5b2cfd9013a5fd8df47fa6b48b1e045f39816240c0b8fee8beadf4d8e9c0566c63a3e6e257f87329b18fae980078116",
|
||||
"0x144e4211384586c16bd3ad4afa99cc9170df3560e77982d0db45f3536814f0bd5871c1908bd478cd1ee605167ff82995"
|
||||
)],
|
||||
# frobenius(2)
|
||||
[Fp2[BLS12_381].fromHex(
|
||||
"0x1",
|
||||
"0x0"
|
||||
),
|
||||
Fp2[BLS12_381].fromHex(
|
||||
"0x5f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffeffff",
|
||||
"0x0"
|
||||
),
|
||||
Fp2[BLS12_381].fromHex(
|
||||
"0x5f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe",
|
||||
"0x0"
|
||||
),
|
||||
Fp2[BLS12_381].fromHex(
|
||||
"0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa",
|
||||
"0x0"
|
||||
),
|
||||
Fp2[BLS12_381].fromHex(
|
||||
"0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac",
|
||||
"0x0"
|
||||
),
|
||||
Fp2[BLS12_381].fromHex(
|
||||
"0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaad",
|
||||
"0x0"
|
||||
)],
|
||||
# frobenius(3)
|
||||
[Fp2[BLS12_381].fromHex(
|
||||
"0x1",
|
||||
"0x0"
|
||||
),
|
||||
Fp2[BLS12_381].fromHex(
|
||||
"0x135203e60180a68ee2e9c448d77a2cd91c3dedd930b1cf60ef396489f61eb45e304466cf3e67fa0af1ee7b04121bdea2",
|
||||
"0x6af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09"
|
||||
),
|
||||
Fp2[BLS12_381].fromHex(
|
||||
"0x0",
|
||||
"0x1"
|
||||
),
|
||||
Fp2[BLS12_381].fromHex(
|
||||
"0x135203e60180a68ee2e9c448d77a2cd91c3dedd930b1cf60ef396489f61eb45e304466cf3e67fa0af1ee7b04121bdea2",
|
||||
"0x135203e60180a68ee2e9c448d77a2cd91c3dedd930b1cf60ef396489f61eb45e304466cf3e67fa0af1ee7b04121bdea2"
|
||||
),
|
||||
Fp2[BLS12_381].fromHex(
|
||||
"0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa",
|
||||
"0x0"
|
||||
),
|
||||
Fp2[BLS12_381].fromHex(
|
||||
"0x6af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09",
|
||||
"0x135203e60180a68ee2e9c448d77a2cd91c3dedd930b1cf60ef396489f61eb45e304466cf3e67fa0af1ee7b04121bdea2"
|
||||
)]]
|
||||
|
||||
func frobenius_map*(r: var Fp4, a: Fp4, k: static int = 1) {.inline.} =
|
||||
## Computes a^(p^k)
|
||||
## The p-power frobenius automorphism on 𝔽p4
|
||||
r.c0.frobenius_map(a.c0, k)
|
||||
r.c1.frobenius_map(a.c1, k)
|
||||
|
||||
r.c1.mulCheckSparse frobMapConst(Fp4.C, 3, k)
|
||||
r.c1.mulCheckSparse FrobMapConst_BLS12_381[k-1][4-1]
|
||||
|
||||
# ψ (Psi) - Untwist-Frobenius-Twist Endomorphisms on twisted curves
|
||||
# -----------------------------------------------------------------
|
||||
@ -166,6 +246,8 @@ const FrobPsiConst_BLS12_381_psi2_coef2 = Fp2[BLS12_381].fromHex(
|
||||
"0x0"
|
||||
)
|
||||
|
||||
{.experimental: "dynamicBindSym".}
|
||||
|
||||
macro frobPsiConst(C: static Curve, psipow, coefpow: static int): untyped =
|
||||
return bindSym("FrobPsiConst_" & $C & "_psi" & $psipow & "_coef" & $coefpow)
|
||||
|
||||
|
@ -48,14 +48,24 @@ print('')
|
||||
# Utilities
|
||||
def fp2_to_hex(a):
|
||||
v = vector(a)
|
||||
return Integer(v[0]).hex() + ' + β * ' + Integer(v[1]).hex()
|
||||
return '0x' + Integer(v[0]).hex() + ' + β * ' + '0x' + Integer(v[1]).hex()
|
||||
|
||||
# Frobenius map constants (D type: use SNR, M type use 1/SNR)
|
||||
print('\nFrobenius extension field constants')
|
||||
FrobConst_map = SNR^((p-1)/6)
|
||||
print('FrobConst_map : ' + fp2_to_hex(FrobConst_map))
|
||||
FrobConst_map_fp4 = FrobConst_map^(12//4)
|
||||
print('FrobConst_map_fp4_y : ' + fp2_to_hex(FrobConst_map_fp4))
|
||||
FrobConst_map_list = []
|
||||
cur = Fp2([1, 0])
|
||||
|
||||
for i in range(6):
|
||||
FrobConst_map_list.append(cur)
|
||||
print(f'FrobConst_map_{i} : {fp2_to_hex(cur)}')
|
||||
cur *= FrobConst_map
|
||||
print('')
|
||||
for i in range(6):
|
||||
print(f'FrobConst_map_{i}_pow2 : {fp2_to_hex(FrobConst_map_list[i]*conjugate(FrobConst_map_list[i]))}')
|
||||
print('')
|
||||
for i in range(6):
|
||||
print(f'FrobConst_map_{i}_pow3 : {fp2_to_hex(FrobConst_map_list[i]**2 * conjugate(FrobConst_map_list[i]))}')
|
||||
|
||||
# Frobenius psi constants (D type: use SNR, M type use 1/SNR)
|
||||
print('\nψ (Psi) - Untwist-Frobenius-Twist constants')
|
||||
|
@ -81,35 +81,43 @@ proc runFrobeniusTowerTests*[N](
|
||||
test(ExtField(ExtDegree, curve), Iters, gen = HighHammingWeight)
|
||||
test(ExtField(ExtDegree, curve), Iters, gen = Long01Sequence)
|
||||
|
||||
# test "Frobenius(a, 2) = a^(p^2) (mod p^" & $ExtDegree & ")":
|
||||
# proc test(Field: typedesc, Iters: static int, gen: RandomGen) =
|
||||
# for _ in 0 ..< Iters:
|
||||
# var a = rng.random_elem(Field, gen)
|
||||
# var fa {.noInit.}: typeof(a)
|
||||
# fa.frobenius_map(a, k = 2)
|
||||
test "Frobenius(a, 2) = a^(p^2) (mod p^" & $ExtDegree & ")":
|
||||
proc test(Field: typedesc, Iters: static int, gen: RandomGen) =
|
||||
for _ in 0 ..< 1:
|
||||
var a = rng.random_elem(Field, gen)
|
||||
var fa {.noInit.}: typeof(a)
|
||||
fa.frobenius_map(a, k = 2)
|
||||
|
||||
# a.powUnsafeExponent(Field.C.Mod, window = 3)
|
||||
# a.powUnsafeExponent(Field.C.Mod, window = 3)
|
||||
# check: bool(a == fa)
|
||||
var fa2 {.noInit.}: typeof(a)
|
||||
fa2.frobenius_map(a, k = 1)
|
||||
fa2.frobenius_map(fa2, k = 1)
|
||||
|
||||
# staticFor(curve, TestCurves):
|
||||
# test(ExtField(ExtDegree, curve), Iters, gen = Uniform)
|
||||
# test(ExtField(ExtDegree, curve), Iters, gen = HighHammingWeight)
|
||||
# test(ExtField(ExtDegree, curve), Iters, gen = Long01Sequence)
|
||||
a.powUnsafeExponent(Field.C.Mod, window = 3)
|
||||
a.powUnsafeExponent(Field.C.Mod, window = 3)
|
||||
|
||||
# test "Frobenius(a, 3) = a^(p^3) (mod p^" & $ExtDegree & ")":
|
||||
# proc test(Field: typedesc, Iters: static int, gen: RandomGen) =
|
||||
# for _ in 0 ..< Iters:
|
||||
# var a = rng.random_elem(Field, gen)
|
||||
# var fa {.noInit.}: typeof(a)
|
||||
# fa.frobenius_map(a, k = 3)
|
||||
check:
|
||||
bool(a == fa)
|
||||
bool(a == fa2)
|
||||
bool(fa == fa2)
|
||||
|
||||
# a.powUnsafeExponent(Field.C.Mod, window = 3)
|
||||
# a.powUnsafeExponent(Field.C.Mod, window = 3)
|
||||
# a.powUnsafeExponent(Field.C.Mod, window = 3)
|
||||
# check: bool(a == fa)
|
||||
staticFor(curve, TestCurves):
|
||||
test(ExtField(ExtDegree, curve), Iters, gen = Uniform)
|
||||
test(ExtField(ExtDegree, curve), Iters, gen = HighHammingWeight)
|
||||
test(ExtField(ExtDegree, curve), Iters, gen = Long01Sequence)
|
||||
|
||||
# staticFor(curve, TestCurves):
|
||||
# test(ExtField(ExtDegree, curve), Iters, gen = Uniform)
|
||||
# test(ExtField(ExtDegree, curve), Iters, gen = HighHammingWeight)
|
||||
# test(ExtField(ExtDegree, curve), Iters, gen = Long01Sequence)
|
||||
test "Frobenius(a, 3) = a^(p^3) (mod p^" & $ExtDegree & ")":
|
||||
proc test(Field: typedesc, Iters: static int, gen: RandomGen) =
|
||||
for _ in 0 ..< Iters:
|
||||
var a = rng.random_elem(Field, gen)
|
||||
var fa {.noInit.}: typeof(a)
|
||||
fa.frobenius_map(a, k = 3)
|
||||
|
||||
a.powUnsafeExponent(Field.C.Mod, window = 3)
|
||||
a.powUnsafeExponent(Field.C.Mod, window = 3)
|
||||
a.powUnsafeExponent(Field.C.Mod, window = 3)
|
||||
check: bool(a == fa)
|
||||
|
||||
staticFor(curve, TestCurves):
|
||||
test(ExtField(ExtDegree, curve), Iters, gen = Uniform)
|
||||
test(ExtField(ExtDegree, curve), Iters, gen = HighHammingWeight)
|
||||
test(ExtField(ExtDegree, curve), Iters, gen = Long01Sequence)
|
||||
|
Loading…
x
Reference in New Issue
Block a user