Skip to content
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

Please check the code for FP12.pow(BIG) #38

Open
mhewett-ks opened this issue Jul 9, 2019 · 23 comments
Open

Please check the code for FP12.pow(BIG) #38

mhewett-ks opened this issue Jul 9, 2019 · 23 comments

Comments

@mhewett-ks
Copy link
Contributor

mhewett-ks commented Jul 9, 2019

I have been testing a number of crypto libraries with the BLS12-381 curve and have noticed a discrepancy in the result of FP12.pow(BIG) in the JS library for AMCL version 3.

Here is a test case:

FP12 pt: 
[[[18cd7a565a749009cc4c5f6601ea0856a47a3323f9ebb5953e4c2b1c4010d0dc7ca86ef548c4332b4cc2602e92e19f0f,09e148c258387a5e91c961df72cd340c19cdcdf799c249458969e00bf4d1275dbfcb139b49857e189f19ce71ae7fa8ee],
[0a2ac22c8737727e985aea988b18549379dc9821dd42d0974e7fd89b3d3c13114371ebfb3304cbda9d26c7a0a0b83025,0728ccef15044f5df498bb80ce5313d6dfc9a3ae9d4e4bb0f3ea398d8a2af607479cd6f66a6daeeb495d22aa8de2e256]],
[[0938dfc7cb18005c641319bb00149ce4a25edfa4aa50557aa8c780cce9cc6351261920f7212a41a3b0b097d3e827d3c3,07e500c72020555a613e32a7726c5d66350163663e4bdbc1b8b65b22c49dd19c91e7c859790a5290c526a391d2e896ef],
[171201bdd27cbe71d915e6e7d3cef10ce7251fa9b863c71652e0e63c16702c83993559129ee682b9c8c597b9849b843d,12c5a8f92088dba00d78e4c33bb18010e5bcd5ae193aedc291186dd9091ada24fc0d61f0efe90857e4528fc013583d12]],
[[1301d3f107fdcbbaffc05707e0e2611dc8d4ed9ad90c0fd221df7e706b4b4d46c943daf03a6f3a1eddd2d2c9bc4ddbc5,018fde8c2958612913a7ac368d9c778adaaf7dd88bedab9ada2e709ef173091735dd153382584c2bc0c7993937318ecd],
[19b0de4003f7f0c81918595a674a1d9d67bfcdafc2194aa7c2d799c3f21015e52018cd6999add6bc685dfc8b33ef41e2,03bce826c38b87e80c66b61ef71d705e67faeb0acf6f89fc5a6d4d9957bb766dc76b5c82d7f0d553260f4e2a7ef1c6b8]]]

BIG num:
0000000000000000000000000000000082fda182fda9e0755870887b25421b85b1f50051a22b4041135f9c153e354e02

(By the way, it would be VERY nice if there was a set(string) function on each class that accepts the output of the toString() for that class.)

For the other libraries I get this result for pt.pow(num):

FP12 result:
00c40389f91081c4a147c38944ec0c8696c45d4404a15990733226fbda393d4f69a70875240304cba6ea58d69a6739f3
15ab5b2d3e69220a755ca5e3eab9c6d2ef3d99fed681fd330a9f9a6ec8365a679e69402b71f6706c3e54ac0af7ff355e
0faeb132568224efce5169db3a9f0754bd3b028a8a9626a31f7673b6658e96f6b70984bd11bb572aa5d5f41cdb0c6c3e
0c2223234ff6fa4525002c36d574d9c70cf9ce4a81162ef54909af38a6768b40ed47348aa6f27f4e63aac352eff23524
0d334017e82fe7b51dace4ea243ba2897226c8eb6a6f16d2eb22e443f42b35a956c47ff83b6b012945253e579b4b903f
0f1063b5f569a9c4946dff4b73dc892f2234f2da0bab7926f3e4190cc3eeb07598f7e39f19456b74ac392a215baceb6e
04145ba9d429a25887aeb091bd03df38b908956665efaa8bff1c1d459ae787f9c7776dde504c7b6371cc0ce5352a5260
05ef1024a7b1cfb5f5f39efce60140d0df9e89ddf7aab232af493ff57cad9409119a19da7018123aac6531eae1068a57
002fd10ca8a397210c31a3fda02f68e1179868fffd6636afab08e14e6f026bce6f203d8b8f2ad5cc88e061ecda56f84a
15ad17363cf7246c68baa971644b3fbbe34f1b8ed8034619373debf0797c0d0096faec29bf29d6b559fb530ebe10e11f
175293de14123c3f530bf11903323f1a525d61f7f0fe9d0ef0fd3056f094bd61060bf1730a0037f71b782ff97f2e752b
10731a03c2a59150f572a8c2bf10241a650f3100faeec7204257222b5938bcb86b7fe00628d93d22e8076aeb59515d61

But in AMCL I get:

[[[17cdc384c7ce3e1ed2d11f04f692012710137e98f9b228e6c8fc9081b41ef35a02372d8f2d75421c210187c5e6f9db58,08b6852d7f5772b1e049f8ca8091c3b0121bb76c412493fc5bdb156e7161dc03a4a792c77d55bec457cf13894316d036],[15fb6af1f71a9e4688067a0bc56e7b547e9ef27feedc40dc91e02f62c252ce65586fff97ec67adad73368ed3474a765a,1224c3ac9873814d8e496e03f4400f8cb43826a86f8ee928cc11d1ae69d83416bc702160ae164371f7ec49fd91bc044d]],[[0f257efbbc8543fb9ce6959eefb9e8e8f1d7d4b9d7f24d04a867df8b1db735dfba3b1c0053e805a805f752a59d9dcc9f,01808b073d9d4fcdc023076e9b659b60da1a415ad213c24d891b0ea81a138cbeb7b369dc4bf8b1a8b1e16f351653dfed],[1799ea9ed9db2cdc6bae34fc4fec3f535500e0bcdf5ee3ed01ed5df4265c609ce8beaba683d0bdc88c40a88b2fb3474d,1969b47f62c7df1f62c8ae4c41527196afeed0dedd2b4587cfa0f79a978359e4fc23a30cb8a5642e4202c0a5a54d7d1f]],[[04950dee0be2ec1e54eb6c338198aaa5a7e0fbe35302ec21e7563b2f8e22707b4c7e80c0b3f39cb53b792e1279217979,02b9288d0c8dc4e821ba23b8c1a79c4afeddc363acc01f36fa7dee1808f873fe16286915065c7c3d4f4e550fb57efe65],[141b039ca264c22502f0f6ad8386c205a5f8e7bc95c70c4b75742eec892812bb11fa162d2156861f7aded25246f13ada,16a4f9a37208a154a7f85abbbd893d8583d077db7fd50a7e7d09d0512016e4f15efda050177a94249324bedc4cfbfbb0]]]

