mirror of
https://github.com/logos-storage/constantine.git
synced 2026-01-04 06:03:08 +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
|
r = a
|
||||||
|
|
||||||
template mulCheckSparse[Fp2](a: var Fp2, b: Fp2) =
|
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)
|
a.mul_sparse_by_0y(b)
|
||||||
elif b.c1.isZero().bool:
|
elif b.c1.isZero().bool:
|
||||||
a.mul_sparse_by_x0(b)
|
a.mul_sparse_by_x0(b)
|
||||||
@ -54,24 +66,92 @@ template mulCheckSparse[Fp2](a: var Fp2, b: Fp2) =
|
|||||||
# Frobenius map - on extension fields
|
# Frobenius map - on extension fields
|
||||||
# -----------------------------------------------------------------
|
# -----------------------------------------------------------------
|
||||||
|
|
||||||
{.experimental: "dynamicBindSym".}
|
# c = (SNR^((p-1)/6)^coef).
|
||||||
|
# Then for frobenius(2): c * conjugate(c)
|
||||||
macro frobMapConst(C: static Curve, coefpow, frobpow: static int): untyped =
|
# And for frobenius(2): c² * conjugate(c)
|
||||||
return bindSym("FrobMapConst_" & $C & "_coef" & $coefpow & "_pow" & $frobpow)
|
const FrobMapConst_BLS12_381 = [
|
||||||
|
# frobenius(1)
|
||||||
# SNR^((p-1)/6)^3
|
[Fp2[BLS12_381].fromHex( # SNR^((p-1)/6)^0
|
||||||
const FrobMapConst_BLS12_381_coef3_pow1 = Fp2[BLS12_381].fromHex(
|
"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",
|
||||||
"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.} =
|
func frobenius_map*(r: var Fp4, a: Fp4, k: static int = 1) {.inline.} =
|
||||||
## Computes a^(p^k)
|
## Computes a^(p^k)
|
||||||
## The p-power frobenius automorphism on 𝔽p4
|
## The p-power frobenius automorphism on 𝔽p4
|
||||||
r.c0.frobenius_map(a.c0, k)
|
r.c0.frobenius_map(a.c0, k)
|
||||||
r.c1.frobenius_map(a.c1, k)
|
r.c1.frobenius_map(a.c1, k)
|
||||||
|
r.c1.mulCheckSparse FrobMapConst_BLS12_381[k-1][4-1]
|
||||||
r.c1.mulCheckSparse frobMapConst(Fp4.C, 3, k)
|
|
||||||
|
|
||||||
# ψ (Psi) - Untwist-Frobenius-Twist Endomorphisms on twisted curves
|
# ψ (Psi) - Untwist-Frobenius-Twist Endomorphisms on twisted curves
|
||||||
# -----------------------------------------------------------------
|
# -----------------------------------------------------------------
|
||||||
@ -166,6 +246,8 @@ const FrobPsiConst_BLS12_381_psi2_coef2 = Fp2[BLS12_381].fromHex(
|
|||||||
"0x0"
|
"0x0"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
{.experimental: "dynamicBindSym".}
|
||||||
|
|
||||||
macro frobPsiConst(C: static Curve, psipow, coefpow: static int): untyped =
|
macro frobPsiConst(C: static Curve, psipow, coefpow: static int): untyped =
|
||||||
return bindSym("FrobPsiConst_" & $C & "_psi" & $psipow & "_coef" & $coefpow)
|
return bindSym("FrobPsiConst_" & $C & "_psi" & $psipow & "_coef" & $coefpow)
|
||||||
|
|
||||||
|
|||||||
@ -48,14 +48,24 @@ print('')
|
|||||||
# Utilities
|
# Utilities
|
||||||
def fp2_to_hex(a):
|
def fp2_to_hex(a):
|
||||||
v = vector(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)
|
# Frobenius map constants (D type: use SNR, M type use 1/SNR)
|
||||||
print('\nFrobenius extension field constants')
|
print('\nFrobenius extension field constants')
|
||||||
FrobConst_map = SNR^((p-1)/6)
|
FrobConst_map = SNR^((p-1)/6)
|
||||||
print('FrobConst_map : ' + fp2_to_hex(FrobConst_map))
|
FrobConst_map_list = []
|
||||||
FrobConst_map_fp4 = FrobConst_map^(12//4)
|
cur = Fp2([1, 0])
|
||||||
print('FrobConst_map_fp4_y : ' + fp2_to_hex(FrobConst_map_fp4))
|
|
||||||
|
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)
|
# Frobenius psi constants (D type: use SNR, M type use 1/SNR)
|
||||||
print('\nψ (Psi) - Untwist-Frobenius-Twist constants')
|
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 = HighHammingWeight)
|
||||||
test(ExtField(ExtDegree, curve), Iters, gen = Long01Sequence)
|
test(ExtField(ExtDegree, curve), Iters, gen = Long01Sequence)
|
||||||
|
|
||||||
# test "Frobenius(a, 2) = a^(p^2) (mod p^" & $ExtDegree & ")":
|
test "Frobenius(a, 2) = a^(p^2) (mod p^" & $ExtDegree & ")":
|
||||||
# proc test(Field: typedesc, Iters: static int, gen: RandomGen) =
|
proc test(Field: typedesc, Iters: static int, gen: RandomGen) =
|
||||||
# for _ in 0 ..< Iters:
|
for _ in 0 ..< 1:
|
||||||
# var a = rng.random_elem(Field, gen)
|
var a = rng.random_elem(Field, gen)
|
||||||
# var fa {.noInit.}: typeof(a)
|
var fa {.noInit.}: typeof(a)
|
||||||
# fa.frobenius_map(a, k = 2)
|
fa.frobenius_map(a, k = 2)
|
||||||
|
|
||||||
# a.powUnsafeExponent(Field.C.Mod, window = 3)
|
var fa2 {.noInit.}: typeof(a)
|
||||||
# a.powUnsafeExponent(Field.C.Mod, window = 3)
|
fa2.frobenius_map(a, k = 1)
|
||||||
# check: bool(a == fa)
|
fa2.frobenius_map(fa2, k = 1)
|
||||||
|
|
||||||
# staticFor(curve, TestCurves):
|
a.powUnsafeExponent(Field.C.Mod, window = 3)
|
||||||
# test(ExtField(ExtDegree, curve), Iters, gen = Uniform)
|
a.powUnsafeExponent(Field.C.Mod, window = 3)
|
||||||
# test(ExtField(ExtDegree, curve), Iters, gen = HighHammingWeight)
|
|
||||||
# test(ExtField(ExtDegree, curve), Iters, gen = Long01Sequence)
|
|
||||||
|
|
||||||
# test "Frobenius(a, 3) = a^(p^3) (mod p^" & $ExtDegree & ")":
|
check:
|
||||||
# proc test(Field: typedesc, Iters: static int, gen: RandomGen) =
|
bool(a == fa)
|
||||||
# for _ in 0 ..< Iters:
|
bool(a == fa2)
|
||||||
# var a = rng.random_elem(Field, gen)
|
bool(fa == fa2)
|
||||||
# var fa {.noInit.}: typeof(a)
|
|
||||||
# fa.frobenius_map(a, k = 3)
|
|
||||||
|
|
||||||
# a.powUnsafeExponent(Field.C.Mod, window = 3)
|
staticFor(curve, TestCurves):
|
||||||
# a.powUnsafeExponent(Field.C.Mod, window = 3)
|
test(ExtField(ExtDegree, curve), Iters, gen = Uniform)
|
||||||
# a.powUnsafeExponent(Field.C.Mod, window = 3)
|
test(ExtField(ExtDegree, curve), Iters, gen = HighHammingWeight)
|
||||||
# check: bool(a == fa)
|
test(ExtField(ExtDegree, curve), Iters, gen = Long01Sequence)
|
||||||
|
|
||||||
# staticFor(curve, TestCurves):
|
test "Frobenius(a, 3) = a^(p^3) (mod p^" & $ExtDegree & ")":
|
||||||
# test(ExtField(ExtDegree, curve), Iters, gen = Uniform)
|
proc test(Field: typedesc, Iters: static int, gen: RandomGen) =
|
||||||
# test(ExtField(ExtDegree, curve), Iters, gen = HighHammingWeight)
|
for _ in 0 ..< Iters:
|
||||||
# test(ExtField(ExtDegree, curve), Iters, gen = Long01Sequence)
|
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