diff --git a/go.mod b/go.mod index 28fb09b21bb..e96248755e5 100644 --- a/go.mod +++ b/go.mod @@ -39,6 +39,7 @@ require ( dario.cat/mergo v1.0.1 // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.3.0 // indirect + github.com/bits-and-blooms/bitset v1.14.3 // indirect github.com/boombuler/barcode v1.0.1 // indirect github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect @@ -50,6 +51,7 @@ require ( github.com/hashicorp/hcl v1.0.0 // indirect github.com/holiman/uint256 v1.2.3 // indirect github.com/huandu/xstrings v1.5.0 // indirect + github.com/leanovate/gopter v0.2.11 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect diff --git a/go.sum b/go.sum index b06cc39b62e..43acdd20bae 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +1,50 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg= cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.3.3 h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFDnH08= github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= @@ -17,12 +56,20 @@ github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSC github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apmckinlay/gsuneido v0.0.0-20180907175622-1f10244968e3/go.mod h1:hJnaqxrCRgMCTWtpNz9XUFkBCREiQdlcyK6YNmOfroM= github.com/apmckinlay/gsuneido v0.0.0-20190404155041-0b6cd442a18f/go.mod h1:JU2DOj5Fc6rol0yaT79Csr47QR0vONGwJtBNGRD7jmc= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bits-and-blooms/bitset v1.14.3 h1:Gd2c8lSNf9pKXom5JtD7AaKO8o7fGQ2LtFj1436qilA= +github.com/bits-and-blooms/bitset v1.14.3/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs= github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= @@ -34,16 +81,24 @@ github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMU github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc= github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/d5/tengo/v2 v2.17.0 h1:BWUN9NoJzw48jZKiYDXDIF3QrIVZRm1uV1gTzeZ2lqM= @@ -62,18 +117,26 @@ github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8 github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/ericlagergren/decimal v0.0.0-20180907214518-0bb163153a5d/go.mod h1:1yj25TwtUlJ+pfOu9apAVaM1RWfZGg+aFpd4hPQZekQ= github.com/ethereum/go-ethereum v1.13.5 h1:U6TCRciCqZRe4FPXmy1sMGxTfuk8P7u2UoinF3VbaFk= github.com/ethereum/go-ethereum v1.13.5/go.mod h1:yMTu38GSuyxaYzQMViqNmQ1s3cE84abZexQmTgenWk0= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/friendsofgo/errors v0.9.2 h1:X6NYxef4efCBdwI7BgS820zFaN7Cphrmb+Pljdzjtgk= github.com/friendsofgo/errors v0.9.2/go.mod h1:yCvFW5AkDIL9qn7suHVLiI/gH228n7PC4Pn44IGoTOI= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= @@ -81,6 +144,7 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= @@ -90,19 +154,75 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69 github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= @@ -113,16 +233,42 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDa github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/holiman/uint256 v1.2.3 h1:K8UWO1HUJpRMXBxbmaY1Y8IAMZC/RsKB+ArEnnK4l5o= github.com/holiman/uint256 v1.2.3/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw= github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI= github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kat-co/vala v0.0.0-20170210184112-42e1d8b61f12 h1:DQVOxR9qdYEybJUr/c7ku34r3PfajaMYXZwgDM7KuSk= github.com/kat-co/vala v0.0.0-20170210184112-42e1d8b61f12/go.mod h1:u9MdXq/QageOOSGp7qG4XAQsYUMP+V5zEel/Vrl6OOc= @@ -130,6 +276,7 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -138,39 +285,61 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leanovate/gopter v0.2.11 h1:vRjThO1EKPb/1NsDXuDrzldR28RLkBflWYcU9CvzWu4= +github.com/leanovate/gopter v0.2.11/go.mod h1:aK3tzZP/C+p1m3SPRE4SYZFGP7jjkuSI4f7Xvpt0S9c= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-sqlite3 v1.14.23 h1:gbShiuAP1W5j9UOksQ06aiiqPMxYecovVGwmTxWtuw0= github.com/mattn/go-sqlite3 v1.14.23/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= +github.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= +github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/pquerna/otp v1.4.0 h1:wZvl1TIVxKRThZIBiwOOHOGP/1+nZyWBil9Y2XNEDzg= github.com/pquerna/otp v1.4.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -184,32 +353,49 @@ github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= +github.com/shurcooL/go v0.0.0-20200502201357-93f07166e636/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= +github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/smarty/assertions v1.15.0/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w= github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= @@ -217,6 +403,7 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= +github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -227,12 +414,15 @@ github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/thrasher-corp/gct-ta v0.0.0-20200623072738-f2b55b7f9f41 h1:oFqn2u2F6cnHskAlQ3j702hBbEfn+5bbIl90pQz9IPo= @@ -258,9 +448,23 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= +go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= @@ -271,65 +475,209 @@ go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9i go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190927073244-c990c680b611/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ= golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -337,34 +685,174 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -372,17 +860,29 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/internal/utils/zklink/bn256/fp/arith.go b/internal/utils/zklink/bn256/fp/arith.go new file mode 100644 index 00000000000..1d2f027ee43 --- /dev/null +++ b/internal/utils/zklink/bn256/fp/arith.go @@ -0,0 +1,64 @@ +// Copyright 2020 ConsenSys Software Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by goff (v0.3.6) DO NOT EDIT + +package fp + +import ( + "math/bits" + + "golang.org/x/sys/cpu" +) + +var supportAdx = cpu.X86.HasADX && cpu.X86.HasBMI2 + +// madd0 hi = a*b + c (discards lo bits) +func madd0(a, b, c uint64) (hi uint64) { + var carry, lo uint64 + hi, lo = bits.Mul64(a, b) + _, carry = bits.Add64(lo, c, 0) + hi, _ = bits.Add64(hi, 0, carry) + return +} + +// madd1 hi, lo = a*b + c +func madd1(a, b, c uint64) (hi uint64, lo uint64) { + var carry uint64 + hi, lo = bits.Mul64(a, b) + lo, carry = bits.Add64(lo, c, 0) + hi, _ = bits.Add64(hi, 0, carry) + return +} + +// madd2 hi, lo = a*b + c + d +func madd2(a, b, c, d uint64) (hi uint64, lo uint64) { + var carry uint64 + hi, lo = bits.Mul64(a, b) + c, carry = bits.Add64(c, d, 0) + hi, _ = bits.Add64(hi, 0, carry) + lo, carry = bits.Add64(lo, c, 0) + hi, _ = bits.Add64(hi, 0, carry) + return +} + +func madd3(a, b, c, d, e uint64) (hi uint64, lo uint64) { + var carry uint64 + hi, lo = bits.Mul64(a, b) + c, carry = bits.Add64(c, d, 0) + hi, _ = bits.Add64(hi, 0, carry) + lo, carry = bits.Add64(lo, c, 0) + hi, _ = bits.Add64(hi, e, carry) + return +} diff --git a/internal/utils/zklink/bn256/fp/element.go b/internal/utils/zklink/bn256/fp/element.go new file mode 100644 index 00000000000..31526ac2633 --- /dev/null +++ b/internal/utils/zklink/bn256/fp/element.go @@ -0,0 +1,790 @@ +// Copyright 2020 ConsenSys Software Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by goff (v0.3.6) DO NOT EDIT + +// Package fp contains field arithmetic operations for modulus 21888242871839275222246405745257275088696311157297823662689037894645226208583 +package fp + +// /!\ WARNING /!\ +// this code has not been audited and is provided as-is. In particular, +// there is no security guarantees such as constant time implementation +// or side-channel attack resistance +// /!\ WARNING /!\ + +import ( + "crypto/rand" + "encoding/binary" + "io" + "math/big" + "math/bits" + "strconv" + "sync" +) + +// Element represents a field element stored on 4 words (uint64) +// Element are assumed to be in Montgomery form in all methods +// field modulus q = +// +// 21888242871839275222246405745257275088696311157297823662689037894645226208583 +type Element [4]uint64 + +// Limbs number of 64 bits words needed to represent Element +const Limbs = 4 + +// Bits number bits needed to represent Element +const Bits = 254 + +// field modulus stored as big.Int +var _modulus big.Int +var onceModulus sync.Once + +// Modulus returns q as a big.Int +// q = +// +// 21888242871839275222246405745257275088696311157297823662689037894645226208583 +func Modulus() *big.Int { + onceModulus.Do(func() { + _modulus.SetString("21888242871839275222246405745257275088696311157297823662689037894645226208583", 10) + }) + return new(big.Int).Set(&_modulus) +} + +// q (modulus) +var qElement = Element{ + 4332616871279656263, + 10917124144477883021, + 13281191951274694749, + 3486998266802970665, +} + +// rSquare +var rSquare = Element{ + 17522657719365597833, + 13107472804851548667, + 5164255478447964150, + 493319470278259999, +} + +// Bytes returns the regular (non montgomery) value +// of z as a big-endian byte slice. +func (z *Element) Bytes() []byte { + _z := z.ToRegular() + var res [Limbs * 8]byte + binary.BigEndian.PutUint64(res[24:32], _z[0]) + binary.BigEndian.PutUint64(res[16:24], _z[1]) + binary.BigEndian.PutUint64(res[8:16], _z[2]) + binary.BigEndian.PutUint64(res[0:8], _z[3]) + + return res[:] +} + +// SetBytes interprets e as the bytes of a big-endian unsigned integer, +// sets z to that value (in Montgomery form), and returns z. +func (z *Element) SetBytes(e []byte) *Element { + var tmp big.Int + tmp.SetBytes(e) + z.SetBigInt(&tmp) + return z +} + +// SetUint64 z = v, sets z LSB to v (non-Montgomery form) and convert z to Montgomery form +func (z *Element) SetUint64(v uint64) *Element { + *z = Element{v} + return z.Mul(z, &rSquare) // z.ToMont() +} + +// Set z = x +func (z *Element) Set(x *Element) *Element { + z[0] = x[0] + z[1] = x[1] + z[2] = x[2] + z[3] = x[3] + return z +} + +// SetInterface converts i1 from uint64, int, string, or Element, big.Int into Element +// panic if provided type is not supported +func (z *Element) SetInterface(i1 interface{}) *Element { + switch c1 := i1.(type) { + case Element: + return z.Set(&c1) + case *Element: + return z.Set(c1) + case uint64: + return z.SetUint64(c1) + case int: + return z.SetString(strconv.Itoa(c1)) + case string: + return z.SetString(c1) + case *big.Int: + return z.SetBigInt(c1) + case big.Int: + return z.SetBigInt(&c1) + case []byte: + return z.SetBytes(c1) + default: + panic("invalid type") + } +} + +// SetZero z = 0 +func (z *Element) SetZero() *Element { + z[0] = 0 + z[1] = 0 + z[2] = 0 + z[3] = 0 + return z +} + +// SetOne z = 1 (in Montgomery form) +func (z *Element) SetOne() *Element { + z[0] = 15230403791020821917 + z[1] = 754611498739239741 + z[2] = 7381016538464732716 + z[3] = 1011752739694698287 + return z +} + +// Div z = x*y^-1 mod q +func (z *Element) Div(x, y *Element) *Element { + var yInv Element + yInv.Inverse(y) + z.Mul(x, &yInv) + return z +} + +// Equal returns z == x +func (z *Element) Equal(x *Element) bool { + return (z[3] == x[3]) && (z[2] == x[2]) && (z[1] == x[1]) && (z[0] == x[0]) +} + +// IsZero returns z == 0 +func (z *Element) IsZero() bool { + return (z[3] | z[2] | z[1] | z[0]) == 0 +} + +// SetRandom sets z to a random element < q +func (z *Element) SetRandom() *Element { + bytes := make([]byte, 32) + io.ReadFull(rand.Reader, bytes) + z[0] = binary.BigEndian.Uint64(bytes[0:8]) + z[1] = binary.BigEndian.Uint64(bytes[8:16]) + z[2] = binary.BigEndian.Uint64(bytes[16:24]) + z[3] = binary.BigEndian.Uint64(bytes[24:32]) + z[3] %= 3486998266802970665 + + // if z > q --> z -= q + // note: this is NOT constant time + if !(z[3] < 3486998266802970665 || (z[3] == 3486998266802970665 && (z[2] < 13281191951274694749 || (z[2] == 13281191951274694749 && (z[1] < 10917124144477883021 || (z[1] == 10917124144477883021 && (z[0] < 4332616871279656263))))))) { + var b uint64 + z[0], b = bits.Sub64(z[0], 4332616871279656263, 0) + z[1], b = bits.Sub64(z[1], 10917124144477883021, b) + z[2], b = bits.Sub64(z[2], 13281191951274694749, b) + z[3], _ = bits.Sub64(z[3], 3486998266802970665, b) + } + + return z +} + +// One returns 1 (in montgommery form) +func One() Element { + var one Element + one.SetOne() + return one +} + +// MulAssign is deprecated +// Deprecated: use Mul instead +func (z *Element) MulAssign(x *Element) *Element { + return z.Mul(z, x) +} + +// AddAssign is deprecated +// Deprecated: use Add instead +func (z *Element) AddAssign(x *Element) *Element { + return z.Add(z, x) +} + +// SubAssign is deprecated +// Deprecated: use Sub instead +func (z *Element) SubAssign(x *Element) *Element { + return z.Sub(z, x) +} + +// API with assembly impl + +// Mul z = x * y mod q +// see https://hackmd.io/@zkteam/modular_multiplication +func (z *Element) Mul(x, y *Element) *Element { + mul(z, x, y) + return z +} + +// Square z = x * x mod q +// see https://hackmd.io/@zkteam/modular_multiplication +func (z *Element) Square(x *Element) *Element { + square(z, x) + return z +} + +// FromMont converts z in place (i.e. mutates) from Montgomery to regular representation +// sets and returns z = z * 1 +func (z *Element) FromMont() *Element { + fromMont(z) + return z +} + +// Add z = x + y mod q +func (z *Element) Add(x, y *Element) *Element { + add(z, x, y) + return z +} + +// Double z = x + x mod q, aka Lsh 1 +func (z *Element) Double(x *Element) *Element { + double(z, x) + return z +} + +// Sub z = x - y mod q +func (z *Element) Sub(x, y *Element) *Element { + sub(z, x, y) + return z +} + +// Neg z = q - x +func (z *Element) Neg(x *Element) *Element { + neg(z, x) + return z +} + +// Generic (no ADX instructions, no AMD64) versions of multiplication and squaring algorithms + +func _mulGeneric(z, x, y *Element) { + + var t [4]uint64 + var c [3]uint64 + { + // round 0 + v := x[0] + c[1], c[0] = bits.Mul64(v, y[0]) + m := c[0] * 9786893198990664585 + c[2] = madd0(m, 4332616871279656263, c[0]) + c[1], c[0] = madd1(v, y[1], c[1]) + c[2], t[0] = madd2(m, 10917124144477883021, c[2], c[0]) + c[1], c[0] = madd1(v, y[2], c[1]) + c[2], t[1] = madd2(m, 13281191951274694749, c[2], c[0]) + c[1], c[0] = madd1(v, y[3], c[1]) + t[3], t[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1]) + } + { + // round 1 + v := x[1] + c[1], c[0] = madd1(v, y[0], t[0]) + m := c[0] * 9786893198990664585 + c[2] = madd0(m, 4332616871279656263, c[0]) + c[1], c[0] = madd2(v, y[1], c[1], t[1]) + c[2], t[0] = madd2(m, 10917124144477883021, c[2], c[0]) + c[1], c[0] = madd2(v, y[2], c[1], t[2]) + c[2], t[1] = madd2(m, 13281191951274694749, c[2], c[0]) + c[1], c[0] = madd2(v, y[3], c[1], t[3]) + t[3], t[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1]) + } + { + // round 2 + v := x[2] + c[1], c[0] = madd1(v, y[0], t[0]) + m := c[0] * 9786893198990664585 + c[2] = madd0(m, 4332616871279656263, c[0]) + c[1], c[0] = madd2(v, y[1], c[1], t[1]) + c[2], t[0] = madd2(m, 10917124144477883021, c[2], c[0]) + c[1], c[0] = madd2(v, y[2], c[1], t[2]) + c[2], t[1] = madd2(m, 13281191951274694749, c[2], c[0]) + c[1], c[0] = madd2(v, y[3], c[1], t[3]) + t[3], t[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1]) + } + { + // round 3 + v := x[3] + c[1], c[0] = madd1(v, y[0], t[0]) + m := c[0] * 9786893198990664585 + c[2] = madd0(m, 4332616871279656263, c[0]) + c[1], c[0] = madd2(v, y[1], c[1], t[1]) + c[2], z[0] = madd2(m, 10917124144477883021, c[2], c[0]) + c[1], c[0] = madd2(v, y[2], c[1], t[2]) + c[2], z[1] = madd2(m, 13281191951274694749, c[2], c[0]) + c[1], c[0] = madd2(v, y[3], c[1], t[3]) + z[3], z[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1]) + } + + // if z > q --> z -= q + // note: this is NOT constant time + if !(z[3] < 3486998266802970665 || (z[3] == 3486998266802970665 && (z[2] < 13281191951274694749 || (z[2] == 13281191951274694749 && (z[1] < 10917124144477883021 || (z[1] == 10917124144477883021 && (z[0] < 4332616871279656263))))))) { + var b uint64 + z[0], b = bits.Sub64(z[0], 4332616871279656263, 0) + z[1], b = bits.Sub64(z[1], 10917124144477883021, b) + z[2], b = bits.Sub64(z[2], 13281191951274694749, b) + z[3], _ = bits.Sub64(z[3], 3486998266802970665, b) + } +} + +func _squareGeneric(z, x *Element) { + + var t [4]uint64 + var c [3]uint64 + { + // round 0 + v := x[0] + c[1], c[0] = bits.Mul64(v, x[0]) + m := c[0] * 9786893198990664585 + c[2] = madd0(m, 4332616871279656263, c[0]) + c[1], c[0] = madd1(v, x[1], c[1]) + c[2], t[0] = madd2(m, 10917124144477883021, c[2], c[0]) + c[1], c[0] = madd1(v, x[2], c[1]) + c[2], t[1] = madd2(m, 13281191951274694749, c[2], c[0]) + c[1], c[0] = madd1(v, x[3], c[1]) + t[3], t[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1]) + } + { + // round 1 + v := x[1] + c[1], c[0] = madd1(v, x[0], t[0]) + m := c[0] * 9786893198990664585 + c[2] = madd0(m, 4332616871279656263, c[0]) + c[1], c[0] = madd2(v, x[1], c[1], t[1]) + c[2], t[0] = madd2(m, 10917124144477883021, c[2], c[0]) + c[1], c[0] = madd2(v, x[2], c[1], t[2]) + c[2], t[1] = madd2(m, 13281191951274694749, c[2], c[0]) + c[1], c[0] = madd2(v, x[3], c[1], t[3]) + t[3], t[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1]) + } + { + // round 2 + v := x[2] + c[1], c[0] = madd1(v, x[0], t[0]) + m := c[0] * 9786893198990664585 + c[2] = madd0(m, 4332616871279656263, c[0]) + c[1], c[0] = madd2(v, x[1], c[1], t[1]) + c[2], t[0] = madd2(m, 10917124144477883021, c[2], c[0]) + c[1], c[0] = madd2(v, x[2], c[1], t[2]) + c[2], t[1] = madd2(m, 13281191951274694749, c[2], c[0]) + c[1], c[0] = madd2(v, x[3], c[1], t[3]) + t[3], t[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1]) + } + { + // round 3 + v := x[3] + c[1], c[0] = madd1(v, x[0], t[0]) + m := c[0] * 9786893198990664585 + c[2] = madd0(m, 4332616871279656263, c[0]) + c[1], c[0] = madd2(v, x[1], c[1], t[1]) + c[2], z[0] = madd2(m, 10917124144477883021, c[2], c[0]) + c[1], c[0] = madd2(v, x[2], c[1], t[2]) + c[2], z[1] = madd2(m, 13281191951274694749, c[2], c[0]) + c[1], c[0] = madd2(v, x[3], c[1], t[3]) + z[3], z[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1]) + } + + // if z > q --> z -= q + // note: this is NOT constant time + if !(z[3] < 3486998266802970665 || (z[3] == 3486998266802970665 && (z[2] < 13281191951274694749 || (z[2] == 13281191951274694749 && (z[1] < 10917124144477883021 || (z[1] == 10917124144477883021 && (z[0] < 4332616871279656263))))))) { + var b uint64 + z[0], b = bits.Sub64(z[0], 4332616871279656263, 0) + z[1], b = bits.Sub64(z[1], 10917124144477883021, b) + z[2], b = bits.Sub64(z[2], 13281191951274694749, b) + z[3], _ = bits.Sub64(z[3], 3486998266802970665, b) + } +} + +func _fromMontGeneric(z *Element) { + // the following lines implement z = z * 1 + // with a modified CIOS montgomery multiplication + { + // m = z[0]n'[0] mod W + m := z[0] * 9786893198990664585 + C := madd0(m, 4332616871279656263, z[0]) + C, z[0] = madd2(m, 10917124144477883021, z[1], C) + C, z[1] = madd2(m, 13281191951274694749, z[2], C) + C, z[2] = madd2(m, 3486998266802970665, z[3], C) + z[3] = C + } + { + // m = z[0]n'[0] mod W + m := z[0] * 9786893198990664585 + C := madd0(m, 4332616871279656263, z[0]) + C, z[0] = madd2(m, 10917124144477883021, z[1], C) + C, z[1] = madd2(m, 13281191951274694749, z[2], C) + C, z[2] = madd2(m, 3486998266802970665, z[3], C) + z[3] = C + } + { + // m = z[0]n'[0] mod W + m := z[0] * 9786893198990664585 + C := madd0(m, 4332616871279656263, z[0]) + C, z[0] = madd2(m, 10917124144477883021, z[1], C) + C, z[1] = madd2(m, 13281191951274694749, z[2], C) + C, z[2] = madd2(m, 3486998266802970665, z[3], C) + z[3] = C + } + { + // m = z[0]n'[0] mod W + m := z[0] * 9786893198990664585 + C := madd0(m, 4332616871279656263, z[0]) + C, z[0] = madd2(m, 10917124144477883021, z[1], C) + C, z[1] = madd2(m, 13281191951274694749, z[2], C) + C, z[2] = madd2(m, 3486998266802970665, z[3], C) + z[3] = C + } + + // if z > q --> z -= q + // note: this is NOT constant time + if !(z[3] < 3486998266802970665 || (z[3] == 3486998266802970665 && (z[2] < 13281191951274694749 || (z[2] == 13281191951274694749 && (z[1] < 10917124144477883021 || (z[1] == 10917124144477883021 && (z[0] < 4332616871279656263))))))) { + var b uint64 + z[0], b = bits.Sub64(z[0], 4332616871279656263, 0) + z[1], b = bits.Sub64(z[1], 10917124144477883021, b) + z[2], b = bits.Sub64(z[2], 13281191951274694749, b) + z[3], _ = bits.Sub64(z[3], 3486998266802970665, b) + } +} + +// Exp z = x^exponent mod q +func (z *Element) Exp(x Element, exponent *big.Int) *Element { + var bZero big.Int + if exponent.Cmp(&bZero) == 0 { + return z.SetOne() + } + + z.Set(&x) + + for i := exponent.BitLen() - 2; i >= 0; i-- { + z.Square(z) + if exponent.Bit(i) == 1 { + z.Mul(z, &x) + } + } + + return z +} + +// ToMont converts z to Montgomery form +// sets and returns z = z * r^2 +func (z *Element) ToMont() *Element { + return z.Mul(z, &rSquare) +} + +// ToRegular returns z in regular form (doesn't mutate z) +func (z Element) ToRegular() Element { + return *z.FromMont() +} + +// String returns the string form of an Element in Montgomery form +func (z *Element) String() string { + var _z big.Int + return z.ToBigIntRegular(&_z).String() +} + +// ToBigInt returns z as a big.Int in Montgomery form +func (z *Element) ToBigInt(res *big.Int) *big.Int { + var b [Limbs * 8]byte + binary.BigEndian.PutUint64(b[24:32], z[0]) + binary.BigEndian.PutUint64(b[16:24], z[1]) + binary.BigEndian.PutUint64(b[8:16], z[2]) + binary.BigEndian.PutUint64(b[0:8], z[3]) + + return res.SetBytes(b[:]) +} + +// ToBigIntRegular returns z as a big.Int in regular form +func (z Element) ToBigIntRegular(res *big.Int) *big.Int { + z.FromMont() + return z.ToBigInt(res) +} + +// SetBigInt sets z to v (regular form) and returns z in Montgomery form +func (z *Element) SetBigInt(v *big.Int) *Element { + z.SetZero() + + var zero big.Int + q := Modulus() + + // fast path + c := v.Cmp(q) + if c == 0 { + // v == 0 + return z + } else if c != 1 && v.Cmp(&zero) != -1 { + // 0 < v < q + return z.setBigInt(v) + } + + // copy input + modular reduction + vv := new(big.Int).Set(v) + vv.Mod(v, q) + + return z.setBigInt(vv) +} + +// setBigInt assumes 0 <= v < q +func (z *Element) setBigInt(v *big.Int) *Element { + vBits := v.Bits() + + if bits.UintSize == 64 { + for i := 0; i < len(vBits); i++ { + z[i] = uint64(vBits[i]) + } + } else { + for i := 0; i < len(vBits); i++ { + if i%2 == 0 { + z[i/2] = uint64(vBits[i]) + } else { + z[i/2] |= uint64(vBits[i]) << 32 + } + } + } + + return z.ToMont() +} + +// SetString creates a big.Int with s (in base 10) and calls SetBigInt on z +func (z *Element) SetString(s string) *Element { + x, ok := new(big.Int).SetString(s, 10) + if !ok { + panic("Element.SetString failed -> can't parse number in base10 into a big.Int") + } + return z.SetBigInt(x) +} + +var ( + _bLegendreExponentElement *big.Int + _bSqrtExponentElement *big.Int +) + +func init() { + _bLegendreExponentElement, _ = new(big.Int).SetString("183227397098d014dc2822db40c0ac2ecbc0b548b438e5469e10460b6c3e7ea3", 16) + const sqrtExponentElement = "c19139cb84c680a6e14116da060561765e05aa45a1c72a34f082305b61f3f52" + _bSqrtExponentElement, _ = new(big.Int).SetString(sqrtExponentElement, 16) +} + +// Legendre returns the Legendre symbol of z (either +1, -1, or 0.) +func (z *Element) Legendre() int { + var l Element + // z^((q-1)/2) + l.Exp(*z, _bLegendreExponentElement) + + if l.IsZero() { + return 0 + } + + // if l == 1 + if (l[3] == 1011752739694698287) && (l[2] == 7381016538464732716) && (l[1] == 754611498739239741) && (l[0] == 15230403791020821917) { + return 1 + } + return -1 +} + +// Sqrt z = √x mod q +// if the square root doesn't exist (x is not a square mod q) +// Sqrt leaves z unchanged and returns nil +func (z *Element) Sqrt(x *Element) *Element { + // q ≡ 3 (mod 4) + // using z ≡ ± x^((p+1)/4) (mod q) + var y, square Element + y.Exp(*x, _bSqrtExponentElement) + // as we didn't compute the legendre symbol, ensure we found y such that y * y = x + square.Square(&y) + if square.Equal(x) { + return z.Set(&y) + } + return nil +} + +// Inverse z = x^-1 mod q +// Algorithm 16 in "Efficient Software-Implementation of Finite Fields with Applications to Cryptography" +// if x == 0, sets and returns z = x +func (z *Element) Inverse(x *Element) *Element { + if x.IsZero() { + return z.Set(x) + } + + // initialize u = q + var u = Element{ + 4332616871279656263, + 10917124144477883021, + 13281191951274694749, + 3486998266802970665, + } + + // initialize s = r^2 + var s = Element{ + 17522657719365597833, + 13107472804851548667, + 5164255478447964150, + 493319470278259999, + } + + // r = 0 + r := Element{} + + v := *x + + var carry, borrow, t, t2 uint64 + var bigger, uIsOne, vIsOne bool + + for !uIsOne && !vIsOne { + for v[0]&1 == 0 { + + // v = v >> 1 + t2 = v[3] << 63 + v[3] >>= 1 + t = t2 + t2 = v[2] << 63 + v[2] = (v[2] >> 1) | t + t = t2 + t2 = v[1] << 63 + v[1] = (v[1] >> 1) | t + t = t2 + v[0] = (v[0] >> 1) | t + + if s[0]&1 == 1 { + + // s = s + q + s[0], carry = bits.Add64(s[0], 4332616871279656263, 0) + s[1], carry = bits.Add64(s[1], 10917124144477883021, carry) + s[2], carry = bits.Add64(s[2], 13281191951274694749, carry) + s[3], _ = bits.Add64(s[3], 3486998266802970665, carry) + + } + + // s = s >> 1 + t2 = s[3] << 63 + s[3] >>= 1 + t = t2 + t2 = s[2] << 63 + s[2] = (s[2] >> 1) | t + t = t2 + t2 = s[1] << 63 + s[1] = (s[1] >> 1) | t + t = t2 + s[0] = (s[0] >> 1) | t + + } + for u[0]&1 == 0 { + + // u = u >> 1 + t2 = u[3] << 63 + u[3] >>= 1 + t = t2 + t2 = u[2] << 63 + u[2] = (u[2] >> 1) | t + t = t2 + t2 = u[1] << 63 + u[1] = (u[1] >> 1) | t + t = t2 + u[0] = (u[0] >> 1) | t + + if r[0]&1 == 1 { + + // r = r + q + r[0], carry = bits.Add64(r[0], 4332616871279656263, 0) + r[1], carry = bits.Add64(r[1], 10917124144477883021, carry) + r[2], carry = bits.Add64(r[2], 13281191951274694749, carry) + r[3], _ = bits.Add64(r[3], 3486998266802970665, carry) + + } + + // r = r >> 1 + t2 = r[3] << 63 + r[3] >>= 1 + t = t2 + t2 = r[2] << 63 + r[2] = (r[2] >> 1) | t + t = t2 + t2 = r[1] << 63 + r[1] = (r[1] >> 1) | t + t = t2 + r[0] = (r[0] >> 1) | t + + } + + // v >= u + bigger = !(v[3] < u[3] || (v[3] == u[3] && (v[2] < u[2] || (v[2] == u[2] && (v[1] < u[1] || (v[1] == u[1] && (v[0] < u[0]))))))) + + if bigger { + + // v = v - u + v[0], borrow = bits.Sub64(v[0], u[0], 0) + v[1], borrow = bits.Sub64(v[1], u[1], borrow) + v[2], borrow = bits.Sub64(v[2], u[2], borrow) + v[3], _ = bits.Sub64(v[3], u[3], borrow) + + // r >= s + bigger = !(r[3] < s[3] || (r[3] == s[3] && (r[2] < s[2] || (r[2] == s[2] && (r[1] < s[1] || (r[1] == s[1] && (r[0] < s[0]))))))) + + if bigger { + + // s = s + q + s[0], carry = bits.Add64(s[0], 4332616871279656263, 0) + s[1], carry = bits.Add64(s[1], 10917124144477883021, carry) + s[2], carry = bits.Add64(s[2], 13281191951274694749, carry) + s[3], _ = bits.Add64(s[3], 3486998266802970665, carry) + + } + + // s = s - r + s[0], borrow = bits.Sub64(s[0], r[0], 0) + s[1], borrow = bits.Sub64(s[1], r[1], borrow) + s[2], borrow = bits.Sub64(s[2], r[2], borrow) + s[3], _ = bits.Sub64(s[3], r[3], borrow) + + } else { + + // u = u - v + u[0], borrow = bits.Sub64(u[0], v[0], 0) + u[1], borrow = bits.Sub64(u[1], v[1], borrow) + u[2], borrow = bits.Sub64(u[2], v[2], borrow) + u[3], _ = bits.Sub64(u[3], v[3], borrow) + + // s >= r + bigger = !(s[3] < r[3] || (s[3] == r[3] && (s[2] < r[2] || (s[2] == r[2] && (s[1] < r[1] || (s[1] == r[1] && (s[0] < r[0]))))))) + + if bigger { + + // r = r + q + r[0], carry = bits.Add64(r[0], 4332616871279656263, 0) + r[1], carry = bits.Add64(r[1], 10917124144477883021, carry) + r[2], carry = bits.Add64(r[2], 13281191951274694749, carry) + r[3], _ = bits.Add64(r[3], 3486998266802970665, carry) + + } + + // r = r - s + r[0], borrow = bits.Sub64(r[0], s[0], 0) + r[1], borrow = bits.Sub64(r[1], s[1], borrow) + r[2], borrow = bits.Sub64(r[2], s[2], borrow) + r[3], _ = bits.Sub64(r[3], s[3], borrow) + + } + uIsOne = (u[0] == 1) && (u[3]|u[2]|u[1]) == 0 + vIsOne = (v[0] == 1) && (v[3]|v[2]|v[1]) == 0 + } + + if uIsOne { + z.Set(&r) + } else { + z.Set(&s) + } + + return z +} diff --git a/internal/utils/zklink/bn256/fp/element_ops_amd64.go b/internal/utils/zklink/bn256/fp/element_ops_amd64.go new file mode 100644 index 00000000000..10069fa4326 --- /dev/null +++ b/internal/utils/zklink/bn256/fp/element_ops_amd64.go @@ -0,0 +1,47 @@ +// Copyright 2020 ConsenSys Software Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by goff (v0.3.6) DO NOT EDIT + +package fp + +// q'[0], see montgommery multiplication algorithm +var ( + qElementInv0 uint64 = 9786893198990664585 + _ = qElementInv0 // used in asm +) + +//go:noescape +func add(res, x, y *Element) + +//go:noescape +func sub(res, x, y *Element) + +//go:noescape +func neg(res, x *Element) + +//go:noescape +func double(res, x *Element) + +//go:noescape +func mul(res, x, y *Element) + +//go:noescape +func square(res, x *Element) + +//go:noescape +func fromMont(res *Element) + +//go:noescape +func reduce(res *Element) diff --git a/internal/utils/zklink/bn256/fp/element_ops_amd64.s b/internal/utils/zklink/bn256/fp/element_ops_amd64.s new file mode 100644 index 00000000000..371f3aca8df --- /dev/null +++ b/internal/utils/zklink/bn256/fp/element_ops_amd64.s @@ -0,0 +1,1166 @@ + + // Copyright 2020 ConsenSys Software Inc. + // + // Licensed under the Apache License, Version 2.0 (the "License"); + // you may not use this file except in compliance with the License. + // You may obtain a copy of the License at + // + // http://www.apache.org/licenses/LICENSE-2.0 + // + // Unless required by applicable law or agreed to in writing, software + // distributed under the License is distributed on an "AS IS" BASIS, + // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + // See the License for the specific language governing permissions and + // limitations under the License. + +#include "textflag.h" +#include "funcdata.h" + +TEXT ·mul(SB), NOSPLIT, $0-24 + + // the algorithm is described here + // https://hackmd.io/@zkteam/modular_multiplication + // however, to benefit from the ADCX and ADOX carry chains + // we split the inner loops in 2: + // for i=0 to N-1 + // for j=0 to N-1 + // (A,t[j]) := t[j] + x[j]*y[i] + A + // m := t[0]*q'[0] mod W + // C,_ := t[0] + m*q[0] + // for j=1 to N-1 + // (C,t[j-1]) := t[j] + m*q[j] + C + // t[N-1] = C + A + + CMPB ·supportAdx(SB), $0x0000000000000001 + JNE l5 + MOVQ x+8(FP), R14 + MOVQ y+16(FP), R15 + XORQ DX, DX + MOVQ 0(R15), DX + MULXQ 0(R14), CX, BX + MULXQ 8(R14), AX, BP + ADOXQ AX, BX + MULXQ 16(R14), AX, SI + ADOXQ AX, BP + MULXQ 24(R14), AX, DI + ADOXQ AX, SI + // add the last carries to DI + MOVQ $0x0000000000000000, DX + ADCXQ DX, DI + ADOXQ DX, DI + MOVQ CX, DX + MULXQ ·qElementInv0(SB), DX, AX // m := t[0]*q'[0] mod W + XORQ AX, AX + // C,_ := t[0] + m*q[0] + MULXQ ·qElement+0(SB), AX, R8 + ADCXQ CX, AX + MOVQ R8, CX + // for j=1 to N-1 + // (C,t[j-1]) := t[j] + m*q[j] + C + ADCXQ BX, CX + MULXQ ·qElement+8(SB), AX, BX + ADOXQ AX, CX + ADCXQ BP, BX + MULXQ ·qElement+16(SB), AX, BP + ADOXQ AX, BX + ADCXQ SI, BP + MULXQ ·qElement+24(SB), AX, SI + ADOXQ AX, BP + MOVQ $0x0000000000000000, AX + ADCXQ AX, SI + ADOXQ DI, SI + XORQ DX, DX + MOVQ 8(R15), DX + MULXQ 0(R14), AX, DI + ADOXQ AX, CX + ADCXQ DI, BX + MULXQ 8(R14), AX, DI + ADOXQ AX, BX + ADCXQ DI, BP + MULXQ 16(R14), AX, DI + ADOXQ AX, BP + ADCXQ DI, SI + MULXQ 24(R14), AX, DI + ADOXQ AX, SI + // add the last carries to DI + MOVQ $0x0000000000000000, DX + ADCXQ DX, DI + ADOXQ DX, DI + MOVQ CX, DX + MULXQ ·qElementInv0(SB), DX, AX // m := t[0]*q'[0] mod W + XORQ AX, AX + // C,_ := t[0] + m*q[0] + MULXQ ·qElement+0(SB), AX, R9 + ADCXQ CX, AX + MOVQ R9, CX + // for j=1 to N-1 + // (C,t[j-1]) := t[j] + m*q[j] + C + ADCXQ BX, CX + MULXQ ·qElement+8(SB), AX, BX + ADOXQ AX, CX + ADCXQ BP, BX + MULXQ ·qElement+16(SB), AX, BP + ADOXQ AX, BX + ADCXQ SI, BP + MULXQ ·qElement+24(SB), AX, SI + ADOXQ AX, BP + MOVQ $0x0000000000000000, AX + ADCXQ AX, SI + ADOXQ DI, SI + XORQ DX, DX + MOVQ 16(R15), DX + MULXQ 0(R14), AX, DI + ADOXQ AX, CX + ADCXQ DI, BX + MULXQ 8(R14), AX, DI + ADOXQ AX, BX + ADCXQ DI, BP + MULXQ 16(R14), AX, DI + ADOXQ AX, BP + ADCXQ DI, SI + MULXQ 24(R14), AX, DI + ADOXQ AX, SI + // add the last carries to DI + MOVQ $0x0000000000000000, DX + ADCXQ DX, DI + ADOXQ DX, DI + MOVQ CX, DX + MULXQ ·qElementInv0(SB), DX, AX // m := t[0]*q'[0] mod W + XORQ AX, AX + // C,_ := t[0] + m*q[0] + MULXQ ·qElement+0(SB), AX, R10 + ADCXQ CX, AX + MOVQ R10, CX + // for j=1 to N-1 + // (C,t[j-1]) := t[j] + m*q[j] + C + ADCXQ BX, CX + MULXQ ·qElement+8(SB), AX, BX + ADOXQ AX, CX + ADCXQ BP, BX + MULXQ ·qElement+16(SB), AX, BP + ADOXQ AX, BX + ADCXQ SI, BP + MULXQ ·qElement+24(SB), AX, SI + ADOXQ AX, BP + MOVQ $0x0000000000000000, AX + ADCXQ AX, SI + ADOXQ DI, SI + XORQ DX, DX + MOVQ 24(R15), DX + MULXQ 0(R14), AX, DI + ADOXQ AX, CX + ADCXQ DI, BX + MULXQ 8(R14), AX, DI + ADOXQ AX, BX + ADCXQ DI, BP + MULXQ 16(R14), AX, DI + ADOXQ AX, BP + ADCXQ DI, SI + MULXQ 24(R14), AX, DI + ADOXQ AX, SI + // add the last carries to DI + MOVQ $0x0000000000000000, DX + ADCXQ DX, DI + ADOXQ DX, DI + MOVQ CX, DX + MULXQ ·qElementInv0(SB), DX, AX // m := t[0]*q'[0] mod W + XORQ AX, AX + // C,_ := t[0] + m*q[0] + MULXQ ·qElement+0(SB), AX, R11 + ADCXQ CX, AX + MOVQ R11, CX + // for j=1 to N-1 + // (C,t[j-1]) := t[j] + m*q[j] + C + ADCXQ BX, CX + MULXQ ·qElement+8(SB), AX, BX + ADOXQ AX, CX + ADCXQ BP, BX + MULXQ ·qElement+16(SB), AX, BP + ADOXQ AX, BX + ADCXQ SI, BP + MULXQ ·qElement+24(SB), AX, SI + ADOXQ AX, BP + MOVQ $0x0000000000000000, AX + ADCXQ AX, SI + ADOXQ DI, SI + MOVQ res+0(FP), R12 + MOVQ CX, R13 + MOVQ BX, R8 + MOVQ BP, R9 + MOVQ SI, R10 + SUBQ ·qElement+0(SB), R13 + SBBQ ·qElement+8(SB), R8 + SBBQ ·qElement+16(SB), R9 + SBBQ ·qElement+24(SB), R10 + CMOVQCC R13, CX + CMOVQCC R8, BX + CMOVQCC R9, BP + CMOVQCC R10, SI + MOVQ CX, 0(R12) + MOVQ BX, 8(R12) + MOVQ BP, 16(R12) + MOVQ SI, 24(R12) + RET +l5: + MOVQ x+8(FP), R15 + MOVQ y+16(FP), R14 + MOVQ 0(R15), AX + MOVQ 0(R14), R8 + MULQ R8 + MOVQ AX, CX + MOVQ DX, R9 + MOVQ ·qElementInv0(SB), R10 + IMULQ CX, R10 + MOVQ $0x3c208c16d87cfd47, AX + MULQ R10 + ADDQ CX, AX + ADCQ $0x0000000000000000, DX + MOVQ DX, DI + MOVQ 8(R15), AX + MULQ R8 + MOVQ R9, BX + ADDQ AX, BX + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0x97816a916871ca8d, AX + MULQ R10 + ADDQ BX, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, CX + MOVQ DX, DI + MOVQ 16(R15), AX + MULQ R8 + MOVQ R9, BP + ADDQ AX, BP + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0xb85045b68181585d, AX + MULQ R10 + ADDQ BP, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, BX + MOVQ DX, DI + MOVQ 24(R15), AX + MULQ R8 + MOVQ R9, SI + ADDQ AX, SI + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0x30644e72e131a029, AX + MULQ R10 + ADDQ SI, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, BP + MOVQ DX, DI + ADDQ DI, R9 + MOVQ R9, SI + MOVQ 0(R15), AX + MOVQ 8(R14), R8 + MULQ R8 + ADDQ AX, CX + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ ·qElementInv0(SB), R10 + IMULQ CX, R10 + MOVQ $0x3c208c16d87cfd47, AX + MULQ R10 + ADDQ CX, AX + ADCQ $0x0000000000000000, DX + MOVQ DX, DI + MOVQ 8(R15), AX + MULQ R8 + ADDQ R9, BX + ADCQ $0x0000000000000000, DX + ADDQ AX, BX + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0x97816a916871ca8d, AX + MULQ R10 + ADDQ BX, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, CX + MOVQ DX, DI + MOVQ 16(R15), AX + MULQ R8 + ADDQ R9, BP + ADCQ $0x0000000000000000, DX + ADDQ AX, BP + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0xb85045b68181585d, AX + MULQ R10 + ADDQ BP, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, BX + MOVQ DX, DI + MOVQ 24(R15), AX + MULQ R8 + ADDQ R9, SI + ADCQ $0x0000000000000000, DX + ADDQ AX, SI + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0x30644e72e131a029, AX + MULQ R10 + ADDQ SI, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, BP + MOVQ DX, DI + ADDQ DI, R9 + MOVQ R9, SI + MOVQ 0(R15), AX + MOVQ 16(R14), R8 + MULQ R8 + ADDQ AX, CX + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ ·qElementInv0(SB), R10 + IMULQ CX, R10 + MOVQ $0x3c208c16d87cfd47, AX + MULQ R10 + ADDQ CX, AX + ADCQ $0x0000000000000000, DX + MOVQ DX, DI + MOVQ 8(R15), AX + MULQ R8 + ADDQ R9, BX + ADCQ $0x0000000000000000, DX + ADDQ AX, BX + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0x97816a916871ca8d, AX + MULQ R10 + ADDQ BX, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, CX + MOVQ DX, DI + MOVQ 16(R15), AX + MULQ R8 + ADDQ R9, BP + ADCQ $0x0000000000000000, DX + ADDQ AX, BP + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0xb85045b68181585d, AX + MULQ R10 + ADDQ BP, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, BX + MOVQ DX, DI + MOVQ 24(R15), AX + MULQ R8 + ADDQ R9, SI + ADCQ $0x0000000000000000, DX + ADDQ AX, SI + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0x30644e72e131a029, AX + MULQ R10 + ADDQ SI, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, BP + MOVQ DX, DI + ADDQ DI, R9 + MOVQ R9, SI + MOVQ 0(R15), AX + MOVQ 24(R14), R8 + MULQ R8 + ADDQ AX, CX + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ ·qElementInv0(SB), R10 + IMULQ CX, R10 + MOVQ $0x3c208c16d87cfd47, AX + MULQ R10 + ADDQ CX, AX + ADCQ $0x0000000000000000, DX + MOVQ DX, DI + MOVQ 8(R15), AX + MULQ R8 + ADDQ R9, BX + ADCQ $0x0000000000000000, DX + ADDQ AX, BX + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0x97816a916871ca8d, AX + MULQ R10 + ADDQ BX, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, CX + MOVQ DX, DI + MOVQ 16(R15), AX + MULQ R8 + ADDQ R9, BP + ADCQ $0x0000000000000000, DX + ADDQ AX, BP + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0xb85045b68181585d, AX + MULQ R10 + ADDQ BP, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, BX + MOVQ DX, DI + MOVQ 24(R15), AX + MULQ R8 + ADDQ R9, SI + ADCQ $0x0000000000000000, DX + ADDQ AX, SI + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0x30644e72e131a029, AX + MULQ R10 + ADDQ SI, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, BP + MOVQ DX, DI + ADDQ DI, R9 + MOVQ R9, SI + MOVQ res+0(FP), R15 + MOVQ CX, R11 + MOVQ BX, R12 + MOVQ BP, R13 + MOVQ SI, DI + SUBQ ·qElement+0(SB), R11 + SBBQ ·qElement+8(SB), R12 + SBBQ ·qElement+16(SB), R13 + SBBQ ·qElement+24(SB), DI + CMOVQCC R11, CX + CMOVQCC R12, BX + CMOVQCC R13, BP + CMOVQCC DI, SI + MOVQ CX, 0(R15) + MOVQ BX, 8(R15) + MOVQ BP, 16(R15) + MOVQ SI, 24(R15) + RET + +TEXT ·square(SB), NOSPLIT, $0-16 + + // the algorithm is described here + // https://hackmd.io/@zkteam/modular_multiplication + // for i=0 to N-1 + // A, t[i] = x[i] * x[i] + t[i] + // p = 0 + // for j=i+1 to N-1 + // p,A,t[j] = 2*x[j]*x[i] + t[j] + (p,A) + // m = t[0] * q'[0] + // C, _ = t[0] + q[0]*m + // for j=1 to N-1 + // C, t[j-1] = q[j]*m + t[j] + C + // t[N-1] = C + A + + + CMPB ·supportAdx(SB), $0x0000000000000001 + JNE l6 + MOVQ x+8(FP), BP + XORQ AX, AX + MOVQ 0(BP), DX + MULXQ 8(BP), DI, R8 + MULXQ 16(BP), AX, R9 + ADCXQ AX, R8 + MULXQ 24(BP), AX, SI + ADCXQ AX, R9 + MOVQ $0x0000000000000000, AX + ADCXQ AX, SI + XORQ AX, AX + MULXQ DX, R14, DX + ADCXQ DI, DI + MOVQ DI, R15 + ADOXQ DX, R15 + ADCXQ R8, R8 + MOVQ R8, CX + ADOXQ AX, CX + ADCXQ R9, R9 + MOVQ R9, BX + ADOXQ AX, BX + ADCXQ SI, SI + ADOXQ AX, SI + MOVQ R14, DX + MULXQ ·qElementInv0(SB), DX, AX // m := t[0]*q'[0] mod W + XORQ AX, AX + MULXQ ·qElement+0(SB), AX, R10 + ADCXQ R14, AX + MOVQ R10, R14 + ADCXQ R15, R14 + MULXQ ·qElement+8(SB), AX, R15 + ADOXQ AX, R14 + ADCXQ CX, R15 + MULXQ ·qElement+16(SB), AX, CX + ADOXQ AX, R15 + ADCXQ BX, CX + MULXQ ·qElement+24(SB), AX, BX + ADOXQ AX, CX + MOVQ $0x0000000000000000, AX + ADCXQ AX, BX + ADOXQ SI, BX + XORQ AX, AX + MOVQ 8(BP), DX + MULXQ 16(BP), R11, R12 + MULXQ 24(BP), AX, SI + ADCXQ AX, R12 + MOVQ $0x0000000000000000, AX + ADCXQ AX, SI + XORQ AX, AX + ADCXQ R11, R11 + ADOXQ R11, CX + ADCXQ R12, R12 + ADOXQ R12, BX + ADCXQ SI, SI + ADOXQ AX, SI + XORQ AX, AX + MULXQ DX, AX, DX + ADOXQ AX, R15 + MOVQ $0x0000000000000000, AX + ADOXQ DX, CX + ADOXQ AX, BX + ADOXQ AX, SI + MOVQ R14, DX + MULXQ ·qElementInv0(SB), DX, AX // m := t[0]*q'[0] mod W + XORQ AX, AX + MULXQ ·qElement+0(SB), AX, R13 + ADCXQ R14, AX + MOVQ R13, R14 + ADCXQ R15, R14 + MULXQ ·qElement+8(SB), AX, R15 + ADOXQ AX, R14 + ADCXQ CX, R15 + MULXQ ·qElement+16(SB), AX, CX + ADOXQ AX, R15 + ADCXQ BX, CX + MULXQ ·qElement+24(SB), AX, BX + ADOXQ AX, CX + MOVQ $0x0000000000000000, AX + ADCXQ AX, BX + ADOXQ SI, BX + XORQ AX, AX + MOVQ 16(BP), DX + MULXQ 24(BP), DI, SI + ADCXQ DI, DI + ADOXQ DI, BX + ADCXQ SI, SI + ADOXQ AX, SI + XORQ AX, AX + MULXQ DX, AX, DX + ADOXQ AX, CX + MOVQ $0x0000000000000000, AX + ADOXQ DX, BX + ADOXQ AX, SI + MOVQ R14, DX + MULXQ ·qElementInv0(SB), DX, AX // m := t[0]*q'[0] mod W + XORQ AX, AX + MULXQ ·qElement+0(SB), AX, R8 + ADCXQ R14, AX + MOVQ R8, R14 + ADCXQ R15, R14 + MULXQ ·qElement+8(SB), AX, R15 + ADOXQ AX, R14 + ADCXQ CX, R15 + MULXQ ·qElement+16(SB), AX, CX + ADOXQ AX, R15 + ADCXQ BX, CX + MULXQ ·qElement+24(SB), AX, BX + ADOXQ AX, CX + MOVQ $0x0000000000000000, AX + ADCXQ AX, BX + ADOXQ SI, BX + XORQ AX, AX + MOVQ 24(BP), DX + MULXQ DX, AX, SI + ADCXQ AX, BX + MOVQ $0x0000000000000000, AX + ADCXQ AX, SI + MOVQ R14, DX + MULXQ ·qElementInv0(SB), DX, AX // m := t[0]*q'[0] mod W + XORQ AX, AX + MULXQ ·qElement+0(SB), AX, R9 + ADCXQ R14, AX + MOVQ R9, R14 + ADCXQ R15, R14 + MULXQ ·qElement+8(SB), AX, R15 + ADOXQ AX, R14 + ADCXQ CX, R15 + MULXQ ·qElement+16(SB), AX, CX + ADOXQ AX, R15 + ADCXQ BX, CX + MULXQ ·qElement+24(SB), AX, BX + ADOXQ AX, CX + MOVQ $0x0000000000000000, AX + ADCXQ AX, BX + ADOXQ SI, BX + MOVQ res+0(FP), R10 + MOVQ R14, R11 + MOVQ R15, R12 + MOVQ CX, R13 + MOVQ BX, DI + SUBQ ·qElement+0(SB), R11 + SBBQ ·qElement+8(SB), R12 + SBBQ ·qElement+16(SB), R13 + SBBQ ·qElement+24(SB), DI + CMOVQCC R11, R14 + CMOVQCC R12, R15 + CMOVQCC R13, CX + CMOVQCC DI, BX + MOVQ R14, 0(R10) + MOVQ R15, 8(R10) + MOVQ CX, 16(R10) + MOVQ BX, 24(R10) + RET +l6: + MOVQ x+8(FP), R15 + MOVQ x+8(FP), R14 + MOVQ 0(R15), AX + MOVQ 0(R14), R8 + MULQ R8 + MOVQ AX, CX + MOVQ DX, R9 + MOVQ ·qElementInv0(SB), R10 + IMULQ CX, R10 + MOVQ $0x3c208c16d87cfd47, AX + MULQ R10 + ADDQ CX, AX + ADCQ $0x0000000000000000, DX + MOVQ DX, DI + MOVQ 8(R15), AX + MULQ R8 + MOVQ R9, BX + ADDQ AX, BX + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0x97816a916871ca8d, AX + MULQ R10 + ADDQ BX, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, CX + MOVQ DX, DI + MOVQ 16(R15), AX + MULQ R8 + MOVQ R9, BP + ADDQ AX, BP + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0xb85045b68181585d, AX + MULQ R10 + ADDQ BP, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, BX + MOVQ DX, DI + MOVQ 24(R15), AX + MULQ R8 + MOVQ R9, SI + ADDQ AX, SI + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0x30644e72e131a029, AX + MULQ R10 + ADDQ SI, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, BP + MOVQ DX, DI + ADDQ DI, R9 + MOVQ R9, SI + MOVQ 0(R15), AX + MOVQ 8(R14), R8 + MULQ R8 + ADDQ AX, CX + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ ·qElementInv0(SB), R10 + IMULQ CX, R10 + MOVQ $0x3c208c16d87cfd47, AX + MULQ R10 + ADDQ CX, AX + ADCQ $0x0000000000000000, DX + MOVQ DX, DI + MOVQ 8(R15), AX + MULQ R8 + ADDQ R9, BX + ADCQ $0x0000000000000000, DX + ADDQ AX, BX + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0x97816a916871ca8d, AX + MULQ R10 + ADDQ BX, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, CX + MOVQ DX, DI + MOVQ 16(R15), AX + MULQ R8 + ADDQ R9, BP + ADCQ $0x0000000000000000, DX + ADDQ AX, BP + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0xb85045b68181585d, AX + MULQ R10 + ADDQ BP, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, BX + MOVQ DX, DI + MOVQ 24(R15), AX + MULQ R8 + ADDQ R9, SI + ADCQ $0x0000000000000000, DX + ADDQ AX, SI + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0x30644e72e131a029, AX + MULQ R10 + ADDQ SI, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, BP + MOVQ DX, DI + ADDQ DI, R9 + MOVQ R9, SI + MOVQ 0(R15), AX + MOVQ 16(R14), R8 + MULQ R8 + ADDQ AX, CX + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ ·qElementInv0(SB), R10 + IMULQ CX, R10 + MOVQ $0x3c208c16d87cfd47, AX + MULQ R10 + ADDQ CX, AX + ADCQ $0x0000000000000000, DX + MOVQ DX, DI + MOVQ 8(R15), AX + MULQ R8 + ADDQ R9, BX + ADCQ $0x0000000000000000, DX + ADDQ AX, BX + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0x97816a916871ca8d, AX + MULQ R10 + ADDQ BX, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, CX + MOVQ DX, DI + MOVQ 16(R15), AX + MULQ R8 + ADDQ R9, BP + ADCQ $0x0000000000000000, DX + ADDQ AX, BP + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0xb85045b68181585d, AX + MULQ R10 + ADDQ BP, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, BX + MOVQ DX, DI + MOVQ 24(R15), AX + MULQ R8 + ADDQ R9, SI + ADCQ $0x0000000000000000, DX + ADDQ AX, SI + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0x30644e72e131a029, AX + MULQ R10 + ADDQ SI, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, BP + MOVQ DX, DI + ADDQ DI, R9 + MOVQ R9, SI + MOVQ 0(R15), AX + MOVQ 24(R14), R8 + MULQ R8 + ADDQ AX, CX + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ ·qElementInv0(SB), R10 + IMULQ CX, R10 + MOVQ $0x3c208c16d87cfd47, AX + MULQ R10 + ADDQ CX, AX + ADCQ $0x0000000000000000, DX + MOVQ DX, DI + MOVQ 8(R15), AX + MULQ R8 + ADDQ R9, BX + ADCQ $0x0000000000000000, DX + ADDQ AX, BX + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0x97816a916871ca8d, AX + MULQ R10 + ADDQ BX, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, CX + MOVQ DX, DI + MOVQ 16(R15), AX + MULQ R8 + ADDQ R9, BP + ADCQ $0x0000000000000000, DX + ADDQ AX, BP + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0xb85045b68181585d, AX + MULQ R10 + ADDQ BP, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, BX + MOVQ DX, DI + MOVQ 24(R15), AX + MULQ R8 + ADDQ R9, SI + ADCQ $0x0000000000000000, DX + ADDQ AX, SI + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0x30644e72e131a029, AX + MULQ R10 + ADDQ SI, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, BP + MOVQ DX, DI + ADDQ DI, R9 + MOVQ R9, SI + MOVQ res+0(FP), R15 + MOVQ CX, R11 + MOVQ BX, R12 + MOVQ BP, R13 + MOVQ SI, DI + SUBQ ·qElement+0(SB), R11 + SBBQ ·qElement+8(SB), R12 + SBBQ ·qElement+16(SB), R13 + SBBQ ·qElement+24(SB), DI + CMOVQCC R11, CX + CMOVQCC R12, BX + CMOVQCC R13, BP + CMOVQCC DI, SI + MOVQ CX, 0(R15) + MOVQ BX, 8(R15) + MOVQ BP, 16(R15) + MOVQ SI, 24(R15) + RET + +TEXT ·fromMont(SB), $8-8 +NO_LOCAL_POINTERS + + // the algorithm is described here + // https://hackmd.io/@zkteam/modular_multiplication + // when y = 1 we have: + // for i=0 to N-1 + // t[i] = x[i] + // for i=0 to N-1 + // m := t[0]*q'[0] mod W + // C,_ := t[0] + m*q[0] + // for j=1 to N-1 + // (C,t[j-1]) := t[j] + m*q[j] + C + // t[N-1] = C + CMPB ·supportAdx(SB), $0x0000000000000001 + JNE l7 + MOVQ res+0(FP), BP + MOVQ 0(BP), R14 + MOVQ 8(BP), R15 + MOVQ 16(BP), CX + MOVQ 24(BP), BX + XORQ DX, DX + MOVQ R14, DX + MULXQ ·qElementInv0(SB), DX, AX // m := t[0]*q'[0] mod W + XORQ AX, AX + // C,_ := t[0] + m*q[0] + MULXQ ·qElement+0(SB), AX, SI + ADCXQ R14, AX + MOVQ SI, R14 + // for j=1 to N-1 + // (C,t[j-1]) := t[j] + m*q[j] + C + ADCXQ R15, R14 + MULXQ ·qElement+8(SB), AX, R15 + ADOXQ AX, R14 + ADCXQ CX, R15 + MULXQ ·qElement+16(SB), AX, CX + ADOXQ AX, R15 + ADCXQ BX, CX + MULXQ ·qElement+24(SB), AX, BX + ADOXQ AX, CX + MOVQ $0x0000000000000000, AX + ADCXQ AX, BX + ADOXQ AX, BX + XORQ DX, DX + MOVQ R14, DX + MULXQ ·qElementInv0(SB), DX, AX // m := t[0]*q'[0] mod W + XORQ AX, AX + // C,_ := t[0] + m*q[0] + MULXQ ·qElement+0(SB), AX, SI + ADCXQ R14, AX + MOVQ SI, R14 + // for j=1 to N-1 + // (C,t[j-1]) := t[j] + m*q[j] + C + ADCXQ R15, R14 + MULXQ ·qElement+8(SB), AX, R15 + ADOXQ AX, R14 + ADCXQ CX, R15 + MULXQ ·qElement+16(SB), AX, CX + ADOXQ AX, R15 + ADCXQ BX, CX + MULXQ ·qElement+24(SB), AX, BX + ADOXQ AX, CX + MOVQ $0x0000000000000000, AX + ADCXQ AX, BX + ADOXQ AX, BX + XORQ DX, DX + MOVQ R14, DX + MULXQ ·qElementInv0(SB), DX, AX // m := t[0]*q'[0] mod W + XORQ AX, AX + // C,_ := t[0] + m*q[0] + MULXQ ·qElement+0(SB), AX, SI + ADCXQ R14, AX + MOVQ SI, R14 + // for j=1 to N-1 + // (C,t[j-1]) := t[j] + m*q[j] + C + ADCXQ R15, R14 + MULXQ ·qElement+8(SB), AX, R15 + ADOXQ AX, R14 + ADCXQ CX, R15 + MULXQ ·qElement+16(SB), AX, CX + ADOXQ AX, R15 + ADCXQ BX, CX + MULXQ ·qElement+24(SB), AX, BX + ADOXQ AX, CX + MOVQ $0x0000000000000000, AX + ADCXQ AX, BX + ADOXQ AX, BX + XORQ DX, DX + MOVQ R14, DX + MULXQ ·qElementInv0(SB), DX, AX // m := t[0]*q'[0] mod W + XORQ AX, AX + // C,_ := t[0] + m*q[0] + MULXQ ·qElement+0(SB), AX, SI + ADCXQ R14, AX + MOVQ SI, R14 + // for j=1 to N-1 + // (C,t[j-1]) := t[j] + m*q[j] + C + ADCXQ R15, R14 + MULXQ ·qElement+8(SB), AX, R15 + ADOXQ AX, R14 + ADCXQ CX, R15 + MULXQ ·qElement+16(SB), AX, CX + ADOXQ AX, R15 + ADCXQ BX, CX + MULXQ ·qElement+24(SB), AX, BX + ADOXQ AX, CX + MOVQ $0x0000000000000000, AX + ADCXQ AX, BX + ADOXQ AX, BX + MOVQ R14, DI + MOVQ R15, R8 + MOVQ CX, R9 + MOVQ BX, R10 + SUBQ ·qElement+0(SB), DI + SBBQ ·qElement+8(SB), R8 + SBBQ ·qElement+16(SB), R9 + SBBQ ·qElement+24(SB), R10 + CMOVQCC DI, R14 + CMOVQCC R8, R15 + CMOVQCC R9, CX + CMOVQCC R10, BX + MOVQ R14, 0(BP) + MOVQ R15, 8(BP) + MOVQ CX, 16(BP) + MOVQ BX, 24(BP) + RET +l7: + MOVQ res+0(FP), AX + MOVQ AX, (SP) +CALL ·_fromMontGeneric(SB) + RET + +TEXT ·reduce(SB), NOSPLIT, $0-8 + MOVQ res+0(FP), AX + MOVQ 0(AX), DX + MOVQ 8(AX), CX + MOVQ 16(AX), BX + MOVQ 24(AX), BP + MOVQ DX, SI + MOVQ CX, DI + MOVQ BX, R8 + MOVQ BP, R9 + SUBQ ·qElement+0(SB), SI + SBBQ ·qElement+8(SB), DI + SBBQ ·qElement+16(SB), R8 + SBBQ ·qElement+24(SB), R9 + CMOVQCC SI, DX + CMOVQCC DI, CX + CMOVQCC R8, BX + CMOVQCC R9, BP + MOVQ DX, 0(AX) + MOVQ CX, 8(AX) + MOVQ BX, 16(AX) + MOVQ BP, 24(AX) + RET + +TEXT ·add(SB), NOSPLIT, $0-24 + MOVQ x+8(FP), AX + MOVQ 0(AX), BX + MOVQ 8(AX), BP + MOVQ 16(AX), SI + MOVQ 24(AX), DI + MOVQ y+16(FP), DX + ADDQ 0(DX), BX + ADCQ 8(DX), BP + ADCQ 16(DX), SI + ADCQ 24(DX), DI + MOVQ res+0(FP), CX + MOVQ BX, R8 + MOVQ BP, R9 + MOVQ SI, R10 + MOVQ DI, R11 + SUBQ ·qElement+0(SB), R8 + SBBQ ·qElement+8(SB), R9 + SBBQ ·qElement+16(SB), R10 + SBBQ ·qElement+24(SB), R11 + CMOVQCC R8, BX + CMOVQCC R9, BP + CMOVQCC R10, SI + CMOVQCC R11, DI + MOVQ BX, 0(CX) + MOVQ BP, 8(CX) + MOVQ SI, 16(CX) + MOVQ DI, 24(CX) + RET + +TEXT ·sub(SB), NOSPLIT, $0-24 + MOVQ x+8(FP), BP + MOVQ 0(BP), AX + MOVQ 8(BP), DX + MOVQ 16(BP), CX + MOVQ 24(BP), BX + MOVQ y+16(FP), SI + SUBQ 0(SI), AX + SBBQ 8(SI), DX + SBBQ 16(SI), CX + SBBQ 24(SI), BX + MOVQ $0x3c208c16d87cfd47, DI + MOVQ $0x97816a916871ca8d, R8 + MOVQ $0xb85045b68181585d, R9 + MOVQ $0x30644e72e131a029, R10 + MOVQ $0x0000000000000000, R11 + CMOVQCC R11, DI + CMOVQCC R11, R8 + CMOVQCC R11, R9 + CMOVQCC R11, R10 + ADDQ DI, AX + ADCQ R8, DX + ADCQ R9, CX + ADCQ R10, BX + MOVQ res+0(FP), R12 + MOVQ AX, 0(R12) + MOVQ DX, 8(R12) + MOVQ CX, 16(R12) + MOVQ BX, 24(R12) + RET + +TEXT ·double(SB), NOSPLIT, $0-16 + MOVQ res+0(FP), DX + MOVQ x+8(FP), AX + MOVQ 0(AX), CX + MOVQ 8(AX), BX + MOVQ 16(AX), BP + MOVQ 24(AX), SI + ADDQ CX, CX + ADCQ BX, BX + ADCQ BP, BP + ADCQ SI, SI + MOVQ CX, DI + MOVQ BX, R8 + MOVQ BP, R9 + MOVQ SI, R10 + SUBQ ·qElement+0(SB), DI + SBBQ ·qElement+8(SB), R8 + SBBQ ·qElement+16(SB), R9 + SBBQ ·qElement+24(SB), R10 + CMOVQCC DI, CX + CMOVQCC R8, BX + CMOVQCC R9, BP + CMOVQCC R10, SI + MOVQ CX, 0(DX) + MOVQ BX, 8(DX) + MOVQ BP, 16(DX) + MOVQ SI, 24(DX) + RET + +TEXT ·neg(SB), NOSPLIT, $0-16 + MOVQ res+0(FP), DX + MOVQ x+8(FP), AX + MOVQ 0(AX), BX + MOVQ 8(AX), BP + MOVQ 16(AX), SI + MOVQ 24(AX), DI + MOVQ BX, AX + ORQ BP, AX + ORQ SI, AX + ORQ DI, AX + TESTQ AX, AX + JNE l8 + MOVQ AX, 0(DX) + MOVQ AX, 8(DX) + RET +l8: + MOVQ $0x3c208c16d87cfd47, CX + SUBQ BX, CX + MOVQ CX, 0(DX) + MOVQ $0x97816a916871ca8d, CX + SBBQ BP, CX + MOVQ CX, 8(DX) + MOVQ $0xb85045b68181585d, CX + SBBQ SI, CX + MOVQ CX, 16(DX) + MOVQ $0x30644e72e131a029, CX + SBBQ DI, CX + MOVQ CX, 24(DX) + RET diff --git a/internal/utils/zklink/bn256/fp/element_ops_noasm.go b/internal/utils/zklink/bn256/fp/element_ops_noasm.go new file mode 100644 index 00000000000..946f1dc56bb --- /dev/null +++ b/internal/utils/zklink/bn256/fp/element_ops_noasm.go @@ -0,0 +1,119 @@ +// +build !amd64 + +// Copyright 2020 ConsenSys Software Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by goff (v0.3.6) DO NOT EDIT + +package fp + +// /!\ WARNING /!\ +// this code has not been audited and is provided as-is. In particular, +// there is no security guarantees such as constant time implementation +// or side-channel attack resistance +// /!\ WARNING /!\ + +import "math/bits" + +func mul(z, x, y *Element) { + _mulGeneric(z, x, y) +} + +func square(z, x *Element) { + _squareGeneric(z, x) +} + +// FromMont converts z in place (i.e. mutates) from Montgomery to regular representation +// sets and returns z = z * 1 +func fromMont(z *Element) { + _fromMontGeneric(z) +} + +func add(z, x, y *Element) { + var carry uint64 + + z[0], carry = bits.Add64(x[0], y[0], 0) + z[1], carry = bits.Add64(x[1], y[1], carry) + z[2], carry = bits.Add64(x[2], y[2], carry) + z[3], _ = bits.Add64(x[3], y[3], carry) + + // if z > q --> z -= q + // note: this is NOT constant time + if !(z[3] < 3486998266802970665 || (z[3] == 3486998266802970665 && (z[2] < 13281191951274694749 || (z[2] == 13281191951274694749 && (z[1] < 10917124144477883021 || (z[1] == 10917124144477883021 && (z[0] < 4332616871279656263))))))) { + var b uint64 + z[0], b = bits.Sub64(z[0], 4332616871279656263, 0) + z[1], b = bits.Sub64(z[1], 10917124144477883021, b) + z[2], b = bits.Sub64(z[2], 13281191951274694749, b) + z[3], _ = bits.Sub64(z[3], 3486998266802970665, b) + } +} + +func double(z, x *Element) { + var carry uint64 + + z[0], carry = bits.Add64(x[0], x[0], 0) + z[1], carry = bits.Add64(x[1], x[1], carry) + z[2], carry = bits.Add64(x[2], x[2], carry) + z[3], _ = bits.Add64(x[3], x[3], carry) + + // if z > q --> z -= q + // note: this is NOT constant time + if !(z[3] < 3486998266802970665 || (z[3] == 3486998266802970665 && (z[2] < 13281191951274694749 || (z[2] == 13281191951274694749 && (z[1] < 10917124144477883021 || (z[1] == 10917124144477883021 && (z[0] < 4332616871279656263))))))) { + var b uint64 + z[0], b = bits.Sub64(z[0], 4332616871279656263, 0) + z[1], b = bits.Sub64(z[1], 10917124144477883021, b) + z[2], b = bits.Sub64(z[2], 13281191951274694749, b) + z[3], _ = bits.Sub64(z[3], 3486998266802970665, b) + } +} + +func sub(z, x, y *Element) { + var b uint64 + z[0], b = bits.Sub64(x[0], y[0], 0) + z[1], b = bits.Sub64(x[1], y[1], b) + z[2], b = bits.Sub64(x[2], y[2], b) + z[3], b = bits.Sub64(x[3], y[3], b) + if b != 0 { + var c uint64 + z[0], c = bits.Add64(z[0], 4332616871279656263, 0) + z[1], c = bits.Add64(z[1], 10917124144477883021, c) + z[2], c = bits.Add64(z[2], 13281191951274694749, c) + z[3], _ = bits.Add64(z[3], 3486998266802970665, c) + } +} + +func neg(z, x *Element) { + if x.IsZero() { + z.SetZero() + return + } + var borrow uint64 + z[0], borrow = bits.Sub64(4332616871279656263, x[0], 0) + z[1], borrow = bits.Sub64(10917124144477883021, x[1], borrow) + z[2], borrow = bits.Sub64(13281191951274694749, x[2], borrow) + z[3], _ = bits.Sub64(3486998266802970665, x[3], borrow) +} + +func reduce(z *Element) { + + // if z > q --> z -= q + // note: this is NOT constant time + if !(z[3] < 3486998266802970665 || (z[3] == 3486998266802970665 && (z[2] < 13281191951274694749 || (z[2] == 13281191951274694749 && (z[1] < 10917124144477883021 || (z[1] == 10917124144477883021 && (z[0] < 4332616871279656263))))))) { + var b uint64 + z[0], b = bits.Sub64(z[0], 4332616871279656263, 0) + z[1], b = bits.Sub64(z[1], 10917124144477883021, b) + z[2], b = bits.Sub64(z[2], 13281191951274694749, b) + z[3], _ = bits.Sub64(z[3], 3486998266802970665, b) + } +} diff --git a/internal/utils/zklink/bn256/fp/element_test.go b/internal/utils/zklink/bn256/fp/element_test.go new file mode 100644 index 00000000000..fa1ddd05555 --- /dev/null +++ b/internal/utils/zklink/bn256/fp/element_test.go @@ -0,0 +1,595 @@ +// Copyright 2020 ConsenSys Software Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by goff (v0.3.6) DO NOT EDIT + +package fp + +import ( + "crypto/rand" + "math/big" + "math/bits" + "testing" + + "github.com/leanovate/gopter" + "github.com/leanovate/gopter/prop" +) + +func TestELEMENTCorrectnessAgainstBigInt(t *testing.T) { + modulus := Modulus() + cmpEandB := func(e *Element, b *big.Int, name string) { + var _e big.Int + if e.FromMont().ToBigInt(&_e).Cmp(b) != 0 { + t.Fatal(name, "failed") + } + } + var modulusMinusOne, one big.Int + one.SetUint64(1) + + modulusMinusOne.Sub(modulus, &one) + + var n int + if testing.Short() { + n = 20 + } else { + n = 500 + } + + sAdx := supportAdx + + for i := 0; i < n; i++ { + if i == n/2 && sAdx { + supportAdx = false // testing without adx instruction + } + // sample 3 random big int + b1, _ := rand.Int(rand.Reader, modulus) + b2, _ := rand.Int(rand.Reader, modulus) + b3, _ := rand.Int(rand.Reader, modulus) // exponent + + // adding edge cases + // TODO need more edge cases + switch i { + case 0: + b3.SetUint64(0) + b1.SetUint64(0) + case 1: + b2.SetUint64(0) + case 2: + b1.SetUint64(0) + b2.SetUint64(0) + case 3: + b3.SetUint64(0) + case 4: + b3.SetUint64(1) + case 5: + b3.SetUint64(^uint64(0)) + case 6: + b3.SetUint64(2) + b1.Set(&modulusMinusOne) + case 7: + b2.Set(&modulusMinusOne) + case 8: + b1.Set(&modulusMinusOne) + b2.Set(&modulusMinusOne) + } + + var bMul, bAdd, bSub, bDiv, bNeg, bLsh, bInv, bExp, bSquare big.Int + + // e1 = mont(b1), e2 = mont(b2) + var e1, e2, eMul, eAdd, eSub, eDiv, eNeg, eLsh, eInv, eExp, eSquare Element + e1.SetBigInt(b1) + e2.SetBigInt(b2) + + // (e1*e2).FromMont() === b1*b2 mod q ... etc + eSquare.Square(&e1) + eMul.Mul(&e1, &e2) + eAdd.Add(&e1, &e2) + eSub.Sub(&e1, &e2) + eDiv.Div(&e1, &e2) + eNeg.Neg(&e1) + eInv.Inverse(&e1) + eExp.Exp(e1, b3) + eLsh.Double(&e1) + + // same operations with big int + bAdd.Add(b1, b2).Mod(&bAdd, modulus) + bMul.Mul(b1, b2).Mod(&bMul, modulus) + bSquare.Mul(b1, b1).Mod(&bSquare, modulus) + bSub.Sub(b1, b2).Mod(&bSub, modulus) + bDiv.ModInverse(b2, modulus) + bDiv.Mul(&bDiv, b1). + Mod(&bDiv, modulus) + bNeg.Neg(b1).Mod(&bNeg, modulus) + + bInv.ModInverse(b1, modulus) + bExp.Exp(b1, b3, modulus) + bLsh.Lsh(b1, 1).Mod(&bLsh, modulus) + + cmpEandB(&eSquare, &bSquare, "Square") + cmpEandB(&eMul, &bMul, "Mul") + cmpEandB(&eAdd, &bAdd, "Add") + cmpEandB(&eSub, &bSub, "Sub") + cmpEandB(&eDiv, &bDiv, "Div") + cmpEandB(&eNeg, &bNeg, "Neg") + cmpEandB(&eInv, &bInv, "Inv") + cmpEandB(&eExp, &bExp, "Exp") + + cmpEandB(&eLsh, &bLsh, "Lsh") + + // legendre symbol + if e1.Legendre() != big.Jacobi(b1, modulus) { + t.Fatal("legendre symbol computation failed") + } + if e2.Legendre() != big.Jacobi(b2, modulus) { + t.Fatal("legendre symbol computation failed") + } + + // these are slow, killing circle ci + if n <= 10 { + // sqrt + var eSqrt Element + var bSqrt big.Int + bSqrt.ModSqrt(b1, modulus) + eSqrt.Sqrt(&e1) + cmpEandB(&eSqrt, &bSqrt, "Sqrt") + } + } + supportAdx = sAdx +} + +func TestELEMENTSetInterface(t *testing.T) { + // TODO + t.Skip("not implemented") +} + +func TestELEMENTIsRandom(t *testing.T) { + for i := 0; i < 50; i++ { + var x, y Element + x.SetRandom() + y.SetRandom() + if x.Equal(&y) { + t.Fatal("2 random numbers are unlikely to be equal") + } + } +} + +func TestByte(t *testing.T) { + + modulus := Modulus() + + // test values + var bs [3][]byte + r1, _ := rand.Int(rand.Reader, modulus) + bs[0] = r1.Bytes() // should be r1 as Element + r2, _ := rand.Int(rand.Reader, modulus) + r2.Add(modulus, r2) + bs[1] = r2.Bytes() // should be r2 as Element + var tmp big.Int + tmp.SetUint64(0) + bs[2] = tmp.Bytes() // should be 0 as Element + + // witness values as Element + var el [3]Element + el[0].SetBigInt(r1) + el[1].SetBigInt(r2) + el[2].SetUint64(0) + + // check conversions + for i := 0; i < 3; i++ { + var z Element + z.SetBytes(bs[i]) + if !z.Equal(&el[i]) { + t.Fatal("SetBytes fails") + } + // check conversion Element to Bytes + b := z.Bytes() + z.SetBytes(b) + if !z.Equal(&el[i]) { + t.Fatal("Bytes fails") + } + } +} + +// ------------------------------------------------------------------------------------------------- +// benchmarks +// most benchmarks are rudimentary and should sample a large number of random inputs +// or be run multiple times to ensure it didn't measure the fastest path of the function + +var benchResElement Element + +func BenchmarkInverseELEMENT(b *testing.B) { + var x Element + x.SetRandom() + benchResElement.SetRandom() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + benchResElement.Inverse(&x) + } + +} +func BenchmarkExpELEMENT(b *testing.B) { + var x Element + x.SetRandom() + benchResElement.SetRandom() + b1, _ := rand.Int(rand.Reader, Modulus()) + b.ResetTimer() + for i := 0; i < b.N; i++ { + benchResElement.Exp(x, b1) + } +} + +func BenchmarkDoubleELEMENT(b *testing.B) { + benchResElement.SetRandom() + b.ResetTimer() + for i := 0; i < b.N; i++ { + benchResElement.Double(&benchResElement) + } +} + +func BenchmarkAddELEMENT(b *testing.B) { + var x Element + x.SetRandom() + benchResElement.SetRandom() + b.ResetTimer() + for i := 0; i < b.N; i++ { + benchResElement.Add(&x, &benchResElement) + } +} + +func BenchmarkSubELEMENT(b *testing.B) { + var x Element + x.SetRandom() + benchResElement.SetRandom() + b.ResetTimer() + for i := 0; i < b.N; i++ { + benchResElement.Sub(&x, &benchResElement) + } +} + +func BenchmarkNegELEMENT(b *testing.B) { + benchResElement.SetRandom() + b.ResetTimer() + for i := 0; i < b.N; i++ { + benchResElement.Neg(&benchResElement) + } +} + +func BenchmarkDivELEMENT(b *testing.B) { + var x Element + x.SetRandom() + benchResElement.SetRandom() + b.ResetTimer() + for i := 0; i < b.N; i++ { + benchResElement.Div(&x, &benchResElement) + } +} + +func BenchmarkFromMontELEMENT(b *testing.B) { + benchResElement.SetRandom() + b.ResetTimer() + for i := 0; i < b.N; i++ { + benchResElement.FromMont() + } +} + +func BenchmarkToMontELEMENT(b *testing.B) { + benchResElement.SetRandom() + b.ResetTimer() + for i := 0; i < b.N; i++ { + benchResElement.ToMont() + } +} +func BenchmarkSquareELEMENT(b *testing.B) { + benchResElement.SetRandom() + b.ResetTimer() + for i := 0; i < b.N; i++ { + benchResElement.Square(&benchResElement) + } +} + +func BenchmarkSqrtELEMENT(b *testing.B) { + var a Element + a.SetRandom() + b.ResetTimer() + for i := 0; i < b.N; i++ { + benchResElement.Sqrt(&a) + } +} + +func BenchmarkMulELEMENT(b *testing.B) { + x := Element{ + 17522657719365597833, + 13107472804851548667, + 5164255478447964150, + 493319470278259999, + } + benchResElement.SetOne() + b.ResetTimer() + for i := 0; i < b.N; i++ { + benchResElement.Mul(&benchResElement, &x) + } +} + +func TestELEMENTreduce(t *testing.T) { + q := Element{ + 4332616871279656263, + 10917124144477883021, + 13281191951274694749, + 3486998266802970665, + } + + var testData []Element + { + a := q + a[3]-- + testData = append(testData, a) + } + { + a := q + a[0]-- + testData = append(testData, a) + } + { + a := q + a[3]++ + testData = append(testData, a) + } + { + a := q + a[0]++ + testData = append(testData, a) + } + { + a := q + testData = append(testData, a) + } + + for _, s := range testData { + expected := s + reduce(&s) + expected.testReduce() + if !s.Equal(&expected) { + t.Fatal("reduce failed") + } + } + +} + +func (z *Element) testReduce() *Element { + + // if z > q --> z -= q + // note: this is NOT constant time + if !(z[3] < 3486998266802970665 || (z[3] == 3486998266802970665 && (z[2] < 13281191951274694749 || (z[2] == 13281191951274694749 && (z[1] < 10917124144477883021 || (z[1] == 10917124144477883021 && (z[0] < 4332616871279656263))))))) { + var b uint64 + z[0], b = bits.Sub64(z[0], 4332616871279656263, 0) + z[1], b = bits.Sub64(z[1], 10917124144477883021, b) + z[2], b = bits.Sub64(z[2], 13281191951274694749, b) + z[3], _ = bits.Sub64(z[3], 3486998266802970665, b) + } + return z +} + +// ------------------------------------------------------------------------------------------------- +// Gopter tests + +func TestELEMENTMul(t *testing.T) { + + parameters := gopter.DefaultTestParameters() + parameters.MinSuccessfulTests = 10000 + + properties := gopter.NewProperties(parameters) + + genA := gen() + genB := gen() + + properties.Property("Having the receiver as operand should output the same result", prop.ForAll( + func(a, b testPairElement) bool { + var c, d Element + d.Set(&a.element) + c.Mul(&a.element, &b.element) + a.element.Mul(&a.element, &b.element) + b.element.Mul(&d, &b.element) + return a.element.Equal(&b.element) && a.element.Equal(&c) && b.element.Equal(&c) + }, + genA, + genB, + )) + + properties.Property("Operation result must match big.Int result", prop.ForAll( + func(a, b testPairElement) bool { + var c Element + c.Mul(&a.element, &b.element) + + var d, e big.Int + d.Mul(&a.bigint, &b.bigint).Mod(&d, Modulus()) + + return c.FromMont().ToBigInt(&e).Cmp(&d) == 0 + }, + genA, + genB, + )) + + properties.Property("Operation result must be smaller than modulus", prop.ForAll( + func(a, b testPairElement) bool { + var c Element + c.Mul(&a.element, &b.element) + return !c.biggerOrEqualModulus() + }, + genA, + genB, + )) + + properties.Property("Assembly implementation must be consistent with generic one", prop.ForAll( + func(a, b testPairElement) bool { + var c, d Element + c.Mul(&a.element, &b.element) + _mulGeneric(&d, &a.element, &b.element) + return c.Equal(&d) + }, + genA, + genB, + )) + + properties.TestingRun(t, gopter.ConsoleReporter(false)) +} + +func TestELEMENTSquare(t *testing.T) { + + parameters := gopter.DefaultTestParameters() + parameters.MinSuccessfulTests = 10000 + + properties := gopter.NewProperties(parameters) + + genA := gen() + + properties.Property("Having the receiver as operand should output the same result", prop.ForAll( + func(a testPairElement) bool { + var b Element + b.Square(&a.element) + a.element.Square(&a.element) + return a.element.Equal(&b) + }, + genA, + )) + + properties.Property("Operation result must match big.Int result", prop.ForAll( + func(a testPairElement) bool { + var b Element + b.Square(&a.element) + + var d, e big.Int + d.Mul(&a.bigint, &a.bigint).Mod(&d, Modulus()) + + return b.FromMont().ToBigInt(&e).Cmp(&d) == 0 + }, + genA, + )) + + properties.Property("Operation result must be smaller than modulus", prop.ForAll( + func(a testPairElement) bool { + var b Element + b.Square(&a.element) + return !b.biggerOrEqualModulus() + }, + genA, + )) + + properties.Property("Square(x) == Mul(x,x)", prop.ForAll( + func(a testPairElement) bool { + var b, c Element + b.Square(&a.element) + c.Mul(&a.element, &a.element) + return c.Equal(&b) + }, + genA, + )) + + properties.Property("Assembly implementation must be consistent with generic one", prop.ForAll( + func(a testPairElement) bool { + var c, d Element + c.Square(&a.element) + _squareGeneric(&d, &a.element) + return c.Equal(&d) + }, + genA, + )) + + properties.TestingRun(t, gopter.ConsoleReporter(false)) +} + +func TestELEMENTFromMont(t *testing.T) { + + parameters := gopter.DefaultTestParameters() + parameters.MinSuccessfulTests = 10000 + + properties := gopter.NewProperties(parameters) + + genA := gen() + + properties.Property("Assembly implementation must be consistent with generic one", prop.ForAll( + func(a testPairElement) bool { + c := a.element + d := a.element + c.FromMont() + _fromMontGeneric(&d) + return c.Equal(&d) + }, + genA, + )) + + properties.TestingRun(t, gopter.ConsoleReporter(false)) +} + +type testPairElement struct { + element Element + bigint big.Int +} + +func (z *Element) biggerOrEqualModulus() bool { + if z[3] > qElement[3] { + return true + } + if z[3] < qElement[3] { + return false + } + + if z[2] > qElement[2] { + return true + } + if z[2] < qElement[2] { + return false + } + + if z[1] > qElement[1] { + return true + } + if z[1] < qElement[1] { + return false + } + + return z[0] >= qElement[0] +} + +func gen() gopter.Gen { + return func(genParams *gopter.GenParameters) *gopter.GenResult { + var g testPairElement + + g.element = Element{ + genParams.NextUint64(), + genParams.NextUint64(), + genParams.NextUint64(), + genParams.NextUint64(), + } + if qElement[3] != ^uint64(0) { + g.element[3] %= (qElement[3] + 1) + } + + for g.element.biggerOrEqualModulus() { + g.element = Element{ + genParams.NextUint64(), + genParams.NextUint64(), + genParams.NextUint64(), + genParams.NextUint64(), + } + if qElement[3] != ^uint64(0) { + g.element[3] %= (qElement[3] + 1) + } + } + + g.element.ToBigIntRegular(&g.bigint) + genResult := gopter.NewGenResult(g, gopter.NoShrinker) + return genResult + } +} diff --git a/internal/utils/zklink/bn256/fr/arith.go b/internal/utils/zklink/bn256/fr/arith.go new file mode 100644 index 00000000000..ca1baaa8385 --- /dev/null +++ b/internal/utils/zklink/bn256/fr/arith.go @@ -0,0 +1,64 @@ +// Copyright 2020 ConsenSys Software Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by goff (v0.3.6) DO NOT EDIT + +package fr + +import ( + "math/bits" + + "golang.org/x/sys/cpu" +) + +var supportAdx = cpu.X86.HasADX && cpu.X86.HasBMI2 + +// madd0 hi = a*b + c (discards lo bits) +func madd0(a, b, c uint64) (hi uint64) { + var carry, lo uint64 + hi, lo = bits.Mul64(a, b) + _, carry = bits.Add64(lo, c, 0) + hi, _ = bits.Add64(hi, 0, carry) + return +} + +// madd1 hi, lo = a*b + c +func madd1(a, b, c uint64) (hi uint64, lo uint64) { + var carry uint64 + hi, lo = bits.Mul64(a, b) + lo, carry = bits.Add64(lo, c, 0) + hi, _ = bits.Add64(hi, 0, carry) + return +} + +// madd2 hi, lo = a*b + c + d +func madd2(a, b, c, d uint64) (hi uint64, lo uint64) { + var carry uint64 + hi, lo = bits.Mul64(a, b) + c, carry = bits.Add64(c, d, 0) + hi, _ = bits.Add64(hi, 0, carry) + lo, carry = bits.Add64(lo, c, 0) + hi, _ = bits.Add64(hi, 0, carry) + return +} + +func madd3(a, b, c, d, e uint64) (hi uint64, lo uint64) { + var carry uint64 + hi, lo = bits.Mul64(a, b) + c, carry = bits.Add64(c, d, 0) + hi, _ = bits.Add64(hi, 0, carry) + lo, carry = bits.Add64(lo, c, 0) + hi, _ = bits.Add64(hi, e, carry) + return +} diff --git a/internal/utils/zklink/bn256/fr/element.go b/internal/utils/zklink/bn256/fr/element.go new file mode 100644 index 00000000000..6bcd336c470 --- /dev/null +++ b/internal/utils/zklink/bn256/fr/element.go @@ -0,0 +1,883 @@ +// Copyright 2020 ConsenSys Software Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by goff (v0.3.6) DO NOT EDIT + +// Package fr contains field arithmetic operations for modulus 21888242871839275222246405745257275088548364400416034343698204186575808495617 +package fr + +// /!\ WARNING /!\ +// this code has not been audited and is provided as-is. In particular, +// there is no security guarantees such as constant time implementation +// or side-channel attack resistance +// /!\ WARNING /!\ + +import ( + "crypto/rand" + "encoding/binary" + "io" + "math/big" + "math/bits" + "strconv" + "sync" +) + +// Element represents a field element stored on 4 words (uint64) +// Element are assumed to be in Montgomery form in all methods +// field modulus q = +// +// 21888242871839275222246405745257275088548364400416034343698204186575808495617 +type Element [4]uint64 + +// Limbs number of 64 bits words needed to represent Element +const Limbs = 4 + +// Bits number bits needed to represent Element +const Bits = 254 + +// field modulus stored as big.Int +var _modulus big.Int +var onceModulus sync.Once + +// Modulus returns q as a big.Int +// q = +// +// 21888242871839275222246405745257275088548364400416034343698204186575808495617 +func Modulus() *big.Int { + onceModulus.Do(func() { + _modulus.SetString("21888242871839275222246405745257275088548364400416034343698204186575808495617", 10) + }) + return new(big.Int).Set(&_modulus) +} + +// q (modulus) +var qElement = Element{ + 4891460686036598785, + 2896914383306846353, + 13281191951274694749, + 3486998266802970665, +} + +// rSquare +var rSquare = Element{ + 1997599621687373223, + 6052339484930628067, + 10108755138030829701, + 150537098327114917, +} + +// Bytes returns the regular (non montgomery) value +// of z as a big-endian byte slice. +func (z *Element) Bytes() []byte { + _z := z.ToRegular() + var res [Limbs * 8]byte + binary.BigEndian.PutUint64(res[24:32], _z[0]) + binary.BigEndian.PutUint64(res[16:24], _z[1]) + binary.BigEndian.PutUint64(res[8:16], _z[2]) + binary.BigEndian.PutUint64(res[0:8], _z[3]) + + return res[:] +} + +// SetBytes interprets e as the bytes of a big-endian unsigned integer, +// sets z to that value (in Montgomery form), and returns z. +func (z *Element) SetBytes(e []byte) *Element { + var tmp big.Int + tmp.SetBytes(e) + z.SetBigInt(&tmp) + return z +} + +// SetUint64 z = v, sets z LSB to v (non-Montgomery form) and convert z to Montgomery form +func (z *Element) SetUint64(v uint64) *Element { + *z = Element{v} + return z.Mul(z, &rSquare) // z.ToMont() +} + +// Set z = x +func (z *Element) Set(x *Element) *Element { + z[0] = x[0] + z[1] = x[1] + z[2] = x[2] + z[3] = x[3] + return z +} + +// SetInterface converts i1 from uint64, int, string, or Element, big.Int into Element +// panic if provided type is not supported +func (z *Element) SetInterface(i1 interface{}) *Element { + switch c1 := i1.(type) { + case Element: + return z.Set(&c1) + case *Element: + return z.Set(c1) + case uint64: + return z.SetUint64(c1) + case int: + return z.SetString(strconv.Itoa(c1)) + case string: + return z.SetString(c1) + case *big.Int: + return z.SetBigInt(c1) + case big.Int: + return z.SetBigInt(&c1) + case []byte: + return z.SetBytes(c1) + default: + panic("invalid type") + } +} + +// SetZero z = 0 +func (z *Element) SetZero() *Element { + z[0] = 0 + z[1] = 0 + z[2] = 0 + z[3] = 0 + return z +} + +// SetOne z = 1 (in Montgomery form) +func (z *Element) SetOne() *Element { + z[0] = 12436184717236109307 + z[1] = 3962172157175319849 + z[2] = 7381016538464732718 + z[3] = 1011752739694698287 + return z +} + +// Div z = x*y^-1 mod q +func (z *Element) Div(x, y *Element) *Element { + var yInv Element + yInv.Inverse(y) + z.Mul(x, &yInv) + return z +} + +// Equal returns z == x +func (z *Element) Equal(x *Element) bool { + return (z[3] == x[3]) && (z[2] == x[2]) && (z[1] == x[1]) && (z[0] == x[0]) +} + +// IsZero returns z == 0 +func (z *Element) IsZero() bool { + return (z[3] | z[2] | z[1] | z[0]) == 0 +} + +// SetRandom sets z to a random element < q +func (z *Element) SetRandom() *Element { + bytes := make([]byte, 32) + io.ReadFull(rand.Reader, bytes) + z[0] = binary.BigEndian.Uint64(bytes[0:8]) + z[1] = binary.BigEndian.Uint64(bytes[8:16]) + z[2] = binary.BigEndian.Uint64(bytes[16:24]) + z[3] = binary.BigEndian.Uint64(bytes[24:32]) + z[3] %= 3486998266802970665 + + // if z > q --> z -= q + // note: this is NOT constant time + if !(z[3] < 3486998266802970665 || (z[3] == 3486998266802970665 && (z[2] < 13281191951274694749 || (z[2] == 13281191951274694749 && (z[1] < 2896914383306846353 || (z[1] == 2896914383306846353 && (z[0] < 4891460686036598785))))))) { + var b uint64 + z[0], b = bits.Sub64(z[0], 4891460686036598785, 0) + z[1], b = bits.Sub64(z[1], 2896914383306846353, b) + z[2], b = bits.Sub64(z[2], 13281191951274694749, b) + z[3], _ = bits.Sub64(z[3], 3486998266802970665, b) + } + + return z +} + +// One returns 1 (in montgommery form) +func One() Element { + var one Element + one.SetOne() + return one +} + +// MulAssign is deprecated +// Deprecated: use Mul instead +func (z *Element) MulAssign(x *Element) *Element { + return z.Mul(z, x) +} + +// AddAssign is deprecated +// Deprecated: use Add instead +func (z *Element) AddAssign(x *Element) *Element { + return z.Add(z, x) +} + +// SubAssign is deprecated +// Deprecated: use Sub instead +func (z *Element) SubAssign(x *Element) *Element { + return z.Sub(z, x) +} + +// API with assembly impl + +// Mul z = x * y mod q +// see https://hackmd.io/@zkteam/modular_multiplication +func (z *Element) Mul(x, y *Element) *Element { + mul(z, x, y) + return z +} + +// Square z = x * x mod q +// see https://hackmd.io/@zkteam/modular_multiplication +func (z *Element) Square(x *Element) *Element { + square(z, x) + return z +} + +// FromMont converts z in place (i.e. mutates) from Montgomery to regular representation +// sets and returns z = z * 1 +func (z *Element) FromMont() *Element { + fromMont(z) + return z +} + +// Add z = x + y mod q +func (z *Element) Add(x, y *Element) *Element { + add(z, x, y) + return z +} + +// Double z = x + x mod q, aka Lsh 1 +func (z *Element) Double(x *Element) *Element { + double(z, x) + return z +} + +// Sub z = x - y mod q +func (z *Element) Sub(x, y *Element) *Element { + sub(z, x, y) + return z +} + +// Neg z = q - x +func (z *Element) Neg(x *Element) *Element { + neg(z, x) + return z +} + +// Generic (no ADX instructions, no AMD64) versions of multiplication and squaring algorithms + +func _mulGeneric(z, x, y *Element) { + + var t [4]uint64 + var c [3]uint64 + { + // round 0 + v := x[0] + c[1], c[0] = bits.Mul64(v, y[0]) + m := c[0] * 14042775128853446655 + c[2] = madd0(m, 4891460686036598785, c[0]) + c[1], c[0] = madd1(v, y[1], c[1]) + c[2], t[0] = madd2(m, 2896914383306846353, c[2], c[0]) + c[1], c[0] = madd1(v, y[2], c[1]) + c[2], t[1] = madd2(m, 13281191951274694749, c[2], c[0]) + c[1], c[0] = madd1(v, y[3], c[1]) + t[3], t[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1]) + } + { + // round 1 + v := x[1] + c[1], c[0] = madd1(v, y[0], t[0]) + m := c[0] * 14042775128853446655 + c[2] = madd0(m, 4891460686036598785, c[0]) + c[1], c[0] = madd2(v, y[1], c[1], t[1]) + c[2], t[0] = madd2(m, 2896914383306846353, c[2], c[0]) + c[1], c[0] = madd2(v, y[2], c[1], t[2]) + c[2], t[1] = madd2(m, 13281191951274694749, c[2], c[0]) + c[1], c[0] = madd2(v, y[3], c[1], t[3]) + t[3], t[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1]) + } + { + // round 2 + v := x[2] + c[1], c[0] = madd1(v, y[0], t[0]) + m := c[0] * 14042775128853446655 + c[2] = madd0(m, 4891460686036598785, c[0]) + c[1], c[0] = madd2(v, y[1], c[1], t[1]) + c[2], t[0] = madd2(m, 2896914383306846353, c[2], c[0]) + c[1], c[0] = madd2(v, y[2], c[1], t[2]) + c[2], t[1] = madd2(m, 13281191951274694749, c[2], c[0]) + c[1], c[0] = madd2(v, y[3], c[1], t[3]) + t[3], t[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1]) + } + { + // round 3 + v := x[3] + c[1], c[0] = madd1(v, y[0], t[0]) + m := c[0] * 14042775128853446655 + c[2] = madd0(m, 4891460686036598785, c[0]) + c[1], c[0] = madd2(v, y[1], c[1], t[1]) + c[2], z[0] = madd2(m, 2896914383306846353, c[2], c[0]) + c[1], c[0] = madd2(v, y[2], c[1], t[2]) + c[2], z[1] = madd2(m, 13281191951274694749, c[2], c[0]) + c[1], c[0] = madd2(v, y[3], c[1], t[3]) + z[3], z[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1]) + } + + // if z > q --> z -= q + // note: this is NOT constant time + if !(z[3] < 3486998266802970665 || (z[3] == 3486998266802970665 && (z[2] < 13281191951274694749 || (z[2] == 13281191951274694749 && (z[1] < 2896914383306846353 || (z[1] == 2896914383306846353 && (z[0] < 4891460686036598785))))))) { + var b uint64 + z[0], b = bits.Sub64(z[0], 4891460686036598785, 0) + z[1], b = bits.Sub64(z[1], 2896914383306846353, b) + z[2], b = bits.Sub64(z[2], 13281191951274694749, b) + z[3], _ = bits.Sub64(z[3], 3486998266802970665, b) + } +} + +func _squareGeneric(z, x *Element) { + + var t [4]uint64 + var c [3]uint64 + { + // round 0 + v := x[0] + c[1], c[0] = bits.Mul64(v, x[0]) + m := c[0] * 14042775128853446655 + c[2] = madd0(m, 4891460686036598785, c[0]) + c[1], c[0] = madd1(v, x[1], c[1]) + c[2], t[0] = madd2(m, 2896914383306846353, c[2], c[0]) + c[1], c[0] = madd1(v, x[2], c[1]) + c[2], t[1] = madd2(m, 13281191951274694749, c[2], c[0]) + c[1], c[0] = madd1(v, x[3], c[1]) + t[3], t[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1]) + } + { + // round 1 + v := x[1] + c[1], c[0] = madd1(v, x[0], t[0]) + m := c[0] * 14042775128853446655 + c[2] = madd0(m, 4891460686036598785, c[0]) + c[1], c[0] = madd2(v, x[1], c[1], t[1]) + c[2], t[0] = madd2(m, 2896914383306846353, c[2], c[0]) + c[1], c[0] = madd2(v, x[2], c[1], t[2]) + c[2], t[1] = madd2(m, 13281191951274694749, c[2], c[0]) + c[1], c[0] = madd2(v, x[3], c[1], t[3]) + t[3], t[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1]) + } + { + // round 2 + v := x[2] + c[1], c[0] = madd1(v, x[0], t[0]) + m := c[0] * 14042775128853446655 + c[2] = madd0(m, 4891460686036598785, c[0]) + c[1], c[0] = madd2(v, x[1], c[1], t[1]) + c[2], t[0] = madd2(m, 2896914383306846353, c[2], c[0]) + c[1], c[0] = madd2(v, x[2], c[1], t[2]) + c[2], t[1] = madd2(m, 13281191951274694749, c[2], c[0]) + c[1], c[0] = madd2(v, x[3], c[1], t[3]) + t[3], t[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1]) + } + { + // round 3 + v := x[3] + c[1], c[0] = madd1(v, x[0], t[0]) + m := c[0] * 14042775128853446655 + c[2] = madd0(m, 4891460686036598785, c[0]) + c[1], c[0] = madd2(v, x[1], c[1], t[1]) + c[2], z[0] = madd2(m, 2896914383306846353, c[2], c[0]) + c[1], c[0] = madd2(v, x[2], c[1], t[2]) + c[2], z[1] = madd2(m, 13281191951274694749, c[2], c[0]) + c[1], c[0] = madd2(v, x[3], c[1], t[3]) + z[3], z[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1]) + } + + // if z > q --> z -= q + // note: this is NOT constant time + if !(z[3] < 3486998266802970665 || (z[3] == 3486998266802970665 && (z[2] < 13281191951274694749 || (z[2] == 13281191951274694749 && (z[1] < 2896914383306846353 || (z[1] == 2896914383306846353 && (z[0] < 4891460686036598785))))))) { + var b uint64 + z[0], b = bits.Sub64(z[0], 4891460686036598785, 0) + z[1], b = bits.Sub64(z[1], 2896914383306846353, b) + z[2], b = bits.Sub64(z[2], 13281191951274694749, b) + z[3], _ = bits.Sub64(z[3], 3486998266802970665, b) + } +} + +func _fromMontGeneric(z *Element) { + // the following lines implement z = z * 1 + // with a modified CIOS montgomery multiplication + { + // m = z[0]n'[0] mod W + m := z[0] * 14042775128853446655 + C := madd0(m, 4891460686036598785, z[0]) + C, z[0] = madd2(m, 2896914383306846353, z[1], C) + C, z[1] = madd2(m, 13281191951274694749, z[2], C) + C, z[2] = madd2(m, 3486998266802970665, z[3], C) + z[3] = C + } + { + // m = z[0]n'[0] mod W + m := z[0] * 14042775128853446655 + C := madd0(m, 4891460686036598785, z[0]) + C, z[0] = madd2(m, 2896914383306846353, z[1], C) + C, z[1] = madd2(m, 13281191951274694749, z[2], C) + C, z[2] = madd2(m, 3486998266802970665, z[3], C) + z[3] = C + } + { + // m = z[0]n'[0] mod W + m := z[0] * 14042775128853446655 + C := madd0(m, 4891460686036598785, z[0]) + C, z[0] = madd2(m, 2896914383306846353, z[1], C) + C, z[1] = madd2(m, 13281191951274694749, z[2], C) + C, z[2] = madd2(m, 3486998266802970665, z[3], C) + z[3] = C + } + { + // m = z[0]n'[0] mod W + m := z[0] * 14042775128853446655 + C := madd0(m, 4891460686036598785, z[0]) + C, z[0] = madd2(m, 2896914383306846353, z[1], C) + C, z[1] = madd2(m, 13281191951274694749, z[2], C) + C, z[2] = madd2(m, 3486998266802970665, z[3], C) + z[3] = C + } + + // if z > q --> z -= q + // note: this is NOT constant time + if !(z[3] < 3486998266802970665 || (z[3] == 3486998266802970665 && (z[2] < 13281191951274694749 || (z[2] == 13281191951274694749 && (z[1] < 2896914383306846353 || (z[1] == 2896914383306846353 && (z[0] < 4891460686036598785))))))) { + var b uint64 + z[0], b = bits.Sub64(z[0], 4891460686036598785, 0) + z[1], b = bits.Sub64(z[1], 2896914383306846353, b) + z[2], b = bits.Sub64(z[2], 13281191951274694749, b) + z[3], _ = bits.Sub64(z[3], 3486998266802970665, b) + } +} + +// Exp z = x^exponent mod q +func (z *Element) Exp(x Element, exponent *big.Int) *Element { + var bZero big.Int + if exponent.Cmp(&bZero) == 0 { + return z.SetOne() + } + + z.Set(&x) + + for i := exponent.BitLen() - 2; i >= 0; i-- { + z.Square(z) + if exponent.Bit(i) == 1 { + z.Mul(z, &x) + } + } + + return z +} + +// ToMont converts z to Montgomery form +// sets and returns z = z * r^2 +func (z *Element) ToMont() *Element { + return z.Mul(z, &rSquare) +} + +// ToRegular returns z in regular form (doesn't mutate z) +func (z Element) ToRegular() Element { + return *z.FromMont() +} + +// String returns the string form of an Element in Montgomery form +func (z *Element) String() string { + var _z big.Int + return z.ToBigIntRegular(&_z).String() +} + +// ToBigInt returns z as a big.Int in Montgomery form +func (z *Element) ToBigInt(res *big.Int) *big.Int { + var b [Limbs * 8]byte + binary.BigEndian.PutUint64(b[24:32], z[0]) + binary.BigEndian.PutUint64(b[16:24], z[1]) + binary.BigEndian.PutUint64(b[8:16], z[2]) + binary.BigEndian.PutUint64(b[0:8], z[3]) + + return res.SetBytes(b[:]) +} + +// ToBigIntRegular returns z as a big.Int in regular form +func (z Element) ToBigIntRegular(res *big.Int) *big.Int { + z.FromMont() + return z.ToBigInt(res) +} + +// SetBigInt sets z to v (regular form) and returns z in Montgomery form +func (z *Element) SetBigInt(v *big.Int) *Element { + z.SetZero() + + var zero big.Int + q := Modulus() + + // fast path + c := v.Cmp(q) + if c == 0 { + // v == 0 + return z + } else if c != 1 && v.Cmp(&zero) != -1 { + // 0 < v < q + return z.setBigInt(v) + } + + // copy input + modular reduction + vv := new(big.Int).Set(v) + vv.Mod(v, q) + + return z.setBigInt(vv) +} + +// setBigInt assumes 0 <= v < q +func (z *Element) setBigInt(v *big.Int) *Element { + vBits := v.Bits() + + if bits.UintSize == 64 { + for i := 0; i < len(vBits); i++ { + z[i] = uint64(vBits[i]) + } + } else { + for i := 0; i < len(vBits); i++ { + if i%2 == 0 { + z[i/2] = uint64(vBits[i]) + } else { + z[i/2] |= uint64(vBits[i]) << 32 + } + } + } + + return z.ToMont() +} + +// SetString creates a big.Int with s (in base 10) and calls SetBigInt on z +func (z *Element) SetString(s string) *Element { + x, ok := new(big.Int).SetString(s, 10) + if !ok { + panic("Element.SetString failed -> can't parse number in base10 into a big.Int") + } + return z.SetBigInt(x) +} + +var ( + _bLegendreExponentElement *big.Int + _bSqrtExponentElement *big.Int +) + +func init() { + _bLegendreExponentElement, _ = new(big.Int).SetString("183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f8000000", 16) + const sqrtExponentElement = "183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f" + _bSqrtExponentElement, _ = new(big.Int).SetString(sqrtExponentElement, 16) +} + +// Legendre returns the Legendre symbol of z (either +1, -1, or 0.) +func (z *Element) Legendre() int { + var l Element + // z^((q-1)/2) + l.Exp(*z, _bLegendreExponentElement) + + if l.IsZero() { + return 0 + } + + // if l == 1 + if (l[3] == 1011752739694698287) && (l[2] == 7381016538464732718) && (l[1] == 3962172157175319849) && (l[0] == 12436184717236109307) { + return 1 + } + return -1 +} + +// Sqrt z = √x mod q +// if the square root doesn't exist (x is not a square mod q) +// Sqrt leaves z unchanged and returns nil +func (z *Element) Sqrt(x *Element) *Element { + // q ≡ 1 (mod 4) + // see modSqrtTonelliShanks in math/big/int.go + // using https://www.maa.org/sites/default/files/pdf/upload_library/22/Polya/07468342.di020786.02p0470a.pdf + + var y, b, t, w Element + // w = x^((s-1)/2)) + w.Exp(*x, _bSqrtExponentElement) + + // y = x^((s+1)/2)) = w * x + y.Mul(x, &w) + + // b = x^s = w * w * x = y * x + b.Mul(&w, &y) + + // g = nonResidue ^ s + var g = Element{ + 7164790868263648668, + 11685701338293206998, + 6216421865291908056, + 1756667274303109607, + } + r := uint64(28) + + // compute legendre symbol + // t = x^((q-1)/2) = r-1 squaring of x^s + t = b + for i := uint64(0); i < r-1; i++ { + t.Square(&t) + } + if t.IsZero() { + return z.SetZero() + } + if !((t[3] == 1011752739694698287) && (t[2] == 7381016538464732718) && (t[1] == 3962172157175319849) && (t[0] == 12436184717236109307)) { + // t != 1, we don't have a square root + return nil + } + for { + var m uint64 + t = b + + // for t != 1 + for !((t[3] == 1011752739694698287) && (t[2] == 7381016538464732718) && (t[1] == 3962172157175319849) && (t[0] == 12436184717236109307)) { + t.Square(&t) + m++ + } + + if m == 0 { + return z.Set(&y) + } + // t = g^(2^(r-m-1)) mod q + ge := int(r - m - 1) + t = g + for ge > 0 { + t.Square(&t) + ge-- + } + + g.Square(&t) + y.Mul(&y, &t) + b.Mul(&b, &g) + r = m + } +} + +// Inverse z = x^-1 mod q +// Algorithm 16 in "Efficient Software-Implementation of Finite Fields with Applications to Cryptography" +// if x == 0, sets and returns z = x +func (z *Element) Inverse(x *Element) *Element { + if x.IsZero() { + return z.Set(x) + } + + // initialize u = q + var u = Element{ + 4891460686036598785, + 2896914383306846353, + 13281191951274694749, + 3486998266802970665, + } + + // initialize s = r^2 + var s = Element{ + 1997599621687373223, + 6052339484930628067, + 10108755138030829701, + 150537098327114917, + } + + // r = 0 + r := Element{} + + v := *x + + var carry, borrow, t, t2 uint64 + var bigger, uIsOne, vIsOne bool + + for !uIsOne && !vIsOne { + for v[0]&1 == 0 { + + // v = v >> 1 + t2 = v[3] << 63 + v[3] >>= 1 + t = t2 + t2 = v[2] << 63 + v[2] = (v[2] >> 1) | t + t = t2 + t2 = v[1] << 63 + v[1] = (v[1] >> 1) | t + t = t2 + v[0] = (v[0] >> 1) | t + + if s[0]&1 == 1 { + + // s = s + q + s[0], carry = bits.Add64(s[0], 4891460686036598785, 0) + s[1], carry = bits.Add64(s[1], 2896914383306846353, carry) + s[2], carry = bits.Add64(s[2], 13281191951274694749, carry) + s[3], _ = bits.Add64(s[3], 3486998266802970665, carry) + + } + + // s = s >> 1 + t2 = s[3] << 63 + s[3] >>= 1 + t = t2 + t2 = s[2] << 63 + s[2] = (s[2] >> 1) | t + t = t2 + t2 = s[1] << 63 + s[1] = (s[1] >> 1) | t + t = t2 + s[0] = (s[0] >> 1) | t + + } + for u[0]&1 == 0 { + + // u = u >> 1 + t2 = u[3] << 63 + u[3] >>= 1 + t = t2 + t2 = u[2] << 63 + u[2] = (u[2] >> 1) | t + t = t2 + t2 = u[1] << 63 + u[1] = (u[1] >> 1) | t + t = t2 + u[0] = (u[0] >> 1) | t + + if r[0]&1 == 1 { + + // r = r + q + r[0], carry = bits.Add64(r[0], 4891460686036598785, 0) + r[1], carry = bits.Add64(r[1], 2896914383306846353, carry) + r[2], carry = bits.Add64(r[2], 13281191951274694749, carry) + r[3], _ = bits.Add64(r[3], 3486998266802970665, carry) + + } + + // r = r >> 1 + t2 = r[3] << 63 + r[3] >>= 1 + t = t2 + t2 = r[2] << 63 + r[2] = (r[2] >> 1) | t + t = t2 + t2 = r[1] << 63 + r[1] = (r[1] >> 1) | t + t = t2 + r[0] = (r[0] >> 1) | t + + } + + // v >= u + bigger = !(v[3] < u[3] || (v[3] == u[3] && (v[2] < u[2] || (v[2] == u[2] && (v[1] < u[1] || (v[1] == u[1] && (v[0] < u[0]))))))) + + if bigger { + + // v = v - u + v[0], borrow = bits.Sub64(v[0], u[0], 0) + v[1], borrow = bits.Sub64(v[1], u[1], borrow) + v[2], borrow = bits.Sub64(v[2], u[2], borrow) + v[3], _ = bits.Sub64(v[3], u[3], borrow) + + // r >= s + bigger = !(r[3] < s[3] || (r[3] == s[3] && (r[2] < s[2] || (r[2] == s[2] && (r[1] < s[1] || (r[1] == s[1] && (r[0] < s[0]))))))) + + if bigger { + + // s = s + q + s[0], carry = bits.Add64(s[0], 4891460686036598785, 0) + s[1], carry = bits.Add64(s[1], 2896914383306846353, carry) + s[2], carry = bits.Add64(s[2], 13281191951274694749, carry) + s[3], _ = bits.Add64(s[3], 3486998266802970665, carry) + + } + + // s = s - r + s[0], borrow = bits.Sub64(s[0], r[0], 0) + s[1], borrow = bits.Sub64(s[1], r[1], borrow) + s[2], borrow = bits.Sub64(s[2], r[2], borrow) + s[3], _ = bits.Sub64(s[3], r[3], borrow) + + } else { + + // u = u - v + u[0], borrow = bits.Sub64(u[0], v[0], 0) + u[1], borrow = bits.Sub64(u[1], v[1], borrow) + u[2], borrow = bits.Sub64(u[2], v[2], borrow) + u[3], _ = bits.Sub64(u[3], v[3], borrow) + + // s >= r + bigger = !(s[3] < r[3] || (s[3] == r[3] && (s[2] < r[2] || (s[2] == r[2] && (s[1] < r[1] || (s[1] == r[1] && (s[0] < r[0]))))))) + + if bigger { + + // r = r + q + r[0], carry = bits.Add64(r[0], 4891460686036598785, 0) + r[1], carry = bits.Add64(r[1], 2896914383306846353, carry) + r[2], carry = bits.Add64(r[2], 13281191951274694749, carry) + r[3], _ = bits.Add64(r[3], 3486998266802970665, carry) + + } + + // r = r - s + r[0], borrow = bits.Sub64(r[0], s[0], 0) + r[1], borrow = bits.Sub64(r[1], s[1], borrow) + r[2], borrow = bits.Sub64(r[2], s[2], borrow) + r[3], _ = bits.Sub64(r[3], s[3], borrow) + + } + uIsOne = (u[0] == 1) && (u[3]|u[2]|u[1]) == 0 + vIsOne = (v[0] == 1) && (v[3]|v[2]|v[1]) == 0 + } + + if uIsOne { + z.Set(&r) + } else { + z.Set(&s) + } + + return z +} + + +// Cmp compares (lexicographic order) z and x and returns: +// +// -1 if z < x +// 0 if z == x +// +1 if z > x +func (z *Element) Cmp(x *Element) int { + _z := z.Bits() + _x := x.Bits() + if _z[3] > _x[3] { + return 1 + } else if _z[3] < _x[3] { + return -1 + } + if _z[2] > _x[2] { + return 1 + } else if _z[2] < _x[2] { + return -1 + } + if _z[1] > _x[1] { + return 1 + } else if _z[1] < _x[1] { + return -1 + } + if _z[0] > _x[0] { + return 1 + } else if _z[0] < _x[0] { + return -1 + } + return 0 +} + +// Bits provides access to z by returning its value as a little-endian [4]uint64 array. +// Bits is intended to support implementation of missing low-level Element +// functionality outside this package; it should be avoided otherwise. +func (z *Element) Bits() [4]uint64 { + _z := *z + fromMont(&_z) + return _z +} \ No newline at end of file diff --git a/internal/utils/zklink/bn256/fr/element_ops_amd64.go b/internal/utils/zklink/bn256/fr/element_ops_amd64.go new file mode 100644 index 00000000000..36659b458be --- /dev/null +++ b/internal/utils/zklink/bn256/fr/element_ops_amd64.go @@ -0,0 +1,47 @@ +// Copyright 2020 ConsenSys Software Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by goff (v0.3.6) DO NOT EDIT + +package fr + +// q'[0], see montgommery multiplication algorithm +var ( + qElementInv0 uint64 = 14042775128853446655 + _ = qElementInv0 // used in asm +) + +//go:noescape +func add(res, x, y *Element) + +//go:noescape +func sub(res, x, y *Element) + +//go:noescape +func neg(res, x *Element) + +//go:noescape +func double(res, x *Element) + +//go:noescape +func mul(res, x, y *Element) + +//go:noescape +func square(res, x *Element) + +//go:noescape +func fromMont(res *Element) + +//go:noescape +func reduce(res *Element) diff --git a/internal/utils/zklink/bn256/fr/element_ops_amd64.s b/internal/utils/zklink/bn256/fr/element_ops_amd64.s new file mode 100644 index 00000000000..0dc31efc2fe --- /dev/null +++ b/internal/utils/zklink/bn256/fr/element_ops_amd64.s @@ -0,0 +1,1166 @@ + + // Copyright 2020 ConsenSys Software Inc. + // + // Licensed under the Apache License, Version 2.0 (the "License"); + // you may not use this file except in compliance with the License. + // You may obtain a copy of the License at + // + // http://www.apache.org/licenses/LICENSE-2.0 + // + // Unless required by applicable law or agreed to in writing, software + // distributed under the License is distributed on an "AS IS" BASIS, + // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + // See the License for the specific language governing permissions and + // limitations under the License. + +#include "textflag.h" +#include "funcdata.h" + +TEXT ·mul(SB), NOSPLIT, $0-24 + + // the algorithm is described here + // https://hackmd.io/@zkteam/modular_multiplication + // however, to benefit from the ADCX and ADOX carry chains + // we split the inner loops in 2: + // for i=0 to N-1 + // for j=0 to N-1 + // (A,t[j]) := t[j] + x[j]*y[i] + A + // m := t[0]*q'[0] mod W + // C,_ := t[0] + m*q[0] + // for j=1 to N-1 + // (C,t[j-1]) := t[j] + m*q[j] + C + // t[N-1] = C + A + + CMPB ·supportAdx(SB), $0x0000000000000001 + JNE l1 + MOVQ x+8(FP), R14 + MOVQ y+16(FP), R15 + XORQ DX, DX + MOVQ 0(R15), DX + MULXQ 0(R14), CX, BX + MULXQ 8(R14), AX, BP + ADOXQ AX, BX + MULXQ 16(R14), AX, SI + ADOXQ AX, BP + MULXQ 24(R14), AX, DI + ADOXQ AX, SI + // add the last carries to DI + MOVQ $0x0000000000000000, DX + ADCXQ DX, DI + ADOXQ DX, DI + MOVQ CX, DX + MULXQ ·qElementInv0(SB), DX, AX // m := t[0]*q'[0] mod W + XORQ AX, AX + // C,_ := t[0] + m*q[0] + MULXQ ·qElement+0(SB), AX, R8 + ADCXQ CX, AX + MOVQ R8, CX + // for j=1 to N-1 + // (C,t[j-1]) := t[j] + m*q[j] + C + ADCXQ BX, CX + MULXQ ·qElement+8(SB), AX, BX + ADOXQ AX, CX + ADCXQ BP, BX + MULXQ ·qElement+16(SB), AX, BP + ADOXQ AX, BX + ADCXQ SI, BP + MULXQ ·qElement+24(SB), AX, SI + ADOXQ AX, BP + MOVQ $0x0000000000000000, AX + ADCXQ AX, SI + ADOXQ DI, SI + XORQ DX, DX + MOVQ 8(R15), DX + MULXQ 0(R14), AX, DI + ADOXQ AX, CX + ADCXQ DI, BX + MULXQ 8(R14), AX, DI + ADOXQ AX, BX + ADCXQ DI, BP + MULXQ 16(R14), AX, DI + ADOXQ AX, BP + ADCXQ DI, SI + MULXQ 24(R14), AX, DI + ADOXQ AX, SI + // add the last carries to DI + MOVQ $0x0000000000000000, DX + ADCXQ DX, DI + ADOXQ DX, DI + MOVQ CX, DX + MULXQ ·qElementInv0(SB), DX, AX // m := t[0]*q'[0] mod W + XORQ AX, AX + // C,_ := t[0] + m*q[0] + MULXQ ·qElement+0(SB), AX, R9 + ADCXQ CX, AX + MOVQ R9, CX + // for j=1 to N-1 + // (C,t[j-1]) := t[j] + m*q[j] + C + ADCXQ BX, CX + MULXQ ·qElement+8(SB), AX, BX + ADOXQ AX, CX + ADCXQ BP, BX + MULXQ ·qElement+16(SB), AX, BP + ADOXQ AX, BX + ADCXQ SI, BP + MULXQ ·qElement+24(SB), AX, SI + ADOXQ AX, BP + MOVQ $0x0000000000000000, AX + ADCXQ AX, SI + ADOXQ DI, SI + XORQ DX, DX + MOVQ 16(R15), DX + MULXQ 0(R14), AX, DI + ADOXQ AX, CX + ADCXQ DI, BX + MULXQ 8(R14), AX, DI + ADOXQ AX, BX + ADCXQ DI, BP + MULXQ 16(R14), AX, DI + ADOXQ AX, BP + ADCXQ DI, SI + MULXQ 24(R14), AX, DI + ADOXQ AX, SI + // add the last carries to DI + MOVQ $0x0000000000000000, DX + ADCXQ DX, DI + ADOXQ DX, DI + MOVQ CX, DX + MULXQ ·qElementInv0(SB), DX, AX // m := t[0]*q'[0] mod W + XORQ AX, AX + // C,_ := t[0] + m*q[0] + MULXQ ·qElement+0(SB), AX, R10 + ADCXQ CX, AX + MOVQ R10, CX + // for j=1 to N-1 + // (C,t[j-1]) := t[j] + m*q[j] + C + ADCXQ BX, CX + MULXQ ·qElement+8(SB), AX, BX + ADOXQ AX, CX + ADCXQ BP, BX + MULXQ ·qElement+16(SB), AX, BP + ADOXQ AX, BX + ADCXQ SI, BP + MULXQ ·qElement+24(SB), AX, SI + ADOXQ AX, BP + MOVQ $0x0000000000000000, AX + ADCXQ AX, SI + ADOXQ DI, SI + XORQ DX, DX + MOVQ 24(R15), DX + MULXQ 0(R14), AX, DI + ADOXQ AX, CX + ADCXQ DI, BX + MULXQ 8(R14), AX, DI + ADOXQ AX, BX + ADCXQ DI, BP + MULXQ 16(R14), AX, DI + ADOXQ AX, BP + ADCXQ DI, SI + MULXQ 24(R14), AX, DI + ADOXQ AX, SI + // add the last carries to DI + MOVQ $0x0000000000000000, DX + ADCXQ DX, DI + ADOXQ DX, DI + MOVQ CX, DX + MULXQ ·qElementInv0(SB), DX, AX // m := t[0]*q'[0] mod W + XORQ AX, AX + // C,_ := t[0] + m*q[0] + MULXQ ·qElement+0(SB), AX, R11 + ADCXQ CX, AX + MOVQ R11, CX + // for j=1 to N-1 + // (C,t[j-1]) := t[j] + m*q[j] + C + ADCXQ BX, CX + MULXQ ·qElement+8(SB), AX, BX + ADOXQ AX, CX + ADCXQ BP, BX + MULXQ ·qElement+16(SB), AX, BP + ADOXQ AX, BX + ADCXQ SI, BP + MULXQ ·qElement+24(SB), AX, SI + ADOXQ AX, BP + MOVQ $0x0000000000000000, AX + ADCXQ AX, SI + ADOXQ DI, SI + MOVQ res+0(FP), R12 + MOVQ CX, R13 + MOVQ BX, R8 + MOVQ BP, R9 + MOVQ SI, R10 + SUBQ ·qElement+0(SB), R13 + SBBQ ·qElement+8(SB), R8 + SBBQ ·qElement+16(SB), R9 + SBBQ ·qElement+24(SB), R10 + CMOVQCC R13, CX + CMOVQCC R8, BX + CMOVQCC R9, BP + CMOVQCC R10, SI + MOVQ CX, 0(R12) + MOVQ BX, 8(R12) + MOVQ BP, 16(R12) + MOVQ SI, 24(R12) + RET +l1: + MOVQ x+8(FP), R15 + MOVQ y+16(FP), R14 + MOVQ 0(R15), AX + MOVQ 0(R14), R8 + MULQ R8 + MOVQ AX, CX + MOVQ DX, R9 + MOVQ ·qElementInv0(SB), R10 + IMULQ CX, R10 + MOVQ $0x43e1f593f0000001, AX + MULQ R10 + ADDQ CX, AX + ADCQ $0x0000000000000000, DX + MOVQ DX, DI + MOVQ 8(R15), AX + MULQ R8 + MOVQ R9, BX + ADDQ AX, BX + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0x2833e84879b97091, AX + MULQ R10 + ADDQ BX, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, CX + MOVQ DX, DI + MOVQ 16(R15), AX + MULQ R8 + MOVQ R9, BP + ADDQ AX, BP + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0xb85045b68181585d, AX + MULQ R10 + ADDQ BP, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, BX + MOVQ DX, DI + MOVQ 24(R15), AX + MULQ R8 + MOVQ R9, SI + ADDQ AX, SI + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0x30644e72e131a029, AX + MULQ R10 + ADDQ SI, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, BP + MOVQ DX, DI + ADDQ DI, R9 + MOVQ R9, SI + MOVQ 0(R15), AX + MOVQ 8(R14), R8 + MULQ R8 + ADDQ AX, CX + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ ·qElementInv0(SB), R10 + IMULQ CX, R10 + MOVQ $0x43e1f593f0000001, AX + MULQ R10 + ADDQ CX, AX + ADCQ $0x0000000000000000, DX + MOVQ DX, DI + MOVQ 8(R15), AX + MULQ R8 + ADDQ R9, BX + ADCQ $0x0000000000000000, DX + ADDQ AX, BX + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0x2833e84879b97091, AX + MULQ R10 + ADDQ BX, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, CX + MOVQ DX, DI + MOVQ 16(R15), AX + MULQ R8 + ADDQ R9, BP + ADCQ $0x0000000000000000, DX + ADDQ AX, BP + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0xb85045b68181585d, AX + MULQ R10 + ADDQ BP, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, BX + MOVQ DX, DI + MOVQ 24(R15), AX + MULQ R8 + ADDQ R9, SI + ADCQ $0x0000000000000000, DX + ADDQ AX, SI + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0x30644e72e131a029, AX + MULQ R10 + ADDQ SI, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, BP + MOVQ DX, DI + ADDQ DI, R9 + MOVQ R9, SI + MOVQ 0(R15), AX + MOVQ 16(R14), R8 + MULQ R8 + ADDQ AX, CX + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ ·qElementInv0(SB), R10 + IMULQ CX, R10 + MOVQ $0x43e1f593f0000001, AX + MULQ R10 + ADDQ CX, AX + ADCQ $0x0000000000000000, DX + MOVQ DX, DI + MOVQ 8(R15), AX + MULQ R8 + ADDQ R9, BX + ADCQ $0x0000000000000000, DX + ADDQ AX, BX + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0x2833e84879b97091, AX + MULQ R10 + ADDQ BX, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, CX + MOVQ DX, DI + MOVQ 16(R15), AX + MULQ R8 + ADDQ R9, BP + ADCQ $0x0000000000000000, DX + ADDQ AX, BP + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0xb85045b68181585d, AX + MULQ R10 + ADDQ BP, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, BX + MOVQ DX, DI + MOVQ 24(R15), AX + MULQ R8 + ADDQ R9, SI + ADCQ $0x0000000000000000, DX + ADDQ AX, SI + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0x30644e72e131a029, AX + MULQ R10 + ADDQ SI, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, BP + MOVQ DX, DI + ADDQ DI, R9 + MOVQ R9, SI + MOVQ 0(R15), AX + MOVQ 24(R14), R8 + MULQ R8 + ADDQ AX, CX + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ ·qElementInv0(SB), R10 + IMULQ CX, R10 + MOVQ $0x43e1f593f0000001, AX + MULQ R10 + ADDQ CX, AX + ADCQ $0x0000000000000000, DX + MOVQ DX, DI + MOVQ 8(R15), AX + MULQ R8 + ADDQ R9, BX + ADCQ $0x0000000000000000, DX + ADDQ AX, BX + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0x2833e84879b97091, AX + MULQ R10 + ADDQ BX, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, CX + MOVQ DX, DI + MOVQ 16(R15), AX + MULQ R8 + ADDQ R9, BP + ADCQ $0x0000000000000000, DX + ADDQ AX, BP + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0xb85045b68181585d, AX + MULQ R10 + ADDQ BP, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, BX + MOVQ DX, DI + MOVQ 24(R15), AX + MULQ R8 + ADDQ R9, SI + ADCQ $0x0000000000000000, DX + ADDQ AX, SI + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0x30644e72e131a029, AX + MULQ R10 + ADDQ SI, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, BP + MOVQ DX, DI + ADDQ DI, R9 + MOVQ R9, SI + MOVQ res+0(FP), R15 + MOVQ CX, R11 + MOVQ BX, R12 + MOVQ BP, R13 + MOVQ SI, DI + SUBQ ·qElement+0(SB), R11 + SBBQ ·qElement+8(SB), R12 + SBBQ ·qElement+16(SB), R13 + SBBQ ·qElement+24(SB), DI + CMOVQCC R11, CX + CMOVQCC R12, BX + CMOVQCC R13, BP + CMOVQCC DI, SI + MOVQ CX, 0(R15) + MOVQ BX, 8(R15) + MOVQ BP, 16(R15) + MOVQ SI, 24(R15) + RET + +TEXT ·square(SB), NOSPLIT, $0-16 + + // the algorithm is described here + // https://hackmd.io/@zkteam/modular_multiplication + // for i=0 to N-1 + // A, t[i] = x[i] * x[i] + t[i] + // p = 0 + // for j=i+1 to N-1 + // p,A,t[j] = 2*x[j]*x[i] + t[j] + (p,A) + // m = t[0] * q'[0] + // C, _ = t[0] + q[0]*m + // for j=1 to N-1 + // C, t[j-1] = q[j]*m + t[j] + C + // t[N-1] = C + A + + + CMPB ·supportAdx(SB), $0x0000000000000001 + JNE l2 + MOVQ x+8(FP), BP + XORQ AX, AX + MOVQ 0(BP), DX + MULXQ 8(BP), DI, R8 + MULXQ 16(BP), AX, R9 + ADCXQ AX, R8 + MULXQ 24(BP), AX, SI + ADCXQ AX, R9 + MOVQ $0x0000000000000000, AX + ADCXQ AX, SI + XORQ AX, AX + MULXQ DX, R14, DX + ADCXQ DI, DI + MOVQ DI, R15 + ADOXQ DX, R15 + ADCXQ R8, R8 + MOVQ R8, CX + ADOXQ AX, CX + ADCXQ R9, R9 + MOVQ R9, BX + ADOXQ AX, BX + ADCXQ SI, SI + ADOXQ AX, SI + MOVQ R14, DX + MULXQ ·qElementInv0(SB), DX, AX // m := t[0]*q'[0] mod W + XORQ AX, AX + MULXQ ·qElement+0(SB), AX, R10 + ADCXQ R14, AX + MOVQ R10, R14 + ADCXQ R15, R14 + MULXQ ·qElement+8(SB), AX, R15 + ADOXQ AX, R14 + ADCXQ CX, R15 + MULXQ ·qElement+16(SB), AX, CX + ADOXQ AX, R15 + ADCXQ BX, CX + MULXQ ·qElement+24(SB), AX, BX + ADOXQ AX, CX + MOVQ $0x0000000000000000, AX + ADCXQ AX, BX + ADOXQ SI, BX + XORQ AX, AX + MOVQ 8(BP), DX + MULXQ 16(BP), R11, R12 + MULXQ 24(BP), AX, SI + ADCXQ AX, R12 + MOVQ $0x0000000000000000, AX + ADCXQ AX, SI + XORQ AX, AX + ADCXQ R11, R11 + ADOXQ R11, CX + ADCXQ R12, R12 + ADOXQ R12, BX + ADCXQ SI, SI + ADOXQ AX, SI + XORQ AX, AX + MULXQ DX, AX, DX + ADOXQ AX, R15 + MOVQ $0x0000000000000000, AX + ADOXQ DX, CX + ADOXQ AX, BX + ADOXQ AX, SI + MOVQ R14, DX + MULXQ ·qElementInv0(SB), DX, AX // m := t[0]*q'[0] mod W + XORQ AX, AX + MULXQ ·qElement+0(SB), AX, R13 + ADCXQ R14, AX + MOVQ R13, R14 + ADCXQ R15, R14 + MULXQ ·qElement+8(SB), AX, R15 + ADOXQ AX, R14 + ADCXQ CX, R15 + MULXQ ·qElement+16(SB), AX, CX + ADOXQ AX, R15 + ADCXQ BX, CX + MULXQ ·qElement+24(SB), AX, BX + ADOXQ AX, CX + MOVQ $0x0000000000000000, AX + ADCXQ AX, BX + ADOXQ SI, BX + XORQ AX, AX + MOVQ 16(BP), DX + MULXQ 24(BP), DI, SI + ADCXQ DI, DI + ADOXQ DI, BX + ADCXQ SI, SI + ADOXQ AX, SI + XORQ AX, AX + MULXQ DX, AX, DX + ADOXQ AX, CX + MOVQ $0x0000000000000000, AX + ADOXQ DX, BX + ADOXQ AX, SI + MOVQ R14, DX + MULXQ ·qElementInv0(SB), DX, AX // m := t[0]*q'[0] mod W + XORQ AX, AX + MULXQ ·qElement+0(SB), AX, R8 + ADCXQ R14, AX + MOVQ R8, R14 + ADCXQ R15, R14 + MULXQ ·qElement+8(SB), AX, R15 + ADOXQ AX, R14 + ADCXQ CX, R15 + MULXQ ·qElement+16(SB), AX, CX + ADOXQ AX, R15 + ADCXQ BX, CX + MULXQ ·qElement+24(SB), AX, BX + ADOXQ AX, CX + MOVQ $0x0000000000000000, AX + ADCXQ AX, BX + ADOXQ SI, BX + XORQ AX, AX + MOVQ 24(BP), DX + MULXQ DX, AX, SI + ADCXQ AX, BX + MOVQ $0x0000000000000000, AX + ADCXQ AX, SI + MOVQ R14, DX + MULXQ ·qElementInv0(SB), DX, AX // m := t[0]*q'[0] mod W + XORQ AX, AX + MULXQ ·qElement+0(SB), AX, R9 + ADCXQ R14, AX + MOVQ R9, R14 + ADCXQ R15, R14 + MULXQ ·qElement+8(SB), AX, R15 + ADOXQ AX, R14 + ADCXQ CX, R15 + MULXQ ·qElement+16(SB), AX, CX + ADOXQ AX, R15 + ADCXQ BX, CX + MULXQ ·qElement+24(SB), AX, BX + ADOXQ AX, CX + MOVQ $0x0000000000000000, AX + ADCXQ AX, BX + ADOXQ SI, BX + MOVQ res+0(FP), R10 + MOVQ R14, R11 + MOVQ R15, R12 + MOVQ CX, R13 + MOVQ BX, DI + SUBQ ·qElement+0(SB), R11 + SBBQ ·qElement+8(SB), R12 + SBBQ ·qElement+16(SB), R13 + SBBQ ·qElement+24(SB), DI + CMOVQCC R11, R14 + CMOVQCC R12, R15 + CMOVQCC R13, CX + CMOVQCC DI, BX + MOVQ R14, 0(R10) + MOVQ R15, 8(R10) + MOVQ CX, 16(R10) + MOVQ BX, 24(R10) + RET +l2: + MOVQ x+8(FP), R15 + MOVQ x+8(FP), R14 + MOVQ 0(R15), AX + MOVQ 0(R14), R8 + MULQ R8 + MOVQ AX, CX + MOVQ DX, R9 + MOVQ ·qElementInv0(SB), R10 + IMULQ CX, R10 + MOVQ $0x43e1f593f0000001, AX + MULQ R10 + ADDQ CX, AX + ADCQ $0x0000000000000000, DX + MOVQ DX, DI + MOVQ 8(R15), AX + MULQ R8 + MOVQ R9, BX + ADDQ AX, BX + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0x2833e84879b97091, AX + MULQ R10 + ADDQ BX, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, CX + MOVQ DX, DI + MOVQ 16(R15), AX + MULQ R8 + MOVQ R9, BP + ADDQ AX, BP + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0xb85045b68181585d, AX + MULQ R10 + ADDQ BP, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, BX + MOVQ DX, DI + MOVQ 24(R15), AX + MULQ R8 + MOVQ R9, SI + ADDQ AX, SI + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0x30644e72e131a029, AX + MULQ R10 + ADDQ SI, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, BP + MOVQ DX, DI + ADDQ DI, R9 + MOVQ R9, SI + MOVQ 0(R15), AX + MOVQ 8(R14), R8 + MULQ R8 + ADDQ AX, CX + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ ·qElementInv0(SB), R10 + IMULQ CX, R10 + MOVQ $0x43e1f593f0000001, AX + MULQ R10 + ADDQ CX, AX + ADCQ $0x0000000000000000, DX + MOVQ DX, DI + MOVQ 8(R15), AX + MULQ R8 + ADDQ R9, BX + ADCQ $0x0000000000000000, DX + ADDQ AX, BX + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0x2833e84879b97091, AX + MULQ R10 + ADDQ BX, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, CX + MOVQ DX, DI + MOVQ 16(R15), AX + MULQ R8 + ADDQ R9, BP + ADCQ $0x0000000000000000, DX + ADDQ AX, BP + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0xb85045b68181585d, AX + MULQ R10 + ADDQ BP, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, BX + MOVQ DX, DI + MOVQ 24(R15), AX + MULQ R8 + ADDQ R9, SI + ADCQ $0x0000000000000000, DX + ADDQ AX, SI + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0x30644e72e131a029, AX + MULQ R10 + ADDQ SI, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, BP + MOVQ DX, DI + ADDQ DI, R9 + MOVQ R9, SI + MOVQ 0(R15), AX + MOVQ 16(R14), R8 + MULQ R8 + ADDQ AX, CX + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ ·qElementInv0(SB), R10 + IMULQ CX, R10 + MOVQ $0x43e1f593f0000001, AX + MULQ R10 + ADDQ CX, AX + ADCQ $0x0000000000000000, DX + MOVQ DX, DI + MOVQ 8(R15), AX + MULQ R8 + ADDQ R9, BX + ADCQ $0x0000000000000000, DX + ADDQ AX, BX + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0x2833e84879b97091, AX + MULQ R10 + ADDQ BX, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, CX + MOVQ DX, DI + MOVQ 16(R15), AX + MULQ R8 + ADDQ R9, BP + ADCQ $0x0000000000000000, DX + ADDQ AX, BP + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0xb85045b68181585d, AX + MULQ R10 + ADDQ BP, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, BX + MOVQ DX, DI + MOVQ 24(R15), AX + MULQ R8 + ADDQ R9, SI + ADCQ $0x0000000000000000, DX + ADDQ AX, SI + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0x30644e72e131a029, AX + MULQ R10 + ADDQ SI, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, BP + MOVQ DX, DI + ADDQ DI, R9 + MOVQ R9, SI + MOVQ 0(R15), AX + MOVQ 24(R14), R8 + MULQ R8 + ADDQ AX, CX + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ ·qElementInv0(SB), R10 + IMULQ CX, R10 + MOVQ $0x43e1f593f0000001, AX + MULQ R10 + ADDQ CX, AX + ADCQ $0x0000000000000000, DX + MOVQ DX, DI + MOVQ 8(R15), AX + MULQ R8 + ADDQ R9, BX + ADCQ $0x0000000000000000, DX + ADDQ AX, BX + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0x2833e84879b97091, AX + MULQ R10 + ADDQ BX, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, CX + MOVQ DX, DI + MOVQ 16(R15), AX + MULQ R8 + ADDQ R9, BP + ADCQ $0x0000000000000000, DX + ADDQ AX, BP + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0xb85045b68181585d, AX + MULQ R10 + ADDQ BP, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, BX + MOVQ DX, DI + MOVQ 24(R15), AX + MULQ R8 + ADDQ R9, SI + ADCQ $0x0000000000000000, DX + ADDQ AX, SI + ADCQ $0x0000000000000000, DX + MOVQ DX, R9 + MOVQ $0x30644e72e131a029, AX + MULQ R10 + ADDQ SI, DI + ADCQ $0x0000000000000000, DX + ADDQ AX, DI + ADCQ $0x0000000000000000, DX + MOVQ DI, BP + MOVQ DX, DI + ADDQ DI, R9 + MOVQ R9, SI + MOVQ res+0(FP), R15 + MOVQ CX, R11 + MOVQ BX, R12 + MOVQ BP, R13 + MOVQ SI, DI + SUBQ ·qElement+0(SB), R11 + SBBQ ·qElement+8(SB), R12 + SBBQ ·qElement+16(SB), R13 + SBBQ ·qElement+24(SB), DI + CMOVQCC R11, CX + CMOVQCC R12, BX + CMOVQCC R13, BP + CMOVQCC DI, SI + MOVQ CX, 0(R15) + MOVQ BX, 8(R15) + MOVQ BP, 16(R15) + MOVQ SI, 24(R15) + RET + +TEXT ·fromMont(SB), $8-8 +NO_LOCAL_POINTERS + + // the algorithm is described here + // https://hackmd.io/@zkteam/modular_multiplication + // when y = 1 we have: + // for i=0 to N-1 + // t[i] = x[i] + // for i=0 to N-1 + // m := t[0]*q'[0] mod W + // C,_ := t[0] + m*q[0] + // for j=1 to N-1 + // (C,t[j-1]) := t[j] + m*q[j] + C + // t[N-1] = C + CMPB ·supportAdx(SB), $0x0000000000000001 + JNE l3 + MOVQ res+0(FP), BP + MOVQ 0(BP), R14 + MOVQ 8(BP), R15 + MOVQ 16(BP), CX + MOVQ 24(BP), BX + XORQ DX, DX + MOVQ R14, DX + MULXQ ·qElementInv0(SB), DX, AX // m := t[0]*q'[0] mod W + XORQ AX, AX + // C,_ := t[0] + m*q[0] + MULXQ ·qElement+0(SB), AX, SI + ADCXQ R14, AX + MOVQ SI, R14 + // for j=1 to N-1 + // (C,t[j-1]) := t[j] + m*q[j] + C + ADCXQ R15, R14 + MULXQ ·qElement+8(SB), AX, R15 + ADOXQ AX, R14 + ADCXQ CX, R15 + MULXQ ·qElement+16(SB), AX, CX + ADOXQ AX, R15 + ADCXQ BX, CX + MULXQ ·qElement+24(SB), AX, BX + ADOXQ AX, CX + MOVQ $0x0000000000000000, AX + ADCXQ AX, BX + ADOXQ AX, BX + XORQ DX, DX + MOVQ R14, DX + MULXQ ·qElementInv0(SB), DX, AX // m := t[0]*q'[0] mod W + XORQ AX, AX + // C,_ := t[0] + m*q[0] + MULXQ ·qElement+0(SB), AX, SI + ADCXQ R14, AX + MOVQ SI, R14 + // for j=1 to N-1 + // (C,t[j-1]) := t[j] + m*q[j] + C + ADCXQ R15, R14 + MULXQ ·qElement+8(SB), AX, R15 + ADOXQ AX, R14 + ADCXQ CX, R15 + MULXQ ·qElement+16(SB), AX, CX + ADOXQ AX, R15 + ADCXQ BX, CX + MULXQ ·qElement+24(SB), AX, BX + ADOXQ AX, CX + MOVQ $0x0000000000000000, AX + ADCXQ AX, BX + ADOXQ AX, BX + XORQ DX, DX + MOVQ R14, DX + MULXQ ·qElementInv0(SB), DX, AX // m := t[0]*q'[0] mod W + XORQ AX, AX + // C,_ := t[0] + m*q[0] + MULXQ ·qElement+0(SB), AX, SI + ADCXQ R14, AX + MOVQ SI, R14 + // for j=1 to N-1 + // (C,t[j-1]) := t[j] + m*q[j] + C + ADCXQ R15, R14 + MULXQ ·qElement+8(SB), AX, R15 + ADOXQ AX, R14 + ADCXQ CX, R15 + MULXQ ·qElement+16(SB), AX, CX + ADOXQ AX, R15 + ADCXQ BX, CX + MULXQ ·qElement+24(SB), AX, BX + ADOXQ AX, CX + MOVQ $0x0000000000000000, AX + ADCXQ AX, BX + ADOXQ AX, BX + XORQ DX, DX + MOVQ R14, DX + MULXQ ·qElementInv0(SB), DX, AX // m := t[0]*q'[0] mod W + XORQ AX, AX + // C,_ := t[0] + m*q[0] + MULXQ ·qElement+0(SB), AX, SI + ADCXQ R14, AX + MOVQ SI, R14 + // for j=1 to N-1 + // (C,t[j-1]) := t[j] + m*q[j] + C + ADCXQ R15, R14 + MULXQ ·qElement+8(SB), AX, R15 + ADOXQ AX, R14 + ADCXQ CX, R15 + MULXQ ·qElement+16(SB), AX, CX + ADOXQ AX, R15 + ADCXQ BX, CX + MULXQ ·qElement+24(SB), AX, BX + ADOXQ AX, CX + MOVQ $0x0000000000000000, AX + ADCXQ AX, BX + ADOXQ AX, BX + MOVQ R14, DI + MOVQ R15, R8 + MOVQ CX, R9 + MOVQ BX, R10 + SUBQ ·qElement+0(SB), DI + SBBQ ·qElement+8(SB), R8 + SBBQ ·qElement+16(SB), R9 + SBBQ ·qElement+24(SB), R10 + CMOVQCC DI, R14 + CMOVQCC R8, R15 + CMOVQCC R9, CX + CMOVQCC R10, BX + MOVQ R14, 0(BP) + MOVQ R15, 8(BP) + MOVQ CX, 16(BP) + MOVQ BX, 24(BP) + RET +l3: + MOVQ res+0(FP), AX + MOVQ AX, (SP) +CALL ·_fromMontGeneric(SB) + RET + +TEXT ·reduce(SB), NOSPLIT, $0-8 + MOVQ res+0(FP), AX + MOVQ 0(AX), DX + MOVQ 8(AX), CX + MOVQ 16(AX), BX + MOVQ 24(AX), BP + MOVQ DX, SI + MOVQ CX, DI + MOVQ BX, R8 + MOVQ BP, R9 + SUBQ ·qElement+0(SB), SI + SBBQ ·qElement+8(SB), DI + SBBQ ·qElement+16(SB), R8 + SBBQ ·qElement+24(SB), R9 + CMOVQCC SI, DX + CMOVQCC DI, CX + CMOVQCC R8, BX + CMOVQCC R9, BP + MOVQ DX, 0(AX) + MOVQ CX, 8(AX) + MOVQ BX, 16(AX) + MOVQ BP, 24(AX) + RET + +TEXT ·add(SB), NOSPLIT, $0-24 + MOVQ x+8(FP), AX + MOVQ 0(AX), BX + MOVQ 8(AX), BP + MOVQ 16(AX), SI + MOVQ 24(AX), DI + MOVQ y+16(FP), DX + ADDQ 0(DX), BX + ADCQ 8(DX), BP + ADCQ 16(DX), SI + ADCQ 24(DX), DI + MOVQ res+0(FP), CX + MOVQ BX, R8 + MOVQ BP, R9 + MOVQ SI, R10 + MOVQ DI, R11 + SUBQ ·qElement+0(SB), R8 + SBBQ ·qElement+8(SB), R9 + SBBQ ·qElement+16(SB), R10 + SBBQ ·qElement+24(SB), R11 + CMOVQCC R8, BX + CMOVQCC R9, BP + CMOVQCC R10, SI + CMOVQCC R11, DI + MOVQ BX, 0(CX) + MOVQ BP, 8(CX) + MOVQ SI, 16(CX) + MOVQ DI, 24(CX) + RET + +TEXT ·sub(SB), NOSPLIT, $0-24 + MOVQ x+8(FP), BP + MOVQ 0(BP), AX + MOVQ 8(BP), DX + MOVQ 16(BP), CX + MOVQ 24(BP), BX + MOVQ y+16(FP), SI + SUBQ 0(SI), AX + SBBQ 8(SI), DX + SBBQ 16(SI), CX + SBBQ 24(SI), BX + MOVQ $0x43e1f593f0000001, DI + MOVQ $0x2833e84879b97091, R8 + MOVQ $0xb85045b68181585d, R9 + MOVQ $0x30644e72e131a029, R10 + MOVQ $0x0000000000000000, R11 + CMOVQCC R11, DI + CMOVQCC R11, R8 + CMOVQCC R11, R9 + CMOVQCC R11, R10 + ADDQ DI, AX + ADCQ R8, DX + ADCQ R9, CX + ADCQ R10, BX + MOVQ res+0(FP), R12 + MOVQ AX, 0(R12) + MOVQ DX, 8(R12) + MOVQ CX, 16(R12) + MOVQ BX, 24(R12) + RET + +TEXT ·double(SB), NOSPLIT, $0-16 + MOVQ res+0(FP), DX + MOVQ x+8(FP), AX + MOVQ 0(AX), CX + MOVQ 8(AX), BX + MOVQ 16(AX), BP + MOVQ 24(AX), SI + ADDQ CX, CX + ADCQ BX, BX + ADCQ BP, BP + ADCQ SI, SI + MOVQ CX, DI + MOVQ BX, R8 + MOVQ BP, R9 + MOVQ SI, R10 + SUBQ ·qElement+0(SB), DI + SBBQ ·qElement+8(SB), R8 + SBBQ ·qElement+16(SB), R9 + SBBQ ·qElement+24(SB), R10 + CMOVQCC DI, CX + CMOVQCC R8, BX + CMOVQCC R9, BP + CMOVQCC R10, SI + MOVQ CX, 0(DX) + MOVQ BX, 8(DX) + MOVQ BP, 16(DX) + MOVQ SI, 24(DX) + RET + +TEXT ·neg(SB), NOSPLIT, $0-16 + MOVQ res+0(FP), DX + MOVQ x+8(FP), AX + MOVQ 0(AX), BX + MOVQ 8(AX), BP + MOVQ 16(AX), SI + MOVQ 24(AX), DI + MOVQ BX, AX + ORQ BP, AX + ORQ SI, AX + ORQ DI, AX + TESTQ AX, AX + JNE l4 + MOVQ AX, 0(DX) + MOVQ AX, 8(DX) + RET +l4: + MOVQ $0x43e1f593f0000001, CX + SUBQ BX, CX + MOVQ CX, 0(DX) + MOVQ $0x2833e84879b97091, CX + SBBQ BP, CX + MOVQ CX, 8(DX) + MOVQ $0xb85045b68181585d, CX + SBBQ SI, CX + MOVQ CX, 16(DX) + MOVQ $0x30644e72e131a029, CX + SBBQ DI, CX + MOVQ CX, 24(DX) + RET diff --git a/internal/utils/zklink/bn256/fr/element_ops_noasm.go b/internal/utils/zklink/bn256/fr/element_ops_noasm.go new file mode 100644 index 00000000000..a596b6da6de --- /dev/null +++ b/internal/utils/zklink/bn256/fr/element_ops_noasm.go @@ -0,0 +1,119 @@ +// +build !amd64 + +// Copyright 2020 ConsenSys Software Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by goff (v0.3.6) DO NOT EDIT + +package fr + +// /!\ WARNING /!\ +// this code has not been audited and is provided as-is. In particular, +// there is no security guarantees such as constant time implementation +// or side-channel attack resistance +// /!\ WARNING /!\ + +import "math/bits" + +func mul(z, x, y *Element) { + _mulGeneric(z, x, y) +} + +func square(z, x *Element) { + _squareGeneric(z, x) +} + +// FromMont converts z in place (i.e. mutates) from Montgomery to regular representation +// sets and returns z = z * 1 +func fromMont(z *Element) { + _fromMontGeneric(z) +} + +func add(z, x, y *Element) { + var carry uint64 + + z[0], carry = bits.Add64(x[0], y[0], 0) + z[1], carry = bits.Add64(x[1], y[1], carry) + z[2], carry = bits.Add64(x[2], y[2], carry) + z[3], _ = bits.Add64(x[3], y[3], carry) + + // if z > q --> z -= q + // note: this is NOT constant time + if !(z[3] < 3486998266802970665 || (z[3] == 3486998266802970665 && (z[2] < 13281191951274694749 || (z[2] == 13281191951274694749 && (z[1] < 2896914383306846353 || (z[1] == 2896914383306846353 && (z[0] < 4891460686036598785))))))) { + var b uint64 + z[0], b = bits.Sub64(z[0], 4891460686036598785, 0) + z[1], b = bits.Sub64(z[1], 2896914383306846353, b) + z[2], b = bits.Sub64(z[2], 13281191951274694749, b) + z[3], _ = bits.Sub64(z[3], 3486998266802970665, b) + } +} + +func double(z, x *Element) { + var carry uint64 + + z[0], carry = bits.Add64(x[0], x[0], 0) + z[1], carry = bits.Add64(x[1], x[1], carry) + z[2], carry = bits.Add64(x[2], x[2], carry) + z[3], _ = bits.Add64(x[3], x[3], carry) + + // if z > q --> z -= q + // note: this is NOT constant time + if !(z[3] < 3486998266802970665 || (z[3] == 3486998266802970665 && (z[2] < 13281191951274694749 || (z[2] == 13281191951274694749 && (z[1] < 2896914383306846353 || (z[1] == 2896914383306846353 && (z[0] < 4891460686036598785))))))) { + var b uint64 + z[0], b = bits.Sub64(z[0], 4891460686036598785, 0) + z[1], b = bits.Sub64(z[1], 2896914383306846353, b) + z[2], b = bits.Sub64(z[2], 13281191951274694749, b) + z[3], _ = bits.Sub64(z[3], 3486998266802970665, b) + } +} + +func sub(z, x, y *Element) { + var b uint64 + z[0], b = bits.Sub64(x[0], y[0], 0) + z[1], b = bits.Sub64(x[1], y[1], b) + z[2], b = bits.Sub64(x[2], y[2], b) + z[3], b = bits.Sub64(x[3], y[3], b) + if b != 0 { + var c uint64 + z[0], c = bits.Add64(z[0], 4891460686036598785, 0) + z[1], c = bits.Add64(z[1], 2896914383306846353, c) + z[2], c = bits.Add64(z[2], 13281191951274694749, c) + z[3], _ = bits.Add64(z[3], 3486998266802970665, c) + } +} + +func neg(z, x *Element) { + if x.IsZero() { + z.SetZero() + return + } + var borrow uint64 + z[0], borrow = bits.Sub64(4891460686036598785, x[0], 0) + z[1], borrow = bits.Sub64(2896914383306846353, x[1], borrow) + z[2], borrow = bits.Sub64(13281191951274694749, x[2], borrow) + z[3], _ = bits.Sub64(3486998266802970665, x[3], borrow) +} + +func reduce(z *Element) { + + // if z > q --> z -= q + // note: this is NOT constant time + if !(z[3] < 3486998266802970665 || (z[3] == 3486998266802970665 && (z[2] < 13281191951274694749 || (z[2] == 13281191951274694749 && (z[1] < 2896914383306846353 || (z[1] == 2896914383306846353 && (z[0] < 4891460686036598785))))))) { + var b uint64 + z[0], b = bits.Sub64(z[0], 4891460686036598785, 0) + z[1], b = bits.Sub64(z[1], 2896914383306846353, b) + z[2], b = bits.Sub64(z[2], 13281191951274694749, b) + z[3], _ = bits.Sub64(z[3], 3486998266802970665, b) + } +} diff --git a/internal/utils/zklink/bn256/fr/element_test.go b/internal/utils/zklink/bn256/fr/element_test.go new file mode 100644 index 00000000000..79f33a8863c --- /dev/null +++ b/internal/utils/zklink/bn256/fr/element_test.go @@ -0,0 +1,595 @@ +// Copyright 2020 ConsenSys Software Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by goff (v0.3.6) DO NOT EDIT + +package fr + +import ( + "crypto/rand" + "math/big" + "math/bits" + "testing" + + "github.com/leanovate/gopter" + "github.com/leanovate/gopter/prop" +) + +func TestELEMENTCorrectnessAgainstBigInt(t *testing.T) { + modulus := Modulus() + cmpEandB := func(e *Element, b *big.Int, name string) { + var _e big.Int + if e.FromMont().ToBigInt(&_e).Cmp(b) != 0 { + t.Fatal(name, "failed") + } + } + var modulusMinusOne, one big.Int + one.SetUint64(1) + + modulusMinusOne.Sub(modulus, &one) + + var n int + if testing.Short() { + n = 20 + } else { + n = 500 + } + + sAdx := supportAdx + + for i := 0; i < n; i++ { + if i == n/2 && sAdx { + supportAdx = false // testing without adx instruction + } + // sample 3 random big int + b1, _ := rand.Int(rand.Reader, modulus) + b2, _ := rand.Int(rand.Reader, modulus) + b3, _ := rand.Int(rand.Reader, modulus) // exponent + + // adding edge cases + // TODO need more edge cases + switch i { + case 0: + b3.SetUint64(0) + b1.SetUint64(0) + case 1: + b2.SetUint64(0) + case 2: + b1.SetUint64(0) + b2.SetUint64(0) + case 3: + b3.SetUint64(0) + case 4: + b3.SetUint64(1) + case 5: + b3.SetUint64(^uint64(0)) + case 6: + b3.SetUint64(2) + b1.Set(&modulusMinusOne) + case 7: + b2.Set(&modulusMinusOne) + case 8: + b1.Set(&modulusMinusOne) + b2.Set(&modulusMinusOne) + } + + var bMul, bAdd, bSub, bDiv, bNeg, bLsh, bInv, bExp, bSquare big.Int + + // e1 = mont(b1), e2 = mont(b2) + var e1, e2, eMul, eAdd, eSub, eDiv, eNeg, eLsh, eInv, eExp, eSquare Element + e1.SetBigInt(b1) + e2.SetBigInt(b2) + + // (e1*e2).FromMont() === b1*b2 mod q ... etc + eSquare.Square(&e1) + eMul.Mul(&e1, &e2) + eAdd.Add(&e1, &e2) + eSub.Sub(&e1, &e2) + eDiv.Div(&e1, &e2) + eNeg.Neg(&e1) + eInv.Inverse(&e1) + eExp.Exp(e1, b3) + eLsh.Double(&e1) + + // same operations with big int + bAdd.Add(b1, b2).Mod(&bAdd, modulus) + bMul.Mul(b1, b2).Mod(&bMul, modulus) + bSquare.Mul(b1, b1).Mod(&bSquare, modulus) + bSub.Sub(b1, b2).Mod(&bSub, modulus) + bDiv.ModInverse(b2, modulus) + bDiv.Mul(&bDiv, b1). + Mod(&bDiv, modulus) + bNeg.Neg(b1).Mod(&bNeg, modulus) + + bInv.ModInverse(b1, modulus) + bExp.Exp(b1, b3, modulus) + bLsh.Lsh(b1, 1).Mod(&bLsh, modulus) + + cmpEandB(&eSquare, &bSquare, "Square") + cmpEandB(&eMul, &bMul, "Mul") + cmpEandB(&eAdd, &bAdd, "Add") + cmpEandB(&eSub, &bSub, "Sub") + cmpEandB(&eDiv, &bDiv, "Div") + cmpEandB(&eNeg, &bNeg, "Neg") + cmpEandB(&eInv, &bInv, "Inv") + cmpEandB(&eExp, &bExp, "Exp") + + cmpEandB(&eLsh, &bLsh, "Lsh") + + // legendre symbol + if e1.Legendre() != big.Jacobi(b1, modulus) { + t.Fatal("legendre symbol computation failed") + } + if e2.Legendre() != big.Jacobi(b2, modulus) { + t.Fatal("legendre symbol computation failed") + } + + // these are slow, killing circle ci + if n <= 10 { + // sqrt + var eSqrt Element + var bSqrt big.Int + bSqrt.ModSqrt(b1, modulus) + eSqrt.Sqrt(&e1) + cmpEandB(&eSqrt, &bSqrt, "Sqrt") + } + } + supportAdx = sAdx +} + +func TestELEMENTSetInterface(t *testing.T) { + // TODO + t.Skip("not implemented") +} + +func TestELEMENTIsRandom(t *testing.T) { + for i := 0; i < 50; i++ { + var x, y Element + x.SetRandom() + y.SetRandom() + if x.Equal(&y) { + t.Fatal("2 random numbers are unlikely to be equal") + } + } +} + +func TestByte(t *testing.T) { + + modulus := Modulus() + + // test values + var bs [3][]byte + r1, _ := rand.Int(rand.Reader, modulus) + bs[0] = r1.Bytes() // should be r1 as Element + r2, _ := rand.Int(rand.Reader, modulus) + r2.Add(modulus, r2) + bs[1] = r2.Bytes() // should be r2 as Element + var tmp big.Int + tmp.SetUint64(0) + bs[2] = tmp.Bytes() // should be 0 as Element + + // witness values as Element + var el [3]Element + el[0].SetBigInt(r1) + el[1].SetBigInt(r2) + el[2].SetUint64(0) + + // check conversions + for i := 0; i < 3; i++ { + var z Element + z.SetBytes(bs[i]) + if !z.Equal(&el[i]) { + t.Fatal("SetBytes fails") + } + // check conversion Element to Bytes + b := z.Bytes() + z.SetBytes(b) + if !z.Equal(&el[i]) { + t.Fatal("Bytes fails") + } + } +} + +// ------------------------------------------------------------------------------------------------- +// benchmarks +// most benchmarks are rudimentary and should sample a large number of random inputs +// or be run multiple times to ensure it didn't measure the fastest path of the function + +var benchResElement Element + +func BenchmarkInverseELEMENT(b *testing.B) { + var x Element + x.SetRandom() + benchResElement.SetRandom() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + benchResElement.Inverse(&x) + } + +} +func BenchmarkExpELEMENT(b *testing.B) { + var x Element + x.SetRandom() + benchResElement.SetRandom() + b1, _ := rand.Int(rand.Reader, Modulus()) + b.ResetTimer() + for i := 0; i < b.N; i++ { + benchResElement.Exp(x, b1) + } +} + +func BenchmarkDoubleELEMENT(b *testing.B) { + benchResElement.SetRandom() + b.ResetTimer() + for i := 0; i < b.N; i++ { + benchResElement.Double(&benchResElement) + } +} + +func BenchmarkAddELEMENT(b *testing.B) { + var x Element + x.SetRandom() + benchResElement.SetRandom() + b.ResetTimer() + for i := 0; i < b.N; i++ { + benchResElement.Add(&x, &benchResElement) + } +} + +func BenchmarkSubELEMENT(b *testing.B) { + var x Element + x.SetRandom() + benchResElement.SetRandom() + b.ResetTimer() + for i := 0; i < b.N; i++ { + benchResElement.Sub(&x, &benchResElement) + } +} + +func BenchmarkNegELEMENT(b *testing.B) { + benchResElement.SetRandom() + b.ResetTimer() + for i := 0; i < b.N; i++ { + benchResElement.Neg(&benchResElement) + } +} + +func BenchmarkDivELEMENT(b *testing.B) { + var x Element + x.SetRandom() + benchResElement.SetRandom() + b.ResetTimer() + for i := 0; i < b.N; i++ { + benchResElement.Div(&x, &benchResElement) + } +} + +func BenchmarkFromMontELEMENT(b *testing.B) { + benchResElement.SetRandom() + b.ResetTimer() + for i := 0; i < b.N; i++ { + benchResElement.FromMont() + } +} + +func BenchmarkToMontELEMENT(b *testing.B) { + benchResElement.SetRandom() + b.ResetTimer() + for i := 0; i < b.N; i++ { + benchResElement.ToMont() + } +} +func BenchmarkSquareELEMENT(b *testing.B) { + benchResElement.SetRandom() + b.ResetTimer() + for i := 0; i < b.N; i++ { + benchResElement.Square(&benchResElement) + } +} + +func BenchmarkSqrtELEMENT(b *testing.B) { + var a Element + a.SetRandom() + b.ResetTimer() + for i := 0; i < b.N; i++ { + benchResElement.Sqrt(&a) + } +} + +func BenchmarkMulELEMENT(b *testing.B) { + x := Element{ + 1997599621687373223, + 6052339484930628067, + 10108755138030829701, + 150537098327114917, + } + benchResElement.SetOne() + b.ResetTimer() + for i := 0; i < b.N; i++ { + benchResElement.Mul(&benchResElement, &x) + } +} + +func TestELEMENTreduce(t *testing.T) { + q := Element{ + 4891460686036598785, + 2896914383306846353, + 13281191951274694749, + 3486998266802970665, + } + + var testData []Element + { + a := q + a[3]-- + testData = append(testData, a) + } + { + a := q + a[0]-- + testData = append(testData, a) + } + { + a := q + a[3]++ + testData = append(testData, a) + } + { + a := q + a[0]++ + testData = append(testData, a) + } + { + a := q + testData = append(testData, a) + } + + for _, s := range testData { + expected := s + reduce(&s) + expected.testReduce() + if !s.Equal(&expected) { + t.Fatal("reduce failed") + } + } + +} + +func (z *Element) testReduce() *Element { + + // if z > q --> z -= q + // note: this is NOT constant time + if !(z[3] < 3486998266802970665 || (z[3] == 3486998266802970665 && (z[2] < 13281191951274694749 || (z[2] == 13281191951274694749 && (z[1] < 2896914383306846353 || (z[1] == 2896914383306846353 && (z[0] < 4891460686036598785))))))) { + var b uint64 + z[0], b = bits.Sub64(z[0], 4891460686036598785, 0) + z[1], b = bits.Sub64(z[1], 2896914383306846353, b) + z[2], b = bits.Sub64(z[2], 13281191951274694749, b) + z[3], _ = bits.Sub64(z[3], 3486998266802970665, b) + } + return z +} + +// ------------------------------------------------------------------------------------------------- +// Gopter tests + +func TestELEMENTMul(t *testing.T) { + + parameters := gopter.DefaultTestParameters() + parameters.MinSuccessfulTests = 10000 + + properties := gopter.NewProperties(parameters) + + genA := gen() + genB := gen() + + properties.Property("Having the receiver as operand should output the same result", prop.ForAll( + func(a, b testPairElement) bool { + var c, d Element + d.Set(&a.element) + c.Mul(&a.element, &b.element) + a.element.Mul(&a.element, &b.element) + b.element.Mul(&d, &b.element) + return a.element.Equal(&b.element) && a.element.Equal(&c) && b.element.Equal(&c) + }, + genA, + genB, + )) + + properties.Property("Operation result must match big.Int result", prop.ForAll( + func(a, b testPairElement) bool { + var c Element + c.Mul(&a.element, &b.element) + + var d, e big.Int + d.Mul(&a.bigint, &b.bigint).Mod(&d, Modulus()) + + return c.FromMont().ToBigInt(&e).Cmp(&d) == 0 + }, + genA, + genB, + )) + + properties.Property("Operation result must be smaller than modulus", prop.ForAll( + func(a, b testPairElement) bool { + var c Element + c.Mul(&a.element, &b.element) + return !c.biggerOrEqualModulus() + }, + genA, + genB, + )) + + properties.Property("Assembly implementation must be consistent with generic one", prop.ForAll( + func(a, b testPairElement) bool { + var c, d Element + c.Mul(&a.element, &b.element) + _mulGeneric(&d, &a.element, &b.element) + return c.Equal(&d) + }, + genA, + genB, + )) + + properties.TestingRun(t, gopter.ConsoleReporter(false)) +} + +func TestELEMENTSquare(t *testing.T) { + + parameters := gopter.DefaultTestParameters() + parameters.MinSuccessfulTests = 10000 + + properties := gopter.NewProperties(parameters) + + genA := gen() + + properties.Property("Having the receiver as operand should output the same result", prop.ForAll( + func(a testPairElement) bool { + var b Element + b.Square(&a.element) + a.element.Square(&a.element) + return a.element.Equal(&b) + }, + genA, + )) + + properties.Property("Operation result must match big.Int result", prop.ForAll( + func(a testPairElement) bool { + var b Element + b.Square(&a.element) + + var d, e big.Int + d.Mul(&a.bigint, &a.bigint).Mod(&d, Modulus()) + + return b.FromMont().ToBigInt(&e).Cmp(&d) == 0 + }, + genA, + )) + + properties.Property("Operation result must be smaller than modulus", prop.ForAll( + func(a testPairElement) bool { + var b Element + b.Square(&a.element) + return !b.biggerOrEqualModulus() + }, + genA, + )) + + properties.Property("Square(x) == Mul(x,x)", prop.ForAll( + func(a testPairElement) bool { + var b, c Element + b.Square(&a.element) + c.Mul(&a.element, &a.element) + return c.Equal(&b) + }, + genA, + )) + + properties.Property("Assembly implementation must be consistent with generic one", prop.ForAll( + func(a testPairElement) bool { + var c, d Element + c.Square(&a.element) + _squareGeneric(&d, &a.element) + return c.Equal(&d) + }, + genA, + )) + + properties.TestingRun(t, gopter.ConsoleReporter(false)) +} + +func TestELEMENTFromMont(t *testing.T) { + + parameters := gopter.DefaultTestParameters() + parameters.MinSuccessfulTests = 10000 + + properties := gopter.NewProperties(parameters) + + genA := gen() + + properties.Property("Assembly implementation must be consistent with generic one", prop.ForAll( + func(a testPairElement) bool { + c := a.element + d := a.element + c.FromMont() + _fromMontGeneric(&d) + return c.Equal(&d) + }, + genA, + )) + + properties.TestingRun(t, gopter.ConsoleReporter(false)) +} + +type testPairElement struct { + element Element + bigint big.Int +} + +func (z *Element) biggerOrEqualModulus() bool { + if z[3] > qElement[3] { + return true + } + if z[3] < qElement[3] { + return false + } + + if z[2] > qElement[2] { + return true + } + if z[2] < qElement[2] { + return false + } + + if z[1] > qElement[1] { + return true + } + if z[1] < qElement[1] { + return false + } + + return z[0] >= qElement[0] +} + +func gen() gopter.Gen { + return func(genParams *gopter.GenParameters) *gopter.GenResult { + var g testPairElement + + g.element = Element{ + genParams.NextUint64(), + genParams.NextUint64(), + genParams.NextUint64(), + genParams.NextUint64(), + } + if qElement[3] != ^uint64(0) { + g.element[3] %= (qElement[3] + 1) + } + + for g.element.biggerOrEqualModulus() { + g.element = Element{ + genParams.NextUint64(), + genParams.NextUint64(), + genParams.NextUint64(), + genParams.NextUint64(), + } + if qElement[3] != ^uint64(0) { + g.element[3] %= (qElement[3] + 1) + } + } + + g.element.ToBigIntRegular(&g.bigint) + genResult := gopter.NewGenResult(g, gopter.NoShrinker) + return genResult + } +} diff --git a/internal/utils/zklink/bn256/twistededwards/point.go b/internal/utils/zklink/bn256/twistededwards/point.go new file mode 100644 index 00000000000..1faee32e505 --- /dev/null +++ b/internal/utils/zklink/bn256/twistededwards/point.go @@ -0,0 +1,208 @@ +/* +Copyright © 2020 ConsenSys + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package twistededwards + +import ( + "math/bits" + + "github.com/thrasher-corp/gocryptotrader/internal/utils/zklink/bn256/fr" +) + +// Point point on a twisted Edwards curve +type Point struct { + X, Y fr.Element +} + +// PointProj point in projective coordinates +type PointProj struct { + X, Y, Z fr.Element +} + +// Set sets p to p1 and return it +func (p *PointProj) Set(p1 *PointProj) *PointProj { + p.X.Set(&p1.X) + p.Y.Set(&p1.Y) + p.Z.Set(&p1.Z) + return p +} + +// NewPoint creates a new instance of Point +func NewPoint(x, y fr.Element) Point { + return Point{x, y} +} + +// IsOnCurve checks if a point is on the twisted Edwards curve +func (p *Point) IsOnCurve() bool { + + ecurve := GetEdwardsCurve() + + var lhs, rhs, tmp fr.Element + + tmp.Mul(&p.Y, &p.Y) + lhs.Mul(&p.X, &p.X). + Mul(&lhs, &ecurve.A). + Add(&lhs, &tmp) + + tmp.Mul(&p.X, &p.X). + Mul(&tmp, &p.Y). + Mul(&tmp, &p.Y). + Mul(&tmp, &ecurve.D) + rhs.SetOne().Add(&rhs, &tmp) + + return lhs.Equal(&rhs) +} + +// Add adds two points (x,y), (u,v) on a twisted Edwards curve with parameters a, d +// modifies p +func (p *Point) Add(p1, p2 *Point) *Point { + + ecurve := GetEdwardsCurve() + + var xu, yv, xv, yu, dxyuv, one, denx, deny fr.Element + pRes := new(Point) + xv.Mul(&p1.X, &p2.Y) + yu.Mul(&p1.Y, &p2.X) + pRes.X.Add(&xv, &yu) + + xu.Mul(&p1.X, &p2.X).Mul(&xu, &ecurve.A) + yv.Mul(&p1.Y, &p2.Y) + pRes.Y.Sub(&yv, &xu) + + dxyuv.Mul(&xv, &yu).Mul(&dxyuv, &ecurve.D) + one.SetOne() + denx.Add(&one, &dxyuv) + deny.Sub(&one, &dxyuv) + + p.X.Div(&pRes.X, &denx) + p.Y.Div(&pRes.Y, &deny) + + return p +} + +// Double doubles point (x,y) on a twisted Edwards curve with parameters a, d +// modifies p +func (p *Point) Double(p1 *Point) *Point { + p.Add(p1, p1) + return p +} + +// FromProj sets p in affine from p in projective +func (p *Point) FromProj(p1 *PointProj) *Point { + p.X.Div(&p1.X, &p1.Z) + p.Y.Div(&p1.Y, &p1.Z) + return p +} + +// FromAffine sets p in projective from p in affine +func (p *PointProj) FromAffine(p1 *Point) *PointProj { + p.X.Set(&p1.X) + p.Y.Set(&p1.Y) + p.Z.SetOne() + return p +} + +// Add adds points in projective coordinates +// cf https://hyperelliptic.org/EFD/g1p/auto-twisted-projective.html +func (p *PointProj) Add(p1, p2 *PointProj) *PointProj { + + var res PointProj + + ecurve := GetEdwardsCurve() + + var A, B, C, D, E, F, G, H, I fr.Element + A.Mul(&p1.Z, &p2.Z) + B.Square(&A) + C.Mul(&p1.X, &p2.X) + D.Mul(&p1.Y, &p2.Y) + E.Mul(&ecurve.D, &C).Mul(&E, &D) + F.Sub(&B, &E) + G.Add(&B, &E) + H.Add(&p1.X, &p1.Y) + I.Add(&p2.X, &p2.Y) + res.X.Mul(&H, &I). + Sub(&res.X, &C). + Sub(&res.X, &D). + Mul(&res.X, &p1.Z). + Mul(&res.X, &F) + H.Mul(&ecurve.A, &C) + res.Y.Sub(&D, &H). + Mul(&res.Y, &p.Z). + Mul(&res.Y, &G) + res.Z.Mul(&F, &G) + + p.Set(&res) + return p +} + +// Double adds points in projective coordinates +// cf https://hyperelliptic.org/EFD/g1p/auto-twisted-projective.html +func (p *PointProj) Double(p1 *PointProj) *PointProj { + + var res PointProj + + ecurve := GetEdwardsCurve() + + var B, C, D, E, F, H, J, tmp fr.Element + + B.Add(&p1.X, &p1.Y).Square(&B) + C.Square(&p1.X) + D.Square(&p1.Y) + E.Mul(&ecurve.A, &C) + F.Add(&E, &D) + H.Square(&p1.Z) + tmp.Double(&H) + J.Sub(&F, &tmp) + res.X.Sub(&B, &C). + Sub(&res.X, &D). + Mul(&res.X, &J) + res.Y.Sub(&E, &D).Mul(&res.Y, &F) + res.Z.Mul(&F, &J) + + p.Set(&res) + return p +} + +// ScalarMul scalar multiplication of a point +// p1 points on the twisted Edwards curve +// c parameters of the twisted Edwards curve +// scal scalar NOT in Montgomery form +// modifies p +func (p *Point) ScalarMul(p1 *Point, scalar fr.Element) *Point { + + var resProj, p1Proj PointProj + resProj.X.SetZero() + resProj.Y.SetOne() + resProj.Z.SetOne() + + p1Proj.FromAffine(p1) + + const wordSize = bits.UintSize + + for i := 4 - 1; i >= 0; i-- { + for j := 0; j < wordSize; j++ { + resProj.Double(&resProj) + b := (scalar[i] & (uint64(1) << uint64(wordSize-1-j))) >> uint64(wordSize-1-j) + if b == 1 { + resProj.Add(&resProj, &p1Proj) + } + } + } + + p.FromProj(&resProj) + + return p +} diff --git a/internal/utils/zklink/bn256/twistededwards/twistededwards.go b/internal/utils/zklink/bn256/twistededwards/twistededwards.go new file mode 100644 index 00000000000..9dfa4e8a979 --- /dev/null +++ b/internal/utils/zklink/bn256/twistededwards/twistededwards.go @@ -0,0 +1,36 @@ +package twistededwards + +import ( + "math/big" + "sync" + + "github.com/thrasher-corp/gocryptotrader/internal/utils/zklink/bn256/fr" +) + +// CurveParams curve parameters: ax^2 + y^2 = 1 + d*x^2*y^2 +type CurveParams struct { + A, D fr.Element // in Montgomery form + Cofactor fr.Element // not in Montgomery form + Order big.Int + Base Point +} + +var edwards CurveParams +var initOnce sync.Once + +// GetEdwardsCurve returns the twisted Edwards curve on BN256's Fr +func GetEdwardsCurve() CurveParams { + initOnce.Do(initEdBN256) + return edwards +} + +func initEdBN256() { + + edwards.A.SetUint64(168700) + edwards.D.SetUint64(168696) + edwards.Cofactor.SetUint64(8).FromMont() + edwards.Order.SetString("2736030358979909402780800718157159386076813972158567259200215660948447373041", 10) + + edwards.Base.X.SetString("5299619240641551281634865583518297030282874472190772894086521144482721001553") + edwards.Base.Y.SetString("16950150798460657717958625567821834550301663161624707787222815936182638968203") +} diff --git a/internal/utils/zklink/bn256/twistededwards/twistededwards_test.go b/internal/utils/zklink/bn256/twistededwards/twistededwards_test.go new file mode 100644 index 00000000000..56afab3ce2a --- /dev/null +++ b/internal/utils/zklink/bn256/twistededwards/twistededwards_test.go @@ -0,0 +1,152 @@ +/* +Copyright © 2020 ConsenSys + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package twistededwards + +import ( + "testing" + + "github.com/thrasher-corp/gocryptotrader/internal/utils/zklink/bn256/fr" +) + +func TestAdd(t *testing.T) { + + var p1, p2 Point + + p1.X.SetString("8728367628344135467582547753719073727968275979035063555332785894244029982715") + p1.Y.SetString("8834462946188529904793384347374734779374831553974460136522409595751449858199") + + p2.X.SetString("9560056125663567360314373555170485462871740364163814576088225107862234393497") + p2.Y.SetString("13024071698463677601393829581435828705327146000694268918451707151508990195684") + + var expectedX, expectedY fr.Element + + expectedX.SetString("15602730788680306249246507407102613100672389871136626657306339018592280799798") + expectedY.SetString("9214827499166027327226786359816287546740571844393227610238633031200971415079") + + p1.Add(&p1, &p2) + + if !p1.X.Equal(&expectedX) { + t.Fatal("wrong x coordinate") + } + if !p1.Y.Equal(&expectedY) { + t.Fatal("wrong y coordinate") + } + +} + +func TestAddProj(t *testing.T) { + + var p1, p2 Point + var p1proj, p2proj PointProj + + p1.X.SetString("8728367628344135467582547753719073727968275979035063555332785894244029982715") + p1.Y.SetString("8834462946188529904793384347374734779374831553974460136522409595751449858199") + + p2.X.SetString("9560056125663567360314373555170485462871740364163814576088225107862234393497") + p2.Y.SetString("13024071698463677601393829581435828705327146000694268918451707151508990195684") + + p1proj.FromAffine(&p1) + p2proj.FromAffine(&p2) + + var expectedX, expectedY fr.Element + + expectedX.SetString("15602730788680306249246507407102613100672389871136626657306339018592280799798") + expectedY.SetString("9214827499166027327226786359816287546740571844393227610238633031200971415079") + + p1proj.Add(&p1proj, &p2proj) + p1.FromProj(&p1proj) + + if !p1.X.Equal(&expectedX) { + t.Fatal("wrong x coordinate") + } + if !p1.Y.Equal(&expectedY) { + t.Fatal("wrong y coordinate") + } + +} + +func TestDouble(t *testing.T) { + + var p Point + + p.X.SetString("8728367628344135467582547753719073727968275979035063555332785894244029982715") + p.Y.SetString("8834462946188529904793384347374734779374831553974460136522409595751449858199") + + p.Double(&p) + + var expectedX, expectedY fr.Element + + expectedX.SetString("17048188201798084482613703497237052386773720266456818725024051932759787099830") + expectedY.SetString("15722506141850766164380928609287974914029282300941585435780118880890915697552") + + if !p.X.Equal(&expectedX) { + t.Fatal("wrong x coordinate") + } + if !p.Y.Equal(&expectedY) { + t.Fatal("wrong y coordinate") + } +} + +func TestDoubleProj(t *testing.T) { + + var p Point + var pproj PointProj + + p.X.SetString("8728367628344135467582547753719073727968275979035063555332785894244029982715") + p.Y.SetString("8834462946188529904793384347374734779374831553974460136522409595751449858199") + + pproj.FromAffine(&p).Double(&pproj) + + p.FromProj(&pproj) + + var expectedX, expectedY fr.Element + + expectedX.SetString("17048188201798084482613703497237052386773720266456818725024051932759787099830") + expectedY.SetString("15722506141850766164380928609287974914029282300941585435780118880890915697552") + + if !p.X.Equal(&expectedX) { + t.Fatal("wrong x coordinate") + } + if !p.Y.Equal(&expectedY) { + t.Fatal("wrong y coordinate") + } +} + +func TestScalarMul(t *testing.T) { + + // set curve parameters + ed := GetEdwardsCurve() + + var scalar fr.Element + scalar.SetUint64(23902374).FromMont() + + var p Point + p.ScalarMul(&ed.Base, scalar) + + var expectedX, expectedY fr.Element + + expectedX.SetString("2617519824163134005353570974989848134508856877236793995668417237392062754831") + expectedY.SetString("12956808000482532416873382696451950668786244907047953547021024966691314258300") + + if !expectedX.Equal(&p.X) { + t.Fatal("wrong x coordinate") + } + if !expectedY.Equal(&p.Y) { + t.Fatal("wrong y coordinate") + } + +} diff --git a/internal/utils/zklink/helper/element.go b/internal/utils/zklink/helper/element.go new file mode 100644 index 00000000000..bd358acc44d --- /dev/null +++ b/internal/utils/zklink/helper/element.go @@ -0,0 +1,72 @@ +package helper + +import ( + // "math/big" + "reflect" + + // "github.com/consensys/gnark-crypto/field/pool" + "github.com/thrasher-corp/gocryptotrader/internal/utils/zklink/bn256/fr" +) + +func NewElement() *fr.Element { + typ := reflect.TypeOf((*fr.Element)(nil)).Elem() + val := reflect.New(typ.Elem()) + return val.Interface().(*fr.Element) +} + +func isNil(t fr.Element) bool { + v := reflect.ValueOf(t) + return v.IsNil() +} + +func zero() *fr.Element { + return NewElement().SetZero() +} + +func one() *fr.Element { + return NewElement().SetOne() +} + +// func Modulus() *big.Int { +// e := NewElement().SetZero() +// e.Sub(e, NewElement().SetOne()) +// b := e.BigInt(new(big.Int)) +// return b.Add(b, big.NewInt(1)) +// } + +// func Bits() int { +// return Modulus().BitLen() +// } + +// func Bytes() int { +// return (Bits() + 7) / 8 +// } + +// Exp is a copy of gnark-crypto's implementation, but takes a pointer argument +// func Exp(z, x *fr.Element, k *big.Int) { +// if k.IsUint64() && k.Uint64() == 0 { +// z.SetOne() +// } + +// e := k +// if k.Sign() == -1 { +// // negative k, we invert +// // if k < 0: xᵏ (mod q) == (x⁻¹)ᵏ (mod q) +// x.Inverse(x) + +// // we negate k in a temp big.Int since +// // Int.Bit(_) of k and -k is different +// e = pool.BigInt.Get() +// defer pool.BigInt.Put(e) +// e.Neg(k) +// } + +// z.Set(x) + +// for i := e.BitLen() - 2; i >= 0; i-- { +// z.Square(z) +// if e.Bit(i) == 1 { +// z.Mul(z, x) +// } +// } +// } diff --git a/internal/utils/zklink/helper/matrix.go b/internal/utils/zklink/helper/matrix.go new file mode 100644 index 00000000000..f7fe5ffe387 --- /dev/null +++ b/internal/utils/zklink/helper/matrix.go @@ -0,0 +1,556 @@ +package helper + +import ( + "errors" + "fmt" + + "github.com/thrasher-corp/gocryptotrader/internal/utils/zklink/bn256/fr" +) + +type Matrix [][]*fr.Element + +type Vector []*fr.Element + +// return the column numbers of the matrix. +func column(m Matrix) int { + if len(m) > 0 { + length := len(m[0]) + for i := 1; i < len(m); i++ { + if len(m[i]) != length { + panic("m is not matrix!") + } + } + return length + } else { + return 0 + } +} + +// return the row numbers of the matrix. +func row(m Matrix) int { + return len(m) +} + +// for 0 <= i < row, 0 <= j < column, compute M_ij*scalar. +func ScalarMul(scalar *fr.Element, m Matrix) Matrix { + res := make([][]*fr.Element, len(m)) + for i := 0; i < len(m); i++ { + res[i] = make([]*fr.Element, len(m[i])) + for j := 0; j < len(m[i]); j++ { + res[i][j] = NewElement().Mul(scalar, m[i][j]) + } + } + + return res +} + +// for 0 <= i < length, compute v_i*scalar. +func ScalarVecMul(scalar *fr.Element, v Vector) Vector { + res := make([]*fr.Element, len(v)) + + for i := 0; i < len(v); i++ { + res[i] = NewElement().Mul(scalar, v[i]) + } + + return res +} + +func VecAdd(a, b Vector) (Vector, error) { + if len(a) != len(b) { + return nil, errors.New("length err: cannot compute vector add") + } + + res := make([]*fr.Element, len(a)) + for i := 0; i < len(a); i++ { + res[i] = NewElement().Add(a[i], b[i]) + } + + return res, nil +} + +func VecSub(a, b Vector) (Vector, error) { + if len(a) != len(b) { + return nil, errors.New("length err: cannot compute vector sub") + } + + res := make([]*fr.Element, len(a)) + for i := 0; i < len(a); i++ { + res[i] = NewElement().Sub(a[i], b[i]) + } + + return res, nil +} + +// compute the product between two vectors. +func VecMul(a, b Vector) (*fr.Element, error) { + res := NewElement() + if len(a) != len(b) { + return res, errors.New("length err: cannot compute vector mul!") + } + + for i := 0; i < len(a); i++ { + tmp := NewElement().Mul(a[i], b[i]) + res.Add(res, tmp) + } + + return res, nil +} + +func IsVecEqual(a, b Vector) bool { + if len(a) != len(b) { + return false + } + + for i := 0; i < len(a); i++ { + if a[i].Cmp(b[i]) != 0 { + return false + } + } + + // time-constant comparison, against timing attacks. + //res := 0 + //for i := 0; i < len(a); i++ { + // res |= a[i].Cmp(b[i]) + //} + //return res == 0 + + return true +} + +// if delta(m)≠0, m is invertible. +// so we can transform m to the upper triangular matrix, +// and if all upper diagonal elements are not zero, then m is invertible. +func IsInvertible(m Matrix) bool { + // need to copy m. + tmp := copyMatrixRows(m, 0, row(m)) + if !IsSquareMatrix(tmp) { + return false + } + + shadow := MakeIdentity(row(tmp)) + upper, _, err := upperTriangular(tmp, shadow) + if err != nil { + panic(err) + } + + for i := 0; i < row(tmp); i++ { + if upper[i][i].Cmp(zero()) == 0 { + return false + } + } + + return true +} + +// compute the product between two matrices. +func MatMul(a, b Matrix) (Matrix, error) { + if row(a) != column(b) { + return nil, errors.New("cannot compute the result") + } + + transb := transpose(b) + + var err error + res := make([][]*fr.Element, row(a)) + for i := 0; i < row(a); i++ { + res[i] = make([]*fr.Element, column(b)) + for j := 0; j < column(b); j++ { + res[i][j], err = VecMul(a[i], transb[j]) + if err != nil { + return nil, fmt.Errorf("vec mul err: %w", err) + } + } + } + + return res, nil +} + +// left Matrix multiplication, denote by M*V, where M is the matrix, and V is the vector. +func LeftMatMul(m Matrix, v Vector) (Vector, error) { + if !IsSquareMatrix(m) { + panic("matrix is not square!") + } + + if row(m) != len(v) { + return nil, errors.New("length err: cannot compute matrix multiplication with the vector") + } + + res := make([]*fr.Element, len(v)) + var err error + for i := 0; i < len(v); i++ { + res[i], err = VecMul(m[i], v) + if err != nil { + return nil, fmt.Errorf("vector mul err: %w", err) + } + } + + return res, nil +} + +// right Matrix multiplication, denote by V*M, where V is the vector, and M is the matrix. +func RightMatMul(v Vector, m Matrix) (Vector, error) { + if !IsSquareMatrix(m) { + return nil, errors.New("matrix is not square") + } + + if row(m) != len(v) { + return nil, errors.New("length err: cannot compute matrix multiplication with the vector") + } + + transm := transpose(m) + res := make([]*fr.Element, len(v)) + var err error + for i := 0; i < len(v); i++ { + res[i], err = VecMul(transm[i], v) + if err != nil { + return nil, fmt.Errorf("vector mul err: %w", err) + } + } + + return res, nil +} + +// swap rows and columns of the matrix. +func transpose(m Matrix) Matrix { + res := make([][]*fr.Element, column(m)) + + for j := 0; j < column(m); j++ { + res[j] = make([]*fr.Element, len(m)) + for i := 0; i < len(m); i++ { + res[j][i] = m[i][j] + } + } + + return res +} + +// the square matrix is a t*t matrix. +func IsSquareMatrix(m Matrix) bool { + return row(m) == column(m) +} + +// make t*t identity matrix. +func MakeIdentity(t int) Matrix { + res := make([][]*fr.Element, t) + + for i := 0; i < t; i++ { + res[i] = make([]*fr.Element, t) + for j := 0; j < t; j++ { + if i == j { + res[i][j] = one() + } else { + res[i][j] = zero() + } + } + } + + return res +} + +// determine if a matrix is identity. +func IsIdentity(m Matrix) bool { + for i := 0; i < row(m); i++ { + for j := 0; j < column(m); j++ { + if ((i == j) && m[i][j].Cmp(one()) != 0) || ((i != j) && (m[i][j].Cmp(zero()) != 0)) { + return false + } + } + } + + return true +} + +func IsEqual(a, b Matrix) bool { + if row(a) != row(b) || column(a) != column(b) { + return false + } + + for i := 0; i < row(a); i++ { + for j := 0; j < column(a); j++ { + if a[i][j].Cmp(b[i][j]) != 0 { + return false + } + } + } + + // time-constant comparison, against timing attacks. + //res := 0 + //for i := 0; i < row(a); i++ { + // for j := 0; j < column(a); j++ { + // res |= a[i][j].Cmp(b[i][j]) + // } + //} + //return res == 0 + + return true +} + +// remove i-th row and j-th column of the matrix. +func minor(m Matrix, rowIndex, columnIndex int) (Matrix, error) { + if !IsSquareMatrix(m) { + return nil, errors.New("matrix is not square!") + } + + res := make([][]*fr.Element, row(m)-1) + + for i := 0; i < row(m); i++ { + if i < rowIndex { + for j := 0; j < column(m); j++ { + if j != columnIndex { + res[i] = append(res[i], m[i][j]) + } + } + } else if i > rowIndex { + for j := 0; j < column(m); j++ { + if j != columnIndex { + res[i-1] = append(res[i-1], m[i][j]) + } + } + } + } + + return res, nil +} + +// determine if the first k elements are zero. +func isFirstKZero(v Vector, k int) bool { + if k == 0 && v[0].Cmp(zero()) == 0 { + return false + } + + for i := 0; i < k; i++ { + if v[i].Cmp(zero()) != 0 { + return false + } + } + return true +} + +// find the first non-zero element in the given column. +func findNonZero(m Matrix, index int) (pivot *fr.Element, pivotIndex int, err error) { + pivotIndex = -1 + + if index > column(m) { + return NewElement(), -1, errors.New("index out of range!") + } + + for i := 0; i < row(m); i++ { + if m[i][index].Cmp(zero()) != 0 { + pivot = m[i][index] + pivotIndex = i + break + } + } + + return +} + +// assume matrix is partially reduced to upper triangular. +func eliminate(m, shadow Matrix, columnIndex int) (Matrix, Matrix, error) { + pivot, pivotIndex, err := findNonZero(m, columnIndex) + if err != nil || pivotIndex == -1 { + return nil, nil, fmt.Errorf("cannot find non-zero element: %w", err) + } + + pivotInv := NewElement().Inverse(pivot) + + for i := 0; i < row(m); i++ { + if i == pivotIndex { + continue + } + + if m[i][columnIndex].Cmp(zero()) != 0 { + factor := NewElement().Mul(m[i][columnIndex], pivotInv) + + scalarPivot := ScalarVecMul(factor, m[pivotIndex]) + + m[i], err = VecSub(m[i], scalarPivot) + if err != nil { + return nil, nil, fmt.Errorf("matrix m eliminate failed, vec sub err: %w", err) + } + + shadowPivot := shadow[pivotIndex] + + scalarShadowPivot := ScalarVecMul(factor, shadowPivot) + + shadow[i], err = VecSub(shadow[i], scalarShadowPivot) + if err != nil { + return nil, nil, fmt.Errorf("matrix shadow eliminate failed, vec sub err: %w", err) + } + } + } + + return m, shadow, nil +} + +// copy rows between start index and end index. +func copyMatrixRows(m Matrix, startIndex, endIndex int) Matrix { + if startIndex >= endIndex { + panic("start index should be less than end index!") + } + + res := make([][]*fr.Element, endIndex-startIndex) + + for i := 0; i < endIndex-startIndex; i++ { + res[i] = make([]*fr.Element, column(m)) + copy(res[i], m[i+startIndex]) + } + + return res +} + +// reverse rows of the matrix. +func reverseRows(m Matrix) Matrix { + res := make([][]*fr.Element, row(m)) + + for i := 0; i < row(m); i++ { + res[i] = make([]*fr.Element, column(m)) + copy(res[i], m[row(m)-i-1]) + } + + return res +} + +// determine if numbers of zero elements equals to n. +func zeroNums(v Vector, n int) bool { + count := 0 + for i := 0; i < len(v); i++ { + if v[i].Cmp(zero()) != 0 { + break + } + count++ + } + + if count == n { + return true + } + + return false +} + +// determine if a matrix is upper triangular. +func isUpperTriangular(m Matrix) bool { + for i := 0; i < row(m); i++ { + if !zeroNums(m[i], i) { + return false + } + } + + return true +} + +// transform a square matrix to upper triangular matrix. +func upperTriangular(m, shadow Matrix) (Matrix, Matrix, error) { + if !IsSquareMatrix(m) { + return nil, nil, errors.New("matrix is not square!") + } + + curr := copyMatrixRows(m, 0, row(m)) + currShadow := copyMatrixRows(shadow, 0, row(shadow)) + result := make([][]*fr.Element, row(m)) + shadowResult := make([][]*fr.Element, row(shadow)) + c := 0 + var err error + for row(curr) > 1 { + result[c] = make([]*fr.Element, column(m)) + shadowResult[c] = make([]*fr.Element, column(shadow)) + curr, currShadow, err = eliminate(curr, currShadow, c) + if err != nil { + return nil, nil, fmt.Errorf("matrix eliminate err: %w", err) + } + + copy(result[c], curr[0]) + copy(shadowResult[c], currShadow[0]) + + c++ + + curr = copyMatrixRows(curr, 1, row(curr)) + currShadow = copyMatrixRows(currShadow, 1, row(currShadow)) + } + result[c] = make([]*fr.Element, column(m)) + shadowResult[c] = make([]*fr.Element, column(shadow)) + copy(result[c], curr[0]) + copy(shadowResult[c], currShadow[0]) + + return result, shadowResult, nil +} + +// reduce a upper triangular matrix to identity matrix. +func reduceToIdentity(m, shadow Matrix) (Matrix, Matrix, error) { + var err error + + result := make([][]*fr.Element, row(m)) + shadowResult := make([][]*fr.Element, row(shadow)) + for i := 0; i < row(m); i++ { + result[i] = make([]*fr.Element, column(m)) + shadowResult[i] = make([]*fr.Element, column(shadow)) + indexi := row(m) - i - 1 + + factor := m[indexi][indexi] + if factor.Cmp(zero()) == 0 { + return nil, nil, errors.New("cannot compute the result!") + } + + factorInv := NewElement().Inverse(factor) + + norm := ScalarVecMul(factorInv, m[indexi]) + + shadowNorm := ScalarVecMul(factorInv, shadow[indexi]) + + for j := 0; j < i; j++ { + indexj := row(m) - j - 1 + val := norm[indexj] + + scalarVal := ScalarVecMul(val, result[j]) + scalarShadow := ScalarVecMul(val, shadowResult[j]) + + norm, err = VecSub(norm, scalarVal) + if err != nil { + return nil, nil, fmt.Errorf("reduces to identity matrix failed, err: %w", err) + } + + shadowNorm, err = VecSub(shadowNorm, scalarShadow) + if err != nil { + return nil, nil, fmt.Errorf("reduces to identity matrix failed, err: %w", err) + } + } + copy(result[i], norm) + copy(shadowResult[i], shadowNorm) + } + + result = reverseRows(result) + shadowResult = reverseRows(shadowResult) + + return result, shadowResult, nil +} + +// use Gaussian elimination to invert a matrix. +// A|I -> I|A^-1. +func Invert(m Matrix) (Matrix, error) { + if !IsInvertible(m) { + return nil, fmt.Errorf("the matrix is not invertible") + } + + shadow := MakeIdentity(row(m)) + + up, upShadow, err := upperTriangular(m, shadow) + if err != nil { + return nil, fmt.Errorf("transform to upper triangular matrix failed, err: %w", err) + } + + if !isUpperTriangular(up) { + return nil, fmt.Errorf("the matrix should be upper triangular before reducing") + } + + // reduce m to identity, so shadow matrix transforms to the inverse of m. + reduce, reducedShadow, err := reduceToIdentity(up, upShadow) + if err != nil { + return nil, fmt.Errorf("reduce to identity failed, err: %w", err) + } + + if !IsIdentity(reduce) { + return nil, errors.New("reduces failed, the result is not the identity matrix") + } + + return reducedShadow, nil +} diff --git a/internal/utils/zklink/helper/matrix_test.go b/internal/utils/zklink/helper/matrix_test.go new file mode 100644 index 00000000000..b341b39895a --- /dev/null +++ b/internal/utils/zklink/helper/matrix_test.go @@ -0,0 +1,492 @@ +package helper + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/thrasher-corp/gocryptotrader/internal/utils/zklink/bn256/fr" +) + +var zeroE = new(fr.Element).SetUint64(0) +var OneE = new(fr.Element).SetUint64(1) +var Two = new(fr.Element).SetUint64(2) +var Three = new(fr.Element).SetUint64(3) +var Four = new(fr.Element).SetUint64(4) +var Five = new(fr.Element).SetUint64(5) +var Six = new(fr.Element).SetUint64(6) +var Seven = new(fr.Element).SetUint64(7) +var Eight = new(fr.Element).SetUint64(8) +var Nine = new(fr.Element).SetUint64(9) + +func TestVector(t *testing.T) { + negTwo := new(fr.Element).Neg(Two) + + sub := []struct { + v1, v2 Vector + want Vector + }{ + {Vector{OneE, Two}, Vector{OneE, Two}, Vector{zeroE, zeroE}}, + {Vector{OneE, Two}, Vector{zeroE, zeroE}, Vector{OneE, Two}}, + {Vector{Three, Four}, Vector{OneE, Two}, Vector{Two, Two}}, + {Vector{OneE, Two}, Vector{Three, Four}, Vector{negTwo, negTwo}}, + } + + for _, cases := range sub { + get, err := VecSub(cases.v1, cases.v2) + assert.NoError(t, err) + assert.Equal(t, get, cases.want) + } + + add := []struct { + v1, v2 Vector + want Vector + }{ + {Vector{OneE, Two}, Vector{OneE, Two}, Vector{Two, Four}}, + {Vector{OneE, Two}, Vector{zeroE, zeroE}, Vector{OneE, Two}}, + {Vector{OneE, Two}, Vector{OneE, negTwo}, Vector{Two, zeroE}}, + } + + for _, cases := range add { + get, err := VecAdd(cases.v1, cases.v2) + assert.NoError(t, err) + assert.Equal(t, get, cases.want) + } + + scalarmul := []struct { + scalar *fr.Element + v Vector + want Vector + }{ + {zeroE, Vector{OneE, Two}, Vector{zeroE, zeroE}}, + {OneE, Vector{OneE, Two}, Vector{OneE, Two}}, + {Two, Vector{OneE, Two}, Vector{Two, Four}}, + } + + for _, cases := range scalarmul { + get := ScalarVecMul(cases.scalar, cases.v) + assert.Equal(t, get, cases.want) + } + + vecmul := []struct { + v1, v2 Vector + want *fr.Element + }{ + {Vector{OneE, Two}, Vector{OneE, Two}, Five}, + {Vector{OneE, Two}, Vector{zeroE, zeroE}, zeroE}, + {Vector{OneE, Two}, Vector{negTwo, OneE}, zeroE}, + } + + for _, cases := range vecmul { + get, err := VecMul(cases.v1, cases.v2) + assert.NoError(t, err) + assert.Equal(t, get, cases.want) + } +} + +func TestMatrixScalarMul(t *testing.T) { + scalarmul := []struct { + scalar *fr.Element + m Matrix + want Matrix + }{ + {zeroE, Matrix{{OneE, Two}, {OneE, Two}}, Matrix{{zeroE, zeroE}, {zeroE, zeroE}}}, + {OneE, Matrix{{OneE, Two}, {OneE, Two}}, Matrix{{OneE, Two}, {OneE, Two}}}, + {Two, Matrix{{OneE, Two}, {Three, Four}}, Matrix{{Two, Four}, {Six, Eight}}}, + } + + for _, cases := range scalarmul { + get := ScalarMul(cases.scalar, cases.m) + assert.Equal(t, get, cases.want) + } +} + +func TestIdentity(t *testing.T) { + get := MakeIdentity(3) + want := Matrix{{OneE, zeroE, zeroE}, {zeroE, OneE, zeroE}, {zeroE, zeroE, OneE}} + assert.Equal(t, get, want) +} + +func TestMinor(t *testing.T) { + m := Matrix{{OneE, Two, Three}, {Four, Five, Six}, {Seven, Eight, Nine}} + + testMatrix := []struct { + i, j int + want Matrix + }{ + {0, 0, Matrix{{Five, Six}, {Eight, Nine}}}, + {0, 1, Matrix{{Four, Six}, {Seven, Nine}}}, + {0, 2, Matrix{{Four, Five}, {Seven, Eight}}}, + {1, 0, Matrix{{Two, Three}, {Eight, Nine}}}, + {1, 1, Matrix{{OneE, Three}, {Seven, Nine}}}, + {1, 2, Matrix{{OneE, Two}, {Seven, Eight}}}, + {2, 0, Matrix{{Two, Three}, {Five, Six}}}, + {2, 1, Matrix{{OneE, Three}, {Four, Six}}}, + {2, 2, Matrix{{OneE, Two}, {Four, Five}}}, + } + + for _, cases := range testMatrix { + get, err := minor(m, cases.i, cases.j) + assert.NoError(t, err) + assert.Equal(t, get, cases.want) + } +} + +func TestcopyMatrix(t *testing.T) { + m := Matrix{{OneE, Two, Three}, {Four, Five, Six}, {Seven, Eight, Nine}} + + testMatrix := []struct { + start, end int + want Matrix + }{ + {0, 1, Matrix{{OneE, Two, Three}}}, + {0, 2, Matrix{{OneE, Two, Three}, {Four, Five, Six}}}, + {0, 3, Matrix{{OneE, Two, Three}, {Four, Five, Six}, {Seven, Eight, Nine}}}, + {1, 2, Matrix{{Four, Five, Six}}}, + {1, 3, Matrix{{Four, Five, Six}, {Seven, Eight, Nine}}}, + {2, 3, Matrix{{Seven, Eight, Nine}}}, + } + + for _, cases := range testMatrix { + get := copyMatrixRows(m, cases.start, cases.end) + assert.Equal(t, get, cases.want) + } +} + +func TestTranspose(t *testing.T) { + testMatrix := []struct { + input, want Matrix + }{ + {Matrix{{OneE, Two}, {Three, Four}}, Matrix{{OneE, Three}, {Two, Four}}}, + {Matrix{{OneE, Two, Three}, {Four, Five, Six}, {Seven, Eight, Nine}}, Matrix{{OneE, Four, Seven}, {Two, Five, Eight}, {Three, Six, Nine}}}, + } + + for _, cases := range testMatrix { + get := transpose(cases.input) + assert.Equal(t, get, cases.want) + } +} + +func TestUpperTriangular(t *testing.T) { + shadow := MakeIdentity(3) + testMatrix := []struct { + m, s Matrix + want bool + }{ + {Matrix{{Two, Three, Four}, {Four, Five, Six}, {Seven, Eight, Eight}}, shadow, true}, + {Matrix{{OneE, Two, Three}, {Four, Five, Six}, {Seven, Eight, Nine}}, shadow, false}, + {Matrix{{OneE, Two, Three}, {zeroE, Three, Four}, {zeroE, zeroE, Three}}, shadow, true}, + {Matrix{{Two, Three, Four}, {zeroE, Two, Four}, {zeroE, zeroE, OneE}}, shadow, true}, + } + + for _, cases := range testMatrix { + m, _, err := upperTriangular(cases.m, cases.s) + assert.NoError(t, err) + get := isUpperTriangular(m) + assert.Equal(t, get, cases.want) + } +} + +func TestFindNonzeroE(t *testing.T) { + vectorSet := []struct { + k int + v Vector + want bool + }{ + {0, Vector{zeroE, OneE, Two, Three}, false}, + {1, Vector{zeroE, OneE, Two, Three}, true}, + {2, Vector{zeroE, OneE, Two, Three}, false}, + {2, Vector{zeroE, zeroE, zeroE, OneE}, true}, + {3, Vector{zeroE, zeroE, zeroE, OneE}, true}, + {3, Vector{zeroE, OneE, Two, Three}, false}, + {4, Vector{zeroE, OneE, Two, Three}, false}, + } + + for _, cases := range vectorSet { + get := isFirstKZero(cases.v, cases.k) + assert.Equal(t, get, cases.want) + } + + nonzeroESet := []struct { + m Matrix + c int + want struct { + e *fr.Element + index int + } + }{ + {Matrix{{Two, Three, Four}, {Four, Five, Six}, {Seven, Eight, Eight}}, 0, struct { + e *fr.Element + index int + }{Two, 0}}, + {Matrix{{Two, Three, Four}, {Four, Five, Six}, {Seven, Eight, Eight}}, 1, struct { + e *fr.Element + index int + }{Three, 0}}, + {Matrix{{Two, Three, Four}, {Four, Five, Six}, {Seven, Eight, Eight}}, 2, struct { + e *fr.Element + index int + }{Four, 0}}, + {Matrix{{OneE, zeroE, zeroE}, {Two, Three, zeroE}, {Four, Five, zeroE}}, 0, struct { + e *fr.Element + index int + }{OneE, 0}}, + {Matrix{{OneE, zeroE, zeroE}, {Two, Three, zeroE}, {Four, Five, zeroE}}, 1, struct { + e *fr.Element + index int + }{Three, 1}}, + {Matrix{{OneE, zeroE, zeroE}, {Two, Three, zeroE}, {Four, Five, zeroE}}, 2, struct { + e *fr.Element + index int + }{nil, -1}}, + } + + for _, cases := range nonzeroESet { + gete, geti, err := findNonZero(cases.m, cases.c) + assert.NoError(t, err) + if gete != nil && cases.want.e != nil { + if gete.Cmp(cases.want.e) != 0 || geti != cases.want.index { + t.Errorf("find non zeroE failed, get element: %v, want element: %v, get index: %d, want index: %d", gete, cases.want.e, geti, cases.want.index) + return + } + } else if gete == nil && cases.want.e == nil { + if geti != cases.want.index || geti != -1 { + t.Errorf("find non zeroE failed, get element: %v, want element: %v, get index: %d, want index: %d", gete, cases.want.e, geti, cases.want.index) + return + } + } else { + t.Errorf("find non zeroE failed, get element: %v, want element: %v, get index: %d, want index: %d", gete, cases.want.e, geti, cases.want.index) + return + } + } +} + +func TestMatMul(t *testing.T) { + // [[1,2,3],[4,5,6],[7,8,9]]*[[2,3,4],[4,5,6],[7,8,8]] + // =[[31,37,40],[70,85,95],[109,133,148]] + m00 := new(fr.Element).SetUint64(31) + m01 := new(fr.Element).SetUint64(37) + m02 := new(fr.Element).SetUint64(40) + m10 := new(fr.Element).SetUint64(70) + m11 := new(fr.Element).SetUint64(85) + m12 := new(fr.Element).SetUint64(94) + m20 := new(fr.Element).SetUint64(109) + m21 := new(fr.Element).SetUint64(133) + m22 := new(fr.Element).SetUint64(148) + + thirteen := new(fr.Element).SetUint64(13) + sixteen := new(fr.Element).SetUint64(16) + eighteen := new(fr.Element).SetUint64(18) + + testMatrix := []struct { + m1, m2 Matrix + want Matrix + }{ + {Matrix{{zeroE, zeroE}, {zeroE, zeroE}}, Matrix{{OneE, Two}, {OneE, Two}}, Matrix{{zeroE, zeroE}, {zeroE, zeroE}}}, + {Matrix{{OneE, Two}, {Two, Three}}, Matrix{{OneE, Two}, {OneE, zeroE}}, Matrix{{Three, Two}, {Five, Four}}}, + {Matrix{{OneE, Two, Three}, {Four, Five, Six}, {Seven, Eight, Nine}}, Matrix{{Two, Three, Four}, {Four, Five, Six}, {Seven, Eight, Eight}}, Matrix{{m00, m01, m02}, {m10, m11, m12}, {m20, m21, m22}}}, + {Matrix{{OneE, OneE, OneE}, {OneE, OneE, OneE}, {OneE, OneE, OneE}}, Matrix{{Two, Three, Four}, {Four, Five, Six}, {Seven, Eight, Eight}}, Matrix{{thirteen, sixteen, eighteen}, {thirteen, sixteen, eighteen}, {thirteen, sixteen, eighteen}}}, + {Matrix{{zeroE, zeroE, zeroE}, {zeroE, zeroE, zeroE}, {zeroE, zeroE, zeroE}}, Matrix{{Two, Three, Four}, {Four, Five, Six}, {Seven, Eight, Eight}}, Matrix{{zeroE, zeroE, zeroE}, {zeroE, zeroE, zeroE}, {zeroE, zeroE, zeroE}}}, + {Matrix{{OneE, zeroE, zeroE}, {zeroE, OneE, zeroE}, {zeroE, zeroE, OneE}}, Matrix{{Two, Three, Four}, {Four, Five, Six}, {Seven, Eight, Eight}}, Matrix{{Two, Three, Four}, {Four, Five, Six}, {Seven, Eight, Eight}}}, + } + + for _, cases := range testMatrix { + get, err := MatMul(cases.m1, cases.m2) + assert.NoError(t, err) + assert.Equal(t, get, cases.want) + } + + // [[1,2,3],[4,5,6],[7,8,9]]*[1,1,1] + // =[6,15,24] + fifteen := new(fr.Element).SetUint64(15) + twentyfour := new(fr.Element).SetUint64(24) + + testLeftMul := []struct { + m Matrix + v Vector + want Vector + }{ + {Matrix{{OneE, Two, Three}, {Four, Five, Six}, {Seven, Eight, Nine}}, Vector{zeroE, zeroE, zeroE}, Vector{zeroE, zeroE, zeroE}}, + {Matrix{{OneE, Two, Three}, {Four, Five, Six}, {Seven, Eight, Nine}}, Vector{OneE, zeroE, zeroE}, Vector{OneE, Four, Seven}}, + {Matrix{{OneE, Two, Three}, {Four, Five, Six}, {Seven, Eight, Nine}}, Vector{OneE, OneE, OneE}, Vector{Six, fifteen, twentyfour}}, + } + + for _, cases := range testLeftMul { + get, err := LeftMatMul(cases.m, cases.v) + assert.NoError(t, err) + assert.Equal(t, get, cases.want) + } + + // [1,1,1]*[[1,2,3],[4,5,6],[7,8,9]] + // =[12,15,18] + twelve := new(fr.Element).SetUint64(12) + + testRightMul := []struct { + v Vector + m Matrix + want Vector + }{ + {Vector{zeroE, zeroE, zeroE}, Matrix{{OneE, Two, Three}, {Four, Five, Six}, {Seven, Eight, Nine}}, Vector{zeroE, zeroE, zeroE}}, + {Vector{OneE, zeroE, zeroE}, Matrix{{OneE, Two, Three}, {Four, Five, Six}, {Seven, Eight, Nine}}, Vector{OneE, Two, Three}}, + {Vector{OneE, OneE, OneE}, Matrix{{OneE, Two, Three}, {Four, Five, Six}, {Seven, Eight, Nine}}, Vector{twelve, fifteen, eighteen}}, + } + + for _, cases := range testRightMul { + get, err := RightMatMul(cases.v, cases.m) + assert.NoError(t, err) + assert.Equal(t, get, cases.want) + } +} + +func TestEliminate(t *testing.T) { + m := Matrix{{Two, Three, Four}, {Four, Five, Six}, {Seven, Eight, Eight}} + shadow := MakeIdentity(3) + + // result of eliminating the first column. + // [[2,3,4],[0,-1,-2],[0,-5/2,-6]] + negoneE := new(fr.Element).Neg(OneE) + negtwo := new(fr.Element).Neg(Two) + negFiveDivTwo := new(fr.Element).Neg(Five) + negFiveDivTwo.Div(negFiveDivTwo, Two) + negsix := new(fr.Element).Neg(Six) + + // result of eliminating the second column. + // [[2,3,4],[2/3,0,-2/3],[5/3,0,-8/3]] + twoDivThree := new(fr.Element).Div(Two, Three) + negTwoDivThree := new(fr.Element).Neg(twoDivThree) + fiveDivThree := new(fr.Element).Div(Five, Three) + negEightDivThree := new(fr.Element).Div(Eight, Three) + negEightDivThree.Neg(negEightDivThree) + + // result of eliminating the third column. + // [[2,3,4],[1,1/2,0],[3,2,0]] + oneEDivTwo := new(fr.Element).Div(OneE, Two) + + testMatrix := []struct { + c int + want Matrix + }{ + {0, Matrix{{Two, Three, Four}, {zeroE, negoneE, negtwo}, {zeroE, negFiveDivTwo, negsix}}}, + {1, Matrix{{Two, Three, Four}, {twoDivThree, zeroE, negTwoDivThree}, {fiveDivThree, zeroE, negEightDivThree}}}, + {2, Matrix{{Two, Three, Four}, {OneE, oneEDivTwo, zeroE}, {Three, Two, zeroE}}}, + } + + for _, cases := range testMatrix { + get, _, err := eliminate(m, shadow, cases.c) + assert.NoError(t, err) + assert.Equal(t, get, cases.want) + } +} + +func TestReduceToIdentity(t *testing.T) { + // m=[[1,2,3],[0,3,4],[0,0,3]] + // m^-1=[[1,-2/3,-1/9],[0,1/3,-4/9],[0,0,1/3]] + negTwoDivThree := new(fr.Element).Div(Two, Three) + negTwoDivThree.Neg(negTwoDivThree) + negoneEDivNine := new(fr.Element).Div(OneE, Nine) + negoneEDivNine.Neg(negoneEDivNine) + oneEDivThree := new(fr.Element).Div(OneE, Three) + negFourDivNine := new(fr.Element).Div(Four, Nine) + negFourDivNine.Neg(negFourDivNine) + + // m=[[2,3,4],[0,2,4],[0,0,1]] + // m^-1=[[1/2,-3/4,1],[0,1/2,-2],[0,0,1]] + oneEDivTwo := new(fr.Element).Div(OneE, Two) + negThreeDivFour := new(fr.Element).Div(Three, Four) + negThreeDivFour.Neg(negThreeDivFour) + negtwo := new(fr.Element).Neg(Two) + + shadow := MakeIdentity(3) + + testMatrix := []struct { + m Matrix + want Matrix + }{ + {Matrix{{OneE, Two, Three}, {zeroE, Three, Four}, {zeroE, zeroE, Three}}, Matrix{{OneE, negTwoDivThree, negoneEDivNine}, {zeroE, oneEDivThree, negFourDivNine}, {zeroE, zeroE, oneEDivThree}}}, + {Matrix{{Two, Three, Four}, {zeroE, Two, Four}, {zeroE, zeroE, OneE}}, Matrix{{oneEDivTwo, negThreeDivFour, OneE}, {zeroE, oneEDivTwo, negtwo}, {zeroE, zeroE, OneE}}}, + } + + for _, cases := range testMatrix { + _, get, err := reduceToIdentity(cases.m, shadow) + assert.NoError(t, err) + assert.Equal(t, get, cases.want) + } +} + +func TestIsInvertible(t *testing.T) { + testMatrix := []struct { + m Matrix + want bool + }{ + {Matrix{{Two, Three, Four}, {Four, Five, Six}, {Seven, Eight, Eight}}, true}, + {Matrix{{OneE, Two, Three}, {zeroE, Three, Four}, {zeroE, zeroE, Three}}, true}, + {Matrix{{Two, Three, Four}, {zeroE, Two, Four}, {zeroE, zeroE, OneE}}, true}, + {Matrix{{OneE, Two, Three}, {Four, Five, Six}, {Seven, Eight, Nine}}, false}, + } + + for _, cases := range testMatrix { + get := IsInvertible(cases.m) + assert.Equal(t, get, cases.want) + } +} + +func TestInvert(t *testing.T) { + // 2*2 m: + // [1 3] + // [2 7] + // m^-1: + // [7 -3] + // [-2 1] + negtwo := new(fr.Element).Neg(Two) + negthree := new(fr.Element).Neg(Three) + + // 3*3 m: + // [1 2 3] + // [0 3 4] + // [0 0 3] + // m^-1: + // [1 -2/3 -1/9] + // [0 1/3 -4/9] + // [0 0 1/3] + negTwoDivThree := new(fr.Element).Div(Two, Three) + negTwoDivThree.Neg(negTwoDivThree) + negoneEDivNine := new(fr.Element).Div(OneE, Nine) + negoneEDivNine.Neg(negoneEDivNine) + oneEDivThree := new(fr.Element).Div(OneE, Three) + negFourDivNine := new(fr.Element).Div(Four, Nine) + negFourDivNine.Neg(negFourDivNine) + + // 3*3 m: + // [2 3 4] + // [4 5 6] + // [7 8 8] + // m^-1: + // [-4 4 -1] + // [5 -6 2] + // [-3/2 5/2 -1] + negoneE := new(fr.Element).Neg(OneE) + negfour := new(fr.Element).Neg(Four) + negsix := new(fr.Element).Neg(Six) + negThreeDivTwo := new(fr.Element).Div(Three, Two) + negThreeDivTwo.Neg(negThreeDivTwo) + fiveDivTwo := new(fr.Element).Div(Five, Two) + + testMatrix := []struct { + m Matrix + want Matrix + }{ + {Matrix{{OneE, Three}, {Two, Seven}}, Matrix{{Seven, negthree}, {negtwo, OneE}}}, + {Matrix{{OneE, Two, Three}, {zeroE, Three, Four}, {zeroE, zeroE, Three}}, Matrix{{OneE, negTwoDivThree, negoneEDivNine}, {zeroE, oneEDivThree, negFourDivNine}, {zeroE, zeroE, oneEDivThree}}}, + {Matrix{{Two, Three, Four}, {Four, Five, Six}, {Seven, Eight, Eight}}, Matrix{{negfour, Four, negoneE}, {Five, negsix, Two}, {negThreeDivTwo, fiveDivTwo, negoneE}}}, + } + + for _, cases := range testMatrix { + res, _ := MatMul(cases.m, cases.want) + if !IsIdentity(res) { + t.Error("test cases err") + } + + get, err := Invert(cases.m) + assert.NoError(t, err) + assert.Equal(t, get, cases.want) + } +} diff --git a/internal/utils/zklink/helper/mds.go b/internal/utils/zklink/helper/mds.go new file mode 100644 index 00000000000..e0cebbe9f63 --- /dev/null +++ b/internal/utils/zklink/helper/mds.go @@ -0,0 +1,230 @@ +package helper + +import ( + "fmt" + + "github.com/thrasher-corp/gocryptotrader/internal/utils/zklink/bn256/fr" +) + +// mdsMatrices is matrices for improving the efficiency of Poseidon hash. +// see more details in the paper https://eprint.iacr.org/2019/458.pdf page 20. +type mdsMatrices struct { + // the input mds matrix. + m Matrix + // mInv is the inverse of the mds matrix. + mInv Matrix + // mHat is the matrix by eliminating the first row and column of the matrix. + mHat Matrix + // mHatInv is the inverse of the mHat matrix. + mHatInv Matrix + // mPrime is the matrix m' in the paper, and it holds m = m'*m''. + // mPrime consists of: + // 1 | 0 + // 0 | mHat + mPrime Matrix + // mDoublePrime is the matrix m'' in the paper, and it holds m = m'*m''. + // mDoublePrime consists of: + // m_00 | v + // w_hat | I + // where M_00 is the first element of the mds matrix, + // w_hat and v are t-1 length vectors, + // I is the (t-1)*(t-1) identity matrix. + mDoublePrime Matrix +} + +// SparseMatrix is specifically one of the form of m”. +// This means its first row and column are each dense, and the interior matrix +// (minor to the element in both the row and column) is the identity. +// For simplicity, we omit the identity matrix in m”. +type SparseMatrix struct { + // WHat is the first column of the M'' matrix, this is a little different with the WHat in the paper because + // we add M_00 to the beginning of the WHat. + WHat Vector + // V contains all but the first element, because it is already included in WHat. + V Vector +} + +// generate the mds (cauchy) matrix, which is invertible, and +// its sub-matrices are invertible as well. +func GenMDS(t int) Matrix { + xVec := make([]*fr.Element, t) + yVec := make([]*fr.Element, t) + +regen: + // generate x and y value where x[i] != y[i] to allow the values to be inverted, and + // there are no duplicates in the x vector or y vector, so that + // the determinant is always non-zero. + for i := 0; i < t; i++ { + xVec[i] = NewElement().SetUint64(uint64(i)) + yVec[i] = NewElement().SetUint64(uint64(i + t)) + } + + m := make([][]*fr.Element, t) + for i := 0; i < t; i++ { + m[i] = make([]*fr.Element, t) + for j := 0; j < t; j++ { + m[i][j] = NewElement().Add(xVec[i], yVec[j]) + m[i][j].Inverse(m[i][j]) + } + } + + // m must be invertible. + if !IsInvertible(m) { + t++ + goto regen + } + + // m must be symmetric. + transm := transpose(m) + if !IsEqual(transm, m) { + panic("m is not symmetric!") + } + + return m +} + +// derive the mds matrices from m. +func deriveMatrices(m Matrix) (*mdsMatrices, error) { + mInv, err := Invert(m) + if err != nil { + return nil, fmt.Errorf("gen mInv failed, err: %w", err) + } + + mHat, err := minor(m, 0, 0) + if err != nil { + return nil, fmt.Errorf("gen mHat failed, err: %w", err) + } + + mHatInv, err := Invert(mHat) + if err != nil { + return nil, fmt.Errorf("gen mHatInv failed, err: %w", err) + } + + mPrime := genPrime(m) + + mDoublePrime, err := genDoublePrime(m, mHatInv) + if err != nil { + return nil, fmt.Errorf("gen double prime m failed, err: %w", err) + } + + return &mdsMatrices{m, mInv, mHat, mHatInv, mPrime, mDoublePrime}, nil +} + +// generate the matrix m', where m = m'*m”. +func genPrime(m Matrix) Matrix { + prime := make([][]*fr.Element, row(m)) + prime[0] = append(prime[0], one()) + for i := 1; i < column(m); i++ { + prime[0] = append(prime[0], zero()) + } + + for i := 1; i < row(m); i++ { + prime[i] = make([]*fr.Element, column(m)) + prime[i][0] = zero() + for j := 1; j < column(m); j++ { + prime[i][j] = m[i][j] + } + } + return prime +} + +// generate the matrix m”, where m = m'*m”. +func genDoublePrime(m, mHatInv Matrix) (Matrix, error) { + w, v := genPreVectors(m) + + wHat, err := LeftMatMul(mHatInv, w) + if err != nil { + return nil, fmt.Errorf("compute WHat failed, err: %w", err) + } + + doublePrime := make([][]*fr.Element, row(m)) + doublePrime[0] = append([]*fr.Element{m[0][0]}, v...) + for i := 1; i < row(m); i++ { + doublePrime[i] = make([]*fr.Element, column(m)) + doublePrime[i][0] = wHat[i-1] + for j := 1; j < column(m); j++ { + if j == i { + doublePrime[i][j] = one() + } else { + doublePrime[i][j] = zero() + } + } + } + + return doublePrime, nil +} + +// generate pre-computed vectors used in the sparse matrix. +func genPreVectors(m Matrix) (Vector, Vector) { + v := make([]*fr.Element, column(m)-1) + copy(v, m[0][1:]) + + w := make([]*fr.Element, row(m)-1) + for i := 1; i < row(m); i++ { + w[i-1] = m[i][0] + } + + return w, v +} + +// parseSparseMatrix parses the sparse matrix. +func parseSparseMatrix(m Matrix) (*SparseMatrix, error) { + sub, err := minor(m, 0, 0) + if err != nil { + return nil, fmt.Errorf("get the sub matrix err: %w", err) + } + + // m should be the sparse matrix, which has a (t-1)*(t-1) sub identity matrix. + if !IsSquareMatrix(m) || !IsIdentity(sub) { + return nil, fmt.Errorf("cannot parse the sparse matrix") + } + + // WHat is the first column of the sparse matrix. + sparse := new(SparseMatrix) + sparse.WHat = make([]*fr.Element, row(m)) + for i := 0; i < column(m); i++ { + sparse.WHat[i] = m[i][0] + } + + // V contains all but the first element. + sparse.V = make([]*fr.Element, column(m)-1) + copy(sparse.V, m[0][1:]) + + return sparse, nil +} + +// generate the sparse and pre-sparse matrices for fast computation of the Poseidon hash. +// we refer to the paper https://eprint.iacr.org/2019/458.pdf page 20 and +// the implementation in https://github.com/filecoin-project/neptune. +// at each partial round, use a sparse matrix instead of a dense matrix. +// to do this, we have to factored into two components, such that m' x m” = m, +// use the sparse matrix m” as the mds matrix, +// then the previous layer's m is replaced by m x m' = m*. +// from the last partial round, do the same work to the first partial round. +func genSparseMatrix(m Matrix, rp int) ([]*SparseMatrix, Matrix, error) { + sparses := make([]*SparseMatrix, rp) + + preSparse := copyMatrixRows(m, 0, row(m)) + for i := 0; i < rp; i++ { + mds, err := deriveMatrices(preSparse) + if err != nil { + return nil, nil, fmt.Errorf("derive mds matrices err: %w", err) + } + + // m* = m x m' + mat, err := MatMul(m, mds.mPrime) + if err != nil { + return nil, nil, fmt.Errorf("get the previous layer's matrix err: %w", err) + } + + // parse the sparse matrix by reverse order. + sparses[rp-i-1], err = parseSparseMatrix(mds.mDoublePrime) + if err != nil { + return nil, nil, fmt.Errorf("parse sparse matrix err: %w", err) + } + + preSparse = copyMatrixRows(mat, 0, row(mat)) + } + + return sparses, preSparse, nil +} diff --git a/internal/utils/zklink/helper/mds_test.go b/internal/utils/zklink/helper/mds_test.go new file mode 100644 index 00000000000..25220afdda1 --- /dev/null +++ b/internal/utils/zklink/helper/mds_test.go @@ -0,0 +1,29 @@ +package helper + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestMDS(t *testing.T) { + for i := 2; i < 50; i++ { + m := GenMDS(i) + mds, err := deriveMatrices(m) + assert.NoError(t, err) + + mul0, err := MatMul(mds.m, mds.mInv) + assert.NoError(t, err) + + mul1, err := MatMul(mds.mHat, mds.mHatInv) + assert.NoError(t, err) + + if !IsIdentity(mul0) || !IsIdentity(mul1) { + t.Error("mds m or mHat is invalid!") + } + + mul2, err := MatMul(mds.mPrime, mds.mDoublePrime) + assert.NoError(t, err) + assert.Equal(t, mds.m, mul2) + } +} diff --git a/internal/utils/zklink/rescue_hash.go b/internal/utils/zklink/rescue_hash.go index f983f6875d9..1a8d550d93b 100644 --- a/internal/utils/zklink/rescue_hash.go +++ b/internal/utils/zklink/rescue_hash.go @@ -7,6 +7,9 @@ import ( "fmt" "math/big" + "github.com/bits-and-blooms/bitset" + "github.com/thrasher-corp/gocryptotrader/internal/utils/zklink/bn256/fr" + "github.com/thrasher-corp/gocryptotrader/internal/utils/zklink/helper" "golang.org/x/crypto/blake2s" "golang.org/x/crypto/chacha20" ) @@ -96,9 +99,9 @@ func (b *Bn256RescueParams) NewForParams(c, r, rounds, securityLevel uint32) (*B stateWidth := c + r numRoundConstants := int((1 + rounds*2) * stateWidth) - roundConstants, err := func() ([]*big.Int, error) { + roundConstants, err := func() ([]*fr.Element, error) { tag := []byte("Rescue_f") - roundConstants := make([]*big.Int, numRoundConstants) + roundConstants := make([]*fr.Element, numRoundConstants) nonce := uint32(0) var nonceBytes []byte @@ -118,9 +121,9 @@ func (b *Bn256RescueParams) NewForParams(c, r, rounds, securityLevel uint32) (*B return nil, fmt.Errorf("expecting a hash length of 32 bytes, got a hash with length %d", len(hashData)) } - constantRepr := big.NewInt(0).SetBytes(hashData) + constantRepr := helper.NewElement().SetBytes(hashData) constant := constantRepr - if constant.Cmp(big.NewInt(0)) != 0 { + if constant.Cmp(helper.NewElement().SetZero()) != 0 { roundConstants = append(roundConstants, constant) } @@ -135,7 +138,7 @@ func (b *Bn256RescueParams) NewForParams(c, r, rounds, securityLevel uint32) (*B return nil, err } - mdsMatrix, err := func() ([]*big.Int, error) { + mdsMatrix, err := func() ([]*fr.Element, error) { // This tag is a first one in a sequence of b"ResMxxxx" // that produces MDS matrix without eigenvalues for rate = 2, // capacity = 1 variant over Bn254 curve @@ -190,14 +193,13 @@ func (b *Bn256RescueParams) NewForParams(c, r, rounds, securityLevel uint32) (*B if err != nil { return nil, err } - var mdsMatrix []*big.Int - mdsMatrix, err = generateMDSMatrix(stateWidth, rng) - if err != nil { - return nil, err - } - // println(rng) - return mdsMatrix, nil + // var mdsMatrix helper.Matrix + return generateMDSMatrix(stateWidth, rng) + // return helper.GenMDS(int(stateWidth)), nil }() + if err != nil { + return nil, err + } return &Bn256RescueParams{ C: c, R: r, @@ -210,9 +212,9 @@ func (b *Bn256RescueParams) NewForParams(c, r, rounds, securityLevel uint32) (*B } // generateMDSMatrix ... -func generateMDSMatrix(t uint32, rng *chacha20.Cipher) ([]*big.Int, error) { +func generateMDSMatrix(t uint32, rng *chacha20.Cipher) ([]*fr.Element, error) { for { - var x, y []*big.Int + var x, y []*fr.Element for range t { x = append(x, genFr(rng)) y = append(y, genFr(rng)) @@ -269,11 +271,11 @@ func generateMDSMatrix(t uint32, rng *chacha20.Cipher) ([]*big.Int, error) { } // by previous checks we can be sure in uniqueness and perform subtractions easily - mdsMatrix := make([]*big.Int, t*t) + mdsMatrix := make([]*fr.Element, t*t) for i, xi := range x { for j, yi := range y { placeInto := uint32(i)*t + uint32(j) - element := new(big.Int).Set(xi) + element := new(fr.Element).Set(xi) element = element.Sub(element, yi) mdsMatrix[placeInto] = element } @@ -281,47 +283,42 @@ func generateMDSMatrix(t uint32, rng *chacha20.Cipher) ([]*big.Int, error) { // now we need to do the inverse // batch_inversion::(&mut mds_matrix[..]); - // BatchInversion(mdsMatrix, bn256.Order) - - // return mds_matrix; - return mdsMatrix, nil - + return BatchInvert(mdsMatrix), nil + // return helper.GenMDS(int(t)), nil } - } // BatchInvert returns a new slice with every element inverted. // Uses Montgomery batch inversion trick -// func BatchInvert(a []Element) []Element { -// res := make([]Element, len(a)) -// if len(a) == 0 { -// return res -// } - -// zeroes := bitset.New(uint(len(a))) -// accumulator := One() - -// for i := 0; i < len(a); i++ { -// if a[i].IsZero() { -// zeroes.Set(uint(i)) -// continue -// } -// res[i] = accumulator -// accumulator.Mul(&accumulator, &a[i]) -// } - -// accumulator.Inverse(&accumulator) - -// for i := len(a) - 1; i >= 0; i-- { -// if zeroes.Test(uint(i)) { -// continue -// } -// res[i].Mul(&res[i], &accumulator) -// accumulator.Mul(&accumulator, &a[i]) -// } - -// return res -// } +func BatchInvert(a []*fr.Element) []*fr.Element { + res := make([]*fr.Element, len(a)) + if len(a) == 0 { + return res + } + + zeroes := bitset.New(uint(len(a))) + accumulator := new(fr.Element).SetUint64(1) + + for i := 0; i < len(a); i++ { + if a[i].IsZero() { + zeroes.Set(uint(i)) + continue + } + res[i] = accumulator + accumulator.Mul(accumulator, a[i]) + } + + accumulator.Inverse(accumulator) + + for i := len(a) - 1; i >= 0; i-- { + if zeroes.Test(uint(i)) { + continue + } + res[i].Mul(res[i], accumulator) + accumulator.Mul(accumulator, a[i]) + } + return res +} // BatchInversion computes the inverses of elements in the slice using Montgomery's trick func BatchInversion(v []*big.Int, modulus *big.Int) { @@ -360,18 +357,20 @@ func BatchInversion(v []*big.Int, modulus *big.Int) { } // genFr simulates generating a random number value using the provided ChaCha20 RNG. -func genFr(rng *chacha20.Cipher) *big.Int { +func genFr(rng *chacha20.Cipher) *fr.Element { buf := make([]byte, 8) // Assuming we need 64 bits for our random values rng.XORKeyStream(buf, buf) // Fill buf with random data value := binary.BigEndian.Uint64(buf) - return big.NewInt(0).SetUint64(value) + return helper.NewElement().SetBigInt(big.NewInt(0).SetUint64(value)) } +// PowerSBox ... type PowerSBox struct { Power *big.Int Inv uint64 } +// QuinticSBox ... type QuinticSBox struct { Marker *big.Int } diff --git a/internal/utils/zklink/zklink.go b/internal/utils/zklink/zklink.go index 1c837f72ac1..36e2a54a902 100644 --- a/internal/utils/zklink/zklink.go +++ b/internal/utils/zklink/zklink.go @@ -1,6 +1,8 @@ package zklink -import "math/big" +import ( + "math/big" +) // NewZkLinkSigner creates a new zklink signer instance. func NewZkLinkSigner() *ZkLinkSigner { @@ -16,6 +18,11 @@ func (sr *ZkLinkSigner) Sign(arg Signable) (*ZkLinkSignature, error) { // It is impossible to restore signer for signature, that is why we provide public key of the signer // along with signature. func (sg *ZkLinkSigner) SignMusig(msg *big.Int) (*ZkLinkSignature, error) { + pGen := 5 + // var publicKey + // newElem := helper.NewElement() + // newElem.Mul() + println(pGen) return nil, nil } diff --git a/internal/utils/zklink/zklink_types.go b/internal/utils/zklink/zklink_types.go index a141a4cd40e..e327cf57d3d 100644 --- a/internal/utils/zklink/zklink_types.go +++ b/internal/utils/zklink/zklink_types.go @@ -3,6 +3,8 @@ package zklink import ( "errors" "math/big" + + "github.com/thrasher-corp/gocryptotrader/internal/utils/zklink/bn256/fr" ) var ( @@ -11,7 +13,6 @@ var ( errInvalidSeed = errors.New("invalid seed") errInvalidPublicKey = errors.New("invalid public key") errInvalidPublicKeyHash = errors.New("invalid public key hash") - errInvalidEthSigner = errors.New("invalid eth signer") errMissingEthPrivateKey = errors.New("Ethereum private key required to perform an operation") errMissingEthSigner = errors.New("EthereumSigner required to perform an operation") @@ -23,7 +24,7 @@ var ( errDefineAddress = errors.New("address determination error") errRecoverAddress = errors.New("recover address from signature failed: {0}") errLengthMismatched = errors.New("signature length mismatch") - errCryptoError = errors.New("Crypto Error") + errCryptoError = errors.New("crypto Error") errInvalidETHSignature = errors.New("invalid eth signature string") ) @@ -90,8 +91,8 @@ type Bn256RescueParams struct { R uint32 Rounds uint32 SecurityLevel uint32 - RoundConstants []*big.Int - MDSMatrix []*big.Int + RoundConstants []*fr.Element + MDSMatrix []*fr.Element SBox0 *PowerSBox SBox1 *QuinticSBox