In case it's not clear, if you remove the brackets from the AMCL result you get 12 hex strings. The result from the other libraries is presented as 12 hex strings, in the same order as the AMCL result. The 12 hex strings from the two results should be exactly the same, in the same order.

I can provide a number of other examples if you need them.

Thank you

@webmaster128
Copy link
Contributor

webmaster128 commented Jul 9, 2019

@mhewett-ks Can you add your example code for AMCL? One caveatis that FP12.pow does not operate in-place whereas FP12.mul does.

@mhewett-ks
Copy link
Contributor Author

Zip file attached (143KB). Open the HTML file in a browser and examine the console log for output. The HTML page has the desired output.

amcl_fp12_big_test.zip

@webmaster128
Copy link
Contributor

One thing I spotted iin the code s that in amcl BIGs are decoded little-endian in ctx.BIG.fromBytes. This means when you left-pad your number, you change the value to something bigger.

@mhewett-ks
Copy link
Contributor Author

mhewett-ks commented Jul 9, 2019

fromBytes() calls frombytearray() which is going left-to-right in the input array and doing a "fshl" operation on the resulting BIG. I would hazard a guess that "fshl" is a left shift. So it does appear to be building left-to-right.

Anyway, I found that if I don't left-pad it, AMCL puts zeroes on the right end and changes it to something bigger. When I left-pad it, it produces the value I want.

@mhewett-ks
Copy link
Contributor Author

The discussion above is another indicator that AMCL needs useful setHex(string) functions. Then the library could handle the details and the programmer wouldn't have to worry about them.

@webmaster128
Copy link
Contributor

You are right, it is big endian and must be left-padded to BIG.MODBYTES. Sorry for the confusion!

@mhewett-ks
Copy link
Contributor Author

Here are five test cases. The first one is the same as above. Because of the way the values are constructed, the answer to f.pow(b) for each one should be exactly the same. This should help you check whether the fix is correct.

For each test case, f12.pow(bignum) should produce the same exact output, an FP12 number:

FP12 result:
00c40389f91081c4a147c38944ec0c8696c45d4404a15990733226fbda393d4f69a70875240304cba6ea58d69a6739f3
15ab5b2d3e69220a755ca5e3eab9c6d2ef3d99fed681fd330a9f9a6ec8365a679e69402b71f6706c3e54ac0af7ff355e
0faeb132568224efce5169db3a9f0754bd3b028a8a9626a31f7673b6658e96f6b70984bd11bb572aa5d5f41cdb0c6c3e
0c2223234ff6fa4525002c36d574d9c70cf9ce4a81162ef54909af38a6768b40ed47348aa6f27f4e63aac352eff23524
0d334017e82fe7b51dace4ea243ba2897226c8eb6a6f16d2eb22e443f42b35a956c47ff83b6b012945253e579b4b903f
0f1063b5f569a9c4946dff4b73dc892f2234f2da0bab7926f3e4190cc3eeb07598f7e39f19456b74ac392a215baceb6e
04145ba9d429a25887aeb091bd03df38b908956665efaa8bff1c1d459ae787f9c7776dde504c7b6371cc0ce5352a5260
05ef1024a7b1cfb5f5f39efce60140d0df9e89ddf7aab232af493ff57cad9409119a19da7018123aac6531eae1068a57
002fd10ca8a397210c31a3fda02f68e1179868fffd6636afab08e14e6f026bce6f203d8b8f2ad5cc88e061ecda56f84a
15ad17363cf7246c68baa971644b3fbbe34f1b8ed8034619373debf0797c0d0096faec29bf29d6b559fb530ebe10e11f
175293de14123c3f530bf11903323f1a525d61f7f0fe9d0ef0fd3056f094bd61060bf1730a0037f71b782ff97f2e752b
10731a03c2a59150f572a8c2bf10241a650f3100faeec7204257222b5938bcb86b7fe00628d93d22e8076aeb59515d61

-------
TEST #1
-------

f12:
18cd7a565a749009cc4c5f6601ea0856a47a3323f9ebb5953e4c2b1c4010d0dc7ca86ef548c4332b4cc2602e92e19f0f
09e148c258387a5e91c961df72cd340c19cdcdf799c249458969e00bf4d1275dbfcb139b49857e189f19ce71ae7fa8ee
0a2ac22c8737727e985aea988b18549379dc9821dd42d0974e7fd89b3d3c13114371ebfb3304cbda9d26c7a0a0b83025
0728ccef15044f5df498bb80ce5313d6dfc9a3ae9d4e4bb0f3ea398d8a2af607479cd6f66a6daeeb495d22aa8de2e256
0938dfc7cb18005c641319bb00149ce4a25edfa4aa50557aa8c780cce9cc6351261920f7212a41a3b0b097d3e827d3c3
07e500c72020555a613e32a7726c5d66350163663e4bdbc1b8b65b22c49dd19c91e7c859790a5290c526a391d2e896ef
171201bdd27cbe71d915e6e7d3cef10ce7251fa9b863c71652e0e63c16702c83993559129ee682b9c8c597b9849b843d
12c5a8f92088dba00d78e4c33bb18010e5bcd5ae193aedc291186dd9091ada24fc0d61f0efe90857e4528fc013583d12
1301d3f107fdcbbaffc05707e0e2611dc8d4ed9ad90c0fd221df7e706b4b4d46c943daf03a6f3a1eddd2d2c9bc4ddbc5
018fde8c2958612913a7ac368d9c778adaaf7dd88bedab9ada2e709ef173091735dd153382584c2bc0c7993937318ecd
19b0de4003f7f0c81918595a674a1d9d67bfcdafc2194aa7c2d799c3f21015e52018cd6999add6bc685dfc8b33ef41e2
03bce826c38b87e80c66b61ef71d705e67faeb0acf6f89fc5a6d4d9957bb766dc76b5c82d7f0d553260f4e2a7ef1c6b8

bignum:
82fda182fda9e0755870887b25421b85b1f50051a22b4041135f9c153e354e02


-------
TEST #2
-------

f12:
18a1b65ded4be6e7552661c50bdaf59bf71b8722a024b07476f222aaa144154c449127701f8cfe00952142dfd2ec2793
0ea7eb259481519b6e56946447f2a9d8f40f9c88c656df7af652544c20d1201bb5d1e3e5d0d0b2fdd6751d8bfd709a97
182a45d223985c03c35a648dc686053b40b2b740ae860a68f32b8abb200d5763facd6d97f57ebbf0908020394395d847
0d3dc48125452b83439ca48f5f46388a743743287103aa659afd5aab7be6c575f5bbc7fe6e9dd797fc005aef5904b67a
08ddd80ba4ec5336ff10d94af7d2ad4b4b28b56eba52aa5e182f86776753307d6d13ec75e59add203a35f8b12542acc9
162c9b1c235761296c26573e5cf2fbd271df9a54a11e4625713e03f556025e876ae545f3962f47f255e51e406cce0934
1149cf3997124800ceb3e8913705c040246e6745c3fdf1eeffda49bf217b154cc8e79c30fd09dbae1ff95b32a32e6252
09241eee653245fde212ba7bdb2dcbc161bba09631cabd00ac4492b95be207587beda307621e4852062ef22d5c08fa5e
0a042f668355f84b895c74002df64f1752bfccf62b848871ca846da887280d6dc674ea9817a9cafdd0d49c19f918526c
073a030c9057ac42c951a2bb521f80213cd6552e77d6aba6525e8db545fd3c22e42f00d731d73b05c1b0b08d55fa74f1
07225aae2f3b6dfb82dfcf889ed193c4e7462977b3eb04b63890db9ad8e0d2094d880c262cf5b8f56a77285b0050aa7e
0fb7b1eed21e8ba8876f052583fe880a2cedc5361e10148f63e444bfaf7f582d5b637fb1e9864a0467084b4a08264a29

bignum:
2daf71c6425ac2120e8faf9c287a6e336d9481b6ff4d2a144af3ad9e529a6c5a

-------
TEST #3
-------

f12:
06508e73cd8f0d50382dda4344f141c6b2bfca21fabfaead14df519fa720522a4df21a77a0ee80035d28107fd99115ae
0e88988b7b4458949e7d38444a7a24e8db71dc4eef7eb41dc33fddf5738db35ea6477dd1052cb0ae618cf6ca3e2025ce
02915017546626e0a6d20ea5eb980c3e971d59090978bbbb623a4991180a53983831762b22209bf72257704af6c6e69c
05fd59618424766606519863741bf284634b4120101601e55a8624f8859efb38a3299711d1c7d938a3b3c4f366b94c80
16056f2b23c2c85f6775357d6426ff9842201b513f617c062e4b0459c59712861124b64d36b1e9b81647c56c84cd1e75
11811cae8dc20048496265a87f44c1344dbbc876f07c352049ebae3d7f587f61a4853e795e68c5f9c038fac47418db63
11d051775c2391e148cee3c7acee00ad80fe96e35943c5a6c7537e9eb1f3b1bf4ea00ceda2b7be14333d381e949e428a
048e943ef0dc4fee481955570c4e92a2fedc8c38a41029a533208513369465b0762244f55497454bae99d8ed1ac99e85
16834f131648e1dcd8880de3a71e979eec0752ce95a599cedba996a531e6affa3e4cb1617f6a2c8409955e3565e37a8e
0925fb863e2b7f36cb6f06b389b914474baaf6e93b6c6b169f0c36621bcfcc0bc323496e1ccba7cb499ce75829c7ff0c
12686874a32a715b4e1325974bfbd2247dbe17a50dad860ee7c145576394132c9f91f8ea7fbbb9e4dc3e18c57ebbe879
1718123b3667b9ffa35eb7cbbba2ae42025816ac87b4c5450a6d6fc4531703be2decacafcf4035dfe6ce607705c9cfb1

bignum:
156454795f9c9f24db07f7b793485aa2c845fdd1dc448020f83c163f4e9955fe

-------
TEST #4
-------

f12:
06b101b7671d0da007f5852810d1c3a276376496041a2ac6cd13abeaa2aef2d579249957671439dd7cbe041a1afaad03
160b8e910a4a98dc0d6426f30bc74b9b71029a5b08b74a54588b5fa6e8248e842615cfa1ac8cb55e64dfbf7c4f32cf1f
06ca71e621a78f83facc92c72e1e2519995325d51f43e5317f0e0b142ec8a6af861926e5cde775d9085ab331b94c8848
06800f168a2579bf62dd2d18de77fdf8071867624c615293d9adafccc894eaf3f2ac046ebbbd5d0e0f756d430e5a6326
06fa9f047fff542986898f6d6d1051dc857e658da8e3aab26a6c190356eb897a0903405a6c97898b740e602d68d45d9d
1617b3d94bd42fafc34aa3ee156bce2f4075a01d9f27fb5dd57a235aef05c298a8561822418512691070295f266a29d0
0f2e65561f34beebdc6c7c610ae821983ec50781980de8ddab7c022adf52754ae07464156d406c39681177fb8f285a10
05711ab3deb3578f00c7b993f887d08373a88bda37becebbb1735b38ab7d55b846cba34c53af98322868ec33b7636034
120e5de6a2bf44dbe4b1175794ef93ac53e4c995bd1a43ed9b67f016204595ca12bc44923954348d9ef4b59a4238f5db
0f3d8739cc49c8c2a8e7f1e8dd15427029bfb68ece8abde22d70c5bfb3acbaeff4c292f31a005c87b6ea65e1a80ca1a1
19dfbbc94337837d383587633cb629796f8bb2cf6c8d4ecd9b08567a3f4e910772235165a3df90760aed6b67e5b5d3cf
1764e65f858deb9a1df16281ba54e4764a37210760d9e89fb710705b47101265a2641a13c772d47cb2c091f00f1c880d

