zkevm_circuits 0.153.9

ZKsync Era circuits for EraVM


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