# Make sure to select a SageMath kernel when running this notebook!
import sage.all as sg
import numpy as np
import random
import time
from itertools import chain
from sage.stats.distributions.discrete_gaussian_polynomial import DiscreteGaussianDistributionPolynomialSampler
kappa = 128 # security parameter
d = 128 # degree of polynomial ring
q = 2**32 - 99 # modulus prime
# Define polynomial rings using sage
IR = sg.IntegerRing()
P = sg.PolynomialRing(IR, 't')
t = P.gen()
R = sg.QuotientRing(P, t**d + 1, 'X')
X = R.gen()
IR_q = sg.IntegerModRing(q)
P_q = sg.PolynomialRing(IR_q, 't')
t_q = P_q.gen()
R_q = sg.QuotientRing(P_q, t_q**d + 1, 'X')
X_q = R_q.gen()
print(f"R: {R}")
print(f"R_q: {R_q}")
print(f"Example R_q polynomial demonstrating wraparound: {X_q**d - X_q}")
R: Univariate Quotient Polynomial Ring in X over Integer Ring with modulus t^128 + 1
R_q: Univariate Quotient Polynomial Ring in X over Ring of integers modulo 4294967197 with modulus t^128 + 1
Example R_q polynomial demonstrating wraparound: 4294967196*X + 4294967196