-
Notifications
You must be signed in to change notification settings - Fork 180
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FP12 to Bytes in golang wrapper #101
Comments
It's not really a big problem as soon as there is an agreement on representation. Say, big-endian 48-byte arrays in order of appearance? |
On a tangential note. The purpose of blst.PairingRawAggregate is to facilitate multi-input operations. It's faster that way. For single inputs one can just as well use blst.Fp12MillerLoop. This is not an objection to using PairingRawAggregate, but merely an informational note in case you find the additional steps incurred by PairingRawAggregate distracting;-) |
No, not a big problem, just that it's not possible to get the bytes representation (since P12 is an alias for a c-struct) |
Do answer the question:-) Can we agree on big-endian? |
That's what the others do: func (z *E12) Bytes() (r [SizeOfGT]byte) {
_z := *z
_z.FromMont()
binary.BigEndian.PutUint64(r[568:576], _z.C0.B0.A0[0])
binary.BigEndian.PutUint64(r[560:568], _z.C0.B0.A0[1])
binary.BigEndian.PutUint64(r[552:560], _z.C0.B0.A0[2])
binary.BigEndian.PutUint64(r[544:552], _z.C0.B0.A0[3])
binary.BigEndian.PutUint64(r[536:544], _z.C0.B0.A0[4])
binary.BigEndian.PutUint64(r[528:536], _z.C0.B0.A0[5])
binary.BigEndian.PutUint64(r[520:528], _z.C0.B0.A1[0])
binary.BigEndian.PutUint64(r[512:520], _z.C0.B0.A1[1])
binary.BigEndian.PutUint64(r[504:512], _z.C0.B0.A1[2])
binary.BigEndian.PutUint64(r[496:504], _z.C0.B0.A1[3])
binary.BigEndian.PutUint64(r[488:496], _z.C0.B0.A1[4])
binary.BigEndian.PutUint64(r[480:488], _z.C0.B0.A1[5])
binary.BigEndian.PutUint64(r[472:480], _z.C0.B1.A0[0])
binary.BigEndian.PutUint64(r[464:472], _z.C0.B1.A0[1])
binary.BigEndian.PutUint64(r[456:464], _z.C0.B1.A0[2])
binary.BigEndian.PutUint64(r[448:456], _z.C0.B1.A0[3])
binary.BigEndian.PutUint64(r[440:448], _z.C0.B1.A0[4])
binary.BigEndian.PutUint64(r[432:440], _z.C0.B1.A0[5])
binary.BigEndian.PutUint64(r[424:432], _z.C0.B1.A1[0])
binary.BigEndian.PutUint64(r[416:424], _z.C0.B1.A1[1])
binary.BigEndian.PutUint64(r[408:416], _z.C0.B1.A1[2])
binary.BigEndian.PutUint64(r[400:408], _z.C0.B1.A1[3])
binary.BigEndian.PutUint64(r[392:400], _z.C0.B1.A1[4])
binary.BigEndian.PutUint64(r[384:392], _z.C0.B1.A1[5])
binary.BigEndian.PutUint64(r[376:384], _z.C0.B2.A0[0])
binary.BigEndian.PutUint64(r[368:376], _z.C0.B2.A0[1])
binary.BigEndian.PutUint64(r[360:368], _z.C0.B2.A0[2])
binary.BigEndian.PutUint64(r[352:360], _z.C0.B2.A0[3])
binary.BigEndian.PutUint64(r[344:352], _z.C0.B2.A0[4])
binary.BigEndian.PutUint64(r[336:344], _z.C0.B2.A0[5])
binary.BigEndian.PutUint64(r[328:336], _z.C0.B2.A1[0])
binary.BigEndian.PutUint64(r[320:328], _z.C0.B2.A1[1])
binary.BigEndian.PutUint64(r[312:320], _z.C0.B2.A1[2])
binary.BigEndian.PutUint64(r[304:312], _z.C0.B2.A1[3])
binary.BigEndian.PutUint64(r[296:304], _z.C0.B2.A1[4])
binary.BigEndian.PutUint64(r[288:296], _z.C0.B2.A1[5])
binary.BigEndian.PutUint64(r[280:288], _z.C1.B0.A0[0])
binary.BigEndian.PutUint64(r[272:280], _z.C1.B0.A0[1])
binary.BigEndian.PutUint64(r[264:272], _z.C1.B0.A0[2])
binary.BigEndian.PutUint64(r[256:264], _z.C1.B0.A0[3])
binary.BigEndian.PutUint64(r[248:256], _z.C1.B0.A0[4])
binary.BigEndian.PutUint64(r[240:248], _z.C1.B0.A0[5])
binary.BigEndian.PutUint64(r[232:240], _z.C1.B0.A1[0])
binary.BigEndian.PutUint64(r[224:232], _z.C1.B0.A1[1])
binary.BigEndian.PutUint64(r[216:224], _z.C1.B0.A1[2])
binary.BigEndian.PutUint64(r[208:216], _z.C1.B0.A1[3])
binary.BigEndian.PutUint64(r[200:208], _z.C1.B0.A1[4])
binary.BigEndian.PutUint64(r[192:200], _z.C1.B0.A1[5])
binary.BigEndian.PutUint64(r[184:192], _z.C1.B1.A0[0])
binary.BigEndian.PutUint64(r[176:184], _z.C1.B1.A0[1])
binary.BigEndian.PutUint64(r[168:176], _z.C1.B1.A0[2])
binary.BigEndian.PutUint64(r[160:168], _z.C1.B1.A0[3])
binary.BigEndian.PutUint64(r[152:160], _z.C1.B1.A0[4])
binary.BigEndian.PutUint64(r[144:152], _z.C1.B1.A0[5])
binary.BigEndian.PutUint64(r[136:144], _z.C1.B1.A1[0])
binary.BigEndian.PutUint64(r[128:136], _z.C1.B1.A1[1])
binary.BigEndian.PutUint64(r[120:128], _z.C1.B1.A1[2])
binary.BigEndian.PutUint64(r[112:120], _z.C1.B1.A1[3])
binary.BigEndian.PutUint64(r[104:112], _z.C1.B1.A1[4])
binary.BigEndian.PutUint64(r[96:104], _z.C1.B1.A1[5])
binary.BigEndian.PutUint64(r[88:96], _z.C1.B2.A0[0])
binary.BigEndian.PutUint64(r[80:88], _z.C1.B2.A0[1])
binary.BigEndian.PutUint64(r[72:80], _z.C1.B2.A0[2])
binary.BigEndian.PutUint64(r[64:72], _z.C1.B2.A0[3])
binary.BigEndian.PutUint64(r[56:64], _z.C1.B2.A0[4])
binary.BigEndian.PutUint64(r[48:56], _z.C1.B2.A0[5])
binary.BigEndian.PutUint64(r[40:48], _z.C1.B2.A1[0])
binary.BigEndian.PutUint64(r[32:40], _z.C1.B2.A1[1])
binary.BigEndian.PutUint64(r[24:32], _z.C1.B2.A1[2])
binary.BigEndian.PutUint64(r[16:24], _z.C1.B2.A1[3])
binary.BigEndian.PutUint64(r[8:16], _z.C1.B2.A1[4])
binary.BigEndian.PutUint64(r[0:8], _z.C1.B2.A1[5])
return
} so I think BigEndian would be in line |
Regarding repr of FP12 elements there will be mismatch with libraries that use Fp->Fp2->Fp4->Fp12 towering like Miracl and Constantine. Given a sextic twist, we can express all elements in terms of z = (1+𝑖)¹ᐟ⁶ An Fp12 element coordinates becomes in the canonical repr:
Fp2 -> Fp4 -> Fp12 toweringTo map the coefficients to the canonical repr we start from this repr
with:
Hence we find: Fp2 -> Fp6 -> Fp12 toweringTo map the coefficients to the canonical repr we start from this repr
with:
Hence we find: ConclusionI suggest:
Discussion |
Canonization makes perfect sense. I have no preferences on coefficient's order, ascending or descending, so I just await for further feedback... |
Py-ECC doesn't use towerings, it goes Fp2 -> Fp12 directly so the canonical representation is well suited for them as well. (cc @hwwhww @pipermerriam) |
See supranational#101 for details.
Please review #102. |
Resolved. Thanks! |
I've been trying to add BLST to our BLS fuzzing framework for go-ethereum in anticipation of EIP-2537.
One thing I struggle with is how to do pairings and get the result instead of just verifying if the result is 1.
I'm pretty sure that I can create the pairing as follows. My problem is now to compare the results from BLST to the other libraries.
Gnark and our internal library both provide a way to marshal the result (an FP12) into bytes, so we can compare them.
It would be great if blst exposed something similar too.
My wip PR for inclusion of blst into geth: ethereum/go-ethereum#24249
The text was updated successfully, but these errors were encountered: