SHA256 (CodeWorker_SRC4_5_3.zip) = b5fdf7b01d280d37b5534fe29890cb21357e11393bcab6f129c1a141485f799f SIZE (CodeWorker_SRC4_5_3.zip) = 3277274 tw44/cgit/dexon-mcl/atom/?h=dev' type='application/atom+xml'/> <link rel='vcs-git' href='https://www.tfcis.org/~lantw44/git/dexon-mcl' title='dexon-mcl Git repository'/> <link rel='vcs-git' href='https://www.lant.com.tw/~lantw44/git/dexon-mcl' title='dexon-mcl Git repository'/> <link rel='vcs-git' href='https://phantom.tfcis.org/~lantw44/git/dexon-mcl' title='dexon-mcl Git repository'/> <link rel='vcs-git' href='https://www.csie.ntu.edu.tw/~b01902062/git/dexon-mcl' title='dexon-mcl Git repository'/> </head> <body> <div id='cgit'><table id='header'> <tr> <td class='logo' rowspan='2'><a href='/~lantw44/cgit/'><img src='/~lantw44/cgit-data/cgit.png' alt='cgit logo'/></a></td> <td class='main'><a href='/~lantw44/cgit/'>index</a> : <a title='dexon-mcl' href='/~lantw44/cgit/dexon-mcl/'>dexon-mcl</a></td><td class='form'><form method='get'> <select name='h' onchange='this.form.submit();'> <option value='dev' selected='selected'>dev</option> <option value='master'>master</option> <option value='sw-encode'>sw-encode</option> </select> <input type='submit' value='switch'/></form></td></tr> <tr><td class='sub'>DEXON fork of mcl (https://github.com/dexon-foundation/mcl)</td><td class='sub right'></td></tr></table> <table class='tabs'><tr><td> <a class='active' href='/~lantw44/cgit/dexon-mcl/about/?h=dev'>about</a><a href='/~lantw44/cgit/dexon-mcl/?h=dev'>summary</a><a href='/~lantw44/cgit/dexon-mcl/refs/?h=dev'>refs</a><a href='/~lantw44/cgit/dexon-mcl/log/?h=dev'>log</a><a href='/~lantw44/cgit/dexon-mcl/tree/?h=dev'>tree</a><a href='/~lantw44/cgit/dexon-mcl/commit/?h=dev'>commit</a><a href='/~lantw44/cgit/dexon-mcl/diff/?h=dev'>diff</a><a href='/~lantw44/cgit/dexon-mcl/stats/?h=dev'>stats</a></td><td class='form'><form class='right' method='get' action='/~lantw44/cgit/dexon-mcl/log/'> <input type='hidden' name='h' value='dev'/><select name='qt'> <option value='grep'>log msg</option> <option value='author'>author</option> <option value='committer'>committer</option> <option value='range'>range</option> </select> <input class='txt' type='search' size='10' name='q' value=''/> <input type='submit' value='search'/> </form> </td></tr></table> <div class='content'><div id='summary'> <style> .markdown-body { font-size: 14px; line-height: 1.6; overflow: hidden; } .markdown-body>*:first-child { margin-top: 0 !important; } .markdown-body>*:last-child { margin-bottom: 0 !important; } .markdown-body a.absent { color: #c00; } .markdown-body a.anchor { display: block; padding-left: 30px; margin-left: -30px; cursor: pointer; position: absolute; top: 0; left: 0; bottom: 0; } .markdown-body h1, .markdown-body h2, .markdown-body h3, .markdown-body h4, .markdown-body h5, .markdown-body h6 { margin: 20px 0 10px; padding: 0; font-weight: bold; -webkit-font-smoothing: antialiased; cursor: text; position: relative; } .markdown-body h1 .mini-icon-link, .markdown-body h2 .mini-icon-link, .markdown-body h3 .mini-icon-link, .markdown-body h4 .mini-icon-link, .markdown-body h5 .mini-icon-link, .markdown-body h6 .mini-icon-link { display: none; color: #000; } .markdown-body h1:hover a.anchor, .markdown-body h2:hover a.anchor, .markdown-body h3:hover a.anchor, .markdown-body h4:hover a.anchor, .markdown-body h5:hover a.anchor, .markdown-body h6:hover a.anchor { text-decoration: none; line-height: 1; padding-left: 0; margin-left: -22px; top: 15%; } .markdown-body h1:hover a.anchor .mini-icon-link, .markdown-body h2:hover a.anchor .mini-icon-link, .markdown-body h3:hover a.anchor .mini-icon-link, .markdown-body h4:hover a.anchor .mini-icon-link, .markdown-body h5:hover a.anchor .mini-icon-link, .markdown-body h6:hover a.anchor .mini-icon-link { display: inline-block; } div#cgit .markdown-body h1 a.toclink, div#cgit .markdown-body h2 a.toclink, div#cgit .markdown-body h3 a.toclink, div#cgit .markdown-body h4 a.toclink, div#cgit .markdown-body h5 a.toclink, div#cgit .markdown-body h6 a.toclink { color: black; } .markdown-body h1 tt, .markdown-body h1 code, .markdown-body h2 tt, .markdown-body h2 code, .markdown-body h3 tt, .markdown-body h3 code, .markdown-body h4 tt, .markdown-body h4 code, .markdown-body h5 tt, .markdown-body h5 code, .markdown-body h6 tt, .markdown-body h6 code { font-size: inherit; } .markdown-body h1 { font-size: 28px; color: #000; } .markdown-body h2 { font-size: 24px; border-bottom: 1px solid #ccc; color: #000; } .markdown-body h3 { font-size: 18px; } .markdown-body h4 { font-size: 16px; } .markdown-body h5 { font-size: 14px; } .markdown-body h6 { color: #777; font-size: 14px; } .markdown-body p, .markdown-body blockquote, .markdown-body ul, .markdown-body ol, .markdown-body dl, .markdown-body table, .markdown-body pre { margin: 15px 0; } .markdown-body hr { background: transparent url("/dirty-shade.png") repeat-x 0 0; border: 0 none; color: #ccc; height: 4px; padding: 0; } .markdown-body>h2:first-child, .markdown-body>h1:first-child, .markdown-body>h1:first-child+h2, .markdown-body>h3:first-child, .markdown-body>h4:first-child, .markdown-body>h5:first-child, .markdown-body>h6:first-child { margin-top: 0; padding-top: 0; } .markdown-body a:first-child h1, .markdown-body a:first-child h2, .markdown-body a:first-child h3, .markdown-body a:first-child h4, .markdown-body a:first-child h5, .markdown-body a:first-child h6 { margin-top: 0; padding-top: 0; } .markdown-body h1+p, .markdown-body h2+p, .markdown-body h3+p, .markdown-body h4+p, .markdown-body h5+p, .markdown-body h6+p { margin-top: 0; } .markdown-body li p.first { display: inline-block; } .markdown-body ul, .markdown-body ol { padding-left: 30px; } .markdown-body ul.no-list, .markdown-body ol.no-list { list-style-type: none; padding: 0; } .markdown-body ul li>:first-child, .markdown-body ul li ul:first-of-type, .markdown-body ul li ol:first-of-type, .markdown-body ol li>:first-child, .markdown-body ol li ul:first-of-type, .markdown-body ol li ol:first-of-type { margin-top: 0px; } .markdown-body ul li p:last-of-type, .markdown-body ol li p:last-of-type { margin-bottom: 0; } .markdown-body ul ul, .markdown-body ul ol, .markdown-body ol ol, .markdown-body ol ul { margin-bottom: 0; } .markdown-body dl { padding: 0; } .markdown-body dl dt { font-size: 14px; font-weight: bold; font-style: italic; padding: 0; margin: 15px 0 5px; } .markdown-body dl dt:first-child { padding: 0; } .markdown-body dl dt>:first-child { margin-top: 0px; } .markdown-body dl dt>:last-child { margin-bottom: 0px; } .markdown-body dl dd { margin: 0 0 15px; padding: 0 15px; } .markdown-body dl dd>:first-child { margin-top: 0px; } .markdown-body dl dd>:last-child { margin-bottom: 0px; } .markdown-body blockquote { border-left: 4px solid #DDD; padding: 0 15px; color: #777; } .markdown-body blockquote>:first-child { margin-top: 0px; } .markdown-body blockquote>:last-child { margin-bottom: 0px; } .markdown-body table th { font-weight: bold; } .markdown-body table th, .markdown-body table td { border: 1px solid #ccc; padding: 6px 13px; } .markdown-body table tr { border-top: 1px solid #ccc; background-color: #fff; } .markdown-body table tr:nth-child(2n) { background-color: #f8f8f8; } .markdown-body img { max-width: 100%; -moz-box-sizing: border-box; box-sizing: border-box; } .markdown-body span.frame { display: block; overflow: hidden; } .markdown-body span.frame>span { border: 1px solid #ddd; display: block; float: left; overflow: hidden; margin: 13px 0 0; padding: 7px; width: auto; } .markdown-body span.frame span img { display: block; float: left; } .markdown-body span.frame span span { clear: both; color: #333; display: block; padding: 5px 0 0; } .markdown-body span.align-center { display: block; overflow: hidden; clear: both; } .markdown-body span.align-center>span { display: block; overflow: hidden; margin: 13px auto 0; text-align: center; } .markdown-body span.align-center span img { margin: 0 auto; text-align: center; } .markdown-body span.align-right { display: block; overflow: hidden; clear: both; } .markdown-body span.align-right>span { display: block; overflow: hidden; margin: 13px 0 0; text-align: right; } .markdown-body span.align-right span img { margin: 0; text-align: right; } .markdown-body span.float-left { display: block; margin-right: 13px; overflow: hidden; float: left; } .markdown-body span.float-left span { margin: 13px 0 0; } .markdown-body span.float-right { display: block; margin-left: 13px; overflow: hidden; float: right; } .markdown-body span.float-right>span { display: block; overflow: hidden; margin: 13px auto 0; text-align: right; } .markdown-body code, .markdown-body tt { margin: 0 2px; padding: 0px 5px; border: 1px solid #eaeaea; background-color: #f8f8f8; border-radius: 3px; } .markdown-body code { white-space: nowrap; } .markdown-body pre>code { margin: 0; padding: 0; white-space: pre; border: none; background: transparent; } .markdown-body .highlight pre, .markdown-body pre { background-color: #f8f8f8; border: 1px solid #ccc; font-size: 13px; line-height: 19px; overflow: auto; padding: 6px 10px; border-radius: 3px; } .markdown-body pre code, .markdown-body pre tt { margin: 0; padding: 0; background-color: transparent; border: none; } pre { line-height: 125%; } td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } .highlight .hll { background-color: #ffffcc } .highlight { background: #ffffff; } .highlight .c { color: #888888 } /* Comment */ .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ .highlight .k { color: #008800; font-weight: bold } /* Keyword */ .highlight .ch { color: #888888 } /* Comment.Hashbang */ .highlight .cm { color: #888888 } /* Comment.Multiline */ .highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ .highlight .cpf { color: #888888 } /* Comment.PreprocFile */ .highlight .c1 { color: #888888 } /* Comment.Single */ .highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */ </style> <div class='markdown-body'><p><a href="https://travis-ci.org/herumi/mcl"><img alt="Build Status" src="https://travis-ci.org/herumi/mcl.png"></a></p> <h1 id="mcl"><a class="toclink" href="#mcl">mcl</a></h1> <p>A portable and fast pairing-based cryptography library.</p> <h1 id="abstract"><a class="toclink" href="#abstract">Abstract</a></h1> <p>mcl is a library for pairing-based cryptography. The current version supports the optimal Ate pairing over BN curves and BLS12-381 curves.</p> <h1 id="news"><a class="toclink" href="#news">News</a></h1> <ul> <li>(Break backward compatibility) libmcl_dy.a is renamed to libmcl.a<ul> <li>The option SHARE_BASENAME_SUF is removed</li> </ul> </li> <li>2nd argument of <code>mclBn_init</code> is changed from <code>maxUnitSize</code> to <code>compiledTimeVar</code>, which must be <code>MCLBN_COMPILED_TIME_VAR</code>.</li> <li>break backward compatibility of mapToGi for BLS12. A map-to-function for BN is used. If <code>MCL_USE_OLD_MAPTO_FOR_BLS12</code> is defined, then the old function is used, but this will be removed in the future.</li> </ul> <h1 id="support-architecture"><a class="toclink" href="#support-architecture">Support architecture</a></h1> <ul> <li>x86-64 Windows + Visual Studio</li> <li>x86, x86-64 Linux + gcc/clang</li> <li>ARM Linux</li> <li>ARM64 Linux</li> <li>(maybe any platform to be supported by LLVM)</li> <li>WebAssembly</li> </ul> <h1 id="support-curves"><a class="toclink" href="#support-curves">Support curves</a></h1> <p>p(z) = 36z^4 + 36z^3 + 24z^2 + 6z + 1.</p> <ul> <li>BN254 ; a BN curve over the 254-bit prime p(z) where z = -(2^62 + 2^55 + 1).</li> <li>BN_SNARK1 ; a BN curve over a 254-bit prime p such that n := p + 1 - t has high 2-adicity.</li> <li>BN381_1 ; a BN curve over the 381-bit prime p(z) where z = -(2^94 + 2^76 + 2^72 + 1).</li> <li>BN462 ; a BN curve over the 462-bit prime p(z) where z = 2^114 + 2^101 - 2^14 - 1.</li> <li>BLS12_381 ; <a href="https://blog.z.cash/new-snark-curve/">a BLS12-381 curve</a></li> </ul> <h1 id="benchmark"><a class="toclink" href="#benchmark">Benchmark</a></h1> <h2 id="the-latest-benchmark2018117"><a class="toclink" href="#the-latest-benchmark2018117">The latest benchmark(2018/11/7)</a></h2> <h3 id="intel-core-i7-6700-34ghzskylake-ubuntu-18041-lts"><a class="toclink" href="#intel-core-i7-6700-34ghzskylake-ubuntu-18041-lts">Intel Core i7-6700 3.4GHz(Skylake), Ubuntu 18.04.1 LTS</a></h3> <table> <thead> <tr> <th>curveType</th> <th>binary</th> <th>clang-6.0.0</th> <th>gcc-7.3.0</th> </tr> </thead> <tbody> <tr> <td>BN254</td> <td>bin/bn_test.exe</td> <td>882Kclk</td> <td>933Kclk</td> </tr> <tr> <td>BLS12-381</td> <td>bin/bls12_test.exe</td> <td>2290Kclk</td> <td>2630Kclk</td> </tr> </tbody> </table> <h3 id="intel-core-i7-7700-36ghzkaby-lake-ubuntu-18041-lts-on-windows-10-vmware"><a class="toclink" href="#intel-core-i7-7700-36ghzkaby-lake-ubuntu-18041-lts-on-windows-10-vmware">Intel Core i7-7700 3.6GHz(Kaby Lake), Ubuntu 18.04.1 LTS on Windows 10 Vmware</a></h3> <table> <thead> <tr> <th>curveType</th> <th>binary</th> <th>clang-6.0.0</th> <th>gcc-7.3.0</th> </tr> </thead> <tbody> <tr> <td>BN254</td> <td>bin/bn_test.exe</td> <td>900Kclk</td> <td>954Kclk</td> </tr> <tr> <td>BLS12-381</td> <td>bin/bls12_test.exe</td> <td>2340Kclk</td> <td>2680Kclk</td> </tr> </tbody> </table> <ul> <li>now investigating the reason why gcc is slower than clang.</li> </ul> <h2 id="higher-bit-bn-curve-benchmark"><a class="toclink" href="#higher-bit-bn-curve-benchmark">Higher-bit BN curve benchmark</a></h2> <p>For JavaScript(WebAssembly), see <a href="https://herumi.github.io/mcl-wasm/ibe-demo.html">ID based encryption demo</a>.</p> <table> <thead> <tr> <th>paramter</th> <th>x64</th> <th>Firefox on x64</th> <th>Safari on iPhone7</th> </tr> </thead> <tbody> <tr> <td>BN254</td> <td>0.25</td> <td>2.48</td> <td>4.78</td> </tr> <tr> <td>BN381_1</td> <td>0.95</td> <td>7.91</td> <td>11.74</td> </tr> <tr> <td>BN462</td> <td>2.16</td> <td>14.73</td> <td>22.77</td> </tr> </tbody> </table> <ul> <li>x64 : 'Kaby Lake Core i7-7700(3.6GHz)'.</li> <li>Firefox : 64-bit version 58.</li> <li>iPhone7 : iOS 11.2.1.</li> <li>BN254 is by <code>test/bn_test.cpp</code>.</li> <li>BN381_1 and BN462 are by <code>test/bn512_test.cpp</code>.</li> <li>All the timings are given in ms(milliseconds).</li> </ul> <p>The other benchmark results are <a href="bench.txt">bench.txt</a>.</p> <h2 id="an-old-benchmark-of-a-bn-curve-bn25420161225"><a class="toclink" href="#an-old-benchmark-of-a-bn-curve-bn25420161225">An old benchmark of a BN curve BN254(2016/12/25).</a></h2> <ul> <li>x64, x86 ; Inte Core i7-6700 3.4GHz(Skylake) upto 4GHz on Ubuntu 16.04.<ul> <li><code>sudo cpufreq-set -g performance</code></li> </ul> </li> <li>arm ; 900MHz quad-core ARM Cortex-A7 on Raspberry Pi2, Linux 4.4.11-v7+</li> <li>arm64 ; 1.2GHz ARM Cortex-A53 <a href="http://www.96boards.org/product/hikey/">HiKey</a></li> </ul> <table> <thead> <tr> <th>software</th> <th>x64</th> <th>x86</th> <th>arm</th> <th>arm64(msec)</th> </tr> </thead> <tbody> <tr> <td><a href="https://github.com/herumi/ate-pairing">ate-pairing</a></td> <td>0.21</td> <td>-</td> <td>-</td> <td>-</td> </tr> <tr> <td>mcl</td> <td>0.31</td> <td>1.6</td> <td>22.6</td> <td>3.9</td> </tr> <tr> <td><a href="http://www.cipher.risk.tsukuba.ac.jp/tepla/">TEPLA</a></td> <td>1.76</td> <td>3.7</td> <td>37</td> <td>17.9</td> </tr> <tr> <td><a href="https://github.com/relic-toolkit/relic">RELIC</a> PRIME=254</td> <td>0.30</td> <td>3.5</td> <td>36</td> <td>-</td> </tr> <tr> <td><a href="https://github.com/miracl/MIRACL">MIRACL</a> ake12bnx</td> <td>4.2</td> <td>-</td> <td>78</td> <td>-</td> </tr> <tr> <td><a href="http://sandia.cs.cinvestav.mx/Site/NEONabe">NEONabe</a></td> <td>-</td> <td>-</td> <td>16</td> <td>-</td> </tr> </tbody> </table> <ul> <li>compile option for RELIC</li> </ul> <div class="highlight"><pre><span></span><code>cmake -DARITH=x64-asm-254 -DFP_PRIME=254 -DFPX_METHD="INTEG;INTEG;LAZYR" -DPP_METHD="LAZYR;OATEP" </code></pre></div> <h1 id="installation-requirements"><a class="toclink" href="#installation-requirements">Installation Requirements</a></h1> <ul> <li><a href="https://gmplib.org/">GMP</a> and OpenSSL</li> </ul> <div class="highlight"><pre><span></span><code>apt install libgmp-dev libssl-dev </code></pre></div> <p>Create a working directory (e.g., work) and clone the following repositories.</p> <div class="highlight"><pre><span></span><code><span class="nt">mkdir</span><span class="w"> </span><span class="nt">work</span> <span class="nt">cd</span><span class="w"> </span><span class="nt">work</span> <span class="nt">git</span><span class="w"> </span><span class="nt">clone</span><span class="w"> </span><span class="nt">git</span><span class="o">://</span><span class="nt">github</span><span class="p">.</span><span class="nc">com</span><span class="o">/</span><span class="nt">herumi</span><span class="o">/</span><span class="nt">mcl</span> <span class="nt">git</span><span class="w"> </span><span class="nt">clone</span><span class="w"> </span><span class="nt">git</span><span class="o">://</span><span class="nt">github</span><span class="p">.</span><span class="nc">com</span><span class="o">/</span><span class="nt">herumi</span><span class="o">/</span><span class="nt">cybozulib_ext</span><span class="w"> </span><span class="o">;</span><span class="w"> </span><span class="nt">for</span><span class="w"> </span><span class="nt">only</span><span class="w"> </span><span class="nt">Windows</span> </code></pre></div> <ul> <li>Cybozulib_ext is a prerequisite for running OpenSSL and GMP on VC (Visual C++).</li> </ul> <h1 id="option-without-gmp"><a class="toclink" href="#option-without-gmp">(Option) Without GMP</a></h1> <div class="highlight"><pre><span></span><code>make MCL_USE_GMP=0 </code></pre></div> <p>Define <code>MCL_USE_VINT</code> before including <code>bn.hpp</code></p> <h1 id="option-without-openssl"><a class="toclink" href="#option-without-openssl">(Option) Without Openssl</a></h1> <div class="highlight"><pre><span></span><code>make MCL_USE_OPENSSL=0 </code></pre></div> <p>Define <code>MCL_DONT_USE_OPENSSL</code> before including <code>bn.hpp</code></p> <h1 id="build-and-test-on-x86-64-linux-macos-arm-and-arm64-linux"><a class="toclink" href="#build-and-test-on-x86-64-linux-macos-arm-and-arm64-linux">Build and test on x86-64 Linux, macOS, ARM and ARM64 Linux</a></h1> <p>To make lib/libmcl.a and test it:</p> <div class="highlight"><pre><span></span><code>cd work/mcl make test </code></pre></div> <p>To benchmark a pairing:</p> <div class="highlight"><pre><span></span><code>bin/bn_test.exe </code></pre></div> <p>To make sample programs:</p> <div class="highlight"><pre><span></span><code>make sample </code></pre></div> <p>if you want to change compiler options for optimization, then set <code>CFLAGS_OPT_USER</code>.</p> <div class="highlight"><pre><span></span><code>make CLFAGS_OPT_USER="-O2" </code></pre></div> <h2 id="build-for-32-bit-linux"><a class="toclink" href="#build-for-32-bit-linux">Build for 32-bit Linux</a></h2> <p>Build openssl and gmp for 32-bit mode and install <code><lib32></code></p> <div class="highlight"><pre><span></span><code>make ARCH=x86 CFLAGS_USER="-I <lib32>/include" LDFLAGS_USER="-L <lib32>/lib -Wl,-rpath,<lib32>/lib" </code></pre></div> <h2 id="build-for-64-bit-windows"><a class="toclink" href="#build-for-64-bit-windows">Build for 64-bit Windows</a></h2> <p>1) make static library and use it</p> <div class="highlight"><pre><span></span><code>mklib mk -s test\bn_c256_test.cpp bin\bn_c256_test.exe </code></pre></div> <p>2) make dynamic library and use it</p> <div class="highlight"><pre><span></span><code>mklib dll mk -d test\bn_c256_test.cpp bin\bn_c256_test.exe </code></pre></div> <p>open mcl.sln and build or if you have msbuild.exe</p> <div class="highlight"><pre><span></span><code>msbuild /p:Configuration=Release </code></pre></div> <h2 id="build-with-cmake"><a class="toclink" href="#build-with-cmake">Build with cmake</a></h2> <p>For Linux,</p> <div class="highlight"><pre><span></span><code>mkdir build cd build cmake .. make </code></pre></div> <p>For Visual Studio,</p> <div class="highlight"><pre><span></span><code>mkdir build cd build cmake .. -A x64 msbuild mcl.sln /p:Configuration=Release /m </code></pre></div> <h2 id="build-for-wasmwebassembly"><a class="toclink" href="#build-for-wasmwebassembly">Build for wasm(WebAssembly)</a></h2> <p>mcl supports emcc (Emscripten) and <code>test/bn_test.cpp</code> runs on browers such as Firefox, Chrome and Edge.</p> <ul> <li><a href="https://herumi.github.io/mcl-wasm/ibe-demo.html">IBE on browser</a></li> <li><a href="https://herumi.github.io/she-wasm/she-demo.html">SHE on browser</a></li> <li><a href="https://herumi.github.io/bls-wasm/bls-demo.html">BLS signature on brower</a></li> </ul> <p>The timing of a pairing on <code>BN254</code> is 2.8msec on 64-bit Firefox with Skylake 3.4GHz.</p> <h3 id="nodejs"><a class="toclink" href="#nodejs">Node.js</a></h3> <ul> <li><a href="https://www.npmjs.com/package/mcl-wasm">mcl-wasm</a> pairing library</li> <li><a href="https://www.npmjs.com/package/bls-wasm">bls-wasm</a> BLS signature library</li> <li><a href="https://www.npmjs.com/package/she-wasm">she-wasm</a> 2 Level Homomorphic Encryption library</li> </ul> <h3 id="selinux"><a class="toclink" href="#selinux">SELinux</a></h3> <p>mcl uses Xbyak JIT engine if it is available on x64 architecture, otherwise mcl uses a little slower functions generated by LLVM. The default mode enables SELinux security policy on CentOS, then JIT is disabled.</p> <div class="highlight"><pre><span></span><code><span class="c">% sudo setenforce 1</span> <span class="c">% getenforce</span> <span class="n">Enforcing</span> <span class="s">%</span><span class="w"> </span><span class="s">bin/bn_test.exe</span> <span class="n">JIT</span><span class="w"> </span><span class="s">0</span> <span class="n">pairing</span><span class="w"> </span><span class="s">1.496Mclk</span> <span class="n">finalExp</span><span class="w"> </span><span class="s">581.081Kclk</span> <span class="c">% sudo setenforce 0</span> <span class="c">% getenforce</span> <span class="n">Permissive</span> <span class="s">%</span><span class="w"> </span><span class="s">bin/bn_test.exe</span> <span class="n">JIT</span><span class="w"> </span><span class="s">1</span> <span class="n">pairing</span><span class="w"> </span><span class="s">1.394Mclk</span> <span class="n">finalExp</span><span class="w"> </span><span class="s">546.259Kclk</span> </code></pre></div> <h1 id="libraries"><a class="toclink" href="#libraries">Libraries</a></h1> <ul> <li>G1 and G2 is defined over Fp</li> <li>The order of G1 and G2 is r.</li> <li>Use <code>bn256.hpp</code> if only BN254 is used.</li> </ul> <h2 id="c-library"><a class="toclink" href="#c-library">C++ library</a></h2> <ul> <li>libmcl.a ; static C++ library of mcl</li> <li>libmcl.so ; shared C++ library of mcl</li> <li>the default parameter of curveType is BN254</li> </ul> <table> <thead> <tr> <th>header</th> <th>support curveType</th> <th>sizeof Fr</th> <th>sizeof Fp</th> </tr> </thead> <tbody> <tr> <td>bn256.hpp</td> <td>BN254</td> <td>32</td> <td>32</td> </tr> <tr> <td>bls12_381.hpp</td> <td>BLS12_381, BN254</td> <td>32</td> <td>48</td> </tr> <tr> <td>bn384.hpp</td> <td>BN381_1, BLS12_381, BN254</td> <td>48</td> <td>48</td> </tr> </tbody> </table> <h2 id="c-library_1"><a class="toclink" href="#c-library_1">C library</a></h2> <ul> <li>Define <code>MCLBN_FR_UNIT_SIZE</code> and <code>MCLBN_FP_UNIT_SIZE</code> and include bn.h</li> <li>set <code>MCLBN_FR_UNIT_SIZE = MCLBN_FP_UNIT_SIZE</code> unless <code>MCLBN_FR_UNIT_SIZE</code> is defined</li> </ul> <table> <thead> <tr> <th>library</th> <th>MCLBN_FR_UNIT_SIZE</th> <th>MCLBN_FP_UNIT_SIZE</th> </tr> </thead> <tbody> <tr> <td>sizeof</td> <td>Fr</td> <td>Fp</td> </tr> <tr> <td>libmclbn256.a</td> <td>4</td> <td>4</td> </tr> <tr> <td>libmclbn384_256.a</td> <td>4</td> <td>6</td> </tr> <tr> <td>libmclbn384.a</td> <td>6</td> <td>6</td> </tr> </tbody> </table> <ul> <li>libmclbn*.a ; static C library</li> <li>libmclbn*.so ; shared C library</li> </ul> <h3 id="2nd-argument-of-mclbn_init"><a class="toclink" href="#2nd-argument-of-mclbn_init">2nd argument of <code>mclBn_init</code></a></h3> <p>Specify <code>MCLBN_COMPILED_TIME_VAR</code> to 2nd argument of <code>mclBn_init</code>, which is defined as <code>MCLBN_FR_UNIT_SIZE * 10 + MCLBN_FP_UNIT_SIZE</code>. This parameter is used to make sure that the values are the same when the library is built and used.</p> <h1 id="how-to-initialize-pairing-library"><a class="toclink" href="#how-to-initialize-pairing-library">How to initialize pairing library</a></h1> <p>Call <code>mcl::bn256::initPairing</code> before calling any operations.</p> <div class="highlight"><pre><span></span><code><span class="cp">#include</span><span class="w"> </span><span class="cpf"><mcl/bn256.hpp></span> <span class="n">mcl</span><span class="o">::</span><span class="n">bn</span><span class="o">::</span><span class="n">CurveParam</span><span class="w"> </span><span class="n">cp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">mcl</span><span class="o">::</span><span class="n">BN254</span><span class="p">;</span><span class="w"> </span><span class="c1">// or mcl::BN_SNARK1</span> <span class="n">mcl</span><span class="o">::</span><span class="n">bn256</span><span class="o">::</span><span class="n">initPairing</span><span class="p">(</span><span class="n">cp</span><span class="p">);</span> <span class="n">mcl</span><span class="o">::</span><span class="n">bn256</span><span class="o">::</span><span class="n">G1</span><span class="w"> </span><span class="nf">P</span><span class="p">(...);</span> <span class="n">mcl</span><span class="o">::</span><span class="n">bn256</span><span class="o">::</span><span class="n">G2</span><span class="w"> </span><span class="nf">Q</span><span class="p">(...);</span> <span class="n">mcl</span><span class="o">::</span><span class="n">bn256</span><span class="o">::</span><span class="n">Fp12</span><span class="w"> </span><span class="n">e</span><span class="p">;</span> <span class="n">mcl</span><span class="o">::</span><span class="n">bn256</span><span class="o">::</span><span class="n">pairing</span><span class="p">(</span><span class="n">e</span><span class="p">,</span><span class="w"> </span><span class="n">P</span><span class="p">,</span><span class="w"> </span><span class="n">Q</span><span class="p">);</span> </code></pre></div> <ol> <li>(BN254) a BN curve over the 254-bit prime p = p(z) where z = -(2^62 + 2^55 + 1).</li> <li>(BN_SNARK1) a BN curve over a 254-bit prime p such that n := p + 1 - t has high 2-adicity.</li> <li>BN381_1 with <code>mcl/bn384.hpp</code>.</li> <li>BN462 with <code>mcl/bn512.hpp</code>.</li> </ol> <p>See <a href="https://github.com/herumi/mcl/blob/master/test/bn_test.cpp">test/bn_test.cpp</a>.</p> <h2 id="default-constructor-of-fp-ec-etc"><a class="toclink" href="#default-constructor-of-fp-ec-etc">Default constructor of Fp, Ec, etc.</a></h2> <p>A default constructor does not initialize the instance. Set a valid value before reffering it.</p> <h2 id="definition-of-groups"><a class="toclink" href="#definition-of-groups">Definition of groups</a></h2> <p>The curve equation for a BN curve is:</p> <div class="highlight"><pre><span></span><code>E/Fp: y^2 = x^3 + b . </code></pre></div> <ul> <li>the cyclic group G1 is instantiated as E(Fp)[n] where n := p + 1 - t;</li> <li>the cyclic group G2 is instantiated as the inverse image of E'(Fp^2)[n] under a twisting isomorphism phi from E' to E; and</li> <li>the pairing e: G1 x G2 -> Fp12 is the optimal ate pairing.</li> </ul> <p>The field Fp12 is constructed via the following tower:</p> <ul> <li>Fp2 = Fp[u] / (u^2 + 1)</li> <li>Fp6 = Fp2[v] / (v^3 - Xi) where Xi = u + 1</li> <li>Fp12 = Fp6[w] / (w^2 - v)</li> <li>GT = { x in Fp12 | x^r = 1 }</li> </ul> <h2 id="arithmetic-operations"><a class="toclink" href="#arithmetic-operations">Arithmetic operations</a></h2> <p>G1 and G2 is additive group and has the following operations:</p> <ul> <li>T::add(T& z, const T& x, const T& y); // z = x + y</li> <li>T::sub(T& z, const T& x, const T& y); // z = x - y</li> <li>T::neg(T& y, const T& x); // y = -x</li> <li>T::mul(T& z, const T& x, const INT& y); // z = y times scalar multiplication of x</li> </ul> <p>Remark: &z == &x or &y are allowed. INT means integer type such as Fr, int and mpz_class.</p> <p><code>T::mul</code> uses GLV method then <code>G2::mul</code> returns wrong value if x is not in G2. Use <code>T::mulGeneric(T& z, const T& x, const INT& y)</code> for x in phi^-1(E'(Fp^2)) - G2.</p> <p>Fp, Fp2, Fp6 and Fp12 have the following operations:</p> <ul> <li>T::add(T& z, const T& x, const T& y); // z = x + y</li> <li>T::sub(T& z, const T& x, const T& y); // z = x - y</li> <li>T::mul(T& z, const T& x, const T& y); // z = x * y</li> <li>T::div(T& z, const T& x, const T& y); // z = x / y</li> <li>T::neg(T& y, const T& x); // y = -x</li> <li>T::inv(T& y, const T& x); // y = 1/x</li> <li>T::pow(T& z, const T& x, const INT& y); // z = x^y</li> <li>Fp12::unitaryInv(T& y, const T& x); // y = conjugate of x</li> </ul> <p>Remark: <code>Fp12::mul</code> uses GLV method then returns wrong value if x is not in GT. Use <code>Fp12::mulGeneric</code> for x in Fp12 - GT.</p> <h2 id="map-to-points"><a class="toclink" href="#map-to-points">Map To points</a></h2> <p>Use these functions to make a point of G1 and G2.</p> <ul> <li>mapToG1(G1& P, const Fp& x); // assume x != 0</li> <li>mapToG2(G2& P, const Fp2& x);</li> <li>hashAndMapToG1(G1& P, const void *buf, size_t bufSize); // set P by the hash value of [buf, bufSize)</li> <li>hashAndMapToG2(G2& P, const void *buf, size_t bufSize);</li> </ul> <p>These functions maps x into Gi according to [[<em>Faster hashing to G2</em>]].</p> <h2 id="string-format-of-g1-and-g2"><a class="toclink" href="#string-format-of-g1-and-g2">String format of G1 and G2</a></h2> <p>G1 and G2 have three elements of Fp (x, y, z) for Jacobi coordinate. normalize() method normalizes it to affine coordinate (x, y, 1) or (0, 0, 0).</p> <p>getStr() method gets</p> <ul> <li><code>0</code> ; infinity</li> <li><code>1 <x> <y></code> ; not compressed format</li> <li><code>2 <x></code> ; compressed format for even y</li> <li><code>3 <x></code> ; compressed format for odd y</li> </ul> <h2 id="generator-of-g1-and-g2"><a class="toclink" href="#generator-of-g1-and-g2">Generator of G1 and G2</a></h2> <p>If you want to use the same generators of BLS12-381 with <a href="https://github.com/zkcrypto/pairing/tree/master/src/bls12_381#g2">zkcrypto</a> then,</p> <div class="highlight"><pre><span></span><code><span class="c1">// G1 P</span> <span class="n">P</span><span class="p">.</span><span class="n">setStr</span><span class="p">(</span><span class="s">'1 3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569'</span><span class="p">)</span> <span class="c1">// G2 Q</span> <span class="n">Q</span><span class="p">.</span><span class="n">setStr</span><span class="p">(</span><span class="s">'1 352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160 3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758 1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905 927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582'</span><span class="p">)</span> </code></pre></div> <h2 id="serialization-format-of-g1-and-g2"><a class="toclink" href="#serialization-format-of-g1-and-g2">Serialization format of G1 and G2</a></h2> <p>pseudo-code to serialize of p</p> <div class="highlight"><pre><span></span><code>if bit-length(p) % 8 != 0: size = Fp::getByteSize() if p is zero: return [0] <span class="gs">* size</span> <span class="gs"> else:</span> <span class="gs"> s = x.serialize()</span> <span class="gs"> # x in Fp2 is odd <=> x.a is odd</span> <span class="gs"> if y is odd:</span> <span class="gs"> s[byte-length(s) - 1] |= 0x80</span> <span class="gs"> return s</span> <span class="gs">else:</span> <span class="gs"> size = Fp::getByteSize() + 1</span> <span class="gs"> if p is zero:</span> <span class="gs"> return [0] *</span> size else: s = x.serialize() if y is odd: return 2:s else: return 3:s </code></pre></div> <h2 id="verify-an-element-in-g2"><a class="toclink" href="#verify-an-element-in-g2">Verify an element in G2</a></h2> <p><code>G2::isValid()</code> checks that the element is in the curve of G2 and the order of it is r for subgroup attack. <code>G2::set()</code>, <code>G2::setStr</code> and <code>operator<<</code> also check the order. If you check it out of the library, then you can stop the verification by calling <code>G2::verifyOrderG2(false)</code>.</p> <h1 id="how-to-make-asm-files-optional"><a class="toclink" href="#how-to-make-asm-files-optional">How to make asm files (optional)</a></h1> <p>The asm files generated by this way are already put in <code>src/asm</code>, then it is not necessary to do this.</p> <p>Install <a href="http://llvm.org/">LLVM</a>.</p> <div class="highlight"><pre><span></span><code>make MCL_USE_LLVM=1 LLVM_VER=<llvm-version> UPDATE_ASM=1 </code></pre></div> <p>For example, specify <code>-3.8</code> for <code><llvm-version></code> if <code>opt-3.8</code> and <code>llc-3.8</code> are installed.</p> <p>If you want to use Fp with 1024-bit prime on x86-64, then</p> <div class="highlight"><pre><span></span><code>make MCL_USE_LLVM=1 LLVM_VER=<llvm-version> UPDATE_ASM=1 MCL_MAX_BIT_SIZE=1024 </code></pre></div> <h1 id="api-for-two-level-homomorphic-encryption"><a class="toclink" href="#api-for-two-level-homomorphic-encryption">API for Two level homomorphic encryption</a></h1> <ul> <li><a href="https://dl.acm.org/citation.cfm?doid=3196494.3196552"><em>Efficient Two-level Homomorphic Encryption in Prime-order Bilinear Groups and A Fast Implementation in WebAssembly</em></a>, N. Attrapadung, G. Hanaoka, S. Mitsunari, Y. Sakai, K. Shimizu, and T. Teruya. ASIACCS 2018</li> <li><a href="https://github.com/herumi/mcl/blob/master/misc/she/she-api.md">she-api</a></li> <li><a href="https://github.com/herumi/mcl/blob/master/misc/she/she-api-ja.md">she-api(Japanese)</a></li> </ul> <h1 id="java-api"><a class="toclink" href="#java-api">Java API</a></h1> <p>See <a href="https://github.com/herumi/mcl/blob/master/java/java.md">java.md</a></p> <h1 id="license"><a class="toclink" href="#license">License</a></h1> <p>modified new BSD License http://opensource.org/licenses/BSD-3-Clause</p> <p>This library contains some part of the followings software licensed by BSD-3-Clause. * <a href="https://github.com/heurmi/xbyak">xbyak</a> * <a href="https://github.com/heurmi/cybozulib">cybozulib</a> * <a href="https://github.com/aistcrypt/Lifted-ElGamal">Lifted-ElGamal</a></p> <h1 id="references"><a class="toclink" href="#references">References</a></h1> <ul> <li><a href="https://github.com/herumi/ate-pairing/">ate-pairing</a></li> <li><a href="http://dx.doi.org/10.1007/978-3-642-20465-4_5"><em>Faster Explicit Formulas for Computing Pairings over Ordinary Curves</em></a>, D.F. Aranha, K. Karabina, P. Longa, C.H. Gebotys, J. Lopez, EUROCRYPTO 2011, (<a href="http://eprint.iacr.org/2010/526">preprint</a>)</li> <li><a href="http://dx.doi.org/10.1007/978-3-642-17455-1_2"><em>High-Speed Software Implementation of the Optimal Ate Pairing over Barreto-Naehrig Curves</em></a>, Jean-Luc Beuchat, Jorge Enrique González Díaz, Shigeo Mitsunari, Eiji Okamoto, Francisco Rodríguez-Henríquez, Tadanori Teruya, Pairing 2010, (<a href="http://eprint.iacr.org/2010/354">preprint</a>)</li> <li><a href="http://dx.doi.org/10.1007/978-3-642-28496-0_25"><em>Faster hashing to G2</em></a>,Laura Fuentes-Castañeda, Edward Knapp, Francisco Rodríguez-Henríquez, SAC 2011, (<a href="https://eprint.iacr.org/2008/530">preprint</a>)</li> <li><a href="https://www.researchgate.net/publication/221282560_Skew_Frobenius_Map_and_Efficient_Scalar_Multiplication_for_Pairing-Based_Cryptography"><em>Skew Frobenius Map and Efficient Scalar Multiplication for Pairing–Based Cryptography</em></a>, Y. Sakemi, Y. Nogami, K. Okeya, Y. Morikawa, CANS 2008.</li> </ul> <h1 id="history"><a class="toclink" href="#history">History</a></h1> <ul> <li>2019/Mar/22 v0.92 shortcut for Ec::mul(Px, P, x) if P = 0</li> <li>2019/Mar/21 python binding of she256 for Linux/Mac/Windows</li> <li>2019/Mar/14 v0.91 modp supports mcl-wasm</li> <li>2019/Mar/12 v0.90 fix Vint::setArray(x) for x == this</li> <li>2019/Mar/07 add mclBnFr_setLittleEndianMod, mclBnFp_setLittleEndianMod</li> <li>2019/Feb/20 LagrangeInterpolation sets out = yVec[0] if k = 1</li> <li>2019/Jan/31 add mclBnFp_mapToG1, mclBnFp2_mapToG2</li> <li>2019/Jan/31 fix crash on x64-CPU without AVX (thanks to mortdeus)</li> </ul> <h1 id="author"><a class="toclink" href="#author">Author</a></h1> <p>光成滋生 MITSUNARI Shigeo(herumi@nifty.com)</p></div>