bignum:
2a626573cf2d0dbfa11e6a674703c133d1e8d7dad3888695d201521cf2ab637

-------
TEST #5
-------

f12:
19a5def930dd216a024bf79698a2e2ee8a34482cab1fff5555254b31f5e26928fec52eff68a7e0a69573c5dc4e9dd536
05dc91584cae5a2b2674097e4503ad9bcb82a7fceb52165943405813e42ad80bc0363e461336f2c7da25a96cfc0f62fe
05b0da4c98ddec37d37d80db1289188eba8b35a2f61cdf86b65b608ab5a930da3afdc397f9db1f43966f358223e06648
09d3293b5de77de9cc8f19067ac047e2cb2257da8776569102230925a7b872dea3fcfa6b5b9bc4e5e17f3b6699e68e35
0a536e998b35690a321f6d1ead65d10aa99c3a08507001516a1b0c289436b7879cbe79b5a6427fc393f98a2f4b4f2989
18c862dc71088909d221a46f7224a338c358b3e1c46ddf00a8392909ae3e3cbeefbdf8bfaafc6ff54839f7293f4de9f7
061ddcfc81ce0efb2136b859ec72825600ff9b7bd53afee85c3715870ea9a08a609fa440d71e302becd7684344d3d466
012d1dafa658a2d69c57b810f846781d42659e0b6b0621cd8e4de828888b8afc838b0ad84cbfe74ae3e226001ae1023d
11d054196b958e872eef1d7920a9e78e08b996522fba4b2373116f0a7020b3a97c90e007f5e1b9d4fe2af29a9d1e5123
15aa3aa4f5b3aa3188f7e599dc64182c63edb92258c3230fd8dadeef173f81bfcacc85693423c43dc9abb8f065b744ea
19b1f477cf26d5a9b8512ee810c4fb11e5ea52b8ee1b33164890b29925f5f22bda1d97cb39219be43b9dcc4ee5a7e9ce
055c10e0a635655a32311be9b1bf93db7881f3e737f447c44ebcb6818fc5e75cd2187811c13148088c383beec6cc9486

bignum:
6ee021889c835aa5d1fc104181e9b843867f44b1583696af05f49708d813f275

@mcarrickscott
Copy link
Contributor

I am not sure I completely understand the problem.

First point: there are different ways of representing an element Fp^{12}, depending on the towering method used. The AMCL library towers 12-4-2-1, and most other libraries tower as 12-6-2-1.

Since the final 2-1 is the same for both we can ignore that. So if A,B,C,D,E,F \in Fp2

For the AMCL towering an element (A,B),(C,D),(E,F) represents the polynomial

(A+Bx^3)+(C+Dx^3)x+(E+Fx^3)x^2 - (1)

For the alternate towering (A,E,D),(C,B,F) represents the polynomial

(A+Ex^2+Dx^4)+(C+Bx^2+Fx^4)x - (2)

Clearly these are both the same, both representations of

A+Cx+Ex^2+Bx^3+Dx^4+Fx^5 - (3)

So clearly it is easy to move between representations, its just a permutation of terms.

I am not clear how the other libraries output an Fp^{12}. Maybe in the order A,C,E,B,D,F? Or maybe following their towering as A,E,D,C,B,F?

(In fact ideally for interoperability it would make sense for everyone to use the towering-independent order (3))

Second point: the functions toString() are intended for internal debugging use only. The external API
representation is via the functions (in javascript) toBytes() and FP12.fromBytes(), which are output as Hex via for example MPIN.bytestostring()

@mcarrickscott
Copy link
Contributor

OK, I think I see (another part of) the problem. The example FP12 you are using [[[18cd...c6b8]]] does not appear to be of the correct order, and is therefore not an element in G_T.

The FP12 powering algorithm is dependent on the FP12 being a member of the cyclotomic subgroup. It uses a fast squaring algorithm usqr() that depends on this. It also uses an optimization that depends on inversions being the same as conjugations (and therefore costing nothing), which only applies if the order is correct.

So I suggest you try again with FP12 values that are the outputs of pairings (and therefore of the correct order).

@mcarrickscott
Copy link
Contributor

Ah, when I apply the simple permutation to your FP12 I get

