mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-03-06 19:35:04 +00:00
supersedes https://github.com/ethereum/go-ethereum/pull/32508/files and builts on top of https://github.com/ethereum/go-ethereum/pull/32184 looks like a ~60% decrease in allocations / op and ~20% speed increase (very variable, between 2-200%) ``` goos: linux goarch: amd64 pkg: github.com/ethereum/go-ethereum/core/vm cpu: Intel(R) Core(TM) Ultra 7 155U │ /tmp/old.txt │ /tmp/new.txt │ │ sec/op │ sec/op vs base │ PrecompiledModExp/eip_example1-Gas=13056-14 23.70µ ± 3% 22.31µ ± 6% -5.89% (p=0.004 n=10) PrecompiledModExp/eip_example2-Gas=13056-14 566.2n ± 12% 267.0n ± 3% -52.85% (p=0.000 n=10) PrecompiledModExp/nagydani-1-square-Gas=204-14 1285.5n ± 3% 995.8n ± 3% -22.54% (p=0.000 n=10) PrecompiledModExp/nagydani-1-qube-Gas=204-14 1.757µ ± 30% 1.410µ ± 16% -19.75% (p=0.000 n=10) PrecompiledModExp/nagydani-1-pow0x10001-Gas=3276-14 8.897µ ± 14% 6.664µ ± 2% -25.10% (p=0.000 n=10) PrecompiledModExp/nagydani-2-square-Gas=665-14 2.107µ ± 8% 1.470µ ± 11% -30.24% (p=0.000 n=10) PrecompiledModExp/nagydani-2-qube-Gas=665-14 3.142µ ± 3% 2.289µ ± 7% -27.16% (p=0.000 n=10) PrecompiledModExp/nagydani-2-pow0x10001-Gas=10649-14 14.76µ ± 3% 13.59µ ± 4% -7.94% (p=0.000 n=10) PrecompiledModExp/nagydani-3-square-Gas=1894-14 3.984µ ± 3% 3.211µ ± 3% -19.42% (p=0.000 n=10) PrecompiledModExp/nagydani-3-qube-Gas=1894-14 7.572µ ± 12% 6.153µ ± 3% -18.74% (p=0.000 n=10) PrecompiledModExp/nagydani-3-pow0x10001-Gas=30310-14 39.07µ ± 7% 37.76µ ± 5% ~ (p=0.123 n=10) PrecompiledModExp/nagydani-4-square-Gas=5580-14 9.613µ ± 2% 9.221µ ± 2% -4.08% (p=0.003 n=10) PrecompiledModExp/nagydani-4-qube-Gas=5580-14 21.66µ ± 5% 21.48µ ± 17% ~ (p=0.971 n=10) PrecompiledModExp/nagydani-4-pow0x10001-Gas=89292-14 120.7µ ± 8% 116.0µ ± 3% -3.93% (p=0.043 n=10) PrecompiledModExp/nagydani-5-square-Gas=17868-14 23.93µ ± 3% 24.82µ ± 3% +3.73% (p=0.000 n=10) PrecompiledModExp/nagydani-5-qube-Gas=17868-14 54.98µ ± 1% 58.08µ ± 4% +5.64% (p=0.000 n=10) PrecompiledModExp/nagydani-5-pow0x10001-Gas=285900-14 340.3µ ± 2% 341.2µ ± 3% ~ (p=0.529 n=10) PrecompiledModExpEip2565/eip_example1-Gas=1360-14 21.99µ ± 3% 21.24µ ± 2% -3.43% (p=0.000 n=10) PrecompiledModExpEip2565/eip_example2-Gas=1360-14 568.1n ± 12% 221.1n ± 2% -61.07% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-1-square-Gas=200-14 1272.0n ± 2% 822.3n ± 13% -35.35% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-1-qube-Gas=200-14 1.633µ ± 3% 1.397µ ± 21% -14.45% (p=0.023 n=10) PrecompiledModExpEip2565/nagydani-1-pow0x10001-Gas=341-14 7.276µ ± 3% 6.703µ ± 5% -7.88% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-2-square-Gas=200-14 1.959µ ± 3% 1.618µ ± 2% -17.43% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-2-qube-Gas=200-14 2.959µ ± 6% 2.611µ ± 5% -11.78% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-2-pow0x10001-Gas=1365-14 14.99µ ± 5% 13.76µ ± 4% -8.17% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-3-square-Gas=341-14 3.870µ ± 4% 3.521µ ± 2% -9.04% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-3-qube-Gas=341-14 6.871µ ± 3% 6.454µ ± 3% -6.07% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-3-pow0x10001-Gas=5461-14 40.18µ ± 7% 35.55µ ± 3% -11.52% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-4-square-Gas=1365-14 9.694µ ± 3% 8.427µ ± 3% -13.08% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-4-qube-Gas=1365-14 21.45µ ± 2% 19.48µ ± 7% -9.18% (p=0.001 n=10) PrecompiledModExpEip2565/nagydani-4-pow0x10001-Gas=21845-14 118.1µ ± 2% 113.7µ ± 2% -3.76% (p=0.003 n=10) PrecompiledModExpEip2565/nagydani-5-square-Gas=5461-14 25.80µ ± 5% 24.05µ ± 3% -6.76% (p=0.001 n=10) PrecompiledModExpEip2565/nagydani-5-qube-Gas=5461-14 57.28µ ± 8% 55.76µ ± 6% ~ (p=0.796 n=10) PrecompiledModExpEip2565/nagydani-5-pow0x10001-Gas=87381-14 335.2µ ± 2% 346.2µ ± 3% +3.28% (p=0.000 n=10) PrecompiledModExpEip2565/marius-1-even-Gas=2057-14 56.24µ ± 3% 55.53µ ± 1% ~ (p=0.280 n=10) PrecompiledModExpEip2565/guido-1-even-Gas=2298-14 38.74µ ± 3% 38.63µ ± 6% ~ (p=0.631 n=10) PrecompiledModExpEip2565/guido-2-even-Gas=2300-14 61.94µ ± 2% 61.38µ ± 11% ~ (p=0.529 n=10) PrecompiledModExpEip2565/guido-3-even-Gas=5400-14 20.27µ ± 2% 20.19µ ± 5% ~ (p=0.853 n=10) PrecompiledModExpEip2565/guido-4-even-Gas=1026-14 805.8n ± 3% 359.1n ± 2% -55.44% (p=0.000 n=10) PrecompiledModExpEip2565/marcin-1-base-heavy-Gas=200-14 4.717µ ± 5% 3.925µ ± 5% -16.79% (p=0.000 n=10) PrecompiledModExpEip2565/marcin-1-exp-heavy-Gas=215-14 15.51µ ± 3% 14.77µ ± 2% -4.76% (p=0.000 n=10) PrecompiledModExpEip2565/marcin-1-balanced-Gas=200-14 10.42µ ± 2% 10.01µ ± 5% -3.94% (p=0.011 n=10) PrecompiledModExpEip2565/marcin-2-base-heavy-Gas=867-14 15.99µ ± 4% 15.65µ ± 4% ~ (p=0.190 n=10) PrecompiledModExpEip2565/marcin-2-exp-heavy-Gas=852-14 24.45µ ± 2% 23.36µ ± 3% -4.47% (p=0.002 n=10) PrecompiledModExpEip2565/marcin-2-balanced-Gas=996-14 34.59µ ± 29% 32.90µ ± 1% -4.90% (p=0.001 n=10) PrecompiledModExpEip2565/marcin-3-base-heavy-Gas=677-14 12.45µ ± 2% 12.00µ ± 16% ~ (p=0.105 n=10) PrecompiledModExpEip2565/marcin-3-exp-heavy-Gas=765-14 16.21µ ± 3% 15.58µ ± 6% ~ (p=0.063 n=10) PrecompiledModExpEip2565/marcin-3-balanced-Gas=1360-14 23.03µ ± 3% 21.34µ ± 2% -7.35% (p=0.000 n=10) PrecompiledModExpEip2565/mod-8-exp-648-Gas=215-14 17.44µ ± 3% 16.03µ ± 1% -8.07% (p=0.000 n=10) PrecompiledModExpEip2565/mod-8-exp-896-Gas=298-14 21.00µ ± 5% 19.52µ ± 2% -7.04% (p=0.000 n=10) PrecompiledModExpEip2565/mod-32-exp-32-Gas=200-14 9.549µ ± 2% 9.322µ ± 2% -2.38% (p=0.005 n=10) PrecompiledModExpEip2565/mod-32-exp-36-Gas=200-14 10.74µ ± 1% 10.31µ ± 2% -4.06% (p=0.000 n=10) PrecompiledModExpEip2565/mod-32-exp-40-Gas=208-14 11.95µ ± 2% 11.43µ ± 2% -4.33% (p=0.000 n=10) PrecompiledModExpEip2565/mod-32-exp-64-Gas=336-14 18.77µ ± 3% 18.10µ ± 2% -3.54% (p=0.002 n=10) PrecompiledModExpEip2565/mod-32-exp-65-Gas=341-14 13.58µ ± 1% 13.47µ ± 1% ~ (p=0.280 n=10) PrecompiledModExpEip2565/mod-32-exp-128-Gas=677-14 13.61µ ± 3% 13.36µ ± 1% -1.83% (p=0.000 n=10) PrecompiledModExpEip2565/mod-256-exp-2-Gas=341-14 6.984µ ± 2% 6.053µ ± 3% -13.33% (p=0.000 n=10) PrecompiledModExpEip2565/mod-264-exp-2-Gas=363-14 7.126µ ± 5% 6.344µ ± 7% -10.97% (p=0.000 n=10) PrecompiledModExpEip2565/mod-1024-exp-2-Gas=5461-14 52.41µ ± 22% 49.85µ ± 4% ~ (p=0.089 n=10) PrecompiledModExpEip2565/pawel-1-exp-heavy-Gas=298-14 20.93µ ± 32% 20.15µ ± 2% -3.69% (p=0.001 n=10) PrecompiledModExpEip2565/pawel-2-exp-heavy-Gas=425-14 19.32µ ± 17% 14.46µ ± 4% -25.16% (p=0.000 n=10) PrecompiledModExpEip2565/pawel-3-exp-heavy-Gas=501-14 20.22µ ± 15% 14.30µ ± 3% -29.27% (p=0.000 n=10) PrecompiledModExpEip2565/pawel-4-exp-heavy-Gas=506-14 14.33µ ± 3% 13.93µ ± 2% -2.80% (p=0.001 n=10) PrecompiledModExpEip2565/mod_vul_pawel_3_exp_8-Gas=200-14 24.30µ ± 16% 16.94µ ± 18% -30.30% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-1-square-Gas=500-14 1477.5n ± 5% 872.8n ± 9% -40.93% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-1-qube-Gas=500-14 2.099µ ± 8% 1.131µ ± 2% -46.13% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-1-pow0x10001-Gas=2048-14 8.920µ ± 4% 6.356µ ± 2% -28.74% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-2-square-Gas=512-14 2.227µ ± 4% 1.396µ ± 2% -37.34% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-2-qube-Gas=512-14 3.507µ ± 8% 2.421µ ± 13% -30.97% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-2-pow0x10001-Gas=8192-14 17.53µ ± 4% 14.17µ ± 5% -19.20% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-3-square-Gas=2048-14 4.801µ ± 12% 3.498µ ± 3% -27.15% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-3-qube-Gas=2048-14 8.284µ ± 4% 6.536µ ± 2% -21.10% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-3-pow0x10001-Gas=32768-14 44.82µ ± 6% 37.01µ ± 24% -17.43% (p=0.007 n=10) PrecompiledModExpEip7883/nagydani-4-square-Gas=8192-14 11.742µ ± 4% 9.000µ ± 4% -23.35% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-4-qube-Gas=8192-14 27.49µ ± 10% 21.34µ ± 5% -22.35% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-4-pow0x10001-Gas=131072-14 141.4µ ± 11% 113.4µ ± 3% -19.80% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-5-square-Gas=32768-14 31.46µ ± 5% 23.53µ ± 1% -25.21% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-5-qube-Gas=32768-14 78.12µ ± 20% 53.74µ ± 4% -31.20% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-5-pow0x10001-Gas=524288-14 446.3µ ± 6% 338.5µ ± 2% -24.15% (p=0.000 n=10) PrecompiledModExpEip7883/marius-1-even-Gas=45296-14 71.25µ ± 4% 55.33µ ± 1% -22.34% (p=0.000 n=10) PrecompiledModExpEip7883/guido-1-even-Gas=51136-14 51.06µ ± 14% 38.19µ ± 3% -25.20% (p=0.000 n=10) PrecompiledModExpEip7883/guido-2-even-Gas=51152-14 86.12µ ± 20% 60.65µ ± 2% -29.57% (p=0.000 n=10) PrecompiledModExpEip7883/guido-3-even-Gas=32400-14 27.53µ ± 32% 20.37µ ± 2% -26.02% (p=0.000 n=10) PrecompiledModExpEip7883/guido-4-even-Gas=94448-14 950.4n ± 5% 354.8n ± 28% -62.67% (p=0.000 n=10) PrecompiledModExpEip7883/marcin-1-base-heavy-Gas=1152-14 5.619µ ± 7% 4.440µ ± 5% -20.98% (p=0.000 n=10) PrecompiledModExpEip7883/marcin-1-exp-heavy-Gas=16624-14 19.03µ ± 19% 15.67µ ± 22% -17.63% (p=0.003 n=10) PrecompiledModExpEip7883/marcin-1-balanced-Gas=1200-14 13.83µ ± 19% 10.91µ ± 10% -21.16% (p=0.000 n=10) PrecompiledModExpEip7883/marcin-2-base-heavy-Gas=5202-14 23.69µ ± 9% 17.79µ ± 13% -24.91% (p=0.000 n=10) PrecompiledModExpEip7883/marcin-2-exp-heavy-Gas=16368-14 38.86µ ± 12% 25.69µ ± 14% -33.89% (p=0.000 n=10) PrecompiledModExpEip7883/marcin-2-balanced-Gas=5978-14 51.47µ ± 28% 33.67µ ± 15% -34.58% (p=0.000 n=10) PrecompiledModExpEip7883/marcin-3-base-heavy-Gas=2032-14 16.69µ ± 17% 12.08µ ± 2% -27.60% (p=0.000 n=10) PrecompiledModExpEip7883/marcin-3-exp-heavy-Gas=4080-14 19.75µ ± 5% 16.13µ ± 11% -18.36% (p=0.000 n=10) PrecompiledModExpEip7883/marcin-3-balanced-Gas=4080-14 28.66µ ± 9% 22.47µ ± 4% -21.59% (p=0.000 n=10) PrecompiledModExpEip7883/mod-8-exp-648-Gas=16624-14 20.78µ ± 14% 16.38µ ± 2% -21.17% (p=0.000 n=10) PrecompiledModExpEip7883/mod-8-exp-896-Gas=24560-14 24.35µ ± 10% 19.62µ ± 1% -19.43% (p=0.000 n=10) PrecompiledModExpEip7883/mod-32-exp-32-Gas=500-14 10.312µ ± 4% 9.293µ ± 3% -9.88% (p=0.000 n=10) PrecompiledModExpEip7883/mod-32-exp-36-Gas=560-14 11.69µ ± 18% 10.37µ ± 3% -11.27% (p=0.000 n=10) PrecompiledModExpEip7883/mod-32-exp-40-Gas=624-14 14.17µ ± 24% 11.60µ ± 6% -18.13% (p=0.000 n=10) PrecompiledModExpEip7883/mod-32-exp-64-Gas=1008-14 22.03µ ± 8% 18.22µ ± 2% -17.28% (p=0.000 n=10) PrecompiledModExpEip7883/mod-32-exp-65-Gas=1024-14 16.48µ ± 11% 13.34µ ± 1% -19.04% (p=0.000 n=10) PrecompiledModExpEip7883/mod-32-exp-128-Gas=2032-14 17.03µ ± 9% 13.44µ ± 1% -21.03% (p=0.000 n=10) PrecompiledModExpEip7883/mod-256-exp-2-Gas=2048-14 8.123µ ± 14% 5.962µ ± 3% -26.61% (p=0.000 n=10) PrecompiledModExpEip7883/mod-264-exp-2-Gas=2178-14 8.155µ ± 28% 6.799µ ± 4% -16.64% (p=0.000 n=10) PrecompiledModExpEip7883/mod-1024-exp-2-Gas=32768-14 62.32µ ± 4% 49.82µ ± 1% -20.06% (p=0.000 n=10) PrecompiledModExpEip7883/pawel-1-exp-heavy-Gas=24560-14 26.90µ ± 7% 20.30µ ± 2% -24.55% (p=0.000 n=10) PrecompiledModExpEip7883/pawel-2-exp-heavy-Gas=6128-14 17.67µ ± 2% 15.61µ ± 11% -11.66% (p=0.001 n=10) PrecompiledModExpEip7883/pawel-3-exp-heavy-Gas=2672-14 17.50µ ± 3% 14.88µ ± 8% -14.98% (p=0.002 n=10) PrecompiledModExpEip7883/pawel-4-exp-heavy-Gas=1520-14 17.32µ ± 2% 14.14µ ± 5% -18.39% (p=0.000 n=10) PrecompiledModExpEip7883/mod_vul_pawel_3_exp_8-Gas=1008-14 21.68µ ± 24% 17.07µ ± 3% -21.25% (p=0.000 n=10) geomean 14.64µ 12.02µ -17.89% │ /tmp/old.txt │ /tmp/new.txt │ │ gas/op │ gas/op vs base │ PrecompiledModExp/eip_example1-Gas=13056-14 13.06k ± 0% 13.06k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExp/eip_example2-Gas=13056-14 13.06k ± 0% 13.06k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExp/nagydani-1-square-Gas=204-14 204.0 ± 0% 204.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExp/nagydani-1-qube-Gas=204-14 204.0 ± 0% 204.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExp/nagydani-1-pow0x10001-Gas=3276-14 3.276k ± 0% 3.276k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExp/nagydani-2-square-Gas=665-14 665.0 ± 0% 665.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExp/nagydani-2-qube-Gas=665-14 665.0 ± 0% 665.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExp/nagydani-2-pow0x10001-Gas=10649-14 10.65k ± 0% 10.65k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExp/nagydani-3-square-Gas=1894-14 1.894k ± 0% 1.894k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExp/nagydani-3-qube-Gas=1894-14 1.894k ± 0% 1.894k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExp/nagydani-3-pow0x10001-Gas=30310-14 30.31k ± 0% 30.31k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExp/nagydani-4-square-Gas=5580-14 5.580k ± 0% 5.580k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExp/nagydani-4-qube-Gas=5580-14 5.580k ± 0% 5.580k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExp/nagydani-4-pow0x10001-Gas=89292-14 89.29k ± 0% 89.29k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExp/nagydani-5-square-Gas=17868-14 17.87k ± 0% 17.87k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExp/nagydani-5-qube-Gas=17868-14 17.87k ± 0% 17.87k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExp/nagydani-5-pow0x10001-Gas=285900-14 285.9k ± 0% 285.9k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/eip_example1-Gas=1360-14 1.360k ± 0% 1.360k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/eip_example2-Gas=1360-14 1.360k ± 0% 1.360k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/nagydani-1-square-Gas=200-14 200.0 ± 0% 200.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/nagydani-1-qube-Gas=200-14 200.0 ± 0% 200.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/nagydani-1-pow0x10001-Gas=341-14 341.0 ± 0% 341.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/nagydani-2-square-Gas=200-14 200.0 ± 0% 200.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/nagydani-2-qube-Gas=200-14 200.0 ± 0% 200.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/nagydani-2-pow0x10001-Gas=1365-14 1.365k ± 0% 1.365k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/nagydani-3-square-Gas=341-14 341.0 ± 0% 341.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/nagydani-3-qube-Gas=341-14 341.0 ± 0% 341.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/nagydani-3-pow0x10001-Gas=5461-14 5.461k ± 0% 5.461k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/nagydani-4-square-Gas=1365-14 1.365k ± 0% 1.365k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/nagydani-4-qube-Gas=1365-14 1.365k ± 0% 1.365k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/nagydani-4-pow0x10001-Gas=21845-14 21.84k ± 0% 21.84k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/nagydani-5-square-Gas=5461-14 5.461k ± 0% 5.461k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/nagydani-5-qube-Gas=5461-14 5.461k ± 0% 5.461k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/nagydani-5-pow0x10001-Gas=87381-14 87.38k ± 0% 87.38k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/marius-1-even-Gas=2057-14 2.057k ± 0% 2.057k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/guido-1-even-Gas=2298-14 2.298k ± 0% 2.298k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/guido-2-even-Gas=2300-14 2.300k ± 0% 2.300k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/guido-3-even-Gas=5400-14 5.400k ± 0% 5.400k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/guido-4-even-Gas=1026-14 1.026k ± 0% 1.026k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/marcin-1-base-heavy-Gas=200-14 200.0 ± 0% 200.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/marcin-1-exp-heavy-Gas=215-14 215.0 ± 0% 215.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/marcin-1-balanced-Gas=200-14 200.0 ± 0% 200.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/marcin-2-base-heavy-Gas=867-14 867.0 ± 0% 867.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/marcin-2-exp-heavy-Gas=852-14 852.0 ± 0% 852.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/marcin-2-balanced-Gas=996-14 996.0 ± 0% 996.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/marcin-3-base-heavy-Gas=677-14 677.0 ± 0% 677.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/marcin-3-exp-heavy-Gas=765-14 765.0 ± 0% 765.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/marcin-3-balanced-Gas=1360-14 1.360k ± 0% 1.360k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/mod-8-exp-648-Gas=215-14 215.0 ± 0% 215.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/mod-8-exp-896-Gas=298-14 298.0 ± 0% 298.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/mod-32-exp-32-Gas=200-14 200.0 ± 0% 200.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/mod-32-exp-36-Gas=200-14 200.0 ± 0% 200.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/mod-32-exp-40-Gas=208-14 208.0 ± 0% 208.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/mod-32-exp-64-Gas=336-14 336.0 ± 0% 336.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/mod-32-exp-65-Gas=341-14 341.0 ± 0% 341.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/mod-32-exp-128-Gas=677-14 677.0 ± 0% 677.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/mod-256-exp-2-Gas=341-14 341.0 ± 0% 341.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/mod-264-exp-2-Gas=363-14 363.0 ± 0% 363.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/mod-1024-exp-2-Gas=5461-14 5.461k ± 0% 5.461k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/pawel-1-exp-heavy-Gas=298-14 298.0 ± 0% 298.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/pawel-2-exp-heavy-Gas=425-14 425.0 ± 0% 425.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/pawel-3-exp-heavy-Gas=501-14 501.0 ± 0% 501.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/pawel-4-exp-heavy-Gas=506-14 506.0 ± 0% 506.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip2565/mod_vul_pawel_3_exp_8-Gas=200-14 200.0 ± 0% 200.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/nagydani-1-square-Gas=500-14 500.0 ± 0% 500.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/nagydani-1-qube-Gas=500-14 500.0 ± 0% 500.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/nagydani-1-pow0x10001-Gas=2048-14 2.048k ± 0% 2.048k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/nagydani-2-square-Gas=512-14 512.0 ± 0% 512.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/nagydani-2-qube-Gas=512-14 512.0 ± 0% 512.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/nagydani-2-pow0x10001-Gas=8192-14 8.192k ± 0% 8.192k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/nagydani-3-square-Gas=2048-14 2.048k ± 0% 2.048k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/nagydani-3-qube-Gas=2048-14 2.048k ± 0% 2.048k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/nagydani-3-pow0x10001-Gas=32768-14 32.77k ± 0% 32.77k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/nagydani-4-square-Gas=8192-14 8.192k ± 0% 8.192k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/nagydani-4-qube-Gas=8192-14 8.192k ± 0% 8.192k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/nagydani-4-pow0x10001-Gas=131072-14 131.1k ± 0% 131.1k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/nagydani-5-square-Gas=32768-14 32.77k ± 0% 32.77k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/nagydani-5-qube-Gas=32768-14 32.77k ± 0% 32.77k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/nagydani-5-pow0x10001-Gas=524288-14 524.3k ± 0% 524.3k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/marius-1-even-Gas=45296-14 45.30k ± 0% 45.30k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/guido-1-even-Gas=51136-14 51.14k ± 0% 51.14k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/guido-2-even-Gas=51152-14 51.15k ± 0% 51.15k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/guido-3-even-Gas=32400-14 32.40k ± 0% 32.40k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/guido-4-even-Gas=94448-14 94.45k ± 0% 94.45k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/marcin-1-base-heavy-Gas=1152-14 1.152k ± 0% 1.152k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/marcin-1-exp-heavy-Gas=16624-14 16.62k ± 0% 16.62k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/marcin-1-balanced-Gas=1200-14 1.200k ± 0% 1.200k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/marcin-2-base-heavy-Gas=5202-14 5.202k ± 0% 5.202k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/marcin-2-exp-heavy-Gas=16368-14 16.37k ± 0% 16.37k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/marcin-2-balanced-Gas=5978-14 5.978k ± 0% 5.978k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/marcin-3-base-heavy-Gas=2032-14 2.032k ± 0% 2.032k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/marcin-3-exp-heavy-Gas=4080-14 4.080k ± 0% 4.080k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/marcin-3-balanced-Gas=4080-14 4.080k ± 0% 4.080k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/mod-8-exp-648-Gas=16624-14 16.62k ± 0% 16.62k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/mod-8-exp-896-Gas=24560-14 24.56k ± 0% 24.56k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/mod-32-exp-32-Gas=500-14 500.0 ± 0% 500.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/mod-32-exp-36-Gas=560-14 560.0 ± 0% 560.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/mod-32-exp-40-Gas=624-14 624.0 ± 0% 624.0 ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/mod-32-exp-64-Gas=1008-14 1.008k ± 0% 1.008k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/mod-32-exp-65-Gas=1024-14 1.024k ± 0% 1.024k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/mod-32-exp-128-Gas=2032-14 2.032k ± 0% 2.032k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/mod-256-exp-2-Gas=2048-14 2.048k ± 0% 2.048k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/mod-264-exp-2-Gas=2178-14 2.178k ± 0% 2.178k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/mod-1024-exp-2-Gas=32768-14 32.77k ± 0% 32.77k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/pawel-1-exp-heavy-Gas=24560-14 24.56k ± 0% 24.56k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/pawel-2-exp-heavy-Gas=6128-14 6.128k ± 0% 6.128k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/pawel-3-exp-heavy-Gas=2672-14 2.672k ± 0% 2.672k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/pawel-4-exp-heavy-Gas=1520-14 1.520k ± 0% 1.520k ± 0% ~ (p=1.000 n=10) ¹ PrecompiledModExpEip7883/mod_vul_pawel_3_exp_8-Gas=1008-14 1.008k ± 0% 1.008k ± 0% ~ (p=1.000 n=10) ¹ geomean 2.342k 2.342k +0.00% ¹ all samples are equal │ /tmp/old.txt │ /tmp/new.txt │ │ mgas/s │ mgas/s vs base │ PrecompiledModExp/eip_example1-Gas=13056-14 550.8 ± 4% 585.3 ± 5% +6.26% (p=0.004 n=10) PrecompiledModExp/eip_example2-Gas=13056-14 23.06k ± 11% 48.91k ± 3% +112.09% (p=0.000 n=10) PrecompiledModExp/nagydani-1-square-Gas=204-14 158.7 ± 3% 204.8 ± 3% +29.08% (p=0.000 n=10) PrecompiledModExp/nagydani-1-qube-Gas=204-14 116.3 ± 23% 144.6 ± 14% +24.33% (p=0.000 n=10) PrecompiledModExp/nagydani-1-pow0x10001-Gas=3276-14 368.3 ± 16% 491.5 ± 2% +33.45% (p=0.000 n=10) PrecompiledModExp/nagydani-2-square-Gas=665-14 315.7 ± 7% 452.9 ± 10% +43.47% (p=0.000 n=10) PrecompiledModExp/nagydani-2-qube-Gas=665-14 211.6 ± 3% 290.6 ± 7% +37.28% (p=0.000 n=10) PrecompiledModExp/nagydani-2-pow0x10001-Gas=10649-14 721.6 ± 3% 783.8 ± 4% +8.62% (p=0.000 n=10) PrecompiledModExp/nagydani-3-square-Gas=1894-14 475.4 ± 3% 590.0 ± 3% +24.10% (p=0.000 n=10) PrecompiledModExp/nagydani-3-qube-Gas=1894-14 250.1 ± 11% 307.8 ± 3% +23.05% (p=0.000 n=10) PrecompiledModExp/nagydani-3-pow0x10001-Gas=30310-14 776.1 ± 6% 802.7 ± 5% ~ (p=0.123 n=10) PrecompiledModExp/nagydani-4-square-Gas=5580-14 580.5 ± 2% 605.1 ± 2% +4.25% (p=0.003 n=10) PrecompiledModExp/nagydani-4-qube-Gas=5580-14 257.6 ± 5% 259.8 ± 15% ~ (p=0.971 n=10) PrecompiledModExp/nagydani-4-pow0x10001-Gas=89292-14 739.7 ± 9% 770.0 ± 3% +4.09% (p=0.043 n=10) PrecompiledModExp/nagydani-5-square-Gas=17868-14 746.6 ± 3% 719.8 ± 3% -3.60% (p=0.000 n=10) PrecompiledModExp/nagydani-5-qube-Gas=17868-14 325.0 ± 1% 307.6 ± 4% -5.35% (p=0.000 n=10) PrecompiledModExp/nagydani-5-pow0x10001-Gas=285900-14 840.1 ± 2% 838.0 ± 3% ~ (p=0.529 n=10) PrecompiledModExpEip2565/eip_example1-Gas=1360-14 61.84 ± 3% 64.03 ± 2% +3.56% (p=0.000 n=10) PrecompiledModExpEip2565/eip_example2-Gas=1360-14 2.394k ± 11% 6.150k ± 2% +156.89% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-1-square-Gas=200-14 157.2 ± 2% 243.2 ± 11% +54.66% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-1-qube-Gas=200-14 122.4 ± 3% 143.2 ± 17% +16.90% (p=0.023 n=10) PrecompiledModExpEip2565/nagydani-1-pow0x10001-Gas=341-14 46.86 ± 3% 50.87 ± 4% +8.55% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-2-square-Gas=200-14 102.1 ± 3% 123.7 ± 2% +21.17% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-2-qube-Gas=200-14 67.59 ± 5% 76.60 ± 5% +13.34% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-2-pow0x10001-Gas=1365-14 91.06 ± 5% 99.16 ± 4% +8.90% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-3-square-Gas=341-14 88.09 ± 4% 96.86 ± 2% +9.96% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-3-qube-Gas=341-14 49.62 ± 3% 52.84 ± 3% +6.48% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-3-pow0x10001-Gas=5461-14 136.0 ± 6% 153.6 ± 3% +12.94% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-4-square-Gas=1365-14 140.8 ± 3% 161.9 ± 3% +15.02% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-4-qube-Gas=1365-14 63.62 ± 2% 70.05 ± 6% +10.12% (p=0.001 n=10) PrecompiledModExpEip2565/nagydani-4-pow0x10001-Gas=21845-14 184.9 ± 2% 192.2 ± 2% +3.92% (p=0.003 n=10) PrecompiledModExpEip2565/nagydani-5-square-Gas=5461-14 211.7 ± 5% 227.0 ± 3% +7.25% (p=0.001 n=10) PrecompiledModExpEip2565/nagydani-5-qube-Gas=5461-14 95.34 ± 9% 97.93 ± 6% ~ (p=0.796 n=10) PrecompiledModExpEip2565/nagydani-5-pow0x10001-Gas=87381-14 260.7 ± 2% 252.4 ± 3% -3.18% (p=0.000 n=10) PrecompiledModExpEip2565/marius-1-even-Gas=2057-14 36.57 ± 3% 37.03 ± 1% ~ (p=0.280 n=10) PrecompiledModExpEip2565/guido-1-even-Gas=2298-14 59.31 ± 3% 59.48 ± 5% ~ (p=0.631 n=10) PrecompiledModExpEip2565/guido-2-even-Gas=2300-14 37.13 ± 2% 37.47 ± 10% ~ (p=0.529 n=10) PrecompiledModExpEip2565/guido-3-even-Gas=5400-14 266.4 ± 2% 267.5 ± 5% ~ (p=0.838 n=10) PrecompiledModExpEip2565/guido-4-even-Gas=1026-14 1.274k ± 3% 2.857k ± 3% +124.34% (p=0.000 n=10) PrecompiledModExpEip2565/marcin-1-base-heavy-Gas=200-14 42.39 ± 5% 50.95 ± 5% +20.18% (p=0.000 n=10) PrecompiledModExpEip2565/marcin-1-exp-heavy-Gas=215-14 13.86 ± 3% 14.55 ± 2% +5.02% (p=0.000 n=10) PrecompiledModExpEip2565/marcin-1-balanced-Gas=200-14 19.19 ± 2% 19.98 ± 5% +4.09% (p=0.011 n=10) PrecompiledModExpEip2565/marcin-2-base-heavy-Gas=867-14 54.23 ± 4% 55.39 ± 4% ~ (p=0.197 n=10) PrecompiledModExpEip2565/marcin-2-exp-heavy-Gas=852-14 34.84 ± 2% 36.47 ± 2% +4.68% (p=0.002 n=10) PrecompiledModExpEip2565/marcin-2-balanced-Gas=996-14 28.79 ± 23% 30.27 ± 1% +5.16% (p=0.001 n=10) PrecompiledModExpEip2565/marcin-3-base-heavy-Gas=677-14 54.37 ± 2% 56.42 ± 14% ~ (p=0.093 n=10) PrecompiledModExpEip2565/marcin-3-exp-heavy-Gas=765-14 47.19 ± 3% 49.11 ± 6% ~ (p=0.063 n=10) PrecompiledModExpEip2565/marcin-3-balanced-Gas=1360-14 59.05 ± 3% 63.73 ± 2% +7.94% (p=0.000 n=10) PrecompiledModExpEip2565/mod-8-exp-648-Gas=215-14 12.32 ± 3% 13.41 ± 1% +8.81% (p=0.000 n=10) PrecompiledModExpEip2565/mod-8-exp-896-Gas=298-14 14.19 ± 5% 15.26 ± 2% +7.58% (p=0.000 n=10) PrecompiledModExpEip2565/mod-32-exp-32-Gas=200-14 20.94 ± 2% 21.45 ± 2% +2.41% (p=0.005 n=10) PrecompiledModExpEip2565/mod-32-exp-36-Gas=200-14 18.61 ± 1% 19.40 ± 2% +4.25% (p=0.000 n=10) PrecompiledModExpEip2565/mod-32-exp-40-Gas=208-14 17.40 ± 2% 18.19 ± 2% +4.54% (p=0.000 n=10) PrecompiledModExpEip2565/mod-32-exp-64-Gas=336-14 17.90 ± 3% 18.55 ± 2% +3.66% (p=0.002 n=10) PrecompiledModExpEip2565/mod-32-exp-65-Gas=341-14 25.10 ± 1% 25.30 ± 1% ~ (p=0.306 n=10) PrecompiledModExpEip2565/mod-32-exp-128-Gas=677-14 49.74 ± 3% 50.66 ± 1% +1.86% (p=0.000 n=10) PrecompiledModExpEip2565/mod-256-exp-2-Gas=341-14 48.82 ± 2% 56.33 ± 3% +15.38% (p=0.000 n=10) PrecompiledModExpEip2565/mod-264-exp-2-Gas=363-14 50.94 ± 5% 57.22 ± 6% +12.33% (p=0.000 n=10) PrecompiledModExpEip2565/mod-1024-exp-2-Gas=5461-14 104.2 ± 18% 109.5 ± 4% ~ (p=0.085 n=10) PrecompiledModExpEip2565/pawel-1-exp-heavy-Gas=298-14 14.23 ± 24% 14.78 ± 2% +3.83% (p=0.001 n=10) PrecompiledModExpEip2565/pawel-2-exp-heavy-Gas=425-14 22.01 ± 20% 29.39 ± 4% +33.55% (p=0.000 n=10) PrecompiledModExpEip2565/pawel-3-exp-heavy-Gas=501-14 24.78 ± 17% 35.03 ± 3% +41.38% (p=0.000 n=10) PrecompiledModExpEip2565/pawel-4-exp-heavy-Gas=506-14 35.30 ± 3% 36.31 ± 2% +2.88% (p=0.001 n=10) PrecompiledModExpEip2565/mod_vul_pawel_3_exp_8-Gas=200-14 8.250 ± 14% 11.805 ± 15% +43.09% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-1-square-Gas=500-14 338.4 ± 5% 574.2 ± 9% +69.72% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-1-qube-Gas=500-14 238.3 ± 7% 442.1 ± 2% +85.54% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-1-pow0x10001-Gas=2048-14 229.6 ± 4% 322.2 ± 2% +40.32% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-2-square-Gas=512-14 229.9 ± 4% 366.8 ± 2% +59.55% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-2-qube-Gas=512-14 146.1 ± 7% 211.8 ± 11% +44.98% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-2-pow0x10001-Gas=8192-14 467.2 ± 4% 578.3 ± 5% +23.77% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-3-square-Gas=2048-14 426.6 ± 11% 585.5 ± 3% +37.26% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-3-qube-Gas=2048-14 247.2 ± 4% 313.4 ± 2% +26.76% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-3-pow0x10001-Gas=32768-14 731.1 ± 5% 885.5 ± 19% +21.11% (p=0.007 n=10) PrecompiledModExpEip7883/nagydani-4-square-Gas=8192-14 697.7 ± 4% 910.3 ± 4% +30.47% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-4-qube-Gas=8192-14 298.0 ± 9% 383.8 ± 5% +28.75% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-4-pow0x10001-Gas=131072-14 926.6 ± 10% 1155.5 ± 3% +24.70% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-5-square-Gas=32768-14 1.042k ± 5% 1.393k ± 1% +33.64% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-5-qube-Gas=32768-14 419.5 ± 16% 609.7 ± 4% +45.33% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-5-pow0x10001-Gas=524288-14 1.175k ± 5% 1.549k ± 2% +31.89% (p=0.000 n=10) PrecompiledModExpEip7883/marius-1-even-Gas=45296-14 635.8 ± 4% 818.6 ± 1% +28.76% (p=0.000 n=10) PrecompiledModExpEip7883/guido-1-even-Gas=51136-14 1.002k ± 13% 1.339k ± 3% +33.66% (p=0.000 n=10) PrecompiledModExpEip7883/guido-2-even-Gas=51152-14 594.0 ± 17% 843.3 ± 2% +41.97% (p=0.000 n=10) PrecompiledModExpEip7883/guido-3-even-Gas=32400-14 1.177k ± 24% 1.591k ± 2% +35.17% (p=0.000 n=10) PrecompiledModExpEip7883/guido-4-even-Gas=94448-14 99.37k ± 5% 266.13k ± 22% +167.81% (p=0.000 n=10) PrecompiledModExpEip7883/marcin-1-base-heavy-Gas=1152-14 205.0 ± 7% 259.5 ± 5% +26.56% (p=0.000 n=10) PrecompiledModExpEip7883/marcin-1-exp-heavy-Gas=16624-14 873.8 ± 16% 1061.0 ± 18% +21.43% (p=0.003 n=10) PrecompiledModExpEip7883/marcin-1-balanced-Gas=1200-14 86.77 ± 16% 110.00 ± 9% +26.77% (p=0.000 n=10) PrecompiledModExpEip7883/marcin-2-base-heavy-Gas=5202-14 219.6 ± 8% 293.5 ± 12% +33.67% (p=0.000 n=10) PrecompiledModExpEip7883/marcin-2-exp-heavy-Gas=16368-14 421.2 ± 14% 637.2 ± 13% +51.28% (p=0.000 n=10) PrecompiledModExpEip7883/marcin-2-balanced-Gas=5978-14 116.2 ± 22% 177.6 ± 13% +52.86% (p=0.000 n=10) PrecompiledModExpEip7883/marcin-3-base-heavy-Gas=2032-14 121.8 ± 14% 168.1 ± 2% +38.11% (p=0.000 n=10) PrecompiledModExpEip7883/marcin-3-exp-heavy-Gas=4080-14 206.6 ± 5% 253.0 ± 10% +22.49% (p=0.000 n=10) PrecompiledModExpEip7883/marcin-3-balanced-Gas=4080-14 142.4 ± 8% 181.6 ± 4% +27.57% (p=0.000 n=10) PrecompiledModExpEip7883/mod-8-exp-648-Gas=16624-14 799.9 ± 12% 1014.5 ± 2% +26.84% (p=0.000 n=10) PrecompiledModExpEip7883/mod-8-exp-896-Gas=24560-14 1.009k ± 9% 1.252k ± 1% +24.05% (p=0.000 n=10) PrecompiledModExpEip7883/mod-32-exp-32-Gas=500-14 48.48 ± 4% 53.80 ± 3% +10.96% (p=0.000 n=10) PrecompiledModExpEip7883/mod-32-exp-36-Gas=560-14 47.91 ± 15% 53.99 ± 3% +12.70% (p=0.000 n=10) PrecompiledModExpEip7883/mod-32-exp-40-Gas=624-14 44.05 ± 19% 53.80 ± 6% +22.12% (p=0.000 n=10) PrecompiledModExpEip7883/mod-32-exp-64-Gas=1008-14 45.75 ± 8% 55.31 ± 2% +20.90% (p=0.000 n=10) PrecompiledModExpEip7883/mod-32-exp-65-Gas=1024-14 62.24 ± 12% 76.77 ± 1% +23.34% (p=0.000 n=10) PrecompiledModExpEip7883/mod-32-exp-128-Gas=2032-14 119.3 ± 8% 151.1 ± 1% +26.66% (p=0.000 n=10) PrecompiledModExpEip7883/mod-256-exp-2-Gas=2048-14 252.2 ± 12% 343.6 ± 3% +36.25% (p=0.000 n=10) PrecompiledModExpEip7883/mod-264-exp-2-Gas=2178-14 267.1 ± 22% 320.4 ± 5% +19.91% (p=0.000 n=10) PrecompiledModExpEip7883/mod-1024-exp-2-Gas=32768-14 525.9 ± 3% 657.7 ± 1% +25.07% (p=0.000 n=10) PrecompiledModExpEip7883/pawel-1-exp-heavy-Gas=24560-14 913.0 ± 7% 1210.0 ± 1% +32.52% (p=0.000 n=10) PrecompiledModExpEip7883/pawel-2-exp-heavy-Gas=6128-14 346.8 ± 2% 392.7 ± 10% +13.24% (p=0.001 n=10) PrecompiledModExpEip7883/pawel-3-exp-heavy-Gas=2672-14 152.7 ± 3% 179.7 ± 8% +17.65% (p=0.002 n=10) PrecompiledModExpEip7883/pawel-4-exp-heavy-Gas=1520-14 87.73 ± 2% 107.55 ± 4% +22.59% (p=0.000 n=10) PrecompiledModExpEip7883/mod_vul_pawel_3_exp_8-Gas=1008-14 46.50 ± 20% 59.03 ± 3% +26.97% (p=0.000 n=10) geomean 159.9 194.8 +21.79% │ /tmp/old.txt │ /tmp/new.txt │ │ B/op │ B/op vs base │ PrecompiledModExp/eip_example1-Gas=13056-14 2.595Ki ± 0% 2.282Ki ± 0% -12.04% (p=0.000 n=10) PrecompiledModExp/eip_example2-Gas=13056-14 672.0 ± 0% 352.0 ± 0% -47.62% (p=0.000 n=10) PrecompiledModExp/nagydani-1-square-Gas=204-14 1160.0 ± 0% 888.0 ± 0% -23.45% (p=0.000 n=10) PrecompiledModExp/nagydani-1-qube-Gas=204-14 1.414Ki ± 0% 1.148Ki ± 0% -18.78% (p=0.000 n=10) PrecompiledModExp/nagydani-1-pow0x10001-Gas=3276-14 1.898Ki ± 0% 1.633Ki ± 0% -13.99% (p=0.000 n=10) PrecompiledModExp/nagydani-2-square-Gas=665-14 1.789Ki ± 0% 1.383Ki ± 0% -22.71% (p=0.000 n=10) PrecompiledModExp/nagydani-2-qube-Gas=665-14 2.321Ki ± 0% 1.915Ki ± 0% -17.50% (p=0.000 n=10) PrecompiledModExp/nagydani-2-pow0x10001-Gas=10649-14 3.196Ki ± 0% 2.790Ki ± 0% -12.71% (p=0.000 n=10) PrecompiledModExp/nagydani-3-square-Gas=1894-14 2.821Ki ± 0% 2.415Ki ± 0% -14.40% (p=0.000 n=10) PrecompiledModExp/nagydani-3-qube-Gas=1894-14 4.010Ki ± 0% 3.604Ki ± 0% -10.13% (p=0.000 n=10) PrecompiledModExp/nagydani-3-pow0x10001-Gas=30310-14 5.698Ki ± 0% 5.292Ki ± 0% -7.13% (p=0.000 n=10) PrecompiledModExp/nagydani-4-square-Gas=5580-14 5.042Ki ± 0% 4.636Ki ± 0% -8.06% (p=0.000 n=10) PrecompiledModExp/nagydani-4-qube-Gas=5580-14 11.93Ki ± 0% 11.52Ki ± 0% -3.42% (p=0.000 n=10) PrecompiledModExp/nagydani-4-pow0x10001-Gas=89292-14 15.30Ki ± 0% 14.89Ki ± 0% -2.66% (p=0.000 n=10) PrecompiledModExp/nagydani-5-square-Gas=17868-14 9.616Ki ± 0% 9.208Ki ± 0% -4.24% (p=0.000 n=10) PrecompiledModExp/nagydani-5-qube-Gas=17868-14 23.26Ki ± 0% 22.85Ki ± 0% -1.77% (p=0.000 n=10) PrecompiledModExp/nagydani-5-pow0x10001-Gas=285900-14 31.90Ki ± 0% 31.49Ki ± 0% -1.29% (p=0.000 n=10) PrecompiledModExpEip2565/eip_example1-Gas=1360-14 2.595Ki ± 0% 2.282Ki ± 0% -12.04% (p=0.000 n=10) PrecompiledModExpEip2565/eip_example2-Gas=1360-14 672.0 ± 0% 352.0 ± 0% -47.62% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-1-square-Gas=200-14 1160.0 ± 0% 888.0 ± 0% -23.45% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-1-qube-Gas=200-14 1.414Ki ± 0% 1.148Ki ± 0% -18.78% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-1-pow0x10001-Gas=341-14 1.898Ki ± 0% 1.633Ki ± 0% -13.99% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-2-square-Gas=200-14 1.648Ki ± 0% 1.383Ki ± 0% -16.11% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-2-qube-Gas=200-14 2.181Ki ± 0% 1.914Ki ± 0% -12.23% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-2-pow0x10001-Gas=1365-14 3.056Ki ± 0% 2.790Ki ± 0% -8.69% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-3-square-Gas=341-14 2.681Ki ± 0% 2.415Ki ± 0% -9.91% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-3-qube-Gas=341-14 3.869Ki ± 0% 3.604Ki ± 0% -6.87% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-3-pow0x10001-Gas=5461-14 5.558Ki ± 0% 5.292Ki ± 0% -4.78% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-4-square-Gas=1365-14 4.901Ki ± 0% 4.636Ki ± 0% -5.42% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-4-qube-Gas=1365-14 11.78Ki ± 0% 11.52Ki ± 0% -2.25% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-4-pow0x10001-Gas=21845-14 15.16Ki ± 0% 14.89Ki ± 0% -1.76% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-5-square-Gas=5461-14 9.475Ki ± 0% 9.209Ki ± 0% -2.80% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-5-qube-Gas=5461-14 23.12Ki ± 0% 22.85Ki ± 0% -1.15% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-5-pow0x10001-Gas=87381-14 31.75Ki ± 0% 31.49Ki ± 0% -0.83% (p=0.000 n=10) PrecompiledModExpEip2565/marius-1-even-Gas=2057-14 2.501Ki ± 0% 2.134Ki ± 0% -14.68% (p=0.000 n=10) PrecompiledModExpEip2565/guido-1-even-Gas=2298-14 2.470Ki ± 0% 2.103Ki ± 0% -14.87% (p=0.000 n=10) PrecompiledModExpEip2565/guido-2-even-Gas=2300-14 2.587Ki ± 0% 2.228Ki ± 0% -13.89% (p=0.000 n=10) PrecompiledModExpEip2565/guido-3-even-Gas=5400-14 8.271Ki ± 0% 8.014Ki ± 0% -3.12% (p=0.000 n=10) PrecompiledModExpEip2565/guido-4-even-Gas=1026-14 1056.0 ± 0% 680.0 ± 0% -35.61% (p=0.000 n=10) PrecompiledModExpEip2565/marcin-1-base-heavy-Gas=200-14 2.954Ki ± 0% 2.696Ki ± 0% -8.73% (p=0.000 n=10) PrecompiledModExpEip2565/marcin-1-exp-heavy-Gas=215-14 1.641Ki ± 0% 1.273Ki ± 0% -22.38% (p=0.000 n=10) PrecompiledModExpEip2565/marcin-1-balanced-Gas=200-14 1.266Ki ± 0% 1.008Ki ± 0% -20.37% (p=0.000 n=10) PrecompiledModExpEip2565/marcin-2-base-heavy-Gas=867-14 9.555Ki ± 0% 9.296Ki ± 0% -2.71% (p=0.000 n=10) PrecompiledModExpEip2565/marcin-2-exp-heavy-Gas=852-14 2.047Ki ± 0% 1.688Ki ± 0% -17.56% (p=0.000 n=10) PrecompiledModExpEip2565/marcin-2-balanced-Gas=996-14 1.993Ki ± 0% 1.727Ki ± 0% -13.38% (p=0.000 n=10) PrecompiledModExpEip2565/marcin-3-base-heavy-Gas=677-14 2.587Ki ± 0% 2.282Ki ± 0% -11.78% (p=0.000 n=10) PrecompiledModExpEip2565/marcin-3-exp-heavy-Gas=765-14 2.313Ki ± 0% 2.000Ki ± 0% -13.55% (p=0.000 n=10) PrecompiledModExpEip2565/marcin-3-balanced-Gas=1360-14 2.610Ki ± 0% 2.298Ki ± 0% -11.97% (p=0.000 n=10) PrecompiledModExpEip2565/mod-8-exp-648-Gas=215-14 1.860Ki ± 0% 1.492Ki ± 0% -19.79% (p=0.000 n=10) PrecompiledModExpEip2565/mod-8-exp-896-Gas=298-14 1.876Ki ± 0% 1.508Ki ± 0% -19.60% (p=0.000 n=10) PrecompiledModExpEip2565/mod-32-exp-32-Gas=200-14 1192.0 ± 0% 920.0 ± 0% -22.82% (p=0.000 n=10) PrecompiledModExpEip2565/mod-32-exp-36-Gas=200-14 1.305Ki ± 0% 1.039Ki ± 0% -20.36% (p=0.000 n=10) PrecompiledModExpEip2565/mod-32-exp-40-Gas=208-14 1184.0 ± 0% 920.0 ± 0% -22.30% (p=0.000 n=10) PrecompiledModExpEip2565/mod-32-exp-64-Gas=336-14 1184.0 ± 0% 920.0 ± 0% -22.30% (p=0.000 n=10) PrecompiledModExpEip2565/mod-32-exp-65-Gas=341-14 3.071Ki ± 0% 2.767Ki ± 0% -9.92% (p=0.000 n=10) PrecompiledModExpEip2565/mod-32-exp-128-Gas=677-14 3.071Ki ± 0% 2.767Ki ± 0% -9.92% (p=0.000 n=10) PrecompiledModExpEip2565/mod-256-exp-2-Gas=341-14 3.869Ki ± 0% 3.604Ki ± 0% -6.87% (p=0.000 n=10) PrecompiledModExpEip2565/mod-264-exp-2-Gas=363-14 3.986Ki ± 0% 3.729Ki ± 0% -6.47% (p=0.000 n=10) PrecompiledModExpEip2565/mod-1024-exp-2-Gas=5461-14 24.12Ki ± 0% 23.85Ki ± 0% -1.10% (p=0.000 n=10) PrecompiledModExpEip2565/pawel-1-exp-heavy-Gas=298-14 1.931Ki ± 0% 1.563Ki ± 0% -19.02% (p=0.000 n=10) PrecompiledModExpEip2565/pawel-2-exp-heavy-Gas=425-14 2.438Ki ± 0% 2.071Ki ± 0% -15.06% (p=0.000 n=10) PrecompiledModExpEip2565/pawel-3-exp-heavy-Gas=501-14 2.798Ki ± 0% 2.485Ki ± 0% -11.17% (p=0.000 n=10) PrecompiledModExpEip2565/pawel-4-exp-heavy-Gas=506-14 3.080Ki ± 0% 2.774Ki ± 0% -9.92% (p=0.000 n=10) PrecompiledModExpEip2565/mod_vul_pawel_3_exp_8-Gas=200-14 1064.0 ± 0% 800.0 ± 0% -24.81% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-1-square-Gas=500-14 1152.0 ± 0% 888.0 ± 0% -22.92% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-1-qube-Gas=500-14 1.406Ki ± 0% 1.148Ki ± 0% -18.33% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-1-pow0x10001-Gas=2048-14 1.891Ki ± 0% 1.633Ki ± 0% -13.64% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-2-square-Gas=512-14 1.641Ki ± 0% 1.383Ki ± 0% -15.71% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-2-qube-Gas=512-14 2.173Ki ± 0% 1.915Ki ± 0% -11.87% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-2-pow0x10001-Gas=8192-14 3.048Ki ± 0% 2.790Ki ± 0% -8.46% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-3-square-Gas=2048-14 2.673Ki ± 0% 2.415Ki ± 0% -9.65% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-3-qube-Gas=2048-14 3.861Ki ± 0% 3.604Ki ± 0% -6.68% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-3-pow0x10001-Gas=32768-14 5.550Ki ± 0% 5.292Ki ± 0% -4.65% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-4-square-Gas=8192-14 4.894Ki ± 0% 4.636Ki ± 0% -5.27% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-4-qube-Gas=8192-14 11.78Ki ± 0% 11.52Ki ± 0% -2.20% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-4-pow0x10001-Gas=131072-14 15.15Ki ± 0% 14.89Ki ± 0% -1.71% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-5-square-Gas=32768-14 9.468Ki ± 0% 9.208Ki ± 0% -2.74% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-5-qube-Gas=32768-14 23.11Ki ± 0% 22.85Ki ± 0% -1.13% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-5-pow0x10001-Gas=524288-14 31.75Ki ± 0% 31.49Ki ± 0% -0.81% (p=0.000 n=10) PrecompiledModExpEip7883/marius-1-even-Gas=45296-14 2.548Ki ± 0% 2.134Ki ± 0% -16.25% (p=0.000 n=10) PrecompiledModExpEip7883/guido-1-even-Gas=51136-14 2.517Ki ± 0% 2.103Ki ± 0% -16.45% (p=0.000 n=10) PrecompiledModExpEip7883/guido-2-even-Gas=51152-14 2.642Ki ± 0% 2.228Ki ± 0% -15.67% (p=0.000 n=10) PrecompiledModExpEip7883/guido-3-even-Gas=32400-14 8.271Ki ± 0% 8.014Ki ± 0% -3.12% (p=0.000 n=10) PrecompiledModExpEip7883/guido-4-even-Gas=94448-14 1104.0 ± 0% 680.0 ± 0% -38.41% (p=0.000 n=10) PrecompiledModExpEip7883/marcin-1-base-heavy-Gas=1152-14 2.954Ki ± 0% 2.696Ki ± 0% -8.73% (p=0.000 n=10) PrecompiledModExpEip7883/marcin-1-exp-heavy-Gas=16624-14 1.688Ki ± 0% 1.273Ki ± 0% -24.54% (p=0.000 n=10) PrecompiledModExpEip7883/marcin-1-balanced-Gas=1200-14 1.266Ki ± 0% 1.008Ki ± 0% -20.37% (p=0.000 n=10) PrecompiledModExpEip7883/marcin-2-base-heavy-Gas=5202-14 9.554Ki ± 0% 9.296Ki ± 0% -2.70% (p=0.000 n=10) PrecompiledModExpEip7883/marcin-2-exp-heavy-Gas=16368-14 2.102Ki ± 0% 1.688Ki ± 0% -19.72% (p=0.000 n=10) PrecompiledModExpEip7883/marcin-2-balanced-Gas=5978-14 1.985Ki ± 0% 1.727Ki ± 0% -13.03% (p=0.000 n=10) PrecompiledModExpEip7883/marcin-3-base-heavy-Gas=2032-14 2.634Ki ± 0% 2.282Ki ± 0% -13.35% (p=0.000 n=10) PrecompiledModExpEip7883/marcin-3-exp-heavy-Gas=4080-14 2.368Ki ± 0% 2.000Ki ± 0% -15.55% (p=0.000 n=10) PrecompiledModExpEip7883/marcin-3-balanced-Gas=4080-14 2.665Ki ± 0% 2.298Ki ± 0% -13.78% (p=0.000 n=10) PrecompiledModExpEip7883/mod-8-exp-648-Gas=16624-14 1.907Ki ± 0% 1.492Ki ± 0% -21.76% (p=0.000 n=10) PrecompiledModExpEip7883/mod-8-exp-896-Gas=24560-14 1.923Ki ± 0% 1.508Ki ± 0% -21.58% (p=0.000 n=10) PrecompiledModExpEip7883/mod-32-exp-32-Gas=500-14 1240.0 ± 0% 920.0 ± 0% -25.81% (p=0.000 n=10) PrecompiledModExpEip7883/mod-32-exp-36-Gas=560-14 1.352Ki ± 0% 1.039Ki ± 0% -23.12% (p=0.000 n=10) PrecompiledModExpEip7883/mod-32-exp-40-Gas=624-14 1240.0 ± 0% 920.0 ± 0% -25.81% (p=0.000 n=10) PrecompiledModExpEip7883/mod-32-exp-64-Gas=1008-14 1240.0 ± 0% 920.0 ± 0% -25.81% (p=0.000 n=10) PrecompiledModExpEip7883/mod-32-exp-65-Gas=1024-14 3.118Ki ± 0% 2.767Ki ± 0% -11.27% (p=0.000 n=10) PrecompiledModExpEip7883/mod-32-exp-128-Gas=2032-14 3.118Ki ± 0% 2.767Ki ± 0% -11.27% (p=0.000 n=10) PrecompiledModExpEip7883/mod-256-exp-2-Gas=2048-14 3.861Ki ± 0% 3.604Ki ± 0% -6.68% (p=0.000 n=10) PrecompiledModExpEip7883/mod-264-exp-2-Gas=2178-14 3.986Ki ± 0% 3.729Ki ± 0% -6.47% (p=0.000 n=10) PrecompiledModExpEip7883/mod-1024-exp-2-Gas=32768-14 24.12Ki ± 0% 23.85Ki ± 0% -1.09% (p=0.000 n=10) PrecompiledModExpEip7883/pawel-1-exp-heavy-Gas=24560-14 1.978Ki ± 0% 1.562Ki ± 0% -20.99% (p=0.000 n=10) PrecompiledModExpEip7883/pawel-2-exp-heavy-Gas=6128-14 2.485Ki ± 0% 2.071Ki ± 0% -16.66% (p=0.000 n=10) PrecompiledModExpEip7883/pawel-3-exp-heavy-Gas=2672-14 2.853Ki ± 0% 2.485Ki ± 0% -12.87% (p=0.000 n=10) PrecompiledModExpEip7883/pawel-4-exp-heavy-Gas=1520-14 3.127Ki ± 0% 2.774Ki ± 0% -11.27% (p=0.000 n=10) PrecompiledModExpEip7883/mod_vul_pawel_3_exp_8-Gas=1008-14 1120.0 ± 0% 800.0 ± 0% -28.57% (p=0.000 n=10) geomean 3.164Ki 2.718Ki -14.08% │ /tmp/old.txt │ /tmp/new.txt │ │ allocs/op │ allocs/op vs base │ PrecompiledModExp/eip_example1-Gas=13056-14 37.00 ± 0% 30.00 ± 0% -18.92% (p=0.000 n=10) PrecompiledModExp/eip_example2-Gas=13056-14 13.000 ± 0% 6.000 ± 0% -53.85% (p=0.000 n=10) PrecompiledModExp/nagydani-1-square-Gas=204-14 18.00 ± 0% 10.00 ± 0% -44.44% (p=0.000 n=10) PrecompiledModExp/nagydani-1-qube-Gas=204-14 19.00 ± 0% 11.00 ± 0% -42.11% (p=0.000 n=10) PrecompiledModExp/nagydani-1-pow0x10001-Gas=3276-14 22.00 ± 0% 14.00 ± 0% -36.36% (p=0.000 n=10) PrecompiledModExp/nagydani-2-square-Gas=665-14 23.00 ± 0% 10.00 ± 0% -56.52% (p=0.000 n=10) PrecompiledModExp/nagydani-2-qube-Gas=665-14 24.00 ± 0% 11.00 ± 0% -54.17% (p=0.000 n=10) PrecompiledModExp/nagydani-2-pow0x10001-Gas=10649-14 27.00 ± 0% 14.00 ± 0% -48.15% (p=0.000 n=10) PrecompiledModExp/nagydani-3-square-Gas=1894-14 23.00 ± 0% 10.00 ± 0% -56.52% (p=0.000 n=10) PrecompiledModExp/nagydani-3-qube-Gas=1894-14 24.00 ± 0% 11.00 ± 0% -54.17% (p=0.000 n=10) PrecompiledModExp/nagydani-3-pow0x10001-Gas=30310-14 27.00 ± 0% 14.00 ± 0% -48.15% (p=0.000 n=10) PrecompiledModExp/nagydani-4-square-Gas=5580-14 23.00 ± 0% 10.00 ± 0% -56.52% (p=0.000 n=10) PrecompiledModExp/nagydani-4-qube-Gas=5580-14 25.00 ± 0% 12.00 ± 0% -52.00% (p=0.000 n=10) PrecompiledModExp/nagydani-4-pow0x10001-Gas=89292-14 28.00 ± 0% 15.00 ± 0% -46.43% (p=0.000 n=10) PrecompiledModExp/nagydani-5-square-Gas=17868-14 24.00 ± 0% 11.00 ± 0% -54.17% (p=0.000 n=10) PrecompiledModExp/nagydani-5-qube-Gas=17868-14 26.00 ± 0% 13.00 ± 0% -50.00% (p=0.000 n=10) PrecompiledModExp/nagydani-5-pow0x10001-Gas=285900-14 44.00 ± 0% 31.00 ± 0% -29.55% (p=0.000 n=10) PrecompiledModExpEip2565/eip_example1-Gas=1360-14 37.00 ± 0% 30.00 ± 0% -18.92% (p=0.000 n=10) PrecompiledModExpEip2565/eip_example2-Gas=1360-14 13.000 ± 0% 6.000 ± 0% -53.85% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-1-square-Gas=200-14 18.00 ± 0% 10.00 ± 0% -44.44% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-1-qube-Gas=200-14 19.00 ± 0% 11.00 ± 0% -42.11% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-1-pow0x10001-Gas=341-14 22.00 ± 0% 14.00 ± 0% -36.36% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-2-square-Gas=200-14 18.00 ± 0% 10.00 ± 0% -44.44% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-2-qube-Gas=200-14 19.00 ± 0% 11.00 ± 0% -42.11% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-2-pow0x10001-Gas=1365-14 22.00 ± 0% 14.00 ± 0% -36.36% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-3-square-Gas=341-14 18.00 ± 0% 10.00 ± 0% -44.44% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-3-qube-Gas=341-14 19.00 ± 0% 11.00 ± 0% -42.11% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-3-pow0x10001-Gas=5461-14 22.00 ± 0% 14.00 ± 0% -36.36% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-4-square-Gas=1365-14 18.00 ± 0% 10.00 ± 0% -44.44% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-4-qube-Gas=1365-14 20.00 ± 0% 12.00 ± 0% -40.00% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-4-pow0x10001-Gas=21845-14 23.00 ± 0% 15.00 ± 0% -34.78% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-5-square-Gas=5461-14 19.00 ± 0% 11.00 ± 0% -42.11% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-5-qube-Gas=5461-14 21.00 ± 0% 13.00 ± 0% -38.10% (p=0.000 n=10) PrecompiledModExpEip2565/nagydani-5-pow0x10001-Gas=87381-14 39.00 ± 0% 31.00 ± 0% -20.51% (p=0.000 n=10) PrecompiledModExpEip2565/marius-1-even-Gas=2057-14 52.00 ± 0% 43.00 ± 0% -17.31% (p=0.000 n=10) PrecompiledModExpEip2565/guido-1-even-Gas=2298-14 55.00 ± 0% 46.00 ± 0% -16.36% (p=0.000 n=10) PrecompiledModExpEip2565/guido-2-even-Gas=2300-14 52.00 ± 0% 44.00 ± 0% -15.38% (p=0.000 n=10) PrecompiledModExpEip2565/guido-3-even-Gas=5400-14 19.00 ± 0% 12.00 ± 0% -36.84% (p=0.000 n=10) PrecompiledModExpEip2565/guido-4-even-Gas=1026-14 18.000 ± 0% 9.000 ± 0% -50.00% (p=0.000 n=10) PrecompiledModExpEip2565/marcin-1-base-heavy-Gas=200-14 18.00 ± 0% 11.00 ± 0% -38.89% (p=0.000 n=10) PrecompiledModExpEip2565/marcin-1-exp-heavy-Gas=215-14 37.00 ± 0% 28.00 ± 0% -24.32% (p=0.000 n=10) PrecompiledModExpEip2565/marcin-1-balanced-Gas=200-14 19.00 ± 0% 12.00 ± 0% -36.84% (p=0.000 n=10) PrecompiledModExpEip2565/marcin-2-base-heavy-Gas=867-14 19.00 ± 0% 12.00 ± 0% -36.84% (p=0.000 n=10) PrecompiledModExpEip2565/marcin-2-exp-heavy-Gas=852-14 36.00 ± 0% 28.00 ± 0% -22.22% (p=0.000 n=10) PrecompiledModExpEip2565/marcin-2-balanced-Gas=996-14 23.00 ± 0% 15.00 ± 0% -34.78% (p=0.000 n=10) PrecompiledModExpEip2565/marcin-3-base-heavy-Gas=677-14 36.00 ± 0% 28.00 ± 0% -22.22% (p=0.000 n=10) PrecompiledModExpEip2565/marcin-3-exp-heavy-Gas=765-14 35.00 ± 0% 28.00 ± 0% -20.00% (p=0.000 n=10) PrecompiledModExpEip2565/marcin-3-balanced-Gas=1360-14 35.00 ± 0% 28.00 ± 0% -20.00% (p=0.000 n=10) PrecompiledModExpEip2565/mod-8-exp-648-Gas=215-14 50.00 ± 0% 41.00 ± 0% -18.00% (p=0.000 n=10) PrecompiledModExpEip2565/mod-8-exp-896-Gas=298-14 50.00 ± 0% 41.00 ± 0% -18.00% (p=0.000 n=10) PrecompiledModExpEip2565/mod-32-exp-32-Gas=200-14 21.00 ± 0% 13.00 ± 0% -38.10% (p=0.000 n=10) PrecompiledModExpEip2565/mod-32-exp-36-Gas=200-14 22.00 ± 0% 14.00 ± 0% -36.36% (p=0.000 n=10) PrecompiledModExpEip2565/mod-32-exp-40-Gas=208-14 20.00 ± 0% 13.00 ± 0% -35.00% (p=0.000 n=10) PrecompiledModExpEip2565/mod-32-exp-64-Gas=336-14 20.00 ± 0% 13.00 ± 0% -35.00% (p=0.000 n=10) PrecompiledModExpEip2565/mod-32-exp-65-Gas=341-14 52.00 ± 0% 44.00 ± 0% -15.38% (p=0.000 n=10) PrecompiledModExpEip2565/mod-32-exp-128-Gas=677-14 52.00 ± 0% 44.00 ± 0% -15.38% (p=0.000 n=10) PrecompiledModExpEip2565/mod-256-exp-2-Gas=341-14 19.00 ± 0% 11.00 ± 0% -42.11% (p=0.000 n=10) PrecompiledModExpEip2565/mod-264-exp-2-Gas=363-14 18.00 ± 0% 11.00 ± 0% -38.89% (p=0.000 n=10) PrecompiledModExpEip2565/mod-1024-exp-2-Gas=5461-14 22.00 ± 0% 14.00 ± 0% -36.36% (p=0.000 n=10) PrecompiledModExpEip2565/pawel-1-exp-heavy-Gas=298-14 52.00 ± 0% 43.00 ± 0% -17.31% (p=0.000 n=10) PrecompiledModExpEip2565/pawel-2-exp-heavy-Gas=425-14 54.00 ± 0% 45.00 ± 0% -16.67% (p=0.000 n=10) PrecompiledModExpEip2565/pawel-3-exp-heavy-Gas=501-14 52.00 ± 0% 45.00 ± 0% -13.46% (p=0.000 n=10) PrecompiledModExpEip2565/pawel-4-exp-heavy-Gas=506-14 53.00 ± 0% 45.00 ± 0% -15.09% (p=0.000 n=10) PrecompiledModExpEip2565/mod_vul_pawel_3_exp_8-Gas=200-14 19.00 ± 0% 12.00 ± 0% -36.84% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-1-square-Gas=500-14 17.00 ± 0% 10.00 ± 0% -41.18% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-1-qube-Gas=500-14 18.00 ± 0% 11.00 ± 0% -38.89% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-1-pow0x10001-Gas=2048-14 21.00 ± 0% 14.00 ± 0% -33.33% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-2-square-Gas=512-14 17.00 ± 0% 10.00 ± 0% -41.18% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-2-qube-Gas=512-14 18.00 ± 0% 11.00 ± 0% -38.89% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-2-pow0x10001-Gas=8192-14 21.00 ± 0% 14.00 ± 0% -33.33% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-3-square-Gas=2048-14 17.00 ± 0% 10.00 ± 0% -41.18% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-3-qube-Gas=2048-14 18.00 ± 0% 11.00 ± 0% -38.89% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-3-pow0x10001-Gas=32768-14 21.00 ± 0% 14.00 ± 0% -33.33% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-4-square-Gas=8192-14 17.00 ± 0% 10.00 ± 0% -41.18% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-4-qube-Gas=8192-14 19.00 ± 0% 12.00 ± 0% -36.84% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-4-pow0x10001-Gas=131072-14 22.00 ± 0% 15.00 ± 0% -31.82% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-5-square-Gas=32768-14 18.00 ± 0% 11.00 ± 0% -38.89% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-5-qube-Gas=32768-14 20.00 ± 0% 13.00 ± 0% -35.00% (p=0.000 n=10) PrecompiledModExpEip7883/nagydani-5-pow0x10001-Gas=524288-14 38.00 ± 0% 31.00 ± 0% -18.42% (p=0.000 n=10) PrecompiledModExpEip7883/marius-1-even-Gas=45296-14 53.00 ± 0% 43.00 ± 0% -18.87% (p=0.000 n=10) PrecompiledModExpEip7883/guido-1-even-Gas=51136-14 56.00 ± 0% 46.00 ± 0% -17.86% (p=0.000 n=10) PrecompiledModExpEip7883/guido-2-even-Gas=51152-14 54.00 ± 0% 44.00 ± 0% -18.52% (p=0.000 n=10) PrecompiledModExpEip7883/guido-3-even-Gas=32400-14 19.00 ± 0% 12.00 ± 0% -36.84% (p=0.000 n=10) PrecompiledModExpEip7883/guido-4-even-Gas=94448-14 19.000 ± 0% 9.000 ± 0% -52.63% (p=0.000 n=10) PrecompiledModExpEip7883/marcin-1-base-heavy-Gas=1152-14 18.00 ± 0% 11.00 ± 0% -38.89% (p=0.000 n=10) PrecompiledModExpEip7883/marcin-1-exp-heavy-Gas=16624-14 38.00 ± 0% 28.00 ± 0% -26.32% (p=0.000 n=10) PrecompiledModExpEip7883/marcin-1-balanced-Gas=1200-14 19.00 ± 0% 12.00 ± 0% -36.84% (p=0.000 n=10) PrecompiledModExpEip7883/marcin-2-base-heavy-Gas=5202-14 19.00 ± 0% 12.00 ± 0% -36.84% (p=0.000 n=10) PrecompiledModExpEip7883/marcin-2-exp-heavy-Gas=16368-14 38.00 ± 0% 28.00 ± 0% -26.32% (p=0.000 n=10) PrecompiledModExpEip7883/marcin-2-balanced-Gas=5978-14 22.00 ± 0% 15.00 ± 0% -31.82% (p=0.000 n=10) PrecompiledModExpEip7883/marcin-3-base-heavy-Gas=2032-14 37.00 ± 0% 28.00 ± 0% -24.32% (p=0.000 n=10) PrecompiledModExpEip7883/marcin-3-exp-heavy-Gas=4080-14 37.00 ± 0% 28.00 ± 0% -24.32% (p=0.000 n=10) PrecompiledModExpEip7883/marcin-3-balanced-Gas=4080-14 37.00 ± 0% 28.00 ± 0% -24.32% (p=0.000 n=10) PrecompiledModExpEip7883/mod-8-exp-648-Gas=16624-14 51.00 ± 0% 41.00 ± 0% -19.61% (p=0.000 n=10) PrecompiledModExpEip7883/mod-8-exp-896-Gas=24560-14 51.00 ± 0% 41.00 ± 0% -19.61% (p=0.000 n=10) PrecompiledModExpEip7883/mod-32-exp-32-Gas=500-14 22.00 ± 0% 13.00 ± 0% -40.91% (p=0.000 n=10) PrecompiledModExpEip7883/mod-32-exp-36-Gas=560-14 23.00 ± 0% 14.00 ± 0% -39.13% (p=0.000 n=10) PrecompiledModExpEip7883/mod-32-exp-40-Gas=624-14 22.00 ± 0% 13.00 ± 0% -40.91% (p=0.000 n=10) PrecompiledModExpEip7883/mod-32-exp-64-Gas=1008-14 22.00 ± 0% 13.00 ± 0% -40.91% (p=0.000 n=10) PrecompiledModExpEip7883/mod-32-exp-65-Gas=1024-14 53.00 ± 0% 44.00 ± 0% -16.98% (p=0.000 n=10) PrecompiledModExpEip7883/mod-32-exp-128-Gas=2032-14 53.00 ± 0% 44.00 ± 0% -16.98% (p=0.000 n=10) PrecompiledModExpEip7883/mod-256-exp-2-Gas=2048-14 18.00 ± 0% 11.00 ± 0% -38.89% (p=0.000 n=10) PrecompiledModExpEip7883/mod-264-exp-2-Gas=2178-14 18.00 ± 0% 11.00 ± 0% -38.89% (p=0.000 n=10) PrecompiledModExpEip7883/mod-1024-exp-2-Gas=32768-14 21.00 ± 0% 14.00 ± 0% -33.33% (p=0.000 n=10) PrecompiledModExpEip7883/pawel-1-exp-heavy-Gas=24560-14 53.00 ± 0% 43.00 ± 0% -18.87% (p=0.000 n=10) PrecompiledModExpEip7883/pawel-2-exp-heavy-Gas=6128-14 55.00 ± 0% 45.00 ± 0% -18.18% (p=0.000 n=10) PrecompiledModExpEip7883/pawel-3-exp-heavy-Gas=2672-14 54.00 ± 0% 45.00 ± 0% -16.67% (p=0.000 n=10) PrecompiledModExpEip7883/pawel-4-exp-heavy-Gas=1520-14 54.00 ± 0% 45.00 ± 0% -16.67% (p=0.000 n=10) PrecompiledModExpEip7883/mod_vul_pawel_3_exp_8-Gas=1008-14 21.00 ± 0% 12.00 ± 0% -42.86% (p=0.000 n=10) geomean 26.59 17.27 -35.03% ``` Co-authored-by: @kevaundray Co-authored-by: Felix Lange <fjl@twurst.com>
1447 lines
45 KiB
Go
1447 lines
45 KiB
Go
// Copyright 2014 The go-ethereum Authors
|
|
// This file is part of the go-ethereum library.
|
|
//
|
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU Lesser General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU Lesser General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Lesser General Public License
|
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
package vm
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/binary"
|
|
"errors"
|
|
"fmt"
|
|
"maps"
|
|
"math"
|
|
"math/big"
|
|
"math/bits"
|
|
|
|
"github.com/consensys/gnark-crypto/ecc"
|
|
bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381"
|
|
"github.com/consensys/gnark-crypto/ecc/bls12-381/fp"
|
|
"github.com/consensys/gnark-crypto/ecc/bls12-381/fr"
|
|
"github.com/ethereum/go-ethereum/common"
|
|
"github.com/ethereum/go-ethereum/common/bitutil"
|
|
"github.com/ethereum/go-ethereum/core/tracing"
|
|
"github.com/ethereum/go-ethereum/crypto"
|
|
"github.com/ethereum/go-ethereum/crypto/blake2b"
|
|
"github.com/ethereum/go-ethereum/crypto/bn256"
|
|
"github.com/ethereum/go-ethereum/crypto/kzg4844"
|
|
"github.com/ethereum/go-ethereum/crypto/secp256r1"
|
|
"github.com/ethereum/go-ethereum/params"
|
|
"github.com/holiman/uint256"
|
|
"golang.org/x/crypto/ripemd160"
|
|
)
|
|
|
|
// PrecompiledContract is the basic interface for native Go contracts. The implementation
|
|
// requires a deterministic gas count based on the input size of the Run method of the
|
|
// contract.
|
|
type PrecompiledContract interface {
|
|
RequiredGas(input []byte) uint64 // RequiredPrice calculates the contract gas use
|
|
Run(input []byte) ([]byte, error) // Run runs the precompiled contract
|
|
Name() string
|
|
}
|
|
|
|
// PrecompiledContracts contains the precompiled contracts supported at the given fork.
|
|
type PrecompiledContracts map[common.Address]PrecompiledContract
|
|
|
|
// PrecompiledContractsHomestead contains the default set of pre-compiled Ethereum
|
|
// contracts used in the Frontier and Homestead releases.
|
|
var PrecompiledContractsHomestead = PrecompiledContracts{
|
|
common.BytesToAddress([]byte{0x1}): &ecrecover{},
|
|
common.BytesToAddress([]byte{0x2}): &sha256hash{},
|
|
common.BytesToAddress([]byte{0x3}): &ripemd160hash{},
|
|
common.BytesToAddress([]byte{0x4}): &dataCopy{},
|
|
}
|
|
|
|
// PrecompiledContractsByzantium contains the default set of pre-compiled Ethereum
|
|
// contracts used in the Byzantium release.
|
|
var PrecompiledContractsByzantium = PrecompiledContracts{
|
|
common.BytesToAddress([]byte{0x1}): &ecrecover{},
|
|
common.BytesToAddress([]byte{0x2}): &sha256hash{},
|
|
common.BytesToAddress([]byte{0x3}): &ripemd160hash{},
|
|
common.BytesToAddress([]byte{0x4}): &dataCopy{},
|
|
common.BytesToAddress([]byte{0x5}): &bigModExp{eip2565: false, eip7823: false, eip7883: false},
|
|
common.BytesToAddress([]byte{0x6}): &bn256AddByzantium{},
|
|
common.BytesToAddress([]byte{0x7}): &bn256ScalarMulByzantium{},
|
|
common.BytesToAddress([]byte{0x8}): &bn256PairingByzantium{},
|
|
}
|
|
|
|
// PrecompiledContractsIstanbul contains the default set of pre-compiled Ethereum
|
|
// contracts used in the Istanbul release.
|
|
var PrecompiledContractsIstanbul = PrecompiledContracts{
|
|
common.BytesToAddress([]byte{0x1}): &ecrecover{},
|
|
common.BytesToAddress([]byte{0x2}): &sha256hash{},
|
|
common.BytesToAddress([]byte{0x3}): &ripemd160hash{},
|
|
common.BytesToAddress([]byte{0x4}): &dataCopy{},
|
|
common.BytesToAddress([]byte{0x5}): &bigModExp{eip2565: false, eip7823: false, eip7883: false},
|
|
common.BytesToAddress([]byte{0x6}): &bn256AddIstanbul{},
|
|
common.BytesToAddress([]byte{0x7}): &bn256ScalarMulIstanbul{},
|
|
common.BytesToAddress([]byte{0x8}): &bn256PairingIstanbul{},
|
|
common.BytesToAddress([]byte{0x9}): &blake2F{},
|
|
}
|
|
|
|
// PrecompiledContractsBerlin contains the default set of pre-compiled Ethereum
|
|
// contracts used in the Berlin release.
|
|
var PrecompiledContractsBerlin = PrecompiledContracts{
|
|
common.BytesToAddress([]byte{0x1}): &ecrecover{},
|
|
common.BytesToAddress([]byte{0x2}): &sha256hash{},
|
|
common.BytesToAddress([]byte{0x3}): &ripemd160hash{},
|
|
common.BytesToAddress([]byte{0x4}): &dataCopy{},
|
|
common.BytesToAddress([]byte{0x5}): &bigModExp{eip2565: true, eip7823: false, eip7883: false},
|
|
common.BytesToAddress([]byte{0x6}): &bn256AddIstanbul{},
|
|
common.BytesToAddress([]byte{0x7}): &bn256ScalarMulIstanbul{},
|
|
common.BytesToAddress([]byte{0x8}): &bn256PairingIstanbul{},
|
|
common.BytesToAddress([]byte{0x9}): &blake2F{},
|
|
}
|
|
|
|
// PrecompiledContractsCancun contains the default set of pre-compiled Ethereum
|
|
// contracts used in the Cancun release.
|
|
var PrecompiledContractsCancun = PrecompiledContracts{
|
|
common.BytesToAddress([]byte{0x1}): &ecrecover{},
|
|
common.BytesToAddress([]byte{0x2}): &sha256hash{},
|
|
common.BytesToAddress([]byte{0x3}): &ripemd160hash{},
|
|
common.BytesToAddress([]byte{0x4}): &dataCopy{},
|
|
common.BytesToAddress([]byte{0x5}): &bigModExp{eip2565: true, eip7823: false, eip7883: false},
|
|
common.BytesToAddress([]byte{0x6}): &bn256AddIstanbul{},
|
|
common.BytesToAddress([]byte{0x7}): &bn256ScalarMulIstanbul{},
|
|
common.BytesToAddress([]byte{0x8}): &bn256PairingIstanbul{},
|
|
common.BytesToAddress([]byte{0x9}): &blake2F{},
|
|
common.BytesToAddress([]byte{0xa}): &kzgPointEvaluation{},
|
|
}
|
|
|
|
// PrecompiledContractsPrague contains the set of pre-compiled Ethereum
|
|
// contracts used in the Prague release.
|
|
var PrecompiledContractsPrague = PrecompiledContracts{
|
|
common.BytesToAddress([]byte{0x01}): &ecrecover{},
|
|
common.BytesToAddress([]byte{0x02}): &sha256hash{},
|
|
common.BytesToAddress([]byte{0x03}): &ripemd160hash{},
|
|
common.BytesToAddress([]byte{0x04}): &dataCopy{},
|
|
common.BytesToAddress([]byte{0x05}): &bigModExp{eip2565: true, eip7823: false, eip7883: false},
|
|
common.BytesToAddress([]byte{0x06}): &bn256AddIstanbul{},
|
|
common.BytesToAddress([]byte{0x07}): &bn256ScalarMulIstanbul{},
|
|
common.BytesToAddress([]byte{0x08}): &bn256PairingIstanbul{},
|
|
common.BytesToAddress([]byte{0x09}): &blake2F{},
|
|
common.BytesToAddress([]byte{0x0a}): &kzgPointEvaluation{},
|
|
common.BytesToAddress([]byte{0x0b}): &bls12381G1Add{},
|
|
common.BytesToAddress([]byte{0x0c}): &bls12381G1MultiExp{},
|
|
common.BytesToAddress([]byte{0x0d}): &bls12381G2Add{},
|
|
common.BytesToAddress([]byte{0x0e}): &bls12381G2MultiExp{},
|
|
common.BytesToAddress([]byte{0x0f}): &bls12381Pairing{},
|
|
common.BytesToAddress([]byte{0x10}): &bls12381MapG1{},
|
|
common.BytesToAddress([]byte{0x11}): &bls12381MapG2{},
|
|
}
|
|
|
|
var PrecompiledContractsBLS = PrecompiledContractsPrague
|
|
|
|
var PrecompiledContractsVerkle = PrecompiledContractsBerlin
|
|
|
|
// PrecompiledContractsOsaka contains the set of pre-compiled Ethereum
|
|
// contracts used in the Osaka release.
|
|
var PrecompiledContractsOsaka = PrecompiledContracts{
|
|
common.BytesToAddress([]byte{0x01}): &ecrecover{},
|
|
common.BytesToAddress([]byte{0x02}): &sha256hash{},
|
|
common.BytesToAddress([]byte{0x03}): &ripemd160hash{},
|
|
common.BytesToAddress([]byte{0x04}): &dataCopy{},
|
|
common.BytesToAddress([]byte{0x05}): &bigModExp{eip2565: true, eip7823: true, eip7883: true},
|
|
common.BytesToAddress([]byte{0x06}): &bn256AddIstanbul{},
|
|
common.BytesToAddress([]byte{0x07}): &bn256ScalarMulIstanbul{},
|
|
common.BytesToAddress([]byte{0x08}): &bn256PairingIstanbul{},
|
|
common.BytesToAddress([]byte{0x09}): &blake2F{},
|
|
common.BytesToAddress([]byte{0x0a}): &kzgPointEvaluation{},
|
|
common.BytesToAddress([]byte{0x0b}): &bls12381G1Add{},
|
|
common.BytesToAddress([]byte{0x0c}): &bls12381G1MultiExp{},
|
|
common.BytesToAddress([]byte{0x0d}): &bls12381G2Add{},
|
|
common.BytesToAddress([]byte{0x0e}): &bls12381G2MultiExp{},
|
|
common.BytesToAddress([]byte{0x0f}): &bls12381Pairing{},
|
|
common.BytesToAddress([]byte{0x10}): &bls12381MapG1{},
|
|
common.BytesToAddress([]byte{0x11}): &bls12381MapG2{},
|
|
|
|
common.BytesToAddress([]byte{0x1, 0x00}): &p256Verify{},
|
|
}
|
|
|
|
// PrecompiledContractsP256Verify contains the precompiled Ethereum
|
|
// contract specified in EIP-7212. This is exported for testing purposes.
|
|
var PrecompiledContractsP256Verify = PrecompiledContracts{
|
|
common.BytesToAddress([]byte{0x1, 0x00}): &p256Verify{},
|
|
}
|
|
|
|
var (
|
|
PrecompiledAddressesOsaka []common.Address
|
|
PrecompiledAddressesPrague []common.Address
|
|
PrecompiledAddressesCancun []common.Address
|
|
PrecompiledAddressesBerlin []common.Address
|
|
PrecompiledAddressesIstanbul []common.Address
|
|
PrecompiledAddressesByzantium []common.Address
|
|
PrecompiledAddressesHomestead []common.Address
|
|
)
|
|
|
|
func init() {
|
|
for k := range PrecompiledContractsHomestead {
|
|
PrecompiledAddressesHomestead = append(PrecompiledAddressesHomestead, k)
|
|
}
|
|
for k := range PrecompiledContractsByzantium {
|
|
PrecompiledAddressesByzantium = append(PrecompiledAddressesByzantium, k)
|
|
}
|
|
for k := range PrecompiledContractsIstanbul {
|
|
PrecompiledAddressesIstanbul = append(PrecompiledAddressesIstanbul, k)
|
|
}
|
|
for k := range PrecompiledContractsBerlin {
|
|
PrecompiledAddressesBerlin = append(PrecompiledAddressesBerlin, k)
|
|
}
|
|
for k := range PrecompiledContractsCancun {
|
|
PrecompiledAddressesCancun = append(PrecompiledAddressesCancun, k)
|
|
}
|
|
for k := range PrecompiledContractsPrague {
|
|
PrecompiledAddressesPrague = append(PrecompiledAddressesPrague, k)
|
|
}
|
|
for k := range PrecompiledContractsOsaka {
|
|
PrecompiledAddressesOsaka = append(PrecompiledAddressesOsaka, k)
|
|
}
|
|
}
|
|
|
|
func activePrecompiledContracts(rules params.Rules) PrecompiledContracts {
|
|
switch {
|
|
case rules.IsVerkle:
|
|
return PrecompiledContractsVerkle
|
|
case rules.IsOsaka:
|
|
return PrecompiledContractsOsaka
|
|
case rules.IsPrague:
|
|
return PrecompiledContractsPrague
|
|
case rules.IsCancun:
|
|
return PrecompiledContractsCancun
|
|
case rules.IsBerlin:
|
|
return PrecompiledContractsBerlin
|
|
case rules.IsIstanbul:
|
|
return PrecompiledContractsIstanbul
|
|
case rules.IsByzantium:
|
|
return PrecompiledContractsByzantium
|
|
default:
|
|
return PrecompiledContractsHomestead
|
|
}
|
|
}
|
|
|
|
// ActivePrecompiledContracts returns a copy of precompiled contracts enabled with the current configuration.
|
|
func ActivePrecompiledContracts(rules params.Rules) PrecompiledContracts {
|
|
return maps.Clone(activePrecompiledContracts(rules))
|
|
}
|
|
|
|
// ActivePrecompiles returns the precompile addresses enabled with the current configuration.
|
|
func ActivePrecompiles(rules params.Rules) []common.Address {
|
|
switch {
|
|
case rules.IsOsaka:
|
|
return PrecompiledAddressesOsaka
|
|
case rules.IsPrague:
|
|
return PrecompiledAddressesPrague
|
|
case rules.IsCancun:
|
|
return PrecompiledAddressesCancun
|
|
case rules.IsBerlin:
|
|
return PrecompiledAddressesBerlin
|
|
case rules.IsIstanbul:
|
|
return PrecompiledAddressesIstanbul
|
|
case rules.IsByzantium:
|
|
return PrecompiledAddressesByzantium
|
|
default:
|
|
return PrecompiledAddressesHomestead
|
|
}
|
|
}
|
|
|
|
// RunPrecompiledContract runs and evaluates the output of a precompiled contract.
|
|
// It returns
|
|
// - the returned bytes,
|
|
// - the _remaining_ gas,
|
|
// - any error that occurred
|
|
func RunPrecompiledContract(p PrecompiledContract, input []byte, suppliedGas uint64, logger *tracing.Hooks) (ret []byte, remainingGas uint64, err error) {
|
|
gasCost := p.RequiredGas(input)
|
|
if suppliedGas < gasCost {
|
|
return nil, 0, ErrOutOfGas
|
|
}
|
|
if logger != nil && logger.OnGasChange != nil {
|
|
logger.OnGasChange(suppliedGas, suppliedGas-gasCost, tracing.GasChangeCallPrecompiledContract)
|
|
}
|
|
suppliedGas -= gasCost
|
|
output, err := p.Run(input)
|
|
return output, suppliedGas, err
|
|
}
|
|
|
|
// ecrecover implemented as a native contract.
|
|
type ecrecover struct{}
|
|
|
|
func (c *ecrecover) RequiredGas(input []byte) uint64 {
|
|
return params.EcrecoverGas
|
|
}
|
|
|
|
func (c *ecrecover) Run(input []byte) ([]byte, error) {
|
|
const ecRecoverInputLength = 128
|
|
|
|
input = common.RightPadBytes(input, ecRecoverInputLength)
|
|
// "input" is (hash, v, r, s), each 32 bytes
|
|
// but for ecrecover we want (r, s, v)
|
|
|
|
r := new(big.Int).SetBytes(input[64:96])
|
|
s := new(big.Int).SetBytes(input[96:128])
|
|
v := input[63] - 27
|
|
|
|
// tighter sig s values input homestead only apply to tx sigs
|
|
if bitutil.TestBytes(input[32:63]) || !crypto.ValidateSignatureValues(v, r, s, false) {
|
|
return nil, nil
|
|
}
|
|
// We must make sure not to modify the 'input', so placing the 'v' along with
|
|
// the signature needs to be done on a new allocation
|
|
sig := make([]byte, 65)
|
|
copy(sig, input[64:128])
|
|
sig[64] = v
|
|
// v needs to be at the end for libsecp256k1
|
|
pubKey, err := crypto.Ecrecover(input[:32], sig)
|
|
// make sure the public key is a valid one
|
|
if err != nil {
|
|
return nil, nil
|
|
}
|
|
|
|
// the first byte of pubkey is bitcoin heritage
|
|
return common.LeftPadBytes(crypto.Keccak256(pubKey[1:])[12:], 32), nil
|
|
}
|
|
|
|
func (c *ecrecover) Name() string {
|
|
return "ECREC"
|
|
}
|
|
|
|
// SHA256 implemented as a native contract.
|
|
type sha256hash struct{}
|
|
|
|
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
|
//
|
|
// This method does not require any overflow checking as the input size gas costs
|
|
// required for anything significant is so high it's impossible to pay for.
|
|
func (c *sha256hash) RequiredGas(input []byte) uint64 {
|
|
return uint64(len(input)+31)/32*params.Sha256PerWordGas + params.Sha256BaseGas
|
|
}
|
|
func (c *sha256hash) Run(input []byte) ([]byte, error) {
|
|
h := sha256.Sum256(input)
|
|
return h[:], nil
|
|
}
|
|
|
|
func (c *sha256hash) Name() string {
|
|
return "SHA256"
|
|
}
|
|
|
|
// RIPEMD160 implemented as a native contract.
|
|
type ripemd160hash struct{}
|
|
|
|
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
|
//
|
|
// This method does not require any overflow checking as the input size gas costs
|
|
// required for anything significant is so high it's impossible to pay for.
|
|
func (c *ripemd160hash) RequiredGas(input []byte) uint64 {
|
|
return uint64(len(input)+31)/32*params.Ripemd160PerWordGas + params.Ripemd160BaseGas
|
|
}
|
|
func (c *ripemd160hash) Run(input []byte) ([]byte, error) {
|
|
ripemd := ripemd160.New()
|
|
ripemd.Write(input)
|
|
return common.LeftPadBytes(ripemd.Sum(nil), 32), nil
|
|
}
|
|
|
|
func (c *ripemd160hash) Name() string {
|
|
return "RIPEMD160"
|
|
}
|
|
|
|
// data copy implemented as a native contract.
|
|
type dataCopy struct{}
|
|
|
|
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
|
//
|
|
// This method does not require any overflow checking as the input size gas costs
|
|
// required for anything significant is so high it's impossible to pay for.
|
|
func (c *dataCopy) RequiredGas(input []byte) uint64 {
|
|
return uint64(len(input)+31)/32*params.IdentityPerWordGas + params.IdentityBaseGas
|
|
}
|
|
func (c *dataCopy) Run(in []byte) ([]byte, error) {
|
|
return common.CopyBytes(in), nil
|
|
}
|
|
|
|
func (c *dataCopy) Name() string {
|
|
return "ID"
|
|
}
|
|
|
|
// bigModExp implements a native big integer exponential modular operation.
|
|
type bigModExp struct {
|
|
eip2565 bool
|
|
eip7823 bool
|
|
eip7883 bool
|
|
}
|
|
|
|
// byzantiumMultComplexity implements the bigModexp multComplexity formula, as defined in EIP-198.
|
|
//
|
|
// def mult_complexity(x):
|
|
// if x <= 64: return x ** 2
|
|
// elif x <= 1024: return x ** 2 // 4 + 96 * x - 3072
|
|
// else: return x ** 2 // 16 + 480 * x - 199680
|
|
//
|
|
// where is x is max(length_of_MODULUS, length_of_BASE)
|
|
// returns MaxUint64 if an overflow occurred.
|
|
func byzantiumMultComplexity(x uint64) uint64 {
|
|
switch {
|
|
case x <= 64:
|
|
return x * x
|
|
case x <= 1024:
|
|
// x^2 / 4 + 96*x - 3072
|
|
return x*x/4 + 96*x - 3072
|
|
|
|
default:
|
|
// For large x, use uint256 arithmetic to avoid overflow
|
|
// x^2 / 16 + 480*x - 199680
|
|
|
|
// xSqr = x^2 / 16
|
|
carry, xSqr := bits.Mul64(x, x)
|
|
if carry != 0 {
|
|
return math.MaxUint64
|
|
}
|
|
xSqr = xSqr >> 4
|
|
|
|
// Calculate 480 * x (can't overflow if x^2 didn't overflow)
|
|
x480 := x * 480
|
|
// Calculate 480 * x - 199680 (will not underflow, since x > 1024)
|
|
x480 = x480 - 199680
|
|
|
|
// xSqr + x480
|
|
sum, carry := bits.Add64(xSqr, x480, 0)
|
|
if carry != 0 {
|
|
return math.MaxUint64
|
|
}
|
|
return sum
|
|
}
|
|
}
|
|
|
|
// berlinMultComplexity implements the multiplication complexity formula for Berlin.
|
|
//
|
|
// def mult_complexity(x):
|
|
//
|
|
// ceiling(x/8)^2
|
|
//
|
|
// where is x is max(length_of_MODULUS, length_of_BASE)
|
|
func berlinMultComplexity(x uint64) uint64 {
|
|
// x = (x + 7) / 8
|
|
x, carry := bits.Add64(x, 7, 0)
|
|
if carry != 0 {
|
|
return math.MaxUint64
|
|
}
|
|
x /= 8
|
|
|
|
// x^2
|
|
carry, x = bits.Mul64(x, x)
|
|
if carry != 0 {
|
|
return math.MaxUint64
|
|
}
|
|
return x
|
|
}
|
|
|
|
// osakaMultComplexity implements the multiplication complexity formula for Osaka.
|
|
//
|
|
// For x <= 32: returns 16
|
|
// For x > 32: returns 2 * ceiling(x/8)^2
|
|
func osakaMultComplexity(x uint64) uint64 {
|
|
if x <= 32 {
|
|
return 16
|
|
}
|
|
// For x > 32, return 2 * berlinMultComplexity(x)
|
|
result := berlinMultComplexity(x)
|
|
carry, result := bits.Mul64(result, 2)
|
|
if carry != 0 {
|
|
return math.MaxUint64
|
|
}
|
|
return result
|
|
}
|
|
|
|
// modexpIterationCount calculates the number of iterations for the modexp precompile.
|
|
// This is the adjusted exponent length used in gas calculation.
|
|
func modexpIterationCount(expLen uint64, expHead uint256.Int, multiplier uint64) uint64 {
|
|
var iterationCount uint64
|
|
|
|
// For large exponents (expLen > 32), add (expLen - 32) * multiplier
|
|
if expLen > 32 {
|
|
iterationCount = (expLen - 32) * multiplier
|
|
}
|
|
|
|
// Add the MSB position - 1 if expHead is non-zero
|
|
if bitLen := expHead.BitLen(); bitLen > 0 {
|
|
iterationCount += uint64(bitLen - 1)
|
|
}
|
|
|
|
return max(iterationCount, 1)
|
|
}
|
|
|
|
// byzantiumModexpGas calculates the gas cost for the modexp precompile using Byzantium rules.
|
|
func byzantiumModexpGas(baseLen, expLen, modLen uint64, expHead uint256.Int) uint64 {
|
|
const (
|
|
multiplier = 8
|
|
divisor = 20
|
|
)
|
|
|
|
maxLen := max(baseLen, modLen)
|
|
multComplexity := byzantiumMultComplexity(maxLen)
|
|
if multComplexity == math.MaxUint64 {
|
|
return math.MaxUint64
|
|
}
|
|
iterationCount := modexpIterationCount(expLen, expHead, multiplier)
|
|
|
|
// Calculate gas: (multComplexity * iterationCount) / divisor
|
|
carry, gas := bits.Mul64(iterationCount, multComplexity)
|
|
gas /= divisor
|
|
if carry != 0 {
|
|
return math.MaxUint64
|
|
}
|
|
return gas
|
|
}
|
|
|
|
// berlinModexpGas calculates the gas cost for the modexp precompile using Berlin rules.
|
|
func berlinModexpGas(baseLen, expLen, modLen uint64, expHead uint256.Int) uint64 {
|
|
const (
|
|
multiplier = 8
|
|
divisor = 3
|
|
minGas = 200
|
|
)
|
|
|
|
maxLen := max(baseLen, modLen)
|
|
multComplexity := berlinMultComplexity(maxLen)
|
|
if multComplexity == math.MaxUint64 {
|
|
return math.MaxUint64
|
|
}
|
|
iterationCount := modexpIterationCount(expLen, expHead, multiplier)
|
|
|
|
// Calculate gas: (multComplexity * iterationCount) / divisor
|
|
carry, gas := bits.Mul64(iterationCount, multComplexity)
|
|
gas /= divisor
|
|
if carry != 0 {
|
|
return math.MaxUint64
|
|
}
|
|
return max(gas, minGas)
|
|
}
|
|
|
|
// osakaModexpGas calculates the gas cost for the modexp precompile using Osaka rules.
|
|
func osakaModexpGas(baseLen, expLen, modLen uint64, expHead uint256.Int) uint64 {
|
|
const (
|
|
multiplier = 16
|
|
divisor = 3
|
|
minGas = 500
|
|
)
|
|
|
|
maxLen := max(baseLen, modLen)
|
|
multComplexity := osakaMultComplexity(maxLen)
|
|
if multComplexity == math.MaxUint64 {
|
|
return math.MaxUint64
|
|
}
|
|
iterationCount := modexpIterationCount(expLen, expHead, multiplier)
|
|
|
|
// Calculate gas: (multComplexity * iterationCount) / osakaDivisor
|
|
carry, gas := bits.Mul64(iterationCount, multComplexity)
|
|
if carry != 0 {
|
|
return math.MaxUint64
|
|
}
|
|
return max(gas, minGas)
|
|
}
|
|
|
|
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
|
func (c *bigModExp) RequiredGas(input []byte) uint64 {
|
|
// Parse input lengths
|
|
baseLenBig := new(uint256.Int).SetBytes(getData(input, 0, 32))
|
|
expLenBig := new(uint256.Int).SetBytes(getData(input, 32, 32))
|
|
modLenBig := new(uint256.Int).SetBytes(getData(input, 64, 32))
|
|
|
|
// Convert to uint64, capping at max value
|
|
baseLen := baseLenBig.Uint64()
|
|
if !baseLenBig.IsUint64() {
|
|
baseLen = math.MaxUint64
|
|
}
|
|
expLen := expLenBig.Uint64()
|
|
if !expLenBig.IsUint64() {
|
|
expLen = math.MaxUint64
|
|
}
|
|
modLen := modLenBig.Uint64()
|
|
if !modLenBig.IsUint64() {
|
|
modLen = math.MaxUint64
|
|
}
|
|
|
|
// Skip the header
|
|
if len(input) > 96 {
|
|
input = input[96:]
|
|
} else {
|
|
input = input[:0]
|
|
}
|
|
|
|
// Retrieve the head 32 bytes of exp for the adjusted exponent length
|
|
var expHead uint256.Int
|
|
if uint64(len(input)) > baseLen {
|
|
if expLen > 32 {
|
|
expHead.SetBytes(getData(input, baseLen, 32))
|
|
} else {
|
|
// TODO: Check that if expLen < baseLen, then getData will return an empty slice
|
|
expHead.SetBytes(getData(input, baseLen, expLen))
|
|
}
|
|
}
|
|
|
|
// Choose the appropriate gas calculation based on the EIP flags
|
|
if c.eip7883 {
|
|
return osakaModexpGas(baseLen, expLen, modLen, expHead)
|
|
} else if c.eip2565 {
|
|
return berlinModexpGas(baseLen, expLen, modLen, expHead)
|
|
} else {
|
|
return byzantiumModexpGas(baseLen, expLen, modLen, expHead)
|
|
}
|
|
}
|
|
|
|
func (c *bigModExp) Run(input []byte) ([]byte, error) {
|
|
var (
|
|
baseLenBig = new(big.Int).SetBytes(getData(input, 0, 32))
|
|
expLenBig = new(big.Int).SetBytes(getData(input, 32, 32))
|
|
modLenBig = new(big.Int).SetBytes(getData(input, 64, 32))
|
|
baseLen = baseLenBig.Uint64()
|
|
expLen = expLenBig.Uint64()
|
|
modLen = modLenBig.Uint64()
|
|
inputLenOverflow = max(baseLenBig.BitLen(), expLenBig.BitLen(), modLenBig.BitLen()) > 64
|
|
)
|
|
if len(input) > 96 {
|
|
input = input[96:]
|
|
} else {
|
|
input = input[:0]
|
|
}
|
|
|
|
// enforce size cap for inputs
|
|
if c.eip7823 && (inputLenOverflow || max(baseLen, expLen, modLen) > 1024) {
|
|
return nil, errors.New("one or more of base/exponent/modulus length exceeded 1024 bytes")
|
|
}
|
|
// Handle a special case when both the base and mod length is zero
|
|
if baseLen == 0 && modLen == 0 {
|
|
return []byte{}, nil
|
|
}
|
|
// Retrieve the operands and execute the exponentiation
|
|
var (
|
|
base = new(big.Int).SetBytes(getData(input, 0, baseLen))
|
|
exp = new(big.Int).SetBytes(getData(input, baseLen, expLen))
|
|
mod = new(big.Int).SetBytes(getData(input, baseLen+expLen, modLen))
|
|
v []byte
|
|
)
|
|
switch {
|
|
case mod.BitLen() == 0:
|
|
// Modulo 0 is undefined, return zero
|
|
return common.LeftPadBytes([]byte{}, int(modLen)), nil
|
|
case base.BitLen() == 1: // a bit length of 1 means it's 1 (or -1).
|
|
//If base == 1, then we can just return base % mod (if mod >= 1, which it is)
|
|
v = base.Mod(base, mod).Bytes()
|
|
default:
|
|
v = base.Exp(base, exp, mod).Bytes()
|
|
}
|
|
return common.LeftPadBytes(v, int(modLen)), nil
|
|
}
|
|
|
|
func (c *bigModExp) Name() string {
|
|
return "MODEXP"
|
|
}
|
|
|
|
// newCurvePoint unmarshals a binary blob into a bn256 elliptic curve point,
|
|
// returning it, or an error if the point is invalid.
|
|
func newCurvePoint(blob []byte) (*bn256.G1, error) {
|
|
p := new(bn256.G1)
|
|
if _, err := p.Unmarshal(blob); err != nil {
|
|
return nil, err
|
|
}
|
|
return p, nil
|
|
}
|
|
|
|
// newTwistPoint unmarshals a binary blob into a bn256 elliptic curve point,
|
|
// returning it, or an error if the point is invalid.
|
|
func newTwistPoint(blob []byte) (*bn256.G2, error) {
|
|
p := new(bn256.G2)
|
|
if _, err := p.Unmarshal(blob); err != nil {
|
|
return nil, err
|
|
}
|
|
return p, nil
|
|
}
|
|
|
|
// runBn256Add implements the Bn256Add precompile, referenced by both
|
|
// Byzantium and Istanbul operations.
|
|
func runBn256Add(input []byte) ([]byte, error) {
|
|
x, err := newCurvePoint(getData(input, 0, 64))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
y, err := newCurvePoint(getData(input, 64, 64))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
res := new(bn256.G1)
|
|
res.Add(x, y)
|
|
return res.Marshal(), nil
|
|
}
|
|
|
|
// bn256AddIstanbul implements a native elliptic curve point addition conforming to
|
|
// Istanbul consensus rules.
|
|
type bn256AddIstanbul struct{}
|
|
|
|
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
|
func (c *bn256AddIstanbul) RequiredGas(input []byte) uint64 {
|
|
return params.Bn256AddGasIstanbul
|
|
}
|
|
|
|
func (c *bn256AddIstanbul) Run(input []byte) ([]byte, error) {
|
|
return runBn256Add(input)
|
|
}
|
|
|
|
func (c *bn256AddIstanbul) Name() string {
|
|
return "BN254_ADD"
|
|
}
|
|
|
|
// bn256AddByzantium implements a native elliptic curve point addition
|
|
// conforming to Byzantium consensus rules.
|
|
type bn256AddByzantium struct{}
|
|
|
|
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
|
func (c *bn256AddByzantium) RequiredGas(input []byte) uint64 {
|
|
return params.Bn256AddGasByzantium
|
|
}
|
|
|
|
func (c *bn256AddByzantium) Run(input []byte) ([]byte, error) {
|
|
return runBn256Add(input)
|
|
}
|
|
|
|
func (c *bn256AddByzantium) Name() string {
|
|
return "BN254_ADD"
|
|
}
|
|
|
|
// runBn256ScalarMul implements the Bn256ScalarMul precompile, referenced by
|
|
// both Byzantium and Istanbul operations.
|
|
func runBn256ScalarMul(input []byte) ([]byte, error) {
|
|
p, err := newCurvePoint(getData(input, 0, 64))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
res := new(bn256.G1)
|
|
res.ScalarMult(p, new(big.Int).SetBytes(getData(input, 64, 32)))
|
|
return res.Marshal(), nil
|
|
}
|
|
|
|
// bn256ScalarMulIstanbul implements a native elliptic curve scalar
|
|
// multiplication conforming to Istanbul consensus rules.
|
|
type bn256ScalarMulIstanbul struct{}
|
|
|
|
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
|
func (c *bn256ScalarMulIstanbul) RequiredGas(input []byte) uint64 {
|
|
return params.Bn256ScalarMulGasIstanbul
|
|
}
|
|
|
|
func (c *bn256ScalarMulIstanbul) Run(input []byte) ([]byte, error) {
|
|
return runBn256ScalarMul(input)
|
|
}
|
|
|
|
func (c *bn256ScalarMulIstanbul) Name() string {
|
|
return "BN254_MUL"
|
|
}
|
|
|
|
// bn256ScalarMulByzantium implements a native elliptic curve scalar
|
|
// multiplication conforming to Byzantium consensus rules.
|
|
type bn256ScalarMulByzantium struct{}
|
|
|
|
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
|
func (c *bn256ScalarMulByzantium) RequiredGas(input []byte) uint64 {
|
|
return params.Bn256ScalarMulGasByzantium
|
|
}
|
|
|
|
func (c *bn256ScalarMulByzantium) Run(input []byte) ([]byte, error) {
|
|
return runBn256ScalarMul(input)
|
|
}
|
|
|
|
func (c *bn256ScalarMulByzantium) Name() string {
|
|
return "BN254_MUL"
|
|
}
|
|
|
|
var (
|
|
// true32Byte is returned if the bn256 pairing check succeeds.
|
|
true32Byte = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}
|
|
|
|
// false32Byte is returned if the bn256 pairing check fails.
|
|
false32Byte = make([]byte, 32)
|
|
|
|
// errBadPairingInput is returned if the bn256 pairing input is invalid.
|
|
errBadPairingInput = errors.New("bad elliptic curve pairing size")
|
|
)
|
|
|
|
// runBn256Pairing implements the Bn256Pairing precompile, referenced by both
|
|
// Byzantium and Istanbul operations.
|
|
func runBn256Pairing(input []byte) ([]byte, error) {
|
|
// Handle some corner cases cheaply
|
|
if len(input)%192 > 0 {
|
|
return nil, errBadPairingInput
|
|
}
|
|
// Convert the input into a set of coordinates
|
|
var (
|
|
cs []*bn256.G1
|
|
ts []*bn256.G2
|
|
)
|
|
for i := 0; i < len(input); i += 192 {
|
|
c, err := newCurvePoint(input[i : i+64])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
t, err := newTwistPoint(input[i+64 : i+192])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
cs = append(cs, c)
|
|
ts = append(ts, t)
|
|
}
|
|
// Execute the pairing checks and return the results
|
|
if bn256.PairingCheck(cs, ts) {
|
|
return true32Byte, nil
|
|
}
|
|
return false32Byte, nil
|
|
}
|
|
|
|
// bn256PairingIstanbul implements a pairing pre-compile for the bn256 curve
|
|
// conforming to Istanbul consensus rules.
|
|
type bn256PairingIstanbul struct{}
|
|
|
|
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
|
func (c *bn256PairingIstanbul) RequiredGas(input []byte) uint64 {
|
|
return params.Bn256PairingBaseGasIstanbul + uint64(len(input)/192)*params.Bn256PairingPerPointGasIstanbul
|
|
}
|
|
|
|
func (c *bn256PairingIstanbul) Run(input []byte) ([]byte, error) {
|
|
return runBn256Pairing(input)
|
|
}
|
|
|
|
func (c *bn256PairingIstanbul) Name() string {
|
|
return "BN254_PAIRING"
|
|
}
|
|
|
|
// bn256PairingByzantium implements a pairing pre-compile for the bn256 curve
|
|
// conforming to Byzantium consensus rules.
|
|
type bn256PairingByzantium struct{}
|
|
|
|
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
|
func (c *bn256PairingByzantium) RequiredGas(input []byte) uint64 {
|
|
return params.Bn256PairingBaseGasByzantium + uint64(len(input)/192)*params.Bn256PairingPerPointGasByzantium
|
|
}
|
|
|
|
func (c *bn256PairingByzantium) Run(input []byte) ([]byte, error) {
|
|
return runBn256Pairing(input)
|
|
}
|
|
|
|
func (c *bn256PairingByzantium) Name() string {
|
|
return "BN254_PAIRING"
|
|
}
|
|
|
|
type blake2F struct{}
|
|
|
|
func (c *blake2F) RequiredGas(input []byte) uint64 {
|
|
// If the input is malformed, we can't calculate the gas, return 0 and let the
|
|
// actual call choke and fault.
|
|
if len(input) != blake2FInputLength {
|
|
return 0
|
|
}
|
|
return uint64(binary.BigEndian.Uint32(input[0:4]))
|
|
}
|
|
|
|
const (
|
|
blake2FInputLength = 213
|
|
blake2FFinalBlockBytes = byte(1)
|
|
blake2FNonFinalBlockBytes = byte(0)
|
|
)
|
|
|
|
var (
|
|
errBlake2FInvalidInputLength = errors.New("invalid input length")
|
|
errBlake2FInvalidFinalFlag = errors.New("invalid final flag")
|
|
)
|
|
|
|
func (c *blake2F) Run(input []byte) ([]byte, error) {
|
|
// Make sure the input is valid (correct length and final flag)
|
|
if len(input) != blake2FInputLength {
|
|
return nil, errBlake2FInvalidInputLength
|
|
}
|
|
if input[212] != blake2FNonFinalBlockBytes && input[212] != blake2FFinalBlockBytes {
|
|
return nil, errBlake2FInvalidFinalFlag
|
|
}
|
|
// Parse the input into the Blake2b call parameters
|
|
var (
|
|
rounds = binary.BigEndian.Uint32(input[0:4])
|
|
final = input[212] == blake2FFinalBlockBytes
|
|
|
|
h [8]uint64
|
|
m [16]uint64
|
|
t [2]uint64
|
|
)
|
|
for i := 0; i < 8; i++ {
|
|
offset := 4 + i*8
|
|
h[i] = binary.LittleEndian.Uint64(input[offset : offset+8])
|
|
}
|
|
for i := 0; i < 16; i++ {
|
|
offset := 68 + i*8
|
|
m[i] = binary.LittleEndian.Uint64(input[offset : offset+8])
|
|
}
|
|
t[0] = binary.LittleEndian.Uint64(input[196:204])
|
|
t[1] = binary.LittleEndian.Uint64(input[204:212])
|
|
|
|
// Execute the compression function, extract and return the result
|
|
blake2b.F(&h, m, t, final, rounds)
|
|
|
|
output := make([]byte, 64)
|
|
for i := 0; i < 8; i++ {
|
|
offset := i * 8
|
|
binary.LittleEndian.PutUint64(output[offset:offset+8], h[i])
|
|
}
|
|
return output, nil
|
|
}
|
|
|
|
func (c *blake2F) Name() string {
|
|
return "BLAKE2F"
|
|
}
|
|
|
|
var (
|
|
errBLS12381InvalidInputLength = errors.New("invalid input length")
|
|
errBLS12381InvalidFieldElementTopBytes = errors.New("invalid field element top bytes")
|
|
errBLS12381G1PointSubgroup = errors.New("g1 point is not on correct subgroup")
|
|
errBLS12381G2PointSubgroup = errors.New("g2 point is not on correct subgroup")
|
|
)
|
|
|
|
// bls12381G1Add implements EIP-2537 G1Add precompile.
|
|
type bls12381G1Add struct{}
|
|
|
|
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
|
func (c *bls12381G1Add) RequiredGas(input []byte) uint64 {
|
|
return params.Bls12381G1AddGas
|
|
}
|
|
|
|
func (c *bls12381G1Add) Run(input []byte) ([]byte, error) {
|
|
// Implements EIP-2537 G1Add precompile.
|
|
// > G1 addition call expects `256` bytes as an input that is interpreted as byte concatenation of two G1 points (`128` bytes each).
|
|
// > Output is an encoding of addition operation result - single G1 point (`128` bytes).
|
|
if len(input) != 256 {
|
|
return nil, errBLS12381InvalidInputLength
|
|
}
|
|
var err error
|
|
var p0, p1 *bls12381.G1Affine
|
|
|
|
// Decode G1 point p_0
|
|
if p0, err = decodePointG1(input[:128]); err != nil {
|
|
return nil, err
|
|
}
|
|
// Decode G1 point p_1
|
|
if p1, err = decodePointG1(input[128:]); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// No need to check the subgroup here, as specified by EIP-2537
|
|
|
|
// Compute r = p_0 + p_1
|
|
p0.Add(p0, p1)
|
|
|
|
// Encode the G1 point result into 128 bytes
|
|
return encodePointG1(p0), nil
|
|
}
|
|
|
|
func (c *bls12381G1Add) Name() string {
|
|
return "BLS12_G1ADD"
|
|
}
|
|
|
|
// bls12381G1MultiExp implements EIP-2537 G1MultiExp precompile.
|
|
type bls12381G1MultiExp struct{}
|
|
|
|
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
|
func (c *bls12381G1MultiExp) RequiredGas(input []byte) uint64 {
|
|
// Calculate G1 point, scalar value pair length
|
|
k := len(input) / 160
|
|
if k == 0 {
|
|
// Return 0 gas for small input length
|
|
return 0
|
|
}
|
|
// Lookup discount value for G1 point, scalar value pair length
|
|
var discount uint64
|
|
if dLen := len(params.Bls12381G1MultiExpDiscountTable); k < dLen {
|
|
discount = params.Bls12381G1MultiExpDiscountTable[k-1]
|
|
} else {
|
|
discount = params.Bls12381G1MultiExpDiscountTable[dLen-1]
|
|
}
|
|
// Calculate gas and return the result
|
|
return (uint64(k) * params.Bls12381G1MulGas * discount) / 1000
|
|
}
|
|
|
|
func (c *bls12381G1MultiExp) Run(input []byte) ([]byte, error) {
|
|
// Implements EIP-2537 G1MultiExp precompile.
|
|
// G1 multiplication call expects `160*k` bytes as an input that is interpreted as byte concatenation of `k` slices each of them being a byte concatenation of encoding of G1 point (`128` bytes) and encoding of a scalar value (`32` bytes).
|
|
// Output is an encoding of multiexponentiation operation result - single G1 point (`128` bytes).
|
|
k := len(input) / 160
|
|
if len(input) == 0 || len(input)%160 != 0 {
|
|
return nil, errBLS12381InvalidInputLength
|
|
}
|
|
points := make([]bls12381.G1Affine, k)
|
|
scalars := make([]fr.Element, k)
|
|
|
|
// Decode point scalar pairs
|
|
for i := 0; i < k; i++ {
|
|
off := 160 * i
|
|
t0, t1, t2 := off, off+128, off+160
|
|
// Decode G1 point
|
|
p, err := decodePointG1(input[t0:t1])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// 'point is on curve' check already done,
|
|
// Here we need to apply subgroup checks.
|
|
if !p.IsInSubGroup() {
|
|
return nil, errBLS12381G1PointSubgroup
|
|
}
|
|
points[i] = *p
|
|
// Decode scalar value
|
|
scalars[i] = *new(fr.Element).SetBytes(input[t1:t2])
|
|
}
|
|
|
|
// Compute r = e_0 * p_0 + e_1 * p_1 + ... + e_(k-1) * p_(k-1)
|
|
r := new(bls12381.G1Affine)
|
|
r.MultiExp(points, scalars, ecc.MultiExpConfig{})
|
|
|
|
// Encode the G1 point to 128 bytes
|
|
return encodePointG1(r), nil
|
|
}
|
|
|
|
func (c *bls12381G1MultiExp) Name() string {
|
|
return "BLS12_G1MSM"
|
|
}
|
|
|
|
// bls12381G2Add implements EIP-2537 G2Add precompile.
|
|
type bls12381G2Add struct{}
|
|
|
|
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
|
func (c *bls12381G2Add) RequiredGas(input []byte) uint64 {
|
|
return params.Bls12381G2AddGas
|
|
}
|
|
|
|
func (c *bls12381G2Add) Run(input []byte) ([]byte, error) {
|
|
// Implements EIP-2537 G2Add precompile.
|
|
// > G2 addition call expects `512` bytes as an input that is interpreted as byte concatenation of two G2 points (`256` bytes each).
|
|
// > Output is an encoding of addition operation result - single G2 point (`256` bytes).
|
|
if len(input) != 512 {
|
|
return nil, errBLS12381InvalidInputLength
|
|
}
|
|
var err error
|
|
var p0, p1 *bls12381.G2Affine
|
|
|
|
// Decode G2 point p_0
|
|
if p0, err = decodePointG2(input[:256]); err != nil {
|
|
return nil, err
|
|
}
|
|
// Decode G2 point p_1
|
|
if p1, err = decodePointG2(input[256:]); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// No need to check the subgroup here, as specified by EIP-2537
|
|
|
|
// Compute r = p_0 + p_1
|
|
r := new(bls12381.G2Affine)
|
|
r.Add(p0, p1)
|
|
|
|
// Encode the G2 point into 256 bytes
|
|
return encodePointG2(r), nil
|
|
}
|
|
|
|
func (c *bls12381G2Add) Name() string {
|
|
return "BLS12_G2ADD"
|
|
}
|
|
|
|
// bls12381G2MultiExp implements EIP-2537 G2MultiExp precompile.
|
|
type bls12381G2MultiExp struct{}
|
|
|
|
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
|
func (c *bls12381G2MultiExp) RequiredGas(input []byte) uint64 {
|
|
// Calculate G2 point, scalar value pair length
|
|
k := len(input) / 288
|
|
if k == 0 {
|
|
// Return 0 gas for small input length
|
|
return 0
|
|
}
|
|
// Lookup discount value for G2 point, scalar value pair length
|
|
var discount uint64
|
|
if dLen := len(params.Bls12381G2MultiExpDiscountTable); k < dLen {
|
|
discount = params.Bls12381G2MultiExpDiscountTable[k-1]
|
|
} else {
|
|
discount = params.Bls12381G2MultiExpDiscountTable[dLen-1]
|
|
}
|
|
// Calculate gas and return the result
|
|
return (uint64(k) * params.Bls12381G2MulGas * discount) / 1000
|
|
}
|
|
|
|
func (c *bls12381G2MultiExp) Run(input []byte) ([]byte, error) {
|
|
// Implements EIP-2537 G2MultiExp precompile logic
|
|
// > G2 multiplication call expects `288*k` bytes as an input that is interpreted as byte concatenation of `k` slices each of them being a byte concatenation of encoding of G2 point (`256` bytes) and encoding of a scalar value (`32` bytes).
|
|
// > Output is an encoding of multiexponentiation operation result - single G2 point (`256` bytes).
|
|
k := len(input) / 288
|
|
if len(input) == 0 || len(input)%288 != 0 {
|
|
return nil, errBLS12381InvalidInputLength
|
|
}
|
|
points := make([]bls12381.G2Affine, k)
|
|
scalars := make([]fr.Element, k)
|
|
|
|
// Decode point scalar pairs
|
|
for i := 0; i < k; i++ {
|
|
off := 288 * i
|
|
t0, t1, t2 := off, off+256, off+288
|
|
// Decode G2 point
|
|
p, err := decodePointG2(input[t0:t1])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// 'point is on curve' check already done,
|
|
// Here we need to apply subgroup checks.
|
|
if !p.IsInSubGroup() {
|
|
return nil, errBLS12381G2PointSubgroup
|
|
}
|
|
points[i] = *p
|
|
// Decode scalar value
|
|
scalars[i] = *new(fr.Element).SetBytes(input[t1:t2])
|
|
}
|
|
|
|
// Compute r = e_0 * p_0 + e_1 * p_1 + ... + e_(k-1) * p_(k-1)
|
|
r := new(bls12381.G2Affine)
|
|
r.MultiExp(points, scalars, ecc.MultiExpConfig{})
|
|
|
|
// Encode the G2 point to 256 bytes.
|
|
return encodePointG2(r), nil
|
|
}
|
|
|
|
func (c *bls12381G2MultiExp) Name() string {
|
|
return "BLS12_G2MSM"
|
|
}
|
|
|
|
// bls12381Pairing implements EIP-2537 Pairing precompile.
|
|
type bls12381Pairing struct{}
|
|
|
|
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
|
func (c *bls12381Pairing) RequiredGas(input []byte) uint64 {
|
|
return params.Bls12381PairingBaseGas + uint64(len(input)/384)*params.Bls12381PairingPerPairGas
|
|
}
|
|
|
|
func (c *bls12381Pairing) Run(input []byte) ([]byte, error) {
|
|
// Implements EIP-2537 Pairing precompile logic.
|
|
// > Pairing call expects `384*k` bytes as an inputs that is interpreted as byte concatenation of `k` slices. Each slice has the following structure:
|
|
// > - `128` bytes of G1 point encoding
|
|
// > - `256` bytes of G2 point encoding
|
|
// > Output is a `32` bytes where last single byte is `0x01` if pairing result is equal to multiplicative identity in a pairing target field and `0x00` otherwise
|
|
// > (which is equivalent of Big Endian encoding of Solidity values `uint256(1)` and `uin256(0)` respectively).
|
|
k := len(input) / 384
|
|
if len(input) == 0 || len(input)%384 != 0 {
|
|
return nil, errBLS12381InvalidInputLength
|
|
}
|
|
|
|
var (
|
|
p []bls12381.G1Affine
|
|
q []bls12381.G2Affine
|
|
)
|
|
|
|
// Decode pairs
|
|
for i := 0; i < k; i++ {
|
|
off := 384 * i
|
|
t0, t1, t2 := off, off+128, off+384
|
|
|
|
// Decode G1 point
|
|
p1, err := decodePointG1(input[t0:t1])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// Decode G2 point
|
|
p2, err := decodePointG2(input[t1:t2])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// 'point is on curve' check already done,
|
|
// Here we need to apply subgroup checks.
|
|
if !p1.IsInSubGroup() {
|
|
return nil, errBLS12381G1PointSubgroup
|
|
}
|
|
if !p2.IsInSubGroup() {
|
|
return nil, errBLS12381G2PointSubgroup
|
|
}
|
|
p = append(p, *p1)
|
|
q = append(q, *p2)
|
|
}
|
|
// Prepare 32 byte output
|
|
out := make([]byte, 32)
|
|
|
|
// Compute pairing and set the result
|
|
ok, err := bls12381.PairingCheck(p, q)
|
|
if err == nil && ok {
|
|
out[31] = 1
|
|
}
|
|
return out, nil
|
|
}
|
|
|
|
func (c *bls12381Pairing) Name() string {
|
|
return "BLS12_PAIRING_CHECK"
|
|
}
|
|
|
|
func decodePointG1(in []byte) (*bls12381.G1Affine, error) {
|
|
if len(in) != 128 {
|
|
return nil, errors.New("invalid g1 point length")
|
|
}
|
|
// decode x
|
|
x, err := decodeBLS12381FieldElement(in[:64])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// decode y
|
|
y, err := decodeBLS12381FieldElement(in[64:])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
elem := bls12381.G1Affine{X: x, Y: y}
|
|
if !elem.IsOnCurve() {
|
|
return nil, errors.New("invalid point: not on curve")
|
|
}
|
|
|
|
return &elem, nil
|
|
}
|
|
|
|
// decodePointG2 given encoded (x, y) coordinates in 256 bytes returns a valid G2 Point.
|
|
func decodePointG2(in []byte) (*bls12381.G2Affine, error) {
|
|
if len(in) != 256 {
|
|
return nil, errors.New("invalid g2 point length")
|
|
}
|
|
x0, err := decodeBLS12381FieldElement(in[:64])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
x1, err := decodeBLS12381FieldElement(in[64:128])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
y0, err := decodeBLS12381FieldElement(in[128:192])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
y1, err := decodeBLS12381FieldElement(in[192:])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
p := bls12381.G2Affine{X: bls12381.E2{A0: x0, A1: x1}, Y: bls12381.E2{A0: y0, A1: y1}}
|
|
if !p.IsOnCurve() {
|
|
return nil, errors.New("invalid point: not on curve")
|
|
}
|
|
return &p, err
|
|
}
|
|
|
|
// decodeBLS12381FieldElement decodes BLS12-381 elliptic curve field element.
|
|
// Removes top 16 bytes of 64 byte input.
|
|
func decodeBLS12381FieldElement(in []byte) (fp.Element, error) {
|
|
if len(in) != 64 {
|
|
return fp.Element{}, errors.New("invalid field element length")
|
|
}
|
|
// check top bytes
|
|
for i := 0; i < 16; i++ {
|
|
if in[i] != byte(0x00) {
|
|
return fp.Element{}, errBLS12381InvalidFieldElementTopBytes
|
|
}
|
|
}
|
|
var res [48]byte
|
|
copy(res[:], in[16:])
|
|
|
|
return fp.BigEndian.Element(&res)
|
|
}
|
|
|
|
// encodePointG1 encodes a point into 128 bytes.
|
|
func encodePointG1(p *bls12381.G1Affine) []byte {
|
|
out := make([]byte, 128)
|
|
fp.BigEndian.PutElement((*[fp.Bytes]byte)(out[16:]), p.X)
|
|
fp.BigEndian.PutElement((*[fp.Bytes]byte)(out[64+16:]), p.Y)
|
|
return out
|
|
}
|
|
|
|
// encodePointG2 encodes a point into 256 bytes.
|
|
func encodePointG2(p *bls12381.G2Affine) []byte {
|
|
out := make([]byte, 256)
|
|
// encode x
|
|
fp.BigEndian.PutElement((*[fp.Bytes]byte)(out[16:16+48]), p.X.A0)
|
|
fp.BigEndian.PutElement((*[fp.Bytes]byte)(out[80:80+48]), p.X.A1)
|
|
// encode y
|
|
fp.BigEndian.PutElement((*[fp.Bytes]byte)(out[144:144+48]), p.Y.A0)
|
|
fp.BigEndian.PutElement((*[fp.Bytes]byte)(out[208:208+48]), p.Y.A1)
|
|
return out
|
|
}
|
|
|
|
// bls12381MapG1 implements EIP-2537 MapG1 precompile.
|
|
type bls12381MapG1 struct{}
|
|
|
|
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
|
func (c *bls12381MapG1) RequiredGas(input []byte) uint64 {
|
|
return params.Bls12381MapG1Gas
|
|
}
|
|
|
|
func (c *bls12381MapG1) Run(input []byte) ([]byte, error) {
|
|
// Implements EIP-2537 Map_To_G1 precompile.
|
|
// > Field-to-curve call expects an `64` bytes input that is interpreted as an element of the base field.
|
|
// > Output of this call is `128` bytes and is G1 point following respective encoding rules.
|
|
if len(input) != 64 {
|
|
return nil, errBLS12381InvalidInputLength
|
|
}
|
|
|
|
// Decode input field element
|
|
fe, err := decodeBLS12381FieldElement(input)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Compute mapping
|
|
r := bls12381.MapToG1(fe)
|
|
|
|
// Encode the G1 point to 128 bytes
|
|
return encodePointG1(&r), nil
|
|
}
|
|
|
|
func (c *bls12381MapG1) Name() string {
|
|
return "BLS12_MAP_FP_TO_G1"
|
|
}
|
|
|
|
// bls12381MapG2 implements EIP-2537 MapG2 precompile.
|
|
type bls12381MapG2 struct{}
|
|
|
|
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
|
func (c *bls12381MapG2) RequiredGas(input []byte) uint64 {
|
|
return params.Bls12381MapG2Gas
|
|
}
|
|
|
|
func (c *bls12381MapG2) Run(input []byte) ([]byte, error) {
|
|
// Implements EIP-2537 Map_FP2_TO_G2 precompile logic.
|
|
// > Field-to-curve call expects an `128` bytes input that is interpreted as an element of the quadratic extension field.
|
|
// > Output of this call is `256` bytes and is G2 point following respective encoding rules.
|
|
if len(input) != 128 {
|
|
return nil, errBLS12381InvalidInputLength
|
|
}
|
|
|
|
// Decode input field element
|
|
c0, err := decodeBLS12381FieldElement(input[:64])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
c1, err := decodeBLS12381FieldElement(input[64:])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Compute mapping
|
|
r := bls12381.MapToG2(bls12381.E2{A0: c0, A1: c1})
|
|
|
|
// Encode the G2 point to 256 bytes
|
|
return encodePointG2(&r), nil
|
|
}
|
|
|
|
func (c *bls12381MapG2) Name() string {
|
|
return "BLS12_MAP_FP2_TO_G2"
|
|
}
|
|
|
|
// kzgPointEvaluation implements the EIP-4844 point evaluation precompile.
|
|
type kzgPointEvaluation struct{}
|
|
|
|
// RequiredGas estimates the gas required for running the point evaluation precompile.
|
|
func (b *kzgPointEvaluation) RequiredGas(input []byte) uint64 {
|
|
return params.BlobTxPointEvaluationPrecompileGas
|
|
}
|
|
|
|
const (
|
|
blobVerifyInputLength = 192 // Max input length for the point evaluation precompile.
|
|
blobCommitmentVersionKZG uint8 = 0x01 // Version byte for the point evaluation precompile.
|
|
blobPrecompileReturnValue = "000000000000000000000000000000000000000000000000000000000000100073eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001"
|
|
)
|
|
|
|
var (
|
|
errBlobVerifyInvalidInputLength = errors.New("invalid input length")
|
|
errBlobVerifyMismatchedVersion = errors.New("mismatched versioned hash")
|
|
errBlobVerifyKZGProof = errors.New("error verifying kzg proof")
|
|
)
|
|
|
|
// Run executes the point evaluation precompile.
|
|
func (b *kzgPointEvaluation) Run(input []byte) ([]byte, error) {
|
|
if len(input) != blobVerifyInputLength {
|
|
return nil, errBlobVerifyInvalidInputLength
|
|
}
|
|
// versioned hash: first 32 bytes
|
|
var versionedHash common.Hash
|
|
copy(versionedHash[:], input[:])
|
|
|
|
var (
|
|
point kzg4844.Point
|
|
claim kzg4844.Claim
|
|
)
|
|
// Evaluation point: next 32 bytes
|
|
copy(point[:], input[32:])
|
|
// Expected output: next 32 bytes
|
|
copy(claim[:], input[64:])
|
|
|
|
// input kzg point: next 48 bytes
|
|
var commitment kzg4844.Commitment
|
|
copy(commitment[:], input[96:])
|
|
if kZGToVersionedHash(commitment) != versionedHash {
|
|
return nil, errBlobVerifyMismatchedVersion
|
|
}
|
|
|
|
// Proof: next 48 bytes
|
|
var proof kzg4844.Proof
|
|
copy(proof[:], input[144:])
|
|
|
|
if err := kzg4844.VerifyProof(commitment, point, claim, proof); err != nil {
|
|
return nil, fmt.Errorf("%w: %v", errBlobVerifyKZGProof, err)
|
|
}
|
|
|
|
return common.Hex2Bytes(blobPrecompileReturnValue), nil
|
|
}
|
|
|
|
func (b *kzgPointEvaluation) Name() string {
|
|
return "KZG_POINT_EVALUATION"
|
|
}
|
|
|
|
// kZGToVersionedHash implements kzg_to_versioned_hash from EIP-4844
|
|
func kZGToVersionedHash(kzg kzg4844.Commitment) common.Hash {
|
|
h := sha256.Sum256(kzg[:])
|
|
h[0] = blobCommitmentVersionKZG
|
|
|
|
return h
|
|
}
|
|
|
|
// P256VERIFY (secp256r1 signature verification)
|
|
// implemented as a native contract
|
|
type p256Verify struct{}
|
|
|
|
// RequiredGas returns the gas required to execute the precompiled contract
|
|
func (c *p256Verify) RequiredGas(input []byte) uint64 {
|
|
return params.P256VerifyGas
|
|
}
|
|
|
|
// Run executes the precompiled contract with given 160 bytes of param, returning the output and the used gas
|
|
func (c *p256Verify) Run(input []byte) ([]byte, error) {
|
|
const p256VerifyInputLength = 160
|
|
if len(input) != p256VerifyInputLength {
|
|
return nil, nil
|
|
}
|
|
|
|
// Extract hash, r, s, x, y from the input.
|
|
hash := input[0:32]
|
|
r, s := new(big.Int).SetBytes(input[32:64]), new(big.Int).SetBytes(input[64:96])
|
|
x, y := new(big.Int).SetBytes(input[96:128]), new(big.Int).SetBytes(input[128:160])
|
|
|
|
// Verify the signature.
|
|
if secp256r1.Verify(hash, r, s, x, y) {
|
|
return true32Byte, nil
|
|
}
|
|
return nil, nil
|
|
}
|
|
|
|
func (c *p256Verify) Name() string {
|
|
return "P256VERIFY"
|
|
}
|