# This file was *autogenerated* from the file torus_params.sage
from sage.all_cmdline import * # import sage library
_sage_const_21888242871839275222246405745257275088696311157297823662689037894645226208583 = Integer(21888242871839275222246405745257275088696311157297823662689037894645226208583); _sage_const_2 = Integer(2); _sage_const_1 = Integer(1); _sage_const_3 = Integer(3); _sage_const_9 = Integer(9); _sage_const_12 = Integer(12); _sage_const_0 = Integer(0); _sage_const_6 = Integer(6); _sage_const_8 = Integer(8); _sage_const_4 = Integer(4); _sage_const_10 = Integer(10); _sage_const_7 = Integer(7); _sage_const_5 = Integer(5); _sage_const_11 = Integer(11); _sage_const_256 = Integer(256); _sage_const_64 = Integer(64); _sage_const_128 = Integer(128); _sage_const_192 = Integer(192)
import json
# Defining the base prime field
q = Integer(_sage_const_21888242871839275222246405745257275088696311157297823662689037894645226208583 ) # EC group order
Fq = GF(q)
# Defining the extensions
# Fq2...
K2 = PolynomialRing(Fq, names=('x',)); (x,) = K2._first_ngens(1)
Fq2 = Fq.extension(x**_sage_const_2 +_sage_const_1 , names=('u',)); (u,) = Fq2._first_ngens(1)
# Fq6...
K6 = PolynomialRing(Fq2, names=('y',)); (y,) = K6._first_ngens(1)
Fq6 = Fq2.extension(y**_sage_const_3 - (u+_sage_const_9 ), names=('v',)); (v,) = Fq6._first_ngens(1)
# Defining the Fq12 is a bit more tricky...
p = Fq.characteristic()
Fq12 = GF(p**_sage_const_12 , names=('G',)); (G,) = Fq12._first_ngens(1)
i = sqrt(Fq12(-_sage_const_1 ))
R12 = PolynomialRing(Fq12, names=('Y',)); (Y,) = R12._first_ngens(1)
j = (Y**_sage_const_3 - (i+_sage_const_9 )).roots(multiplicities=False)[_sage_const_0 ]
w = sqrt(j)
P = w.minpoly()
Fq12 = GF(p**_sage_const_12 , modulus=P, names=('W',)); (W,) = Fq12._first_ngens(1)
# Preparing helper debugging lambda functions
fq2_to_dictionary = lambda f : {
'c0': str(f[_sage_const_0 ]),
'c1': str(f[_sage_const_1 ])
}
fq6_to_dictionary = lambda f : {
'c0': {
'c0': str(f[_sage_const_0 ][_sage_const_0 ]),
'c1': str(f[_sage_const_0 ][_sage_const_1 ])
},
'c1': {
'c0': str(f[_sage_const_1 ][_sage_const_0 ]),
'c1': str(f[_sage_const_1 ][_sage_const_1 ])
},
'c2': {
'c0': str(f[_sage_const_2 ][_sage_const_0 ]),
'c1': str(f[_sage_const_2 ][_sage_const_1 ])
}
}
fq12_to_dictionary = lambda f: {
'c0': { # Fq6
'c0': { #Fq2
'c0': str(f[_sage_const_0 ]+_sage_const_9 *f[_sage_const_6 ]),
'c1': str(f[_sage_const_6 ]),
},
'c1': { #Fq2
'c0': str(f[_sage_const_2 ]+_sage_const_9 *f[_sage_const_8 ]),
'c1': str(f[_sage_const_8 ]),
},
'c2': { #Fq2
'c0': str(f[_sage_const_4 ]+_sage_const_9 *f[_sage_const_10 ]),
'c1': str(f[_sage_const_10 ]),
}
},
'c1': { # Fq6
'c0': { #Fq2
'c0': str(f[_sage_const_1 ]+_sage_const_9 *f[_sage_const_7 ]),
'c1': str(f[_sage_const_7 ]),
},
'c1': { #Fq2
'c0': str(f[_sage_const_3 ]+_sage_const_9 *f[_sage_const_9 ]),
'c1': str(f[_sage_const_9 ]),
},
'c2': { #Fq2
'c0': str(f[_sage_const_5 ]+_sage_const_9 *f[_sage_const_11 ]),
'c1': str(f[_sage_const_11 ]),
}
}
}
# Converts the Fq number to 4 64-bit limbs in Montgomery form
def to_montgomery_limbs(number: Fq):
number = Fq(number) * Fq(_sage_const_2 **(_sage_const_256 ))
number = Integer(number)
# Building limbs
limb_1 = number % _sage_const_2 **_sage_const_64
limb_2 = (number // _sage_const_2 **_sage_const_64 ) % _sage_const_2 **_sage_const_64
limb_3 = (number // _sage_const_2 **_sage_const_128 ) % _sage_const_2 **_sage_const_64
limb_4 = (number // _sage_const_2 **_sage_const_192 ) % _sage_const_2 **_sage_const_64
return [limb_1, limb_2, limb_3, limb_4]
def print_montgomery_limbs(number: Fq):
limbs = to_montgomery_limbs(number)
print([Integer(limb).hex() for limb in limbs])
# Finding inverse of an Fq12 element 0+1*w:
w = _sage_const_0 + _sage_const_1 *W
w_inv = w.inverse()
assert w*w_inv == _sage_const_1 , 'inverse of w was found incorrectly'
w_inv_dict = fq12_to_dictionary(w_inv)
print(f'w^(-1) = {w_inv_dict}')
# Printing individual coefficients as montgomery limbs
# to further use as constants in the code
c2_c3_c0 = w_inv_dict['c1']['c2']['c0']
c2_c3_c1 = w_inv_dict['c1']['c2']['c1']
print_montgomery_limbs(c2_c3_c0)
print_montgomery_limbs(c2_c3_c1)
# Finding the inverse of two:
two = Fq12(_sage_const_2 )
two_inv = two.inverse()
assert two*two_inv == _sage_const_1 , 'inverse of 2 was found incorrectly'
two_inv_dict = fq12_to_dictionary(two_inv)
print(f'2^(-1) = {two_inv_dict}')
c0 = two_inv_dict['c0']['c0']['c0']
print_montgomery_limbs(c0)