[[[18cd7a565a749009cc4c5f6601ea0856a47a3323f9ebb5953e4c2b1c4010d0dc7ca86ef548c4332b4cc2602e92e19f0f,09e148c258387a5e91c961df72cd340c19cdcdf799c249458969e00bf4d1275dbfcb139b49857e189f19ce71ae7fa8ee],[1301d3f107fdcbbaffc05707e0e2611dc8d4ed9ad90c0fd221df7e706b4b4d46c943daf03a6f3a1eddd2d2c9bc4ddbc5,018fde8c2958612913a7ac368d9c778adaaf7dd88bedab9ada2e709ef173091735dd153382584c2bc0c7993937318ecd]],[[171201bdd27cbe71d915e6e7d3cef10ce7251fa9b863c71652e0e63c16702c83993559129ee682b9c8c597b9849b843d,12c5a8f92088dba00d78e4c33bb18010e5bcd5ae193aedc291186dd9091ada24fc0d61f0efe90857e4528fc013583d12],[0938dfc7cb18005c641319bb00149ce4a25edfa4aa50557aa8c780cce9cc6351261920f7212a41a3b0b097d3e827d3c3,07e500c72020555a613e32a7726c5d66350163663e4bdbc1b8b65b22c49dd19c91e7c859790a5290c526a391d2e896ef]],[[0a2ac22c8737727e985aea988b18549379dc9821dd42d0974e7fd89b3d3c13114371ebfb3304cbda9d26c7a0a0b83025,0728ccef15044f5df498bb80ce5313d6dfc9a3ae9d4e4bb0f3ea398d8a2af607479cd6f66a6daeeb495d22aa8de2e256],[19b0de4003f7f0c81918595a674a1d9d67bfcdafc2194aa7c2d799c3f21015e52018cd6999add6bc685dfc8b33ef41e2,03bce826c38b87e80c66b61ef71d705e67faeb0acf6f89fc5a6d4d9957bb766dc76b5c82d7f0d553260f4e2a7ef1c6b8]]]

And now it is of the correct order!

To test FP12 for correct order in AMCL.

// Compute T^order
r=new ctx.BIG(0); r.rcopy(ctx.ROM_CURVE.CURVE_Order);
let result = T.pow(r);
console.log("T^order = " + result.toString());
let resultStr = result.toString().replace(/[[]()]/g, "").replace(/[,]/g, " "); // remove brackets and parens

the output should be 1.

@mhewett-ks
Copy link
Contributor Author

My pairings are constructed by a different library and they are definitely in GT. However, the other library does use a different tower.

Good work on detecting the ordering problem. I should have thought of that. I'll permute the values and run some more tests.

Ethereum has proposed a standard representation for G1 points. I don't know if they have extended it to G2 and GT but perhaps AMCL should propose a standard and support it. The Ethereum standard is here: https://github.com/ethereum/eth2.0-specs/blob/dev/specs/simple-serialize.md

@mcarrickscott
Copy link
Contributor

Since G1 are just points on an elliptic curve, a standard already exists. See section 2.3.3 of http://www.secg.org/sec1-v2.pdf

Basically its 04|x|y, or 02|x if point compression is used and the least significant bit of y is 0, or 03|x if the least significant bit is a 1. As far as I know nothing has been proposed for G2 and GT. Both can be compressed, which complicates matters...

@mhewett-ks
Copy link
Contributor Author

I have confirmed that swapping elements 2 and 8, 3 and 9, 4 and 6, & 5 and 7 permutes the FP12 values from the other representation to AMCL's representation. After that change my code produces the value I was expecting. Thanks for the help.

@mcarrickscott
Copy link
Contributor

Great!

@mhewett-ks
Copy link
Contributor Author

Now I am seeing different results from FP12.pow(BIG) and PAIR.GTpow(FP12, BIG). I have tested both the Java and JavaScript implementations and both produce different results. This is using the BLS381 curve

In both cases I am using an actual computed FP12 value, NOT transliterating from object to text and back to object.

Here is a trace from Java:

// This is computed from PAIR.ate(ECP2, ECP);
pairing = [[[04f242b1e59415f18f496e9b112c4fd0adaab7cf8131d2e5cfa97f9ddab4b720607914b42db1ec3bced8f1634212f993,1185e7ee461118457b06d7788b033a7ffed1fdf1140c6ae0e4923ac484b237c67c9cfdcebddf9aec8667861ed570e35c],[051966ebd8e5e90114519331729e9f25474359fc04b93a702779af67e65f2b7c295df5933e28c6222773ce2704704419,07e843f5a2b609144b00ca915da9d24b094c7b8cc9c014fd04e2da6a9774581458dcc60c2e0b8843a2000219727e10fb]],[[10e899fe0170de55488937c26fc9046ef3c5bbc2b4e3a39fcf35e1bb73f90cc69ea66cccec6682e38358ce0024b982cd,119545b6487a80fbd0aaeabc4b61891ff158ab76bcd4c2690d654519061b8e5a7cc8fce5c616fa881d0b37a5efce24a5],[0a0652b4e4b547e78f61429239a881ea53cfc1c7b1201302e9f04fac4e8b1e364c070045578f0681628028524fd33823,02fb1f35a9303d4855cacacf211cbbaac7d3fdb96c6c98ae42f5fcf92b809065aca799946c3b84f1edf46e275b63800b]],[[12d0dbbb39b763e1b69a754ee2d6fa1443e8993f00c55bb4bf3139aa36b79cb97a6924fa61e302699893edc7be1e7b0e,190fac90fa9afff159399bf650385485945ad3f82814a357f134394fd098dd236985cea46c9f284206c24827eca0b238],[0e8a002ca6569824a3e68bf33a9ed5b0655cf68fd7ca4e7df18412e16864b28683fbe201bfadb1eb78948d8f87ed20b1,08ef9db2c22f0bd790f8c41afe3c0ce6e9a414df7fbd2c8e2d1a62db6a740aebf62acf5c88db85acedc4c1a9aef2ee42]]]

