Skip to content

Instantly share code, notes, and snippets.

@maple3142
Last active September 19, 2024 04:18
Show Gist options
  • Save maple3142/8933b70e6011043b65849314563fba55 to your computer and use it in GitHub Desktop.
Save maple3142/8933b70e6011043b65849314563fba55 to your computer and use it in GitHub Desktop.
BLS12-381 pairing in sage
# BLS12-381
# https://hackmd.io/@benjaminion/bls12-381
x = var("x")
q = 0x1A0111EA397FE69A4B1BA7B6434BACD764774B84F38512BF6730D2A0F6B0F6241EABFFFEB153FFFFB9FEFFFFFFFFAAAB
r = 0x73EDA753299D7D483339D80809A1D80553BDA402FFFE5BFEFFFFFFFF00000001
Fq = GF(q)
Fq2 = GF(q ^ 2, "i", x ^ 2 + 1)
i = Fq2.gen()
u6 = 1 / (1 + i)
b = 4
E1 = EllipticCurve(Fq, (0, b))
E2 = EllipticCurve(Fq2, (0, b / u6))
G1 = E1.lift_x(
3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507
)
G2 = E2.lift_x(
352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160
+ i
* 3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758
)
assert r * G1 == 0
assert r * G2 == 0
tr = E1.trace_of_frobenius()
# find field extension
x = polygen(Fq2)
Fq12 = Fq2.extension(x ^ 6 - u6, "u")
u = Fq12.gen()
E3 = EllipticCurve(Fq12, [0, 4])
G1x = E3(G1)
G2x = E3(u ^ 2 * G2[0], u ^ 3 * G2[1])
assert r * G1x == 0
assert r * G2x == 0
# weil & tate pairing is broken when the field is constructed like this...
def pairing(P, Q):
return P.ate_pairing(Q, r, 12, tr, q)
print(pairing(14 * G1x, 15 * G2x) == pairing(10 * G1x, 21 * G2x))
# try to get weil & tate pairing working
u, i = polygens(Fq, "u,i")
mod = ((1 + i) * u ^ 6 - 1).sylvester_matrix(i ^ 2 + 1, i).det().univariate_polynomial()
Fq12_v2 = GF(q ^ 12, "u", mod)
u = Fq12_v2.gen()
E3 = EllipticCurve(Fq12_v2, [0, 4])
i_in_fq12_v2 = (
Fq2.modulus().change_ring(ZZ)(polygen(Fq12_v2)).roots(multiplicities=False)[1]
)
assert i_in_fq12_v2**2 + 1 == 0
def fp2_to_fq12v2(el):
return el.polynomial()(i_in_fq12_v2)
G1x = E3(G1)
G2x = E3(u ^ 2 * fp2_to_fq12v2(G2[0]), u ^ 3 * fp2_to_fq12v2(G2[1]))
assert r * G1x == 0
assert r * G2x == 0
def pairing(P, Q):
return P.tate_pairing(Q, r, 12)
print(pairing(14 * G1x, 15 * G2x) == pairing(10 * G1x, 21 * G2x))
def pairing(P, Q):
return P.weil_pairing(Q, r)
print(pairing(14 * G1x, 15 * G2x) == pairing(10 * G1x, 21 * G2x))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment