Higher-power frobenius applications

This commit is contained in:
Mamy André-Ratsimbazafy 2020-09-23 00:55:32 +02:00
parent d84edcd217
commit 406d999a9b
No known key found for this signature in database
GPG Key ID: 7B88AD1FE79492E1
3 changed files with 142 additions and 42 deletions

View File

@ -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)

View File

@ -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')

View File

@ -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)