// Here I make a copy of the above to ensure that the input value is not accidentally modified
pairing2 = [[[04f242b1e59415f18f496e9b112c4fd0adaab7cf8131d2e5cfa97f9ddab4b720607914b42db1ec3bced8f1634212f993,1185e7ee461118457b06d7788b033a7ffed1fdf1140c6ae0e4923ac484b237c67c9cfdcebddf9aec8667861ed570e35c],[051966ebd8e5e90114519331729e9f25474359fc04b93a702779af67e65f2b7c295df5933e28c6222773ce2704704419,07e843f5a2b609144b00ca915da9d24b094c7b8cc9c014fd04e2da6a9774581458dcc60c2e0b8843a2000219727e10fb]],[[10e899fe0170de55488937c26fc9046ef3c5bbc2b4e3a39fcf35e1bb73f90cc69ea66cccec6682e38358ce0024b982cd,119545b6487a80fbd0aaeabc4b61891ff158ab76bcd4c2690d654519061b8e5a7cc8fce5c616fa881d0b37a5efce24a5],[0a0652b4e4b547e78f61429239a881ea53cfc1c7b1201302e9f04fac4e8b1e364c070045578f0681628028524fd33823,02fb1f35a9303d4855cacacf211cbbaac7d3fdb96c6c98ae42f5fcf92b809065aca799946c3b84f1edf46e275b63800b]],[[12d0dbbb39b763e1b69a754ee2d6fa1443e8993f00c55bb4bf3139aa36b79cb97a6924fa61e302699893edc7be1e7b0e,190fac90fa9afff159399bf650385485945ad3f82814a357f134394fd098dd236985cea46c9f284206c24827eca0b238],[0e8a002ca6569824a3e68bf33a9ed5b0655cf68fd7ca4e7df18412e16864b28683fbe201bfadb1eb78948d8f87ed20b1,08ef9db2c22f0bd790f8c41afe3c0ce6e9a414df7fbd2c8e2d1a62db6a740aebf62acf5c88db85acedc4c1a9aef2ee42]]]

// Here is the BIG constant I compute with
testmul = 08d4303680fad3807b53a0ae44c25acc2297185ea03d1e3817582978e6d86d7a4f312ab9c16f60a715eb71bccb16702d

// Output of pairing.pow(testmul)
pairing  ^ testmul = [[[189e790443389c2c92c90c7ba94bc997e79a386a2840c9c8d7bafdfd2328a4e9db9a3884300b4265f952ce562fcb0947,045c310a1cd7a8fd3636c7f81c6381a1fee2b4bdc09a24e406103846aff30a7191890fb828901e8129390f1766bc097e],[170a1579b4240cb8b2d3a6ad32fe9569adbb55e008ab06db29146accf59ac68e75d5277949990ede1dd6b1dba2cb8d96,0afbb5c4e5d7ec3f33b2338844b65585f4e90d7e0b208facacb4b8f208b91c50678f5f53863dc344110642917f447a50]],[[18126c2f025573f6fbbe8e696933db5ce6e99662c4d17315558dca5664ee880e7e4e690902786d5eeccf1453b5567157,04f0dca5a4eb9b81318c8035a20545320446f19f7156baa3845d312bfb1e31075666050ffbd9fa272620e2bb73864006],[0c2024e5ce5f03defa102eb9c20bfd5ae6c22c953fb396d9d2edfdc2b7c881da87d0b3c842a1869c8a84b17c63f66d9b,0a306b4d3c036311f00e39e8bfa7211f4de73eb1a2136d7a12431e384092a5ffab7e19ea5c427aca18a62540717af60f]],[[0b58c3476e344d163b20836249bbefba8352e8d33a6315762bd9f9f12dfb3f23faaa38a5e74852aaf44d2c888edea7d0,0f33e8ba2a32157e21b0679ecd50e4c44910756a798c9a934811212350a8f0df57b0b034c5a6cd34e2b53b10c7944b89],[037b6c675b9fe058c1cb7b80758b49504733a6a1e3b7ad16304ef612d3c59bc86aad3d1255ac1fc99e86497cff398264,18628d4f4faf933818427dd0c32388cd86b30accb01e34ab6b6a5a2afc06cc721d6cf8450a048a618dd41cd7af164962]]]

// Echo testmul to make sure it didn't change
testmul = 08d4303680fad3807b53a0ae44c25acc2297185ea03d1e3817582978e6d86d7a4f312ab9c16f60a715eb71bccb16702d

// Result of PAIR.GTpow(pairing2, testmul)
pairing2 ^ testmul = [[[0224ae7e5b63d1813b097cdf6240f07ce4b2c3c5b15a64002273250aba8c0b81e9a8879a2f393fbf76dc9704d96e72b5,0e2a396f6ad34b868eefb2d0cca881968f45e2111d4e1346a6be85ddfffe04fcb8761f639ffb7e4d5a58bb8743edbf49],[11f20204213b5e91ab3f2bd4955cb2facb9f57010312a373ceeb76c56aea710345d98dd7c84959ad9bc18b0c4ba9dee0,0eed27fd223b30ab36dcc0cf6ddb036e0413d6e6f19b352ff1cb6e12888d93d4c536ffc2fb8372a3f924b67b95599174]],[[0999bb65e61cb9dab1b9ad5be427eacc7340edcc47f40c316458598ca89f008866b31fad02ea700e52eba752b6448794,05f15c82729559528e246954bd00af01e1919ada5c678c6d5fc6e0bb23effa1ac194179c3e701eca9e216a0fdd2070fa],[0685a00ac23af29f9541c87998ba92f0cbd217c210aadc66609548f2fcd64d6df60715ed38ee7c7b41e67b3f16729d4e,19d2972b537defa518a690444f3e3f50d21bc92e5d989fa0fbb6a5ee06fa3a2615ee43ca99f4e7794fbcda557397fe18]],[[02fbeff393ae67fff3cd78a9eb1401dede03d1e5c1e7600a11bd038c8402447fbdc8e371d0190b7f764b4b0b9041dd7c,1892276a1c2a82f75a67e152e073465e6943fcb025b85f0085417744ab11ca1c48db55b0cab78b4d4bcb7ef5db38e442],[0f2659b703afd906541372eaae7608260a7e45331981e0a0d76ecda57ec8ef8b817a7ca7b74fe87c946b3dba70e089eb,17116ee3f1a2ca6394c935f8c8e14d06c3896fdbf1cfa28b292e453d77333963fa42f4910c949a44086c1f4bec9194e8]]]

The results should be the same, right?

