# Independent exact verifier B for SageMath 10.x.
# Run: sage verify_sage.py
from sage.all import *
import json, hashlib, os

R = PolynomialRing(QQ, names=('x','y','z'))
x,y,z = R.gens()


def construct(k, d):
    v = x**k*y
    t = x**(k+1)*z
    u = 1+v
    gamma = 1-QQ(d+k)/d*v-t
    w = u*gamma
    q = QQ(k+1)/(d-k)*w**k-QQ(d+1)/(d-k)*w**d
    Q = QQ(1)/(d-k)*w**(k+1)-QQ(1)/(d-k)*w**(d+1)
    p = (w*q-Q)/QQ(k+1)
    alpha = (p + QQ(1)/(k+1)*u*gamma**(k+1)).quo_rem(gamma**(k+1))
    beta = (q + gamma**k).quo_rem(gamma**k)
    assert alpha[1] == 0 and beta[1] == 0
    A = alpha[0].quo_rem(x**(k+1)); B = beta[0].quo_rem(x**k)
    assert A[1] == 0 and B[1] == 0
    return [A[0], B[0], x*gamma]


def jacobian_det(F):
    M = matrix(R, [[f.derivative(var) for var in (x,y,z)] for f in F])
    return M.det()

rows=[]
for k in range(1,7):
    for d in range(k+1,9):
        F=construct(k,d)
        det=jacobian_det(F)
        assert det == -QQ(k)/(k+1)
        rows.append({'k':k,'d':d,'jacobian':str(det)})

collisions=[]
for k in range(1,8,2):
    for d in range(k+2,10,2):
        F=construct(k,d)
        p1=(-1,0,2); p2=(1,0,0)
        im1=[f(*p1) for f in F]; im2=[f(*p2) for f in F]
        assert p1 != p2
        assert im1 == im2 == [0,0,1]
        collisions.append({'k':k,'d':d})

F=construct(2,3)
a=x**2*y
expanded=[z*(1+a)**4+x*y**2*(5*a**3+17*a**2+20*a+8)/3,
          4*x*z*(1+a)**3+y*(20*a**3+48*a**2+33*a+2)/3,
          -x**4*z+x*(3-5*a)/3]
assert F == expanded
assert jacobian_det(expanded) == -QQ(2)/3
p1=(QQ(8)/3,-QQ(9)/64,QQ(495)/4096)
p2=(QQ(8)/3,QQ(9)/64,-QQ(225)/4096)
im1=[f(*p1) for f in expanded]; im2=[f(*p2) for f in expanded]
assert p1 != p2 and im1 == im2 == [0,QQ(9)/64,1]

certificate={'engine':'SageMath','sage_version':SAGE_VERSION,'status':'PASS','family_grid_count':len(rows),'odd_collision_count':len(collisions),'degree_eight_image':[str(v) for v in im1]}
payload=json.dumps(certificate,sort_keys=True,indent=2)
open(os.path.join(os.path.dirname(__file__),'certificate_sage.json'),'w').write(payload)
print(json.dumps({'status':'PASS','sha256':hashlib.sha256(payload.encode()).hexdigest(),**certificate},indent=2))
