Last active
September 19, 2024 04:18
-
-
Save maple3142/8933b70e6011043b65849314563fba55 to your computer and use it in GitHub Desktop.
BLS12-381 pairing in sage
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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