Here is my Java code:

        // Testing -------------------------------------------------------
        BIG testmul = new BIG(myBigNum);
        testmul.invmodp(modulus);

        FP12 pairing2 = new FP12(pairing);
        System.out.println("pairing2 = " + pairing2.toString());
        System.out.println("testmul = " + testmul.toString());

        // Compute T^secret
        FP12 test1 = pairing.pow(testmul);
        System.out.println("pairing  ^ testmul = " + test1.toString());
        System.out.println("testmul = " + testmul.toString());

        // Compute T2^secret
        FP12 test2 = PAIR.GTpow(pairing2, testmul);
        System.out.println("pairing2 ^ testmul = " + test2.toString());
        // END Testing ---------------------------------------------------

Here is the curve configuration CONFIG_CURVE.java:

public class CONFIG_CURVE {
	public static final int WEIERSTRASS=0;
	public static final int EDWARDS=1;
	public static final int MONTGOMERY=2;
	public static final int NOT=0;
	public static final int BN=1;
	public static final int BLS=2;
	public static final int D_TYPE=0;
	public static final int M_TYPE=1;
	public static final int POSITIVEX=0;
	public static final int NEGATIVEX=1;

	public static final int CURVETYPE=WEIERSTRASS;
	public static final int CURVE_PAIRING_TYPE=BLS;
	public static final int SEXTIC_TWIST=M_TYPE;
	public static final int SIGN_OF_X=NEGATIVEX;
	public static final int ATE_BITS= 65;


	public static final int SHA256=32;
	public static final int SHA384=48;
	public static final int SHA512=64;

	public static final int HASH_TYPE=32;
	public static final int AESKEY=16;

	public static final boolean USE_GLV =true;
	public static final boolean USE_GS_G2 =true;
	public static final boolean USE_GS_GT =true;	
}

The JavaScript code does exactly the same thing. Both of them produce different values for the two varieties of pow(). I am using the same set of libraries that I sent earlier in this Issue.

@mcarrickscott
Copy link
Contributor

OK, I suspect the problem here is that PAIR.fexp(..) is not called after PAIR.ate(..).

PAIR.ate(..) does not calculate a complete pairing. It must be followed by the "final exponentiation" to produce the pairing value of the correct order.

The complete ate pairing requires a call to PAIR.ate() followed by PAIR.fexp(), for example

			g = PAIR.ate(Q, P);
			g = PAIR.fexp(g);

These functions are kept separate as a multi-pairing can share the same final exponentiation, as in

	g = PAIR.ate2(Q, R, sQ, P);
	g = PAIR.fexp(g);

@mhewett-ks
Copy link
Contributor Author

Adding fexp() resolved the problem. Thanks.

@mhewett-ks
Copy link
Contributor Author

I am having a problem with AMCL that I had with another library. When I do FP12.pow(BIG), it produces the result I expect iff BIG is at most a 255-bit number but not if BIG is a larger number. Is there a theoretical reason why if my BIG > r the FP12.pow() function wouldn't work as expected?

@mcarrickscott
Copy link
Contributor

When powering to a BIG value x, mathematically its the same as powering to x mod r, where r is the group order. If x < r then this clearly makes no difference, and if x>r there is no point is using an unnecessarily large value for x, and it makes sense to reduce it modulo r.

The powering functions do not automatically do this reduction, as they assume that the input x<r, and implicitly assume that the function is only called with such a constraint. But they could easily be modified to internally reduce the proffered exponent modulo r (and maybe they should be!)

@mhewett-ks
Copy link
Contributor Author

Final note: Thanks for all your help. I have a pure-AMCL version of my code working using JS on the front end and Java on the backend.

I may have some future comments as I try to also get it to run in IE 11 and Swift (:-)

@webmaster128
Copy link
Contributor

@mhewett-ks Could you share a final test case of externally generated test data for FP12.pow? Would be great to have that in the unitests. I tried to follow the permutation from #38 (comment) but do get different results.

@mhewett-ks
Copy link
Contributor Author

Here are a couple of test cases. These are all in AMCL-compatible format:

TEST #1

in:BIG

00000000000000000000000000000000308e6a1f3447d6f8396e9852b014ac671b70b487026ee56fc703ac07d8cbcb2d

in:FP12

1811d37042135ae36711af0e94840a8e6cd0ed34798b59eeb7ff78d4fa0b403ccba4d47349bf5a752f73d538a401e965
001983adb8839bd27b143e7d0654326da08beca7935e54c2eb9dd00017287a8c80c1eb5c3a5d8c92beb83576f66f9232
006fe1878077e3205e3d5e5c4b84dbd6526e8197bea0160ba3d8dc2eb1a2fbd0aa099b3c31071551c161a15862f6d45d
0feb0e2c218b2e4f94b4e7a23d0c1dc0bc0821911c2aba96c5e5c23328ec7614dcaaa18fb735f63c864283c806d328f0
05e9602f793c10bab1d76ac12032220d941e5413fedc298b260b7ff7743ecf6cd137c5599245bc0453b4d61d08d63e49
0caa0ae7a81a27345d88da9f2065915ec6c758a4e1b8a18654f815937d4fa481e0f4399d6c066bf697420a031a608968
10d3c6699f556470013d735a7cab4f8f96542698efe9fb34ffc0ca5f196e7d20756659bd25f13b2ba45cb1920f9e056b
0b60d733670c44b2bf025364204d863b3428eb53878cc263609d507ac1623f0e169843c4ef1da4239db30f2abae678ce
038c41e621383670986238f366560ab46a582328905c0e40191e133e2f3dfc0842d873cb6be936f67acc6f4c2b2881cc
07531c8e0a1d902b22dea7d242cf57315951ee3eda2f3290723b4b118e4de9fb3a8c46ae3c9cd744b8598dc46483005d
0303af33f147826e0ee2da56d5849fb4e84b76edb8f490e774dbdc7d4aa686448b4293d72ddc53ec4f9aa83c8192a856
0f9e2f478175a5dfbfa4466c09016a88ef350d69f287f11ee61d979b42d90692f7be247e0a87d6a08657d59ed011f5ac

out:FP12^BIG

03022c9299dbf5d3ef355510132ccfb7df519f3df0edec89b76981853eaa497d5ce050f3c5b2898b19682b443001c0c3
0a256234d5f0398467f1cd5b4ac15214d9d6657731f9297a493204639e910b64fedb7a58c8712acb96d358e63c6d4e40
056ce041cde136fcfdd4c5f15020b67d54d612ec01e20bc1e92db4e3861a27c90f6c776d5a09429d091c8a8a926d1410
02fdb14f1d44f594b00c52e76ec5cb3475f73665dfb75f7ffb2212ea8648339077b7a7a236451718635097008bf2f6fc
175d8be7433d680d749b19cd8703a225f62d3cd54758afdaa192af5a1e6859edf051cc42bae76e25f6f8560d3be7d70b
0afb29f7d8ee46512ab2fc4e12250d692662fc96bed89df4fb4ce274f9463a7d2248fe70a76e08b28c33cc72793c37fc
08f663ee2ae9ecc5d0599e8d547ee2d1744f9cd7bf9d278a0a5878fe89259cdeb18a2ceec9e7d11b84aad6eb4fc051ac
1691d1819423fad024e2e4634a398f9e7034aa4c337d10ab9f0f9925e9f0ea5961c95dd9618f1ecaa0df9f1447caed80
1843b6d22960d88929260189942731befe8e4b2d8ed226cf2be92c4285386af03278d064ea86a343473849ed418f0be0
0370f7b04673a7feea7b4975405c6774ccc1b9669fcc6df757d7c05f785d7b39b13c61f8bfaa727002222eebe6fa248b
01d2c9db0df63f559a0ea72b8c7cea2c111a95a54ec7dd03f2cecc29d9273750b65d87aa6262d48ee3e5cc43b9d36b87
113757b5626f0b5488cc731f4ba0bbd7b1a289db1ef71aea0abf911fb51fd5270eaefa455adad378e8c89182d9df674c

TEST #2

in:BIG

000000000000000000000000000000003b1b154974a83c8df7b052ea1ed6bae3fba9d2b3ebac17095be04f172e7a7e7d

in:FP12

151195972a629276cda4360b6f787caa120094f3c913792a1272932d00829b8f99bd88c88aeef0115bc5847aa26597f5
0908145282ad4485b0b2efdf68761d5e0e23b9082538e2971d6afcaec800cc266d769f1423641da6274a3f357840d801
081fe057edc10faa6d140bc1c6f265e8fa59c4233e230b7e9b97e39a378ca4876090ca31141587e1f401f2c01b0e4dd1
09aed9f776c3046067a95ae930193cdc48d5feb887ed1e9581f46582f7bdc42aad7ed401f3b8c35a34fc68504a19ff00
12eca5bfec4541378e34b444d049b68538f959433803a1556683ea350cfa899692457a5e713147f5afb6ce4e637da298
168153909d7379cb810565213c2fec4651eb48cae8624c636eecaae97324d105908c974ea5c70da05753ab64f77925c1
08b8e2026b40845513b674776c9b1a75dd972d0b6fb579d68286f1b62f7f0974b7207ceedf899da98342caf4c3b1cd37
195a4316cd5fb519abaaa60313c27c12cefb99164488f7b1cce16da077443b77d831502adabb821979c360ab9e374800
17a9ff861a0475c45df65c96a7518c5c9fd87ad370c359e4a57e312712a1a2aeed99d2d8b815edee985bd06c2767482f
15de3f5b3465061627119bee84784d6f37c48ec9a3d08e167bff5a10f5e4edebab71f5902b07ec8ca9504b9dfeec672e
03c0e865457c95fedf301ce0bf8c229b7829197db038cf0a6a6f8b82c9fe5d2e3fee3db409c29bb0e79fb16573d696c2
19a0c6d5bd5b924da1c8dc7452a806bb7c192af567f0e8c151fb9cc38532ea7aef2467da1a68620797ace15b157d6c1b

out:FP12^BIG

14821e49c71fb12ecc5a4f80df6c0c6c6269936a6b0e1262483b20456588e044c414051b6be0baf599af71556d72c6f9
0525e09c45f14512cc66df90cd2ebe365f3995385db46976a1ce85bde3f6efe1abae44f2e2e87d44ac89bfa1b3a623bf
01031d7725f969073e9f729dc8ec44aea2a50d318a436c94d16ff66d84ca0b7db40d2f9006a726194b32955711e083e9
0c63c199a8c60e612f2f2aa16a496cbce8494b1933b4a78b39aa69f3f8a645b90e1d30454fd1c0524cd72c4de9131637
09850573b68932ebac73c9b31527bdbed53a3bdaa16fa956fcde388e191594ad88d7094075d1eb3adb338d96b5486c8e
0d6e4c36d65bef64cc68c45f74040cb2e33851a9ddfec6375de6f80441f266138b199800b025ad4557355b3806afb64d
139aa53378e315ddc381e5f35b1bd24556faf8474c40466d938f7ba5799d48f33490b8c8215c5a7bae5d8e63b4ecb74d
12b55817ad4c2c7ebdbec8a83c30c05a0efea4706ef76d0eae1e8a2ce685f7918928592ad452ac96def98251e044afc5
0b32eb7e135c91d3a3078db3edd05ebb3bd451e4e31cf3e814155058f89b0f6241ea418c85d5629c49993850ef2ff08d
19a43892c90119f61d59ab01bdd1077fdef13677c7adafc11198a44dbe5ddcf1565388bc2d5a7fc2a26449a21cc57865
0e1e10146a10fba372756b6b94e84fc25815d45c282a181ae3e36f34d405789787cc3d88fd92616796014c76c075d16c
0041e0dae22ff314d1ef0d7cb2a584da953d18514f6644c6aa3fef304f6e7e7ccac054e8a70bd0aed6962a98b96d0d44

@webmaster128
Copy link
Contributor

Great, thanks. Added the first one in #45. I'd add more if there is test data with some specific properties (e.g. exponent larger than group order). But this should be a great base-line and also work as example code for users.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants