mirror of
https://github.com/k3s-io/k3s.git
synced 2024-06-07 19:41:36 +00:00
pin down grpc and related library in go.mod (#2222)
* pin down grpc and related library in go.mod Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com> * go mod tidy Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com>
This commit is contained in:
parent
cc8cc1a58b
commit
041f18f6da
6
go.mod
6
go.mod
@ -24,8 +24,12 @@ replace (
|
|||||||
github.com/matryer/moq => github.com/rancher/moq v0.0.0-20190404221404-ee5226d43009
|
github.com/matryer/moq => github.com/rancher/moq v0.0.0-20190404221404-ee5226d43009
|
||||||
github.com/opencontainers/runc => github.com/opencontainers/runc v1.0.0-rc92
|
github.com/opencontainers/runc => github.com/opencontainers/runc v1.0.0-rc92
|
||||||
github.com/opencontainers/runtime-spec => github.com/opencontainers/runtime-spec v1.0.3-0.20200728170252-4d89ac9fbff6
|
github.com/opencontainers/runtime-spec => github.com/opencontainers/runtime-spec v1.0.3-0.20200728170252-4d89ac9fbff6
|
||||||
|
go.etcd.io/etcd => go.etcd.io/etcd v0.5.0-alpha.5.0.20200824191128-ae9734ed278b
|
||||||
|
golang.org/x/crypto => golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2
|
||||||
|
golang.org/x/net => golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7
|
||||||
|
golang.org/x/sys => golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456
|
||||||
google.golang.org/genproto => google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63
|
google.golang.org/genproto => google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63
|
||||||
google.golang.org/grpc => google.golang.org/grpc v1.27.1
|
google.golang.org/grpc => google.golang.org/grpc v1.26.0
|
||||||
gopkg.in/square/go-jose.v2 => gopkg.in/square/go-jose.v2 v2.2.2
|
gopkg.in/square/go-jose.v2 => gopkg.in/square/go-jose.v2 v2.2.2
|
||||||
k8s.io/api => github.com/rancher/kubernetes/staging/src/k8s.io/api v1.19.1-k3s1
|
k8s.io/api => github.com/rancher/kubernetes/staging/src/k8s.io/api v1.19.1-k3s1
|
||||||
k8s.io/apiextensions-apiserver => github.com/rancher/kubernetes/staging/src/k8s.io/apiextensions-apiserver v1.19.1-k3s1
|
k8s.io/apiextensions-apiserver => github.com/rancher/kubernetes/staging/src/k8s.io/apiextensions-apiserver v1.19.1-k3s1
|
||||||
|
105
go.sum
105
go.sum
@ -849,9 +849,8 @@ go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
|||||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||||
go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0=
|
go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0=
|
||||||
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
||||||
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
|
go.etcd.io/etcd v0.5.0-alpha.5.0.20200824191128-ae9734ed278b h1:3kC4J3eQF6p1UEfQTkC67eEeb3rTk+shQqdX6tFyq9Q=
|
||||||
go.etcd.io/etcd v0.5.0-alpha.5.0.20200819165624-17cef6e3e9d5 h1:Gqga3zA9tdAcfqobUGjSoCob5L3f8Dt5EuOp3ihNZko=
|
go.etcd.io/etcd v0.5.0-alpha.5.0.20200824191128-ae9734ed278b/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg=
|
||||||
go.etcd.io/etcd v0.5.0-alpha.5.0.20200819165624-17cef6e3e9d5/go.mod h1:skWido08r9w6Lq/w70DO5XYIKMu4QFu1+4VsqLQuJy8=
|
|
||||||
go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
||||||
go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
||||||
go.mongodb.org/mongo-driver v1.1.2 h1:jxcFYjlkl8xaERsgLo+RNquI0epW6zuy/ZRQs6jnrFA=
|
go.mongodb.org/mongo-driver v1.1.2 h1:jxcFYjlkl8xaERsgLo+RNquI0epW6zuy/ZRQs6jnrFA=
|
||||||
@ -867,22 +866,8 @@ go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
|
|||||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||||
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
|
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
|
||||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
|
||||||
golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
|
||||||
golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
|
||||||
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
|
||||||
golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/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-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
|
||||||
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
@ -909,38 +894,8 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
|
|||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
|
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 h1:fHDIZ2oxGnUZRN6WgWFCbYBjH9uqVPRCUVUDhs0wnbA=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/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-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-20190125091013-d26f9f9a57f3/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-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
||||||
golang.org/x/net v0.0.0-20190328230028-74de082e2cca/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-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/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-20200226121028-0de0cce0169b/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-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU=
|
|
||||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
|
||||||
golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
|
|
||||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
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-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
@ -954,54 +909,8 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ
|
|||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/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 h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
|
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456 h1:ng0gs1AKnRRuEMZoTLLlbOd+C17zUDepwGQBb/n+JVg=
|
||||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/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-20190124100055-b90733256f2e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20190209173611-3b5209105503/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-20190228124157-a34e9553db1e/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-20190321052220-f7bb7a8bee54/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-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190812073006-9eafafc0a87e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200120151820-655fe14d7479/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200217220822-9197077df867/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-20200501145240-bc7a7d42d5c3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4 h1:5/PjkGUjvEU5Gl6BxmvKRPpqo2uNMv4rcHBMwzk/st8=
|
|
||||||
golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1 h1:sIky/MyNRSHTrdxfsiUSS4WIAMvInbeXljJz+jDjeYE=
|
|
||||||
golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6 h1:DvY3Zkh7KabQE/kfzMvYvKirSiguP9Q/veMtkYyf0o8=
|
|
||||||
golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/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.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.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
@ -1071,8 +980,8 @@ google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpC
|
|||||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63 h1:YzfoEYWbODU5Fbt37+h7X16BWQbad7Q4S6gclTKFXM8=
|
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63 h1:YzfoEYWbODU5Fbt37+h7X16BWQbad7Q4S6gclTKFXM8=
|
||||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||||
google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk=
|
google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg=
|
||||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||||
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
|
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||||
|
4
vendor/go.etcd.io/etcd/pkg/fileutil/fileutil.go
generated
vendored
4
vendor/go.etcd.io/etcd/pkg/fileutil/fileutil.go
generated
vendored
@ -49,7 +49,7 @@ func TouchDirAll(dir string) error {
|
|||||||
if Exist(dir) {
|
if Exist(dir) {
|
||||||
err := CheckDirPermission(dir, PrivateDirMode)
|
err := CheckDirPermission(dir, PrivateDirMode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
plog.Warningf("check file permission: %v", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
err := os.MkdirAll(dir, PrivateDirMode)
|
err := os.MkdirAll(dir, PrivateDirMode)
|
||||||
@ -122,7 +122,7 @@ func CheckDirPermission(dir string, perm os.FileMode) error {
|
|||||||
}
|
}
|
||||||
dirMode := dirInfo.Mode().Perm()
|
dirMode := dirInfo.Mode().Perm()
|
||||||
if dirMode != perm {
|
if dirMode != perm {
|
||||||
err = fmt.Errorf("directory %q,%q exist without desired file permission %q.", dir, dirInfo.Mode(), os.FileMode(PrivateDirMode))
|
err = fmt.Errorf("directory %q exist, but the permission is %q. The recommended permission is %q to prevent possible unprivileged access to the data.", dir, dirInfo.Mode(), os.FileMode(PrivateDirMode))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
2
vendor/go.etcd.io/etcd/version/version.go
generated
vendored
2
vendor/go.etcd.io/etcd/version/version.go
generated
vendored
@ -26,7 +26,7 @@ import (
|
|||||||
var (
|
var (
|
||||||
// MinClusterVersion is the min cluster version this etcd binary is compatible with.
|
// MinClusterVersion is the min cluster version this etcd binary is compatible with.
|
||||||
MinClusterVersion = "3.0.0"
|
MinClusterVersion = "3.0.0"
|
||||||
Version = "3.4.12"
|
Version = "3.4.13"
|
||||||
APIVersion = "unknown"
|
APIVersion = "unknown"
|
||||||
|
|
||||||
// Git SHA Value will be set during build
|
// Git SHA Value will be set during build
|
||||||
|
16
vendor/golang.org/x/crypto/chacha20/chacha_arm64.go
generated
vendored
16
vendor/golang.org/x/crypto/chacha20/chacha_arm64.go
generated
vendored
@ -1,16 +0,0 @@
|
|||||||
// Copyright 2018 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build go1.11,!gccgo,!purego
|
|
||||||
|
|
||||||
package chacha20
|
|
||||||
|
|
||||||
const bufSize = 256
|
|
||||||
|
|
||||||
//go:noescape
|
|
||||||
func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32)
|
|
||||||
|
|
||||||
func (c *Cipher) xorKeyStreamBlocks(dst, src []byte) {
|
|
||||||
xorKeyStreamVX(dst, src, &c.key, &c.nonce, &c.counter)
|
|
||||||
}
|
|
398
vendor/golang.org/x/crypto/chacha20/chacha_generic.go
generated
vendored
398
vendor/golang.org/x/crypto/chacha20/chacha_generic.go
generated
vendored
@ -1,398 +0,0 @@
|
|||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// Package chacha20 implements the ChaCha20 and XChaCha20 encryption algorithms
|
|
||||||
// as specified in RFC 8439 and draft-irtf-cfrg-xchacha-01.
|
|
||||||
package chacha20
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/cipher"
|
|
||||||
"encoding/binary"
|
|
||||||
"errors"
|
|
||||||
"math/bits"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/internal/subtle"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// KeySize is the size of the key used by this cipher, in bytes.
|
|
||||||
KeySize = 32
|
|
||||||
|
|
||||||
// NonceSize is the size of the nonce used with the standard variant of this
|
|
||||||
// cipher, in bytes.
|
|
||||||
//
|
|
||||||
// Note that this is too short to be safely generated at random if the same
|
|
||||||
// key is reused more than 2³² times.
|
|
||||||
NonceSize = 12
|
|
||||||
|
|
||||||
// NonceSizeX is the size of the nonce used with the XChaCha20 variant of
|
|
||||||
// this cipher, in bytes.
|
|
||||||
NonceSizeX = 24
|
|
||||||
)
|
|
||||||
|
|
||||||
// Cipher is a stateful instance of ChaCha20 or XChaCha20 using a particular key
|
|
||||||
// and nonce. A *Cipher implements the cipher.Stream interface.
|
|
||||||
type Cipher struct {
|
|
||||||
// The ChaCha20 state is 16 words: 4 constant, 8 of key, 1 of counter
|
|
||||||
// (incremented after each block), and 3 of nonce.
|
|
||||||
key [8]uint32
|
|
||||||
counter uint32
|
|
||||||
nonce [3]uint32
|
|
||||||
|
|
||||||
// The last len bytes of buf are leftover key stream bytes from the previous
|
|
||||||
// XORKeyStream invocation. The size of buf depends on how many blocks are
|
|
||||||
// computed at a time by xorKeyStreamBlocks.
|
|
||||||
buf [bufSize]byte
|
|
||||||
len int
|
|
||||||
|
|
||||||
// overflow is set when the counter overflowed, no more blocks can be
|
|
||||||
// generated, and the next XORKeyStream call should panic.
|
|
||||||
overflow bool
|
|
||||||
|
|
||||||
// The counter-independent results of the first round are cached after they
|
|
||||||
// are computed the first time.
|
|
||||||
precompDone bool
|
|
||||||
p1, p5, p9, p13 uint32
|
|
||||||
p2, p6, p10, p14 uint32
|
|
||||||
p3, p7, p11, p15 uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ cipher.Stream = (*Cipher)(nil)
|
|
||||||
|
|
||||||
// NewUnauthenticatedCipher creates a new ChaCha20 stream cipher with the given
|
|
||||||
// 32 bytes key and a 12 or 24 bytes nonce. If a nonce of 24 bytes is provided,
|
|
||||||
// the XChaCha20 construction will be used. It returns an error if key or nonce
|
|
||||||
// have any other length.
|
|
||||||
//
|
|
||||||
// Note that ChaCha20, like all stream ciphers, is not authenticated and allows
|
|
||||||
// attackers to silently tamper with the plaintext. For this reason, it is more
|
|
||||||
// appropriate as a building block than as a standalone encryption mechanism.
|
|
||||||
// Instead, consider using package golang.org/x/crypto/chacha20poly1305.
|
|
||||||
func NewUnauthenticatedCipher(key, nonce []byte) (*Cipher, error) {
|
|
||||||
// This function is split into a wrapper so that the Cipher allocation will
|
|
||||||
// be inlined, and depending on how the caller uses the return value, won't
|
|
||||||
// escape to the heap.
|
|
||||||
c := &Cipher{}
|
|
||||||
return newUnauthenticatedCipher(c, key, nonce)
|
|
||||||
}
|
|
||||||
|
|
||||||
func newUnauthenticatedCipher(c *Cipher, key, nonce []byte) (*Cipher, error) {
|
|
||||||
if len(key) != KeySize {
|
|
||||||
return nil, errors.New("chacha20: wrong key size")
|
|
||||||
}
|
|
||||||
if len(nonce) == NonceSizeX {
|
|
||||||
// XChaCha20 uses the ChaCha20 core to mix 16 bytes of the nonce into a
|
|
||||||
// derived key, allowing it to operate on a nonce of 24 bytes. See
|
|
||||||
// draft-irtf-cfrg-xchacha-01, Section 2.3.
|
|
||||||
key, _ = HChaCha20(key, nonce[0:16])
|
|
||||||
cNonce := make([]byte, NonceSize)
|
|
||||||
copy(cNonce[4:12], nonce[16:24])
|
|
||||||
nonce = cNonce
|
|
||||||
} else if len(nonce) != NonceSize {
|
|
||||||
return nil, errors.New("chacha20: wrong nonce size")
|
|
||||||
}
|
|
||||||
|
|
||||||
key, nonce = key[:KeySize], nonce[:NonceSize] // bounds check elimination hint
|
|
||||||
c.key = [8]uint32{
|
|
||||||
binary.LittleEndian.Uint32(key[0:4]),
|
|
||||||
binary.LittleEndian.Uint32(key[4:8]),
|
|
||||||
binary.LittleEndian.Uint32(key[8:12]),
|
|
||||||
binary.LittleEndian.Uint32(key[12:16]),
|
|
||||||
binary.LittleEndian.Uint32(key[16:20]),
|
|
||||||
binary.LittleEndian.Uint32(key[20:24]),
|
|
||||||
binary.LittleEndian.Uint32(key[24:28]),
|
|
||||||
binary.LittleEndian.Uint32(key[28:32]),
|
|
||||||
}
|
|
||||||
c.nonce = [3]uint32{
|
|
||||||
binary.LittleEndian.Uint32(nonce[0:4]),
|
|
||||||
binary.LittleEndian.Uint32(nonce[4:8]),
|
|
||||||
binary.LittleEndian.Uint32(nonce[8:12]),
|
|
||||||
}
|
|
||||||
return c, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// The constant first 4 words of the ChaCha20 state.
|
|
||||||
const (
|
|
||||||
j0 uint32 = 0x61707865 // expa
|
|
||||||
j1 uint32 = 0x3320646e // nd 3
|
|
||||||
j2 uint32 = 0x79622d32 // 2-by
|
|
||||||
j3 uint32 = 0x6b206574 // te k
|
|
||||||
)
|
|
||||||
|
|
||||||
const blockSize = 64
|
|
||||||
|
|
||||||
// quarterRound is the core of ChaCha20. It shuffles the bits of 4 state words.
|
|
||||||
// It's executed 4 times for each of the 20 ChaCha20 rounds, operating on all 16
|
|
||||||
// words each round, in columnar or diagonal groups of 4 at a time.
|
|
||||||
func quarterRound(a, b, c, d uint32) (uint32, uint32, uint32, uint32) {
|
|
||||||
a += b
|
|
||||||
d ^= a
|
|
||||||
d = bits.RotateLeft32(d, 16)
|
|
||||||
c += d
|
|
||||||
b ^= c
|
|
||||||
b = bits.RotateLeft32(b, 12)
|
|
||||||
a += b
|
|
||||||
d ^= a
|
|
||||||
d = bits.RotateLeft32(d, 8)
|
|
||||||
c += d
|
|
||||||
b ^= c
|
|
||||||
b = bits.RotateLeft32(b, 7)
|
|
||||||
return a, b, c, d
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetCounter sets the Cipher counter. The next invocation of XORKeyStream will
|
|
||||||
// behave as if (64 * counter) bytes had been encrypted so far.
|
|
||||||
//
|
|
||||||
// To prevent accidental counter reuse, SetCounter panics if counter is less
|
|
||||||
// than the current value.
|
|
||||||
//
|
|
||||||
// Note that the execution time of XORKeyStream is not independent of the
|
|
||||||
// counter value.
|
|
||||||
func (s *Cipher) SetCounter(counter uint32) {
|
|
||||||
// Internally, s may buffer multiple blocks, which complicates this
|
|
||||||
// implementation slightly. When checking whether the counter has rolled
|
|
||||||
// back, we must use both s.counter and s.len to determine how many blocks
|
|
||||||
// we have already output.
|
|
||||||
outputCounter := s.counter - uint32(s.len)/blockSize
|
|
||||||
if s.overflow || counter < outputCounter {
|
|
||||||
panic("chacha20: SetCounter attempted to rollback counter")
|
|
||||||
}
|
|
||||||
|
|
||||||
// In the general case, we set the new counter value and reset s.len to 0,
|
|
||||||
// causing the next call to XORKeyStream to refill the buffer. However, if
|
|
||||||
// we're advancing within the existing buffer, we can save work by simply
|
|
||||||
// setting s.len.
|
|
||||||
if counter < s.counter {
|
|
||||||
s.len = int(s.counter-counter) * blockSize
|
|
||||||
} else {
|
|
||||||
s.counter = counter
|
|
||||||
s.len = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// XORKeyStream XORs each byte in the given slice with a byte from the
|
|
||||||
// cipher's key stream. Dst and src must overlap entirely or not at all.
|
|
||||||
//
|
|
||||||
// If len(dst) < len(src), XORKeyStream will panic. It is acceptable
|
|
||||||
// to pass a dst bigger than src, and in that case, XORKeyStream will
|
|
||||||
// only update dst[:len(src)] and will not touch the rest of dst.
|
|
||||||
//
|
|
||||||
// Multiple calls to XORKeyStream behave as if the concatenation of
|
|
||||||
// the src buffers was passed in a single run. That is, Cipher
|
|
||||||
// maintains state and does not reset at each XORKeyStream call.
|
|
||||||
func (s *Cipher) XORKeyStream(dst, src []byte) {
|
|
||||||
if len(src) == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if len(dst) < len(src) {
|
|
||||||
panic("chacha20: output smaller than input")
|
|
||||||
}
|
|
||||||
dst = dst[:len(src)]
|
|
||||||
if subtle.InexactOverlap(dst, src) {
|
|
||||||
panic("chacha20: invalid buffer overlap")
|
|
||||||
}
|
|
||||||
|
|
||||||
// First, drain any remaining key stream from a previous XORKeyStream.
|
|
||||||
if s.len != 0 {
|
|
||||||
keyStream := s.buf[bufSize-s.len:]
|
|
||||||
if len(src) < len(keyStream) {
|
|
||||||
keyStream = keyStream[:len(src)]
|
|
||||||
}
|
|
||||||
_ = src[len(keyStream)-1] // bounds check elimination hint
|
|
||||||
for i, b := range keyStream {
|
|
||||||
dst[i] = src[i] ^ b
|
|
||||||
}
|
|
||||||
s.len -= len(keyStream)
|
|
||||||
dst, src = dst[len(keyStream):], src[len(keyStream):]
|
|
||||||
}
|
|
||||||
if len(src) == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we'd need to let the counter overflow and keep generating output,
|
|
||||||
// panic immediately. If instead we'd only reach the last block, remember
|
|
||||||
// not to generate any more output after the buffer is drained.
|
|
||||||
numBlocks := (uint64(len(src)) + blockSize - 1) / blockSize
|
|
||||||
if s.overflow || uint64(s.counter)+numBlocks > 1<<32 {
|
|
||||||
panic("chacha20: counter overflow")
|
|
||||||
} else if uint64(s.counter)+numBlocks == 1<<32 {
|
|
||||||
s.overflow = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// xorKeyStreamBlocks implementations expect input lengths that are a
|
|
||||||
// multiple of bufSize. Platform-specific ones process multiple blocks at a
|
|
||||||
// time, so have bufSizes that are a multiple of blockSize.
|
|
||||||
|
|
||||||
full := len(src) - len(src)%bufSize
|
|
||||||
if full > 0 {
|
|
||||||
s.xorKeyStreamBlocks(dst[:full], src[:full])
|
|
||||||
}
|
|
||||||
dst, src = dst[full:], src[full:]
|
|
||||||
|
|
||||||
// If using a multi-block xorKeyStreamBlocks would overflow, use the generic
|
|
||||||
// one that does one block at a time.
|
|
||||||
const blocksPerBuf = bufSize / blockSize
|
|
||||||
if uint64(s.counter)+blocksPerBuf > 1<<32 {
|
|
||||||
s.buf = [bufSize]byte{}
|
|
||||||
numBlocks := (len(src) + blockSize - 1) / blockSize
|
|
||||||
buf := s.buf[bufSize-numBlocks*blockSize:]
|
|
||||||
copy(buf, src)
|
|
||||||
s.xorKeyStreamBlocksGeneric(buf, buf)
|
|
||||||
s.len = len(buf) - copy(dst, buf)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we have a partial (multi-)block, pad it for xorKeyStreamBlocks, and
|
|
||||||
// keep the leftover keystream for the next XORKeyStream invocation.
|
|
||||||
if len(src) > 0 {
|
|
||||||
s.buf = [bufSize]byte{}
|
|
||||||
copy(s.buf[:], src)
|
|
||||||
s.xorKeyStreamBlocks(s.buf[:], s.buf[:])
|
|
||||||
s.len = bufSize - copy(dst, s.buf[:])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Cipher) xorKeyStreamBlocksGeneric(dst, src []byte) {
|
|
||||||
if len(dst) != len(src) || len(dst)%blockSize != 0 {
|
|
||||||
panic("chacha20: internal error: wrong dst and/or src length")
|
|
||||||
}
|
|
||||||
|
|
||||||
// To generate each block of key stream, the initial cipher state
|
|
||||||
// (represented below) is passed through 20 rounds of shuffling,
|
|
||||||
// alternatively applying quarterRounds by columns (like 1, 5, 9, 13)
|
|
||||||
// or by diagonals (like 1, 6, 11, 12).
|
|
||||||
//
|
|
||||||
// 0:cccccccc 1:cccccccc 2:cccccccc 3:cccccccc
|
|
||||||
// 4:kkkkkkkk 5:kkkkkkkk 6:kkkkkkkk 7:kkkkkkkk
|
|
||||||
// 8:kkkkkkkk 9:kkkkkkkk 10:kkkkkkkk 11:kkkkkkkk
|
|
||||||
// 12:bbbbbbbb 13:nnnnnnnn 14:nnnnnnnn 15:nnnnnnnn
|
|
||||||
//
|
|
||||||
// c=constant k=key b=blockcount n=nonce
|
|
||||||
var (
|
|
||||||
c0, c1, c2, c3 = j0, j1, j2, j3
|
|
||||||
c4, c5, c6, c7 = s.key[0], s.key[1], s.key[2], s.key[3]
|
|
||||||
c8, c9, c10, c11 = s.key[4], s.key[5], s.key[6], s.key[7]
|
|
||||||
_, c13, c14, c15 = s.counter, s.nonce[0], s.nonce[1], s.nonce[2]
|
|
||||||
)
|
|
||||||
|
|
||||||
// Three quarters of the first round don't depend on the counter, so we can
|
|
||||||
// calculate them here, and reuse them for multiple blocks in the loop, and
|
|
||||||
// for future XORKeyStream invocations.
|
|
||||||
if !s.precompDone {
|
|
||||||
s.p1, s.p5, s.p9, s.p13 = quarterRound(c1, c5, c9, c13)
|
|
||||||
s.p2, s.p6, s.p10, s.p14 = quarterRound(c2, c6, c10, c14)
|
|
||||||
s.p3, s.p7, s.p11, s.p15 = quarterRound(c3, c7, c11, c15)
|
|
||||||
s.precompDone = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// A condition of len(src) > 0 would be sufficient, but this also
|
|
||||||
// acts as a bounds check elimination hint.
|
|
||||||
for len(src) >= 64 && len(dst) >= 64 {
|
|
||||||
// The remainder of the first column round.
|
|
||||||
fcr0, fcr4, fcr8, fcr12 := quarterRound(c0, c4, c8, s.counter)
|
|
||||||
|
|
||||||
// The second diagonal round.
|
|
||||||
x0, x5, x10, x15 := quarterRound(fcr0, s.p5, s.p10, s.p15)
|
|
||||||
x1, x6, x11, x12 := quarterRound(s.p1, s.p6, s.p11, fcr12)
|
|
||||||
x2, x7, x8, x13 := quarterRound(s.p2, s.p7, fcr8, s.p13)
|
|
||||||
x3, x4, x9, x14 := quarterRound(s.p3, fcr4, s.p9, s.p14)
|
|
||||||
|
|
||||||
// The remaining 18 rounds.
|
|
||||||
for i := 0; i < 9; i++ {
|
|
||||||
// Column round.
|
|
||||||
x0, x4, x8, x12 = quarterRound(x0, x4, x8, x12)
|
|
||||||
x1, x5, x9, x13 = quarterRound(x1, x5, x9, x13)
|
|
||||||
x2, x6, x10, x14 = quarterRound(x2, x6, x10, x14)
|
|
||||||
x3, x7, x11, x15 = quarterRound(x3, x7, x11, x15)
|
|
||||||
|
|
||||||
// Diagonal round.
|
|
||||||
x0, x5, x10, x15 = quarterRound(x0, x5, x10, x15)
|
|
||||||
x1, x6, x11, x12 = quarterRound(x1, x6, x11, x12)
|
|
||||||
x2, x7, x8, x13 = quarterRound(x2, x7, x8, x13)
|
|
||||||
x3, x4, x9, x14 = quarterRound(x3, x4, x9, x14)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add back the initial state to generate the key stream, then
|
|
||||||
// XOR the key stream with the source and write out the result.
|
|
||||||
addXor(dst[0:4], src[0:4], x0, c0)
|
|
||||||
addXor(dst[4:8], src[4:8], x1, c1)
|
|
||||||
addXor(dst[8:12], src[8:12], x2, c2)
|
|
||||||
addXor(dst[12:16], src[12:16], x3, c3)
|
|
||||||
addXor(dst[16:20], src[16:20], x4, c4)
|
|
||||||
addXor(dst[20:24], src[20:24], x5, c5)
|
|
||||||
addXor(dst[24:28], src[24:28], x6, c6)
|
|
||||||
addXor(dst[28:32], src[28:32], x7, c7)
|
|
||||||
addXor(dst[32:36], src[32:36], x8, c8)
|
|
||||||
addXor(dst[36:40], src[36:40], x9, c9)
|
|
||||||
addXor(dst[40:44], src[40:44], x10, c10)
|
|
||||||
addXor(dst[44:48], src[44:48], x11, c11)
|
|
||||||
addXor(dst[48:52], src[48:52], x12, s.counter)
|
|
||||||
addXor(dst[52:56], src[52:56], x13, c13)
|
|
||||||
addXor(dst[56:60], src[56:60], x14, c14)
|
|
||||||
addXor(dst[60:64], src[60:64], x15, c15)
|
|
||||||
|
|
||||||
s.counter += 1
|
|
||||||
|
|
||||||
src, dst = src[blockSize:], dst[blockSize:]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// HChaCha20 uses the ChaCha20 core to generate a derived key from a 32 bytes
|
|
||||||
// key and a 16 bytes nonce. It returns an error if key or nonce have any other
|
|
||||||
// length. It is used as part of the XChaCha20 construction.
|
|
||||||
func HChaCha20(key, nonce []byte) ([]byte, error) {
|
|
||||||
// This function is split into a wrapper so that the slice allocation will
|
|
||||||
// be inlined, and depending on how the caller uses the return value, won't
|
|
||||||
// escape to the heap.
|
|
||||||
out := make([]byte, 32)
|
|
||||||
return hChaCha20(out, key, nonce)
|
|
||||||
}
|
|
||||||
|
|
||||||
func hChaCha20(out, key, nonce []byte) ([]byte, error) {
|
|
||||||
if len(key) != KeySize {
|
|
||||||
return nil, errors.New("chacha20: wrong HChaCha20 key size")
|
|
||||||
}
|
|
||||||
if len(nonce) != 16 {
|
|
||||||
return nil, errors.New("chacha20: wrong HChaCha20 nonce size")
|
|
||||||
}
|
|
||||||
|
|
||||||
x0, x1, x2, x3 := j0, j1, j2, j3
|
|
||||||
x4 := binary.LittleEndian.Uint32(key[0:4])
|
|
||||||
x5 := binary.LittleEndian.Uint32(key[4:8])
|
|
||||||
x6 := binary.LittleEndian.Uint32(key[8:12])
|
|
||||||
x7 := binary.LittleEndian.Uint32(key[12:16])
|
|
||||||
x8 := binary.LittleEndian.Uint32(key[16:20])
|
|
||||||
x9 := binary.LittleEndian.Uint32(key[20:24])
|
|
||||||
x10 := binary.LittleEndian.Uint32(key[24:28])
|
|
||||||
x11 := binary.LittleEndian.Uint32(key[28:32])
|
|
||||||
x12 := binary.LittleEndian.Uint32(nonce[0:4])
|
|
||||||
x13 := binary.LittleEndian.Uint32(nonce[4:8])
|
|
||||||
x14 := binary.LittleEndian.Uint32(nonce[8:12])
|
|
||||||
x15 := binary.LittleEndian.Uint32(nonce[12:16])
|
|
||||||
|
|
||||||
for i := 0; i < 10; i++ {
|
|
||||||
// Diagonal round.
|
|
||||||
x0, x4, x8, x12 = quarterRound(x0, x4, x8, x12)
|
|
||||||
x1, x5, x9, x13 = quarterRound(x1, x5, x9, x13)
|
|
||||||
x2, x6, x10, x14 = quarterRound(x2, x6, x10, x14)
|
|
||||||
x3, x7, x11, x15 = quarterRound(x3, x7, x11, x15)
|
|
||||||
|
|
||||||
// Column round.
|
|
||||||
x0, x5, x10, x15 = quarterRound(x0, x5, x10, x15)
|
|
||||||
x1, x6, x11, x12 = quarterRound(x1, x6, x11, x12)
|
|
||||||
x2, x7, x8, x13 = quarterRound(x2, x7, x8, x13)
|
|
||||||
x3, x4, x9, x14 = quarterRound(x3, x4, x9, x14)
|
|
||||||
}
|
|
||||||
|
|
||||||
_ = out[31] // bounds check elimination hint
|
|
||||||
binary.LittleEndian.PutUint32(out[0:4], x0)
|
|
||||||
binary.LittleEndian.PutUint32(out[4:8], x1)
|
|
||||||
binary.LittleEndian.PutUint32(out[8:12], x2)
|
|
||||||
binary.LittleEndian.PutUint32(out[12:16], x3)
|
|
||||||
binary.LittleEndian.PutUint32(out[16:20], x12)
|
|
||||||
binary.LittleEndian.PutUint32(out[20:24], x13)
|
|
||||||
binary.LittleEndian.PutUint32(out[24:28], x14)
|
|
||||||
binary.LittleEndian.PutUint32(out[28:32], x15)
|
|
||||||
return out, nil
|
|
||||||
}
|
|
16
vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.go
generated
vendored
16
vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.go
generated
vendored
@ -1,16 +0,0 @@
|
|||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build !gccgo,!purego
|
|
||||||
|
|
||||||
package chacha20
|
|
||||||
|
|
||||||
const bufSize = 256
|
|
||||||
|
|
||||||
//go:noescape
|
|
||||||
func chaCha20_ctr32_vsx(out, inp *byte, len int, key *[8]uint32, counter *uint32)
|
|
||||||
|
|
||||||
func (c *Cipher) xorKeyStreamBlocks(dst, src []byte) {
|
|
||||||
chaCha20_ctr32_vsx(&dst[0], &src[0], len(src), &c.key, &c.counter)
|
|
||||||
}
|
|
449
vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.s
generated
vendored
449
vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.s
generated
vendored
@ -1,449 +0,0 @@
|
|||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// Based on CRYPTOGAMS code with the following comment:
|
|
||||||
// # ====================================================================
|
|
||||||
// # Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
|
|
||||||
// # project. The module is, however, dual licensed under OpenSSL and
|
|
||||||
// # CRYPTOGAMS licenses depending on where you obtain it. For further
|
|
||||||
// # details see http://www.openssl.org/~appro/cryptogams/.
|
|
||||||
// # ====================================================================
|
|
||||||
|
|
||||||
// Code for the perl script that generates the ppc64 assembler
|
|
||||||
// can be found in the cryptogams repository at the link below. It is based on
|
|
||||||
// the original from openssl.
|
|
||||||
|
|
||||||
// https://github.com/dot-asm/cryptogams/commit/a60f5b50ed908e91
|
|
||||||
|
|
||||||
// The differences in this and the original implementation are
|
|
||||||
// due to the calling conventions and initialization of constants.
|
|
||||||
|
|
||||||
// +build !gccgo,!purego
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
#define OUT R3
|
|
||||||
#define INP R4
|
|
||||||
#define LEN R5
|
|
||||||
#define KEY R6
|
|
||||||
#define CNT R7
|
|
||||||
#define TMP R15
|
|
||||||
|
|
||||||
#define CONSTBASE R16
|
|
||||||
#define BLOCKS R17
|
|
||||||
|
|
||||||
DATA consts<>+0x00(SB)/8, $0x3320646e61707865
|
|
||||||
DATA consts<>+0x08(SB)/8, $0x6b20657479622d32
|
|
||||||
DATA consts<>+0x10(SB)/8, $0x0000000000000001
|
|
||||||
DATA consts<>+0x18(SB)/8, $0x0000000000000000
|
|
||||||
DATA consts<>+0x20(SB)/8, $0x0000000000000004
|
|
||||||
DATA consts<>+0x28(SB)/8, $0x0000000000000000
|
|
||||||
DATA consts<>+0x30(SB)/8, $0x0a0b08090e0f0c0d
|
|
||||||
DATA consts<>+0x38(SB)/8, $0x0203000106070405
|
|
||||||
DATA consts<>+0x40(SB)/8, $0x090a0b080d0e0f0c
|
|
||||||
DATA consts<>+0x48(SB)/8, $0x0102030005060704
|
|
||||||
DATA consts<>+0x50(SB)/8, $0x6170786561707865
|
|
||||||
DATA consts<>+0x58(SB)/8, $0x6170786561707865
|
|
||||||
DATA consts<>+0x60(SB)/8, $0x3320646e3320646e
|
|
||||||
DATA consts<>+0x68(SB)/8, $0x3320646e3320646e
|
|
||||||
DATA consts<>+0x70(SB)/8, $0x79622d3279622d32
|
|
||||||
DATA consts<>+0x78(SB)/8, $0x79622d3279622d32
|
|
||||||
DATA consts<>+0x80(SB)/8, $0x6b2065746b206574
|
|
||||||
DATA consts<>+0x88(SB)/8, $0x6b2065746b206574
|
|
||||||
DATA consts<>+0x90(SB)/8, $0x0000000100000000
|
|
||||||
DATA consts<>+0x98(SB)/8, $0x0000000300000002
|
|
||||||
GLOBL consts<>(SB), RODATA, $0xa0
|
|
||||||
|
|
||||||
//func chaCha20_ctr32_vsx(out, inp *byte, len int, key *[8]uint32, counter *uint32)
|
|
||||||
TEXT ·chaCha20_ctr32_vsx(SB),NOSPLIT,$64-40
|
|
||||||
MOVD out+0(FP), OUT
|
|
||||||
MOVD inp+8(FP), INP
|
|
||||||
MOVD len+16(FP), LEN
|
|
||||||
MOVD key+24(FP), KEY
|
|
||||||
MOVD counter+32(FP), CNT
|
|
||||||
|
|
||||||
// Addressing for constants
|
|
||||||
MOVD $consts<>+0x00(SB), CONSTBASE
|
|
||||||
MOVD $16, R8
|
|
||||||
MOVD $32, R9
|
|
||||||
MOVD $48, R10
|
|
||||||
MOVD $64, R11
|
|
||||||
SRD $6, LEN, BLOCKS
|
|
||||||
// V16
|
|
||||||
LXVW4X (CONSTBASE)(R0), VS48
|
|
||||||
ADD $80,CONSTBASE
|
|
||||||
|
|
||||||
// Load key into V17,V18
|
|
||||||
LXVW4X (KEY)(R0), VS49
|
|
||||||
LXVW4X (KEY)(R8), VS50
|
|
||||||
|
|
||||||
// Load CNT, NONCE into V19
|
|
||||||
LXVW4X (CNT)(R0), VS51
|
|
||||||
|
|
||||||
// Clear V27
|
|
||||||
VXOR V27, V27, V27
|
|
||||||
|
|
||||||
// V28
|
|
||||||
LXVW4X (CONSTBASE)(R11), VS60
|
|
||||||
|
|
||||||
// splat slot from V19 -> V26
|
|
||||||
VSPLTW $0, V19, V26
|
|
||||||
|
|
||||||
VSLDOI $4, V19, V27, V19
|
|
||||||
VSLDOI $12, V27, V19, V19
|
|
||||||
|
|
||||||
VADDUWM V26, V28, V26
|
|
||||||
|
|
||||||
MOVD $10, R14
|
|
||||||
MOVD R14, CTR
|
|
||||||
|
|
||||||
loop_outer_vsx:
|
|
||||||
// V0, V1, V2, V3
|
|
||||||
LXVW4X (R0)(CONSTBASE), VS32
|
|
||||||
LXVW4X (R8)(CONSTBASE), VS33
|
|
||||||
LXVW4X (R9)(CONSTBASE), VS34
|
|
||||||
LXVW4X (R10)(CONSTBASE), VS35
|
|
||||||
|
|
||||||
// splat values from V17, V18 into V4-V11
|
|
||||||
VSPLTW $0, V17, V4
|
|
||||||
VSPLTW $1, V17, V5
|
|
||||||
VSPLTW $2, V17, V6
|
|
||||||
VSPLTW $3, V17, V7
|
|
||||||
VSPLTW $0, V18, V8
|
|
||||||
VSPLTW $1, V18, V9
|
|
||||||
VSPLTW $2, V18, V10
|
|
||||||
VSPLTW $3, V18, V11
|
|
||||||
|
|
||||||
// VOR
|
|
||||||
VOR V26, V26, V12
|
|
||||||
|
|
||||||
// splat values from V19 -> V13, V14, V15
|
|
||||||
VSPLTW $1, V19, V13
|
|
||||||
VSPLTW $2, V19, V14
|
|
||||||
VSPLTW $3, V19, V15
|
|
||||||
|
|
||||||
// splat const values
|
|
||||||
VSPLTISW $-16, V27
|
|
||||||
VSPLTISW $12, V28
|
|
||||||
VSPLTISW $8, V29
|
|
||||||
VSPLTISW $7, V30
|
|
||||||
|
|
||||||
loop_vsx:
|
|
||||||
VADDUWM V0, V4, V0
|
|
||||||
VADDUWM V1, V5, V1
|
|
||||||
VADDUWM V2, V6, V2
|
|
||||||
VADDUWM V3, V7, V3
|
|
||||||
|
|
||||||
VXOR V12, V0, V12
|
|
||||||
VXOR V13, V1, V13
|
|
||||||
VXOR V14, V2, V14
|
|
||||||
VXOR V15, V3, V15
|
|
||||||
|
|
||||||
VRLW V12, V27, V12
|
|
||||||
VRLW V13, V27, V13
|
|
||||||
VRLW V14, V27, V14
|
|
||||||
VRLW V15, V27, V15
|
|
||||||
|
|
||||||
VADDUWM V8, V12, V8
|
|
||||||
VADDUWM V9, V13, V9
|
|
||||||
VADDUWM V10, V14, V10
|
|
||||||
VADDUWM V11, V15, V11
|
|
||||||
|
|
||||||
VXOR V4, V8, V4
|
|
||||||
VXOR V5, V9, V5
|
|
||||||
VXOR V6, V10, V6
|
|
||||||
VXOR V7, V11, V7
|
|
||||||
|
|
||||||
VRLW V4, V28, V4
|
|
||||||
VRLW V5, V28, V5
|
|
||||||
VRLW V6, V28, V6
|
|
||||||
VRLW V7, V28, V7
|
|
||||||
|
|
||||||
VADDUWM V0, V4, V0
|
|
||||||
VADDUWM V1, V5, V1
|
|
||||||
VADDUWM V2, V6, V2
|
|
||||||
VADDUWM V3, V7, V3
|
|
||||||
|
|
||||||
VXOR V12, V0, V12
|
|
||||||
VXOR V13, V1, V13
|
|
||||||
VXOR V14, V2, V14
|
|
||||||
VXOR V15, V3, V15
|
|
||||||
|
|
||||||
VRLW V12, V29, V12
|
|
||||||
VRLW V13, V29, V13
|
|
||||||
VRLW V14, V29, V14
|
|
||||||
VRLW V15, V29, V15
|
|
||||||
|
|
||||||
VADDUWM V8, V12, V8
|
|
||||||
VADDUWM V9, V13, V9
|
|
||||||
VADDUWM V10, V14, V10
|
|
||||||
VADDUWM V11, V15, V11
|
|
||||||
|
|
||||||
VXOR V4, V8, V4
|
|
||||||
VXOR V5, V9, V5
|
|
||||||
VXOR V6, V10, V6
|
|
||||||
VXOR V7, V11, V7
|
|
||||||
|
|
||||||
VRLW V4, V30, V4
|
|
||||||
VRLW V5, V30, V5
|
|
||||||
VRLW V6, V30, V6
|
|
||||||
VRLW V7, V30, V7
|
|
||||||
|
|
||||||
VADDUWM V0, V5, V0
|
|
||||||
VADDUWM V1, V6, V1
|
|
||||||
VADDUWM V2, V7, V2
|
|
||||||
VADDUWM V3, V4, V3
|
|
||||||
|
|
||||||
VXOR V15, V0, V15
|
|
||||||
VXOR V12, V1, V12
|
|
||||||
VXOR V13, V2, V13
|
|
||||||
VXOR V14, V3, V14
|
|
||||||
|
|
||||||
VRLW V15, V27, V15
|
|
||||||
VRLW V12, V27, V12
|
|
||||||
VRLW V13, V27, V13
|
|
||||||
VRLW V14, V27, V14
|
|
||||||
|
|
||||||
VADDUWM V10, V15, V10
|
|
||||||
VADDUWM V11, V12, V11
|
|
||||||
VADDUWM V8, V13, V8
|
|
||||||
VADDUWM V9, V14, V9
|
|
||||||
|
|
||||||
VXOR V5, V10, V5
|
|
||||||
VXOR V6, V11, V6
|
|
||||||
VXOR V7, V8, V7
|
|
||||||
VXOR V4, V9, V4
|
|
||||||
|
|
||||||
VRLW V5, V28, V5
|
|
||||||
VRLW V6, V28, V6
|
|
||||||
VRLW V7, V28, V7
|
|
||||||
VRLW V4, V28, V4
|
|
||||||
|
|
||||||
VADDUWM V0, V5, V0
|
|
||||||
VADDUWM V1, V6, V1
|
|
||||||
VADDUWM V2, V7, V2
|
|
||||||
VADDUWM V3, V4, V3
|
|
||||||
|
|
||||||
VXOR V15, V0, V15
|
|
||||||
VXOR V12, V1, V12
|
|
||||||
VXOR V13, V2, V13
|
|
||||||
VXOR V14, V3, V14
|
|
||||||
|
|
||||||
VRLW V15, V29, V15
|
|
||||||
VRLW V12, V29, V12
|
|
||||||
VRLW V13, V29, V13
|
|
||||||
VRLW V14, V29, V14
|
|
||||||
|
|
||||||
VADDUWM V10, V15, V10
|
|
||||||
VADDUWM V11, V12, V11
|
|
||||||
VADDUWM V8, V13, V8
|
|
||||||
VADDUWM V9, V14, V9
|
|
||||||
|
|
||||||
VXOR V5, V10, V5
|
|
||||||
VXOR V6, V11, V6
|
|
||||||
VXOR V7, V8, V7
|
|
||||||
VXOR V4, V9, V4
|
|
||||||
|
|
||||||
VRLW V5, V30, V5
|
|
||||||
VRLW V6, V30, V6
|
|
||||||
VRLW V7, V30, V7
|
|
||||||
VRLW V4, V30, V4
|
|
||||||
BC 16, LT, loop_vsx
|
|
||||||
|
|
||||||
VADDUWM V12, V26, V12
|
|
||||||
|
|
||||||
WORD $0x13600F8C // VMRGEW V0, V1, V27
|
|
||||||
WORD $0x13821F8C // VMRGEW V2, V3, V28
|
|
||||||
|
|
||||||
WORD $0x10000E8C // VMRGOW V0, V1, V0
|
|
||||||
WORD $0x10421E8C // VMRGOW V2, V3, V2
|
|
||||||
|
|
||||||
WORD $0x13A42F8C // VMRGEW V4, V5, V29
|
|
||||||
WORD $0x13C63F8C // VMRGEW V6, V7, V30
|
|
||||||
|
|
||||||
XXPERMDI VS32, VS34, $0, VS33
|
|
||||||
XXPERMDI VS32, VS34, $3, VS35
|
|
||||||
XXPERMDI VS59, VS60, $0, VS32
|
|
||||||
XXPERMDI VS59, VS60, $3, VS34
|
|
||||||
|
|
||||||
WORD $0x10842E8C // VMRGOW V4, V5, V4
|
|
||||||
WORD $0x10C63E8C // VMRGOW V6, V7, V6
|
|
||||||
|
|
||||||
WORD $0x13684F8C // VMRGEW V8, V9, V27
|
|
||||||
WORD $0x138A5F8C // VMRGEW V10, V11, V28
|
|
||||||
|
|
||||||
XXPERMDI VS36, VS38, $0, VS37
|
|
||||||
XXPERMDI VS36, VS38, $3, VS39
|
|
||||||
XXPERMDI VS61, VS62, $0, VS36
|
|
||||||
XXPERMDI VS61, VS62, $3, VS38
|
|
||||||
|
|
||||||
WORD $0x11084E8C // VMRGOW V8, V9, V8
|
|
||||||
WORD $0x114A5E8C // VMRGOW V10, V11, V10
|
|
||||||
|
|
||||||
WORD $0x13AC6F8C // VMRGEW V12, V13, V29
|
|
||||||
WORD $0x13CE7F8C // VMRGEW V14, V15, V30
|
|
||||||
|
|
||||||
XXPERMDI VS40, VS42, $0, VS41
|
|
||||||
XXPERMDI VS40, VS42, $3, VS43
|
|
||||||
XXPERMDI VS59, VS60, $0, VS40
|
|
||||||
XXPERMDI VS59, VS60, $3, VS42
|
|
||||||
|
|
||||||
WORD $0x118C6E8C // VMRGOW V12, V13, V12
|
|
||||||
WORD $0x11CE7E8C // VMRGOW V14, V15, V14
|
|
||||||
|
|
||||||
VSPLTISW $4, V27
|
|
||||||
VADDUWM V26, V27, V26
|
|
||||||
|
|
||||||
XXPERMDI VS44, VS46, $0, VS45
|
|
||||||
XXPERMDI VS44, VS46, $3, VS47
|
|
||||||
XXPERMDI VS61, VS62, $0, VS44
|
|
||||||
XXPERMDI VS61, VS62, $3, VS46
|
|
||||||
|
|
||||||
VADDUWM V0, V16, V0
|
|
||||||
VADDUWM V4, V17, V4
|
|
||||||
VADDUWM V8, V18, V8
|
|
||||||
VADDUWM V12, V19, V12
|
|
||||||
|
|
||||||
CMPU LEN, $64
|
|
||||||
BLT tail_vsx
|
|
||||||
|
|
||||||
// Bottom of loop
|
|
||||||
LXVW4X (INP)(R0), VS59
|
|
||||||
LXVW4X (INP)(R8), VS60
|
|
||||||
LXVW4X (INP)(R9), VS61
|
|
||||||
LXVW4X (INP)(R10), VS62
|
|
||||||
|
|
||||||
VXOR V27, V0, V27
|
|
||||||
VXOR V28, V4, V28
|
|
||||||
VXOR V29, V8, V29
|
|
||||||
VXOR V30, V12, V30
|
|
||||||
|
|
||||||
STXVW4X VS59, (OUT)(R0)
|
|
||||||
STXVW4X VS60, (OUT)(R8)
|
|
||||||
ADD $64, INP
|
|
||||||
STXVW4X VS61, (OUT)(R9)
|
|
||||||
ADD $-64, LEN
|
|
||||||
STXVW4X VS62, (OUT)(R10)
|
|
||||||
ADD $64, OUT
|
|
||||||
BEQ done_vsx
|
|
||||||
|
|
||||||
VADDUWM V1, V16, V0
|
|
||||||
VADDUWM V5, V17, V4
|
|
||||||
VADDUWM V9, V18, V8
|
|
||||||
VADDUWM V13, V19, V12
|
|
||||||
|
|
||||||
CMPU LEN, $64
|
|
||||||
BLT tail_vsx
|
|
||||||
|
|
||||||
LXVW4X (INP)(R0), VS59
|
|
||||||
LXVW4X (INP)(R8), VS60
|
|
||||||
LXVW4X (INP)(R9), VS61
|
|
||||||
LXVW4X (INP)(R10), VS62
|
|
||||||
VXOR V27, V0, V27
|
|
||||||
|
|
||||||
VXOR V28, V4, V28
|
|
||||||
VXOR V29, V8, V29
|
|
||||||
VXOR V30, V12, V30
|
|
||||||
|
|
||||||
STXVW4X VS59, (OUT)(R0)
|
|
||||||
STXVW4X VS60, (OUT)(R8)
|
|
||||||
ADD $64, INP
|
|
||||||
STXVW4X VS61, (OUT)(R9)
|
|
||||||
ADD $-64, LEN
|
|
||||||
STXVW4X VS62, (OUT)(V10)
|
|
||||||
ADD $64, OUT
|
|
||||||
BEQ done_vsx
|
|
||||||
|
|
||||||
VADDUWM V2, V16, V0
|
|
||||||
VADDUWM V6, V17, V4
|
|
||||||
VADDUWM V10, V18, V8
|
|
||||||
VADDUWM V14, V19, V12
|
|
||||||
|
|
||||||
CMPU LEN, $64
|
|
||||||
BLT tail_vsx
|
|
||||||
|
|
||||||
LXVW4X (INP)(R0), VS59
|
|
||||||
LXVW4X (INP)(R8), VS60
|
|
||||||
LXVW4X (INP)(R9), VS61
|
|
||||||
LXVW4X (INP)(R10), VS62
|
|
||||||
|
|
||||||
VXOR V27, V0, V27
|
|
||||||
VXOR V28, V4, V28
|
|
||||||
VXOR V29, V8, V29
|
|
||||||
VXOR V30, V12, V30
|
|
||||||
|
|
||||||
STXVW4X VS59, (OUT)(R0)
|
|
||||||
STXVW4X VS60, (OUT)(R8)
|
|
||||||
ADD $64, INP
|
|
||||||
STXVW4X VS61, (OUT)(R9)
|
|
||||||
ADD $-64, LEN
|
|
||||||
STXVW4X VS62, (OUT)(R10)
|
|
||||||
ADD $64, OUT
|
|
||||||
BEQ done_vsx
|
|
||||||
|
|
||||||
VADDUWM V3, V16, V0
|
|
||||||
VADDUWM V7, V17, V4
|
|
||||||
VADDUWM V11, V18, V8
|
|
||||||
VADDUWM V15, V19, V12
|
|
||||||
|
|
||||||
CMPU LEN, $64
|
|
||||||
BLT tail_vsx
|
|
||||||
|
|
||||||
LXVW4X (INP)(R0), VS59
|
|
||||||
LXVW4X (INP)(R8), VS60
|
|
||||||
LXVW4X (INP)(R9), VS61
|
|
||||||
LXVW4X (INP)(R10), VS62
|
|
||||||
|
|
||||||
VXOR V27, V0, V27
|
|
||||||
VXOR V28, V4, V28
|
|
||||||
VXOR V29, V8, V29
|
|
||||||
VXOR V30, V12, V30
|
|
||||||
|
|
||||||
STXVW4X VS59, (OUT)(R0)
|
|
||||||
STXVW4X VS60, (OUT)(R8)
|
|
||||||
ADD $64, INP
|
|
||||||
STXVW4X VS61, (OUT)(R9)
|
|
||||||
ADD $-64, LEN
|
|
||||||
STXVW4X VS62, (OUT)(R10)
|
|
||||||
ADD $64, OUT
|
|
||||||
|
|
||||||
MOVD $10, R14
|
|
||||||
MOVD R14, CTR
|
|
||||||
BNE loop_outer_vsx
|
|
||||||
|
|
||||||
done_vsx:
|
|
||||||
// Increment counter by number of 64 byte blocks
|
|
||||||
MOVD (CNT), R14
|
|
||||||
ADD BLOCKS, R14
|
|
||||||
MOVD R14, (CNT)
|
|
||||||
RET
|
|
||||||
|
|
||||||
tail_vsx:
|
|
||||||
ADD $32, R1, R11
|
|
||||||
MOVD LEN, CTR
|
|
||||||
|
|
||||||
// Save values on stack to copy from
|
|
||||||
STXVW4X VS32, (R11)(R0)
|
|
||||||
STXVW4X VS36, (R11)(R8)
|
|
||||||
STXVW4X VS40, (R11)(R9)
|
|
||||||
STXVW4X VS44, (R11)(R10)
|
|
||||||
ADD $-1, R11, R12
|
|
||||||
ADD $-1, INP
|
|
||||||
ADD $-1, OUT
|
|
||||||
|
|
||||||
looptail_vsx:
|
|
||||||
// Copying the result to OUT
|
|
||||||
// in bytes.
|
|
||||||
MOVBZU 1(R12), KEY
|
|
||||||
MOVBZU 1(INP), TMP
|
|
||||||
XOR KEY, TMP, KEY
|
|
||||||
MOVBU KEY, 1(OUT)
|
|
||||||
BC 16, LT, looptail_vsx
|
|
||||||
|
|
||||||
// Clear the stack values
|
|
||||||
STXVW4X VS48, (R11)(R0)
|
|
||||||
STXVW4X VS48, (R11)(R8)
|
|
||||||
STXVW4X VS48, (R11)(R9)
|
|
||||||
STXVW4X VS48, (R11)(R10)
|
|
||||||
BR done_vsx
|
|
26
vendor/golang.org/x/crypto/chacha20/chacha_s390x.go
generated
vendored
26
vendor/golang.org/x/crypto/chacha20/chacha_s390x.go
generated
vendored
@ -1,26 +0,0 @@
|
|||||||
// Copyright 2018 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build !gccgo,!purego
|
|
||||||
|
|
||||||
package chacha20
|
|
||||||
|
|
||||||
import "golang.org/x/sys/cpu"
|
|
||||||
|
|
||||||
var haveAsm = cpu.S390X.HasVX
|
|
||||||
|
|
||||||
const bufSize = 256
|
|
||||||
|
|
||||||
// xorKeyStreamVX is an assembly implementation of XORKeyStream. It must only
|
|
||||||
// be called when the vector facility is available. Implementation in asm_s390x.s.
|
|
||||||
//go:noescape
|
|
||||||
func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32)
|
|
||||||
|
|
||||||
func (c *Cipher) xorKeyStreamBlocks(dst, src []byte) {
|
|
||||||
if cpu.S390X.HasVX {
|
|
||||||
xorKeyStreamVX(dst, src, &c.key, &c.nonce, &c.counter)
|
|
||||||
} else {
|
|
||||||
c.xorKeyStreamBlocksGeneric(dst, src)
|
|
||||||
}
|
|
||||||
}
|
|
11
vendor/golang.org/x/crypto/cryptobyte/asn1.go
generated
vendored
11
vendor/golang.org/x/crypto/cryptobyte/asn1.go
generated
vendored
@ -81,7 +81,7 @@ func (b *Builder) AddASN1BigInt(n *big.Int) {
|
|||||||
for i := range bytes {
|
for i := range bytes {
|
||||||
bytes[i] ^= 0xff
|
bytes[i] ^= 0xff
|
||||||
}
|
}
|
||||||
if len(bytes) == 0 || bytes[0]&0x80 == 0 {
|
if bytes[0]&0x80 == 0 {
|
||||||
c.add(0xff)
|
c.add(0xff)
|
||||||
}
|
}
|
||||||
c.add(bytes...)
|
c.add(bytes...)
|
||||||
@ -230,12 +230,12 @@ func (b *Builder) AddASN1(tag asn1.Tag, f BuilderContinuation) {
|
|||||||
|
|
||||||
// String
|
// String
|
||||||
|
|
||||||
// ReadASN1Boolean decodes an ASN.1 BOOLEAN and converts it to a boolean
|
// ReadASN1Boolean decodes an ASN.1 INTEGER and converts it to a boolean
|
||||||
// representation into out and advances. It reports whether the read
|
// representation into out and advances. It reports whether the read
|
||||||
// was successful.
|
// was successful.
|
||||||
func (s *String) ReadASN1Boolean(out *bool) bool {
|
func (s *String) ReadASN1Boolean(out *bool) bool {
|
||||||
var bytes String
|
var bytes String
|
||||||
if !s.ReadASN1(&bytes, asn1.BOOLEAN) || len(bytes) != 1 {
|
if !s.ReadASN1(&bytes, asn1.INTEGER) || len(bytes) != 1 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -470,8 +470,7 @@ func (s *String) ReadASN1GeneralizedTime(out *time.Time) bool {
|
|||||||
// It reports whether the read was successful.
|
// It reports whether the read was successful.
|
||||||
func (s *String) ReadASN1BitString(out *encoding_asn1.BitString) bool {
|
func (s *String) ReadASN1BitString(out *encoding_asn1.BitString) bool {
|
||||||
var bytes String
|
var bytes String
|
||||||
if !s.ReadASN1(&bytes, asn1.BIT_STRING) || len(bytes) == 0 ||
|
if !s.ReadASN1(&bytes, asn1.BIT_STRING) || len(bytes) == 0 {
|
||||||
len(bytes)*8/8 != len(bytes) {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -741,7 +740,7 @@ func (s *String) readASN1(out *String, outTag *asn1.Tag, skipHeader bool) bool {
|
|||||||
length = headerLen + len32
|
length = headerLen + len32
|
||||||
}
|
}
|
||||||
|
|
||||||
if int(length) < 0 || !s.ReadBytes((*[]byte)(out), int(length)) {
|
if uint32(int(length)) != length || !s.ReadBytes((*[]byte)(out), int(length)) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if skipHeader && !out.Skip(int(headerLen)) {
|
if skipHeader && !out.Skip(int(headerLen)) {
|
||||||
|
7
vendor/golang.org/x/crypto/cryptobyte/string.go
generated
vendored
7
vendor/golang.org/x/crypto/cryptobyte/string.go
generated
vendored
@ -24,7 +24,7 @@ type String []byte
|
|||||||
// read advances a String by n bytes and returns them. If less than n bytes
|
// read advances a String by n bytes and returns them. If less than n bytes
|
||||||
// remain, it returns nil.
|
// remain, it returns nil.
|
||||||
func (s *String) read(n int) []byte {
|
func (s *String) read(n int) []byte {
|
||||||
if len(*s) < n || n < 0 {
|
if len(*s) < n {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
v := (*s)[:n]
|
v := (*s)[:n]
|
||||||
@ -105,6 +105,11 @@ func (s *String) readLengthPrefixed(lenLen int, outChild *String) bool {
|
|||||||
length = length << 8
|
length = length << 8
|
||||||
length = length | uint32(b)
|
length = length | uint32(b)
|
||||||
}
|
}
|
||||||
|
if int(length) < 0 {
|
||||||
|
// This currently cannot overflow because we read uint24 at most, but check
|
||||||
|
// anyway in case that changes in the future.
|
||||||
|
return false
|
||||||
|
}
|
||||||
v := s.read(int(length))
|
v := s.read(int(length))
|
||||||
if v == nil {
|
if v == nil {
|
||||||
return false
|
return false
|
||||||
|
8
vendor/golang.org/x/crypto/curve25519/const_amd64.h
generated
vendored
Normal file
8
vendor/golang.org/x/crypto/curve25519/const_amd64.h
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// This code was translated into a form compatible with 6a from the public
|
||||||
|
// domain sources in SUPERCOP: https://bench.cr.yp.to/supercop.html
|
||||||
|
|
||||||
|
#define REDMASK51 0x0007FFFFFFFFFFFF
|
20
vendor/golang.org/x/crypto/curve25519/const_amd64.s
generated
vendored
Normal file
20
vendor/golang.org/x/crypto/curve25519/const_amd64.s
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// This code was translated into a form compatible with 6a from the public
|
||||||
|
// domain sources in SUPERCOP: https://bench.cr.yp.to/supercop.html
|
||||||
|
|
||||||
|
// +build amd64,!gccgo,!appengine
|
||||||
|
|
||||||
|
// These constants cannot be encoded in non-MOVQ immediates.
|
||||||
|
// We access them directly from memory instead.
|
||||||
|
|
||||||
|
DATA ·_121666_213(SB)/8, $996687872
|
||||||
|
GLOBL ·_121666_213(SB), 8, $8
|
||||||
|
|
||||||
|
DATA ·_2P0(SB)/8, $0xFFFFFFFFFFFDA
|
||||||
|
GLOBL ·_2P0(SB), 8, $8
|
||||||
|
|
||||||
|
DATA ·_2P1234(SB)/8, $0xFFFFFFFFFFFFE
|
||||||
|
GLOBL ·_2P1234(SB), 8, $8
|
65
vendor/golang.org/x/crypto/curve25519/cswap_amd64.s
generated
vendored
Normal file
65
vendor/golang.org/x/crypto/curve25519/cswap_amd64.s
generated
vendored
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build amd64,!gccgo,!appengine
|
||||||
|
|
||||||
|
// func cswap(inout *[4][5]uint64, v uint64)
|
||||||
|
TEXT ·cswap(SB),7,$0
|
||||||
|
MOVQ inout+0(FP),DI
|
||||||
|
MOVQ v+8(FP),SI
|
||||||
|
|
||||||
|
SUBQ $1, SI
|
||||||
|
NOTQ SI
|
||||||
|
MOVQ SI, X15
|
||||||
|
PSHUFD $0x44, X15, X15
|
||||||
|
|
||||||
|
MOVOU 0(DI), X0
|
||||||
|
MOVOU 16(DI), X2
|
||||||
|
MOVOU 32(DI), X4
|
||||||
|
MOVOU 48(DI), X6
|
||||||
|
MOVOU 64(DI), X8
|
||||||
|
MOVOU 80(DI), X1
|
||||||
|
MOVOU 96(DI), X3
|
||||||
|
MOVOU 112(DI), X5
|
||||||
|
MOVOU 128(DI), X7
|
||||||
|
MOVOU 144(DI), X9
|
||||||
|
|
||||||
|
MOVO X1, X10
|
||||||
|
MOVO X3, X11
|
||||||
|
MOVO X5, X12
|
||||||
|
MOVO X7, X13
|
||||||
|
MOVO X9, X14
|
||||||
|
|
||||||
|
PXOR X0, X10
|
||||||
|
PXOR X2, X11
|
||||||
|
PXOR X4, X12
|
||||||
|
PXOR X6, X13
|
||||||
|
PXOR X8, X14
|
||||||
|
PAND X15, X10
|
||||||
|
PAND X15, X11
|
||||||
|
PAND X15, X12
|
||||||
|
PAND X15, X13
|
||||||
|
PAND X15, X14
|
||||||
|
PXOR X10, X0
|
||||||
|
PXOR X10, X1
|
||||||
|
PXOR X11, X2
|
||||||
|
PXOR X11, X3
|
||||||
|
PXOR X12, X4
|
||||||
|
PXOR X12, X5
|
||||||
|
PXOR X13, X6
|
||||||
|
PXOR X13, X7
|
||||||
|
PXOR X14, X8
|
||||||
|
PXOR X14, X9
|
||||||
|
|
||||||
|
MOVOU X0, 0(DI)
|
||||||
|
MOVOU X2, 16(DI)
|
||||||
|
MOVOU X4, 32(DI)
|
||||||
|
MOVOU X6, 48(DI)
|
||||||
|
MOVOU X8, 64(DI)
|
||||||
|
MOVOU X1, 80(DI)
|
||||||
|
MOVOU X3, 96(DI)
|
||||||
|
MOVOU X5, 112(DI)
|
||||||
|
MOVOU X7, 128(DI)
|
||||||
|
MOVOU X9, 144(DI)
|
||||||
|
RET
|
897
vendor/golang.org/x/crypto/curve25519/curve25519.go
generated
vendored
897
vendor/golang.org/x/crypto/curve25519/curve25519.go
generated
vendored
@ -1,95 +1,834 @@
|
|||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
// Copyright 2013 The Go Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// Package curve25519 provides an implementation of the X25519 function, which
|
// We have an implementation in amd64 assembly so this code is only run on
|
||||||
// performs scalar multiplication on the elliptic curve known as Curve25519.
|
// non-amd64 platforms. The amd64 assembly does not support gccgo.
|
||||||
// See RFC 7748.
|
// +build !amd64 gccgo appengine
|
||||||
package curve25519 // import "golang.org/x/crypto/curve25519"
|
|
||||||
|
package curve25519
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/subtle"
|
"encoding/binary"
|
||||||
"fmt"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ScalarMult sets dst to the product scalar * point.
|
// This code is a port of the public domain, "ref10" implementation of
|
||||||
//
|
// curve25519 from SUPERCOP 20130419 by D. J. Bernstein.
|
||||||
// Deprecated: when provided a low-order point, ScalarMult will set dst to all
|
|
||||||
// zeroes, irrespective of the scalar. Instead, use the X25519 function, which
|
|
||||||
// will return an error.
|
|
||||||
func ScalarMult(dst, scalar, point *[32]byte) {
|
|
||||||
scalarMult(dst, scalar, point)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ScalarBaseMult sets dst to the product scalar * base where base is the
|
// fieldElement represents an element of the field GF(2^255 - 19). An element
|
||||||
// standard generator.
|
// t, entries t[0]...t[9], represents the integer t[0]+2^26 t[1]+2^51 t[2]+2^77
|
||||||
//
|
// t[3]+2^102 t[4]+...+2^230 t[9]. Bounds on each t[i] vary depending on
|
||||||
// It is recommended to use the X25519 function with Basepoint instead, as
|
// context.
|
||||||
// copying into fixed size arrays can lead to unexpected bugs.
|
type fieldElement [10]int32
|
||||||
func ScalarBaseMult(dst, scalar *[32]byte) {
|
|
||||||
ScalarMult(dst, scalar, &basePoint)
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
func feZero(fe *fieldElement) {
|
||||||
// ScalarSize is the size of the scalar input to X25519.
|
for i := range fe {
|
||||||
ScalarSize = 32
|
fe[i] = 0
|
||||||
// PointSize is the size of the point input to X25519.
|
|
||||||
PointSize = 32
|
|
||||||
)
|
|
||||||
|
|
||||||
// Basepoint is the canonical Curve25519 generator.
|
|
||||||
var Basepoint []byte
|
|
||||||
|
|
||||||
var basePoint = [32]byte{9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
|
||||||
|
|
||||||
func init() { Basepoint = basePoint[:] }
|
|
||||||
|
|
||||||
func checkBasepoint() {
|
|
||||||
if subtle.ConstantTimeCompare(Basepoint, []byte{
|
|
||||||
0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
}) != 1 {
|
|
||||||
panic("curve25519: global Basepoint value was modified")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// X25519 returns the result of the scalar multiplication (scalar * point),
|
func feOne(fe *fieldElement) {
|
||||||
// according to RFC 7748, Section 5. scalar, point and the return value are
|
feZero(fe)
|
||||||
// slices of 32 bytes.
|
fe[0] = 1
|
||||||
//
|
|
||||||
// scalar can be generated at random, for example with crypto/rand. point should
|
|
||||||
// be either Basepoint or the output of another X25519 call.
|
|
||||||
//
|
|
||||||
// If point is Basepoint (but not if it's a different slice with the same
|
|
||||||
// contents) a precomputed implementation might be used for performance.
|
|
||||||
func X25519(scalar, point []byte) ([]byte, error) {
|
|
||||||
// Outline the body of function, to let the allocation be inlined in the
|
|
||||||
// caller, and possibly avoid escaping to the heap.
|
|
||||||
var dst [32]byte
|
|
||||||
return x25519(&dst, scalar, point)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) {
|
func feAdd(dst, a, b *fieldElement) {
|
||||||
var in [32]byte
|
for i := range dst {
|
||||||
if l := len(scalar); l != 32 {
|
dst[i] = a[i] + b[i]
|
||||||
return nil, fmt.Errorf("bad scalar length: %d, expected %d", l, 32)
|
|
||||||
}
|
}
|
||||||
if l := len(point); l != 32 {
|
}
|
||||||
return nil, fmt.Errorf("bad point length: %d, expected %d", l, 32)
|
|
||||||
}
|
func feSub(dst, a, b *fieldElement) {
|
||||||
copy(in[:], scalar)
|
for i := range dst {
|
||||||
if &point[0] == &Basepoint[0] {
|
dst[i] = a[i] - b[i]
|
||||||
checkBasepoint()
|
}
|
||||||
ScalarBaseMult(dst, &in)
|
}
|
||||||
} else {
|
|
||||||
var base, zero [32]byte
|
func feCopy(dst, src *fieldElement) {
|
||||||
copy(base[:], point)
|
for i := range dst {
|
||||||
ScalarMult(dst, &in, &base)
|
dst[i] = src[i]
|
||||||
if subtle.ConstantTimeCompare(dst[:], zero[:]) == 1 {
|
}
|
||||||
return nil, fmt.Errorf("bad input point: low order point")
|
}
|
||||||
}
|
|
||||||
}
|
// feCSwap replaces (f,g) with (g,f) if b == 1; replaces (f,g) with (f,g) if b == 0.
|
||||||
return dst[:], nil
|
//
|
||||||
|
// Preconditions: b in {0,1}.
|
||||||
|
func feCSwap(f, g *fieldElement, b int32) {
|
||||||
|
b = -b
|
||||||
|
for i := range f {
|
||||||
|
t := b & (f[i] ^ g[i])
|
||||||
|
f[i] ^= t
|
||||||
|
g[i] ^= t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// load3 reads a 24-bit, little-endian value from in.
|
||||||
|
func load3(in []byte) int64 {
|
||||||
|
var r int64
|
||||||
|
r = int64(in[0])
|
||||||
|
r |= int64(in[1]) << 8
|
||||||
|
r |= int64(in[2]) << 16
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
// load4 reads a 32-bit, little-endian value from in.
|
||||||
|
func load4(in []byte) int64 {
|
||||||
|
return int64(binary.LittleEndian.Uint32(in))
|
||||||
|
}
|
||||||
|
|
||||||
|
func feFromBytes(dst *fieldElement, src *[32]byte) {
|
||||||
|
h0 := load4(src[:])
|
||||||
|
h1 := load3(src[4:]) << 6
|
||||||
|
h2 := load3(src[7:]) << 5
|
||||||
|
h3 := load3(src[10:]) << 3
|
||||||
|
h4 := load3(src[13:]) << 2
|
||||||
|
h5 := load4(src[16:])
|
||||||
|
h6 := load3(src[20:]) << 7
|
||||||
|
h7 := load3(src[23:]) << 5
|
||||||
|
h8 := load3(src[26:]) << 4
|
||||||
|
h9 := (load3(src[29:]) & 0x7fffff) << 2
|
||||||
|
|
||||||
|
var carry [10]int64
|
||||||
|
carry[9] = (h9 + 1<<24) >> 25
|
||||||
|
h0 += carry[9] * 19
|
||||||
|
h9 -= carry[9] << 25
|
||||||
|
carry[1] = (h1 + 1<<24) >> 25
|
||||||
|
h2 += carry[1]
|
||||||
|
h1 -= carry[1] << 25
|
||||||
|
carry[3] = (h3 + 1<<24) >> 25
|
||||||
|
h4 += carry[3]
|
||||||
|
h3 -= carry[3] << 25
|
||||||
|
carry[5] = (h5 + 1<<24) >> 25
|
||||||
|
h6 += carry[5]
|
||||||
|
h5 -= carry[5] << 25
|
||||||
|
carry[7] = (h7 + 1<<24) >> 25
|
||||||
|
h8 += carry[7]
|
||||||
|
h7 -= carry[7] << 25
|
||||||
|
|
||||||
|
carry[0] = (h0 + 1<<25) >> 26
|
||||||
|
h1 += carry[0]
|
||||||
|
h0 -= carry[0] << 26
|
||||||
|
carry[2] = (h2 + 1<<25) >> 26
|
||||||
|
h3 += carry[2]
|
||||||
|
h2 -= carry[2] << 26
|
||||||
|
carry[4] = (h4 + 1<<25) >> 26
|
||||||
|
h5 += carry[4]
|
||||||
|
h4 -= carry[4] << 26
|
||||||
|
carry[6] = (h6 + 1<<25) >> 26
|
||||||
|
h7 += carry[6]
|
||||||
|
h6 -= carry[6] << 26
|
||||||
|
carry[8] = (h8 + 1<<25) >> 26
|
||||||
|
h9 += carry[8]
|
||||||
|
h8 -= carry[8] << 26
|
||||||
|
|
||||||
|
dst[0] = int32(h0)
|
||||||
|
dst[1] = int32(h1)
|
||||||
|
dst[2] = int32(h2)
|
||||||
|
dst[3] = int32(h3)
|
||||||
|
dst[4] = int32(h4)
|
||||||
|
dst[5] = int32(h5)
|
||||||
|
dst[6] = int32(h6)
|
||||||
|
dst[7] = int32(h7)
|
||||||
|
dst[8] = int32(h8)
|
||||||
|
dst[9] = int32(h9)
|
||||||
|
}
|
||||||
|
|
||||||
|
// feToBytes marshals h to s.
|
||||||
|
// Preconditions:
|
||||||
|
// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
|
||||||
|
//
|
||||||
|
// Write p=2^255-19; q=floor(h/p).
|
||||||
|
// Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))).
|
||||||
|
//
|
||||||
|
// Proof:
|
||||||
|
// Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4.
|
||||||
|
// Also have |h-2^230 h9|<2^230 so |19 2^(-255)(h-2^230 h9)|<1/4.
|
||||||
|
//
|
||||||
|
// Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9).
|
||||||
|
// Then 0<y<1.
|
||||||
|
//
|
||||||
|
// Write r=h-pq.
|
||||||
|
// Have 0<=r<=p-1=2^255-20.
|
||||||
|
// Thus 0<=r+19(2^-255)r<r+19(2^-255)2^255<=2^255-1.
|
||||||
|
//
|
||||||
|
// Write x=r+19(2^-255)r+y.
|
||||||
|
// Then 0<x<2^255 so floor(2^(-255)x) = 0 so floor(q+2^(-255)x) = q.
|
||||||
|
//
|
||||||
|
// Have q+2^(-255)x = 2^(-255)(h + 19 2^(-25) h9 + 2^(-1))
|
||||||
|
// so floor(2^(-255)(h + 19 2^(-25) h9 + 2^(-1))) = q.
|
||||||
|
func feToBytes(s *[32]byte, h *fieldElement) {
|
||||||
|
var carry [10]int32
|
||||||
|
|
||||||
|
q := (19*h[9] + (1 << 24)) >> 25
|
||||||
|
q = (h[0] + q) >> 26
|
||||||
|
q = (h[1] + q) >> 25
|
||||||
|
q = (h[2] + q) >> 26
|
||||||
|
q = (h[3] + q) >> 25
|
||||||
|
q = (h[4] + q) >> 26
|
||||||
|
q = (h[5] + q) >> 25
|
||||||
|
q = (h[6] + q) >> 26
|
||||||
|
q = (h[7] + q) >> 25
|
||||||
|
q = (h[8] + q) >> 26
|
||||||
|
q = (h[9] + q) >> 25
|
||||||
|
|
||||||
|
// Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20.
|
||||||
|
h[0] += 19 * q
|
||||||
|
// Goal: Output h-2^255 q, which is between 0 and 2^255-20.
|
||||||
|
|
||||||
|
carry[0] = h[0] >> 26
|
||||||
|
h[1] += carry[0]
|
||||||
|
h[0] -= carry[0] << 26
|
||||||
|
carry[1] = h[1] >> 25
|
||||||
|
h[2] += carry[1]
|
||||||
|
h[1] -= carry[1] << 25
|
||||||
|
carry[2] = h[2] >> 26
|
||||||
|
h[3] += carry[2]
|
||||||
|
h[2] -= carry[2] << 26
|
||||||
|
carry[3] = h[3] >> 25
|
||||||
|
h[4] += carry[3]
|
||||||
|
h[3] -= carry[3] << 25
|
||||||
|
carry[4] = h[4] >> 26
|
||||||
|
h[5] += carry[4]
|
||||||
|
h[4] -= carry[4] << 26
|
||||||
|
carry[5] = h[5] >> 25
|
||||||
|
h[6] += carry[5]
|
||||||
|
h[5] -= carry[5] << 25
|
||||||
|
carry[6] = h[6] >> 26
|
||||||
|
h[7] += carry[6]
|
||||||
|
h[6] -= carry[6] << 26
|
||||||
|
carry[7] = h[7] >> 25
|
||||||
|
h[8] += carry[7]
|
||||||
|
h[7] -= carry[7] << 25
|
||||||
|
carry[8] = h[8] >> 26
|
||||||
|
h[9] += carry[8]
|
||||||
|
h[8] -= carry[8] << 26
|
||||||
|
carry[9] = h[9] >> 25
|
||||||
|
h[9] -= carry[9] << 25
|
||||||
|
// h10 = carry9
|
||||||
|
|
||||||
|
// Goal: Output h[0]+...+2^255 h10-2^255 q, which is between 0 and 2^255-20.
|
||||||
|
// Have h[0]+...+2^230 h[9] between 0 and 2^255-1;
|
||||||
|
// evidently 2^255 h10-2^255 q = 0.
|
||||||
|
// Goal: Output h[0]+...+2^230 h[9].
|
||||||
|
|
||||||
|
s[0] = byte(h[0] >> 0)
|
||||||
|
s[1] = byte(h[0] >> 8)
|
||||||
|
s[2] = byte(h[0] >> 16)
|
||||||
|
s[3] = byte((h[0] >> 24) | (h[1] << 2))
|
||||||
|
s[4] = byte(h[1] >> 6)
|
||||||
|
s[5] = byte(h[1] >> 14)
|
||||||
|
s[6] = byte((h[1] >> 22) | (h[2] << 3))
|
||||||
|
s[7] = byte(h[2] >> 5)
|
||||||
|
s[8] = byte(h[2] >> 13)
|
||||||
|
s[9] = byte((h[2] >> 21) | (h[3] << 5))
|
||||||
|
s[10] = byte(h[3] >> 3)
|
||||||
|
s[11] = byte(h[3] >> 11)
|
||||||
|
s[12] = byte((h[3] >> 19) | (h[4] << 6))
|
||||||
|
s[13] = byte(h[4] >> 2)
|
||||||
|
s[14] = byte(h[4] >> 10)
|
||||||
|
s[15] = byte(h[4] >> 18)
|
||||||
|
s[16] = byte(h[5] >> 0)
|
||||||
|
s[17] = byte(h[5] >> 8)
|
||||||
|
s[18] = byte(h[5] >> 16)
|
||||||
|
s[19] = byte((h[5] >> 24) | (h[6] << 1))
|
||||||
|
s[20] = byte(h[6] >> 7)
|
||||||
|
s[21] = byte(h[6] >> 15)
|
||||||
|
s[22] = byte((h[6] >> 23) | (h[7] << 3))
|
||||||
|
s[23] = byte(h[7] >> 5)
|
||||||
|
s[24] = byte(h[7] >> 13)
|
||||||
|
s[25] = byte((h[7] >> 21) | (h[8] << 4))
|
||||||
|
s[26] = byte(h[8] >> 4)
|
||||||
|
s[27] = byte(h[8] >> 12)
|
||||||
|
s[28] = byte((h[8] >> 20) | (h[9] << 6))
|
||||||
|
s[29] = byte(h[9] >> 2)
|
||||||
|
s[30] = byte(h[9] >> 10)
|
||||||
|
s[31] = byte(h[9] >> 18)
|
||||||
|
}
|
||||||
|
|
||||||
|
// feMul calculates h = f * g
|
||||||
|
// Can overlap h with f or g.
|
||||||
|
//
|
||||||
|
// Preconditions:
|
||||||
|
// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
|
||||||
|
// |g| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
|
||||||
|
//
|
||||||
|
// Postconditions:
|
||||||
|
// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
|
||||||
|
//
|
||||||
|
// Notes on implementation strategy:
|
||||||
|
//
|
||||||
|
// Using schoolbook multiplication.
|
||||||
|
// Karatsuba would save a little in some cost models.
|
||||||
|
//
|
||||||
|
// Most multiplications by 2 and 19 are 32-bit precomputations;
|
||||||
|
// cheaper than 64-bit postcomputations.
|
||||||
|
//
|
||||||
|
// There is one remaining multiplication by 19 in the carry chain;
|
||||||
|
// one *19 precomputation can be merged into this,
|
||||||
|
// but the resulting data flow is considerably less clean.
|
||||||
|
//
|
||||||
|
// There are 12 carries below.
|
||||||
|
// 10 of them are 2-way parallelizable and vectorizable.
|
||||||
|
// Can get away with 11 carries, but then data flow is much deeper.
|
||||||
|
//
|
||||||
|
// With tighter constraints on inputs can squeeze carries into int32.
|
||||||
|
func feMul(h, f, g *fieldElement) {
|
||||||
|
f0 := f[0]
|
||||||
|
f1 := f[1]
|
||||||
|
f2 := f[2]
|
||||||
|
f3 := f[3]
|
||||||
|
f4 := f[4]
|
||||||
|
f5 := f[5]
|
||||||
|
f6 := f[6]
|
||||||
|
f7 := f[7]
|
||||||
|
f8 := f[8]
|
||||||
|
f9 := f[9]
|
||||||
|
g0 := g[0]
|
||||||
|
g1 := g[1]
|
||||||
|
g2 := g[2]
|
||||||
|
g3 := g[3]
|
||||||
|
g4 := g[4]
|
||||||
|
g5 := g[5]
|
||||||
|
g6 := g[6]
|
||||||
|
g7 := g[7]
|
||||||
|
g8 := g[8]
|
||||||
|
g9 := g[9]
|
||||||
|
g1_19 := 19 * g1 // 1.4*2^29
|
||||||
|
g2_19 := 19 * g2 // 1.4*2^30; still ok
|
||||||
|
g3_19 := 19 * g3
|
||||||
|
g4_19 := 19 * g4
|
||||||
|
g5_19 := 19 * g5
|
||||||
|
g6_19 := 19 * g6
|
||||||
|
g7_19 := 19 * g7
|
||||||
|
g8_19 := 19 * g8
|
||||||
|
g9_19 := 19 * g9
|
||||||
|
f1_2 := 2 * f1
|
||||||
|
f3_2 := 2 * f3
|
||||||
|
f5_2 := 2 * f5
|
||||||
|
f7_2 := 2 * f7
|
||||||
|
f9_2 := 2 * f9
|
||||||
|
f0g0 := int64(f0) * int64(g0)
|
||||||
|
f0g1 := int64(f0) * int64(g1)
|
||||||
|
f0g2 := int64(f0) * int64(g2)
|
||||||
|
f0g3 := int64(f0) * int64(g3)
|
||||||
|
f0g4 := int64(f0) * int64(g4)
|
||||||
|
f0g5 := int64(f0) * int64(g5)
|
||||||
|
f0g6 := int64(f0) * int64(g6)
|
||||||
|
f0g7 := int64(f0) * int64(g7)
|
||||||
|
f0g8 := int64(f0) * int64(g8)
|
||||||
|
f0g9 := int64(f0) * int64(g9)
|
||||||
|
f1g0 := int64(f1) * int64(g0)
|
||||||
|
f1g1_2 := int64(f1_2) * int64(g1)
|
||||||
|
f1g2 := int64(f1) * int64(g2)
|
||||||
|
f1g3_2 := int64(f1_2) * int64(g3)
|
||||||
|
f1g4 := int64(f1) * int64(g4)
|
||||||
|
f1g5_2 := int64(f1_2) * int64(g5)
|
||||||
|
f1g6 := int64(f1) * int64(g6)
|
||||||
|
f1g7_2 := int64(f1_2) * int64(g7)
|
||||||
|
f1g8 := int64(f1) * int64(g8)
|
||||||
|
f1g9_38 := int64(f1_2) * int64(g9_19)
|
||||||
|
f2g0 := int64(f2) * int64(g0)
|
||||||
|
f2g1 := int64(f2) * int64(g1)
|
||||||
|
f2g2 := int64(f2) * int64(g2)
|
||||||
|
f2g3 := int64(f2) * int64(g3)
|
||||||
|
f2g4 := int64(f2) * int64(g4)
|
||||||
|
f2g5 := int64(f2) * int64(g5)
|
||||||
|
f2g6 := int64(f2) * int64(g6)
|
||||||
|
f2g7 := int64(f2) * int64(g7)
|
||||||
|
f2g8_19 := int64(f2) * int64(g8_19)
|
||||||
|
f2g9_19 := int64(f2) * int64(g9_19)
|
||||||
|
f3g0 := int64(f3) * int64(g0)
|
||||||
|
f3g1_2 := int64(f3_2) * int64(g1)
|
||||||
|
f3g2 := int64(f3) * int64(g2)
|
||||||
|
f3g3_2 := int64(f3_2) * int64(g3)
|
||||||
|
f3g4 := int64(f3) * int64(g4)
|
||||||
|
f3g5_2 := int64(f3_2) * int64(g5)
|
||||||
|
f3g6 := int64(f3) * int64(g6)
|
||||||
|
f3g7_38 := int64(f3_2) * int64(g7_19)
|
||||||
|
f3g8_19 := int64(f3) * int64(g8_19)
|
||||||
|
f3g9_38 := int64(f3_2) * int64(g9_19)
|
||||||
|
f4g0 := int64(f4) * int64(g0)
|
||||||
|
f4g1 := int64(f4) * int64(g1)
|
||||||
|
f4g2 := int64(f4) * int64(g2)
|
||||||
|
f4g3 := int64(f4) * int64(g3)
|
||||||
|
f4g4 := int64(f4) * int64(g4)
|
||||||
|
f4g5 := int64(f4) * int64(g5)
|
||||||
|
f4g6_19 := int64(f4) * int64(g6_19)
|
||||||
|
f4g7_19 := int64(f4) * int64(g7_19)
|
||||||
|
f4g8_19 := int64(f4) * int64(g8_19)
|
||||||
|
f4g9_19 := int64(f4) * int64(g9_19)
|
||||||
|
f5g0 := int64(f5) * int64(g0)
|
||||||
|
f5g1_2 := int64(f5_2) * int64(g1)
|
||||||
|
f5g2 := int64(f5) * int64(g2)
|
||||||
|
f5g3_2 := int64(f5_2) * int64(g3)
|
||||||
|
f5g4 := int64(f5) * int64(g4)
|
||||||
|
f5g5_38 := int64(f5_2) * int64(g5_19)
|
||||||
|
f5g6_19 := int64(f5) * int64(g6_19)
|
||||||
|
f5g7_38 := int64(f5_2) * int64(g7_19)
|
||||||
|
f5g8_19 := int64(f5) * int64(g8_19)
|
||||||
|
f5g9_38 := int64(f5_2) * int64(g9_19)
|
||||||
|
f6g0 := int64(f6) * int64(g0)
|
||||||
|
f6g1 := int64(f6) * int64(g1)
|
||||||
|
f6g2 := int64(f6) * int64(g2)
|
||||||
|
f6g3 := int64(f6) * int64(g3)
|
||||||
|
f6g4_19 := int64(f6) * int64(g4_19)
|
||||||
|
f6g5_19 := int64(f6) * int64(g5_19)
|
||||||
|
f6g6_19 := int64(f6) * int64(g6_19)
|
||||||
|
f6g7_19 := int64(f6) * int64(g7_19)
|
||||||
|
f6g8_19 := int64(f6) * int64(g8_19)
|
||||||
|
f6g9_19 := int64(f6) * int64(g9_19)
|
||||||
|
f7g0 := int64(f7) * int64(g0)
|
||||||
|
f7g1_2 := int64(f7_2) * int64(g1)
|
||||||
|
f7g2 := int64(f7) * int64(g2)
|
||||||
|
f7g3_38 := int64(f7_2) * int64(g3_19)
|
||||||
|
f7g4_19 := int64(f7) * int64(g4_19)
|
||||||
|
f7g5_38 := int64(f7_2) * int64(g5_19)
|
||||||
|
f7g6_19 := int64(f7) * int64(g6_19)
|
||||||
|
f7g7_38 := int64(f7_2) * int64(g7_19)
|
||||||
|
f7g8_19 := int64(f7) * int64(g8_19)
|
||||||
|
f7g9_38 := int64(f7_2) * int64(g9_19)
|
||||||
|
f8g0 := int64(f8) * int64(g0)
|
||||||
|
f8g1 := int64(f8) * int64(g1)
|
||||||
|
f8g2_19 := int64(f8) * int64(g2_19)
|
||||||
|
f8g3_19 := int64(f8) * int64(g3_19)
|
||||||
|
f8g4_19 := int64(f8) * int64(g4_19)
|
||||||
|
f8g5_19 := int64(f8) * int64(g5_19)
|
||||||
|
f8g6_19 := int64(f8) * int64(g6_19)
|
||||||
|
f8g7_19 := int64(f8) * int64(g7_19)
|
||||||
|
f8g8_19 := int64(f8) * int64(g8_19)
|
||||||
|
f8g9_19 := int64(f8) * int64(g9_19)
|
||||||
|
f9g0 := int64(f9) * int64(g0)
|
||||||
|
f9g1_38 := int64(f9_2) * int64(g1_19)
|
||||||
|
f9g2_19 := int64(f9) * int64(g2_19)
|
||||||
|
f9g3_38 := int64(f9_2) * int64(g3_19)
|
||||||
|
f9g4_19 := int64(f9) * int64(g4_19)
|
||||||
|
f9g5_38 := int64(f9_2) * int64(g5_19)
|
||||||
|
f9g6_19 := int64(f9) * int64(g6_19)
|
||||||
|
f9g7_38 := int64(f9_2) * int64(g7_19)
|
||||||
|
f9g8_19 := int64(f9) * int64(g8_19)
|
||||||
|
f9g9_38 := int64(f9_2) * int64(g9_19)
|
||||||
|
h0 := f0g0 + f1g9_38 + f2g8_19 + f3g7_38 + f4g6_19 + f5g5_38 + f6g4_19 + f7g3_38 + f8g2_19 + f9g1_38
|
||||||
|
h1 := f0g1 + f1g0 + f2g9_19 + f3g8_19 + f4g7_19 + f5g6_19 + f6g5_19 + f7g4_19 + f8g3_19 + f9g2_19
|
||||||
|
h2 := f0g2 + f1g1_2 + f2g0 + f3g9_38 + f4g8_19 + f5g7_38 + f6g6_19 + f7g5_38 + f8g4_19 + f9g3_38
|
||||||
|
h3 := f0g3 + f1g2 + f2g1 + f3g0 + f4g9_19 + f5g8_19 + f6g7_19 + f7g6_19 + f8g5_19 + f9g4_19
|
||||||
|
h4 := f0g4 + f1g3_2 + f2g2 + f3g1_2 + f4g0 + f5g9_38 + f6g8_19 + f7g7_38 + f8g6_19 + f9g5_38
|
||||||
|
h5 := f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + f6g9_19 + f7g8_19 + f8g7_19 + f9g6_19
|
||||||
|
h6 := f0g6 + f1g5_2 + f2g4 + f3g3_2 + f4g2 + f5g1_2 + f6g0 + f7g9_38 + f8g8_19 + f9g7_38
|
||||||
|
h7 := f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 + f8g9_19 + f9g8_19
|
||||||
|
h8 := f0g8 + f1g7_2 + f2g6 + f3g5_2 + f4g4 + f5g3_2 + f6g2 + f7g1_2 + f8g0 + f9g9_38
|
||||||
|
h9 := f0g9 + f1g8 + f2g7 + f3g6 + f4g5 + f5g4 + f6g3 + f7g2 + f8g1 + f9g0
|
||||||
|
var carry [10]int64
|
||||||
|
|
||||||
|
// |h0| <= (1.1*1.1*2^52*(1+19+19+19+19)+1.1*1.1*2^50*(38+38+38+38+38))
|
||||||
|
// i.e. |h0| <= 1.2*2^59; narrower ranges for h2, h4, h6, h8
|
||||||
|
// |h1| <= (1.1*1.1*2^51*(1+1+19+19+19+19+19+19+19+19))
|
||||||
|
// i.e. |h1| <= 1.5*2^58; narrower ranges for h3, h5, h7, h9
|
||||||
|
|
||||||
|
carry[0] = (h0 + (1 << 25)) >> 26
|
||||||
|
h1 += carry[0]
|
||||||
|
h0 -= carry[0] << 26
|
||||||
|
carry[4] = (h4 + (1 << 25)) >> 26
|
||||||
|
h5 += carry[4]
|
||||||
|
h4 -= carry[4] << 26
|
||||||
|
// |h0| <= 2^25
|
||||||
|
// |h4| <= 2^25
|
||||||
|
// |h1| <= 1.51*2^58
|
||||||
|
// |h5| <= 1.51*2^58
|
||||||
|
|
||||||
|
carry[1] = (h1 + (1 << 24)) >> 25
|
||||||
|
h2 += carry[1]
|
||||||
|
h1 -= carry[1] << 25
|
||||||
|
carry[5] = (h5 + (1 << 24)) >> 25
|
||||||
|
h6 += carry[5]
|
||||||
|
h5 -= carry[5] << 25
|
||||||
|
// |h1| <= 2^24; from now on fits into int32
|
||||||
|
// |h5| <= 2^24; from now on fits into int32
|
||||||
|
// |h2| <= 1.21*2^59
|
||||||
|
// |h6| <= 1.21*2^59
|
||||||
|
|
||||||
|
carry[2] = (h2 + (1 << 25)) >> 26
|
||||||
|
h3 += carry[2]
|
||||||
|
h2 -= carry[2] << 26
|
||||||
|
carry[6] = (h6 + (1 << 25)) >> 26
|
||||||
|
h7 += carry[6]
|
||||||
|
h6 -= carry[6] << 26
|
||||||
|
// |h2| <= 2^25; from now on fits into int32 unchanged
|
||||||
|
// |h6| <= 2^25; from now on fits into int32 unchanged
|
||||||
|
// |h3| <= 1.51*2^58
|
||||||
|
// |h7| <= 1.51*2^58
|
||||||
|
|
||||||
|
carry[3] = (h3 + (1 << 24)) >> 25
|
||||||
|
h4 += carry[3]
|
||||||
|
h3 -= carry[3] << 25
|
||||||
|
carry[7] = (h7 + (1 << 24)) >> 25
|
||||||
|
h8 += carry[7]
|
||||||
|
h7 -= carry[7] << 25
|
||||||
|
// |h3| <= 2^24; from now on fits into int32 unchanged
|
||||||
|
// |h7| <= 2^24; from now on fits into int32 unchanged
|
||||||
|
// |h4| <= 1.52*2^33
|
||||||
|
// |h8| <= 1.52*2^33
|
||||||
|
|
||||||
|
carry[4] = (h4 + (1 << 25)) >> 26
|
||||||
|
h5 += carry[4]
|
||||||
|
h4 -= carry[4] << 26
|
||||||
|
carry[8] = (h8 + (1 << 25)) >> 26
|
||||||
|
h9 += carry[8]
|
||||||
|
h8 -= carry[8] << 26
|
||||||
|
// |h4| <= 2^25; from now on fits into int32 unchanged
|
||||||
|
// |h8| <= 2^25; from now on fits into int32 unchanged
|
||||||
|
// |h5| <= 1.01*2^24
|
||||||
|
// |h9| <= 1.51*2^58
|
||||||
|
|
||||||
|
carry[9] = (h9 + (1 << 24)) >> 25
|
||||||
|
h0 += carry[9] * 19
|
||||||
|
h9 -= carry[9] << 25
|
||||||
|
// |h9| <= 2^24; from now on fits into int32 unchanged
|
||||||
|
// |h0| <= 1.8*2^37
|
||||||
|
|
||||||
|
carry[0] = (h0 + (1 << 25)) >> 26
|
||||||
|
h1 += carry[0]
|
||||||
|
h0 -= carry[0] << 26
|
||||||
|
// |h0| <= 2^25; from now on fits into int32 unchanged
|
||||||
|
// |h1| <= 1.01*2^24
|
||||||
|
|
||||||
|
h[0] = int32(h0)
|
||||||
|
h[1] = int32(h1)
|
||||||
|
h[2] = int32(h2)
|
||||||
|
h[3] = int32(h3)
|
||||||
|
h[4] = int32(h4)
|
||||||
|
h[5] = int32(h5)
|
||||||
|
h[6] = int32(h6)
|
||||||
|
h[7] = int32(h7)
|
||||||
|
h[8] = int32(h8)
|
||||||
|
h[9] = int32(h9)
|
||||||
|
}
|
||||||
|
|
||||||
|
// feSquare calculates h = f*f. Can overlap h with f.
|
||||||
|
//
|
||||||
|
// Preconditions:
|
||||||
|
// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
|
||||||
|
//
|
||||||
|
// Postconditions:
|
||||||
|
// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
|
||||||
|
func feSquare(h, f *fieldElement) {
|
||||||
|
f0 := f[0]
|
||||||
|
f1 := f[1]
|
||||||
|
f2 := f[2]
|
||||||
|
f3 := f[3]
|
||||||
|
f4 := f[4]
|
||||||
|
f5 := f[5]
|
||||||
|
f6 := f[6]
|
||||||
|
f7 := f[7]
|
||||||
|
f8 := f[8]
|
||||||
|
f9 := f[9]
|
||||||
|
f0_2 := 2 * f0
|
||||||
|
f1_2 := 2 * f1
|
||||||
|
f2_2 := 2 * f2
|
||||||
|
f3_2 := 2 * f3
|
||||||
|
f4_2 := 2 * f4
|
||||||
|
f5_2 := 2 * f5
|
||||||
|
f6_2 := 2 * f6
|
||||||
|
f7_2 := 2 * f7
|
||||||
|
f5_38 := 38 * f5 // 1.31*2^30
|
||||||
|
f6_19 := 19 * f6 // 1.31*2^30
|
||||||
|
f7_38 := 38 * f7 // 1.31*2^30
|
||||||
|
f8_19 := 19 * f8 // 1.31*2^30
|
||||||
|
f9_38 := 38 * f9 // 1.31*2^30
|
||||||
|
f0f0 := int64(f0) * int64(f0)
|
||||||
|
f0f1_2 := int64(f0_2) * int64(f1)
|
||||||
|
f0f2_2 := int64(f0_2) * int64(f2)
|
||||||
|
f0f3_2 := int64(f0_2) * int64(f3)
|
||||||
|
f0f4_2 := int64(f0_2) * int64(f4)
|
||||||
|
f0f5_2 := int64(f0_2) * int64(f5)
|
||||||
|
f0f6_2 := int64(f0_2) * int64(f6)
|
||||||
|
f0f7_2 := int64(f0_2) * int64(f7)
|
||||||
|
f0f8_2 := int64(f0_2) * int64(f8)
|
||||||
|
f0f9_2 := int64(f0_2) * int64(f9)
|
||||||
|
f1f1_2 := int64(f1_2) * int64(f1)
|
||||||
|
f1f2_2 := int64(f1_2) * int64(f2)
|
||||||
|
f1f3_4 := int64(f1_2) * int64(f3_2)
|
||||||
|
f1f4_2 := int64(f1_2) * int64(f4)
|
||||||
|
f1f5_4 := int64(f1_2) * int64(f5_2)
|
||||||
|
f1f6_2 := int64(f1_2) * int64(f6)
|
||||||
|
f1f7_4 := int64(f1_2) * int64(f7_2)
|
||||||
|
f1f8_2 := int64(f1_2) * int64(f8)
|
||||||
|
f1f9_76 := int64(f1_2) * int64(f9_38)
|
||||||
|
f2f2 := int64(f2) * int64(f2)
|
||||||
|
f2f3_2 := int64(f2_2) * int64(f3)
|
||||||
|
f2f4_2 := int64(f2_2) * int64(f4)
|
||||||
|
f2f5_2 := int64(f2_2) * int64(f5)
|
||||||
|
f2f6_2 := int64(f2_2) * int64(f6)
|
||||||
|
f2f7_2 := int64(f2_2) * int64(f7)
|
||||||
|
f2f8_38 := int64(f2_2) * int64(f8_19)
|
||||||
|
f2f9_38 := int64(f2) * int64(f9_38)
|
||||||
|
f3f3_2 := int64(f3_2) * int64(f3)
|
||||||
|
f3f4_2 := int64(f3_2) * int64(f4)
|
||||||
|
f3f5_4 := int64(f3_2) * int64(f5_2)
|
||||||
|
f3f6_2 := int64(f3_2) * int64(f6)
|
||||||
|
f3f7_76 := int64(f3_2) * int64(f7_38)
|
||||||
|
f3f8_38 := int64(f3_2) * int64(f8_19)
|
||||||
|
f3f9_76 := int64(f3_2) * int64(f9_38)
|
||||||
|
f4f4 := int64(f4) * int64(f4)
|
||||||
|
f4f5_2 := int64(f4_2) * int64(f5)
|
||||||
|
f4f6_38 := int64(f4_2) * int64(f6_19)
|
||||||
|
f4f7_38 := int64(f4) * int64(f7_38)
|
||||||
|
f4f8_38 := int64(f4_2) * int64(f8_19)
|
||||||
|
f4f9_38 := int64(f4) * int64(f9_38)
|
||||||
|
f5f5_38 := int64(f5) * int64(f5_38)
|
||||||
|
f5f6_38 := int64(f5_2) * int64(f6_19)
|
||||||
|
f5f7_76 := int64(f5_2) * int64(f7_38)
|
||||||
|
f5f8_38 := int64(f5_2) * int64(f8_19)
|
||||||
|
f5f9_76 := int64(f5_2) * int64(f9_38)
|
||||||
|
f6f6_19 := int64(f6) * int64(f6_19)
|
||||||
|
f6f7_38 := int64(f6) * int64(f7_38)
|
||||||
|
f6f8_38 := int64(f6_2) * int64(f8_19)
|
||||||
|
f6f9_38 := int64(f6) * int64(f9_38)
|
||||||
|
f7f7_38 := int64(f7) * int64(f7_38)
|
||||||
|
f7f8_38 := int64(f7_2) * int64(f8_19)
|
||||||
|
f7f9_76 := int64(f7_2) * int64(f9_38)
|
||||||
|
f8f8_19 := int64(f8) * int64(f8_19)
|
||||||
|
f8f9_38 := int64(f8) * int64(f9_38)
|
||||||
|
f9f9_38 := int64(f9) * int64(f9_38)
|
||||||
|
h0 := f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38
|
||||||
|
h1 := f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38
|
||||||
|
h2 := f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19
|
||||||
|
h3 := f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38
|
||||||
|
h4 := f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38
|
||||||
|
h5 := f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38
|
||||||
|
h6 := f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19
|
||||||
|
h7 := f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38
|
||||||
|
h8 := f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38
|
||||||
|
h9 := f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2
|
||||||
|
var carry [10]int64
|
||||||
|
|
||||||
|
carry[0] = (h0 + (1 << 25)) >> 26
|
||||||
|
h1 += carry[0]
|
||||||
|
h0 -= carry[0] << 26
|
||||||
|
carry[4] = (h4 + (1 << 25)) >> 26
|
||||||
|
h5 += carry[4]
|
||||||
|
h4 -= carry[4] << 26
|
||||||
|
|
||||||
|
carry[1] = (h1 + (1 << 24)) >> 25
|
||||||
|
h2 += carry[1]
|
||||||
|
h1 -= carry[1] << 25
|
||||||
|
carry[5] = (h5 + (1 << 24)) >> 25
|
||||||
|
h6 += carry[5]
|
||||||
|
h5 -= carry[5] << 25
|
||||||
|
|
||||||
|
carry[2] = (h2 + (1 << 25)) >> 26
|
||||||
|
h3 += carry[2]
|
||||||
|
h2 -= carry[2] << 26
|
||||||
|
carry[6] = (h6 + (1 << 25)) >> 26
|
||||||
|
h7 += carry[6]
|
||||||
|
h6 -= carry[6] << 26
|
||||||
|
|
||||||
|
carry[3] = (h3 + (1 << 24)) >> 25
|
||||||
|
h4 += carry[3]
|
||||||
|
h3 -= carry[3] << 25
|
||||||
|
carry[7] = (h7 + (1 << 24)) >> 25
|
||||||
|
h8 += carry[7]
|
||||||
|
h7 -= carry[7] << 25
|
||||||
|
|
||||||
|
carry[4] = (h4 + (1 << 25)) >> 26
|
||||||
|
h5 += carry[4]
|
||||||
|
h4 -= carry[4] << 26
|
||||||
|
carry[8] = (h8 + (1 << 25)) >> 26
|
||||||
|
h9 += carry[8]
|
||||||
|
h8 -= carry[8] << 26
|
||||||
|
|
||||||
|
carry[9] = (h9 + (1 << 24)) >> 25
|
||||||
|
h0 += carry[9] * 19
|
||||||
|
h9 -= carry[9] << 25
|
||||||
|
|
||||||
|
carry[0] = (h0 + (1 << 25)) >> 26
|
||||||
|
h1 += carry[0]
|
||||||
|
h0 -= carry[0] << 26
|
||||||
|
|
||||||
|
h[0] = int32(h0)
|
||||||
|
h[1] = int32(h1)
|
||||||
|
h[2] = int32(h2)
|
||||||
|
h[3] = int32(h3)
|
||||||
|
h[4] = int32(h4)
|
||||||
|
h[5] = int32(h5)
|
||||||
|
h[6] = int32(h6)
|
||||||
|
h[7] = int32(h7)
|
||||||
|
h[8] = int32(h8)
|
||||||
|
h[9] = int32(h9)
|
||||||
|
}
|
||||||
|
|
||||||
|
// feMul121666 calculates h = f * 121666. Can overlap h with f.
|
||||||
|
//
|
||||||
|
// Preconditions:
|
||||||
|
// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
|
||||||
|
//
|
||||||
|
// Postconditions:
|
||||||
|
// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
|
||||||
|
func feMul121666(h, f *fieldElement) {
|
||||||
|
h0 := int64(f[0]) * 121666
|
||||||
|
h1 := int64(f[1]) * 121666
|
||||||
|
h2 := int64(f[2]) * 121666
|
||||||
|
h3 := int64(f[3]) * 121666
|
||||||
|
h4 := int64(f[4]) * 121666
|
||||||
|
h5 := int64(f[5]) * 121666
|
||||||
|
h6 := int64(f[6]) * 121666
|
||||||
|
h7 := int64(f[7]) * 121666
|
||||||
|
h8 := int64(f[8]) * 121666
|
||||||
|
h9 := int64(f[9]) * 121666
|
||||||
|
var carry [10]int64
|
||||||
|
|
||||||
|
carry[9] = (h9 + (1 << 24)) >> 25
|
||||||
|
h0 += carry[9] * 19
|
||||||
|
h9 -= carry[9] << 25
|
||||||
|
carry[1] = (h1 + (1 << 24)) >> 25
|
||||||
|
h2 += carry[1]
|
||||||
|
h1 -= carry[1] << 25
|
||||||
|
carry[3] = (h3 + (1 << 24)) >> 25
|
||||||
|
h4 += carry[3]
|
||||||
|
h3 -= carry[3] << 25
|
||||||
|
carry[5] = (h5 + (1 << 24)) >> 25
|
||||||
|
h6 += carry[5]
|
||||||
|
h5 -= carry[5] << 25
|
||||||
|
carry[7] = (h7 + (1 << 24)) >> 25
|
||||||
|
h8 += carry[7]
|
||||||
|
h7 -= carry[7] << 25
|
||||||
|
|
||||||
|
carry[0] = (h0 + (1 << 25)) >> 26
|
||||||
|
h1 += carry[0]
|
||||||
|
h0 -= carry[0] << 26
|
||||||
|
carry[2] = (h2 + (1 << 25)) >> 26
|
||||||
|
h3 += carry[2]
|
||||||
|
h2 -= carry[2] << 26
|
||||||
|
carry[4] = (h4 + (1 << 25)) >> 26
|
||||||
|
h5 += carry[4]
|
||||||
|
h4 -= carry[4] << 26
|
||||||
|
carry[6] = (h6 + (1 << 25)) >> 26
|
||||||
|
h7 += carry[6]
|
||||||
|
h6 -= carry[6] << 26
|
||||||
|
carry[8] = (h8 + (1 << 25)) >> 26
|
||||||
|
h9 += carry[8]
|
||||||
|
h8 -= carry[8] << 26
|
||||||
|
|
||||||
|
h[0] = int32(h0)
|
||||||
|
h[1] = int32(h1)
|
||||||
|
h[2] = int32(h2)
|
||||||
|
h[3] = int32(h3)
|
||||||
|
h[4] = int32(h4)
|
||||||
|
h[5] = int32(h5)
|
||||||
|
h[6] = int32(h6)
|
||||||
|
h[7] = int32(h7)
|
||||||
|
h[8] = int32(h8)
|
||||||
|
h[9] = int32(h9)
|
||||||
|
}
|
||||||
|
|
||||||
|
// feInvert sets out = z^-1.
|
||||||
|
func feInvert(out, z *fieldElement) {
|
||||||
|
var t0, t1, t2, t3 fieldElement
|
||||||
|
var i int
|
||||||
|
|
||||||
|
feSquare(&t0, z)
|
||||||
|
for i = 1; i < 1; i++ {
|
||||||
|
feSquare(&t0, &t0)
|
||||||
|
}
|
||||||
|
feSquare(&t1, &t0)
|
||||||
|
for i = 1; i < 2; i++ {
|
||||||
|
feSquare(&t1, &t1)
|
||||||
|
}
|
||||||
|
feMul(&t1, z, &t1)
|
||||||
|
feMul(&t0, &t0, &t1)
|
||||||
|
feSquare(&t2, &t0)
|
||||||
|
for i = 1; i < 1; i++ {
|
||||||
|
feSquare(&t2, &t2)
|
||||||
|
}
|
||||||
|
feMul(&t1, &t1, &t2)
|
||||||
|
feSquare(&t2, &t1)
|
||||||
|
for i = 1; i < 5; i++ {
|
||||||
|
feSquare(&t2, &t2)
|
||||||
|
}
|
||||||
|
feMul(&t1, &t2, &t1)
|
||||||
|
feSquare(&t2, &t1)
|
||||||
|
for i = 1; i < 10; i++ {
|
||||||
|
feSquare(&t2, &t2)
|
||||||
|
}
|
||||||
|
feMul(&t2, &t2, &t1)
|
||||||
|
feSquare(&t3, &t2)
|
||||||
|
for i = 1; i < 20; i++ {
|
||||||
|
feSquare(&t3, &t3)
|
||||||
|
}
|
||||||
|
feMul(&t2, &t3, &t2)
|
||||||
|
feSquare(&t2, &t2)
|
||||||
|
for i = 1; i < 10; i++ {
|
||||||
|
feSquare(&t2, &t2)
|
||||||
|
}
|
||||||
|
feMul(&t1, &t2, &t1)
|
||||||
|
feSquare(&t2, &t1)
|
||||||
|
for i = 1; i < 50; i++ {
|
||||||
|
feSquare(&t2, &t2)
|
||||||
|
}
|
||||||
|
feMul(&t2, &t2, &t1)
|
||||||
|
feSquare(&t3, &t2)
|
||||||
|
for i = 1; i < 100; i++ {
|
||||||
|
feSquare(&t3, &t3)
|
||||||
|
}
|
||||||
|
feMul(&t2, &t3, &t2)
|
||||||
|
feSquare(&t2, &t2)
|
||||||
|
for i = 1; i < 50; i++ {
|
||||||
|
feSquare(&t2, &t2)
|
||||||
|
}
|
||||||
|
feMul(&t1, &t2, &t1)
|
||||||
|
feSquare(&t1, &t1)
|
||||||
|
for i = 1; i < 5; i++ {
|
||||||
|
feSquare(&t1, &t1)
|
||||||
|
}
|
||||||
|
feMul(out, &t1, &t0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func scalarMult(out, in, base *[32]byte) {
|
||||||
|
var e [32]byte
|
||||||
|
|
||||||
|
copy(e[:], in[:])
|
||||||
|
e[0] &= 248
|
||||||
|
e[31] &= 127
|
||||||
|
e[31] |= 64
|
||||||
|
|
||||||
|
var x1, x2, z2, x3, z3, tmp0, tmp1 fieldElement
|
||||||
|
feFromBytes(&x1, base)
|
||||||
|
feOne(&x2)
|
||||||
|
feCopy(&x3, &x1)
|
||||||
|
feOne(&z3)
|
||||||
|
|
||||||
|
swap := int32(0)
|
||||||
|
for pos := 254; pos >= 0; pos-- {
|
||||||
|
b := e[pos/8] >> uint(pos&7)
|
||||||
|
b &= 1
|
||||||
|
swap ^= int32(b)
|
||||||
|
feCSwap(&x2, &x3, swap)
|
||||||
|
feCSwap(&z2, &z3, swap)
|
||||||
|
swap = int32(b)
|
||||||
|
|
||||||
|
feSub(&tmp0, &x3, &z3)
|
||||||
|
feSub(&tmp1, &x2, &z2)
|
||||||
|
feAdd(&x2, &x2, &z2)
|
||||||
|
feAdd(&z2, &x3, &z3)
|
||||||
|
feMul(&z3, &tmp0, &x2)
|
||||||
|
feMul(&z2, &z2, &tmp1)
|
||||||
|
feSquare(&tmp0, &tmp1)
|
||||||
|
feSquare(&tmp1, &x2)
|
||||||
|
feAdd(&x3, &z3, &z2)
|
||||||
|
feSub(&z2, &z3, &z2)
|
||||||
|
feMul(&x2, &tmp1, &tmp0)
|
||||||
|
feSub(&tmp1, &tmp1, &tmp0)
|
||||||
|
feSquare(&z2, &z2)
|
||||||
|
feMul121666(&z3, &tmp1)
|
||||||
|
feSquare(&x3, &x3)
|
||||||
|
feAdd(&tmp0, &tmp0, &z3)
|
||||||
|
feMul(&z3, &x1, &z2)
|
||||||
|
feMul(&z2, &tmp1, &tmp0)
|
||||||
|
}
|
||||||
|
|
||||||
|
feCSwap(&x2, &x3, swap)
|
||||||
|
feCSwap(&z2, &z3, swap)
|
||||||
|
|
||||||
|
feInvert(&z2, &z2)
|
||||||
|
feMul(&x2, &x2, &z2)
|
||||||
|
feToBytes(out, &x2)
|
||||||
}
|
}
|
||||||
|
828
vendor/golang.org/x/crypto/curve25519/curve25519_generic.go
generated
vendored
828
vendor/golang.org/x/crypto/curve25519/curve25519_generic.go
generated
vendored
@ -1,828 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package curve25519
|
|
||||||
|
|
||||||
import "encoding/binary"
|
|
||||||
|
|
||||||
// This code is a port of the public domain, "ref10" implementation of
|
|
||||||
// curve25519 from SUPERCOP 20130419 by D. J. Bernstein.
|
|
||||||
|
|
||||||
// fieldElement represents an element of the field GF(2^255 - 19). An element
|
|
||||||
// t, entries t[0]...t[9], represents the integer t[0]+2^26 t[1]+2^51 t[2]+2^77
|
|
||||||
// t[3]+2^102 t[4]+...+2^230 t[9]. Bounds on each t[i] vary depending on
|
|
||||||
// context.
|
|
||||||
type fieldElement [10]int32
|
|
||||||
|
|
||||||
func feZero(fe *fieldElement) {
|
|
||||||
for i := range fe {
|
|
||||||
fe[i] = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func feOne(fe *fieldElement) {
|
|
||||||
feZero(fe)
|
|
||||||
fe[0] = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
func feAdd(dst, a, b *fieldElement) {
|
|
||||||
for i := range dst {
|
|
||||||
dst[i] = a[i] + b[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func feSub(dst, a, b *fieldElement) {
|
|
||||||
for i := range dst {
|
|
||||||
dst[i] = a[i] - b[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func feCopy(dst, src *fieldElement) {
|
|
||||||
for i := range dst {
|
|
||||||
dst[i] = src[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// feCSwap replaces (f,g) with (g,f) if b == 1; replaces (f,g) with (f,g) if b == 0.
|
|
||||||
//
|
|
||||||
// Preconditions: b in {0,1}.
|
|
||||||
func feCSwap(f, g *fieldElement, b int32) {
|
|
||||||
b = -b
|
|
||||||
for i := range f {
|
|
||||||
t := b & (f[i] ^ g[i])
|
|
||||||
f[i] ^= t
|
|
||||||
g[i] ^= t
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// load3 reads a 24-bit, little-endian value from in.
|
|
||||||
func load3(in []byte) int64 {
|
|
||||||
var r int64
|
|
||||||
r = int64(in[0])
|
|
||||||
r |= int64(in[1]) << 8
|
|
||||||
r |= int64(in[2]) << 16
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
// load4 reads a 32-bit, little-endian value from in.
|
|
||||||
func load4(in []byte) int64 {
|
|
||||||
return int64(binary.LittleEndian.Uint32(in))
|
|
||||||
}
|
|
||||||
|
|
||||||
func feFromBytes(dst *fieldElement, src *[32]byte) {
|
|
||||||
h0 := load4(src[:])
|
|
||||||
h1 := load3(src[4:]) << 6
|
|
||||||
h2 := load3(src[7:]) << 5
|
|
||||||
h3 := load3(src[10:]) << 3
|
|
||||||
h4 := load3(src[13:]) << 2
|
|
||||||
h5 := load4(src[16:])
|
|
||||||
h6 := load3(src[20:]) << 7
|
|
||||||
h7 := load3(src[23:]) << 5
|
|
||||||
h8 := load3(src[26:]) << 4
|
|
||||||
h9 := (load3(src[29:]) & 0x7fffff) << 2
|
|
||||||
|
|
||||||
var carry [10]int64
|
|
||||||
carry[9] = (h9 + 1<<24) >> 25
|
|
||||||
h0 += carry[9] * 19
|
|
||||||
h9 -= carry[9] << 25
|
|
||||||
carry[1] = (h1 + 1<<24) >> 25
|
|
||||||
h2 += carry[1]
|
|
||||||
h1 -= carry[1] << 25
|
|
||||||
carry[3] = (h3 + 1<<24) >> 25
|
|
||||||
h4 += carry[3]
|
|
||||||
h3 -= carry[3] << 25
|
|
||||||
carry[5] = (h5 + 1<<24) >> 25
|
|
||||||
h6 += carry[5]
|
|
||||||
h5 -= carry[5] << 25
|
|
||||||
carry[7] = (h7 + 1<<24) >> 25
|
|
||||||
h8 += carry[7]
|
|
||||||
h7 -= carry[7] << 25
|
|
||||||
|
|
||||||
carry[0] = (h0 + 1<<25) >> 26
|
|
||||||
h1 += carry[0]
|
|
||||||
h0 -= carry[0] << 26
|
|
||||||
carry[2] = (h2 + 1<<25) >> 26
|
|
||||||
h3 += carry[2]
|
|
||||||
h2 -= carry[2] << 26
|
|
||||||
carry[4] = (h4 + 1<<25) >> 26
|
|
||||||
h5 += carry[4]
|
|
||||||
h4 -= carry[4] << 26
|
|
||||||
carry[6] = (h6 + 1<<25) >> 26
|
|
||||||
h7 += carry[6]
|
|
||||||
h6 -= carry[6] << 26
|
|
||||||
carry[8] = (h8 + 1<<25) >> 26
|
|
||||||
h9 += carry[8]
|
|
||||||
h8 -= carry[8] << 26
|
|
||||||
|
|
||||||
dst[0] = int32(h0)
|
|
||||||
dst[1] = int32(h1)
|
|
||||||
dst[2] = int32(h2)
|
|
||||||
dst[3] = int32(h3)
|
|
||||||
dst[4] = int32(h4)
|
|
||||||
dst[5] = int32(h5)
|
|
||||||
dst[6] = int32(h6)
|
|
||||||
dst[7] = int32(h7)
|
|
||||||
dst[8] = int32(h8)
|
|
||||||
dst[9] = int32(h9)
|
|
||||||
}
|
|
||||||
|
|
||||||
// feToBytes marshals h to s.
|
|
||||||
// Preconditions:
|
|
||||||
// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
|
|
||||||
//
|
|
||||||
// Write p=2^255-19; q=floor(h/p).
|
|
||||||
// Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))).
|
|
||||||
//
|
|
||||||
// Proof:
|
|
||||||
// Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4.
|
|
||||||
// Also have |h-2^230 h9|<2^230 so |19 2^(-255)(h-2^230 h9)|<1/4.
|
|
||||||
//
|
|
||||||
// Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9).
|
|
||||||
// Then 0<y<1.
|
|
||||||
//
|
|
||||||
// Write r=h-pq.
|
|
||||||
// Have 0<=r<=p-1=2^255-20.
|
|
||||||
// Thus 0<=r+19(2^-255)r<r+19(2^-255)2^255<=2^255-1.
|
|
||||||
//
|
|
||||||
// Write x=r+19(2^-255)r+y.
|
|
||||||
// Then 0<x<2^255 so floor(2^(-255)x) = 0 so floor(q+2^(-255)x) = q.
|
|
||||||
//
|
|
||||||
// Have q+2^(-255)x = 2^(-255)(h + 19 2^(-25) h9 + 2^(-1))
|
|
||||||
// so floor(2^(-255)(h + 19 2^(-25) h9 + 2^(-1))) = q.
|
|
||||||
func feToBytes(s *[32]byte, h *fieldElement) {
|
|
||||||
var carry [10]int32
|
|
||||||
|
|
||||||
q := (19*h[9] + (1 << 24)) >> 25
|
|
||||||
q = (h[0] + q) >> 26
|
|
||||||
q = (h[1] + q) >> 25
|
|
||||||
q = (h[2] + q) >> 26
|
|
||||||
q = (h[3] + q) >> 25
|
|
||||||
q = (h[4] + q) >> 26
|
|
||||||
q = (h[5] + q) >> 25
|
|
||||||
q = (h[6] + q) >> 26
|
|
||||||
q = (h[7] + q) >> 25
|
|
||||||
q = (h[8] + q) >> 26
|
|
||||||
q = (h[9] + q) >> 25
|
|
||||||
|
|
||||||
// Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20.
|
|
||||||
h[0] += 19 * q
|
|
||||||
// Goal: Output h-2^255 q, which is between 0 and 2^255-20.
|
|
||||||
|
|
||||||
carry[0] = h[0] >> 26
|
|
||||||
h[1] += carry[0]
|
|
||||||
h[0] -= carry[0] << 26
|
|
||||||
carry[1] = h[1] >> 25
|
|
||||||
h[2] += carry[1]
|
|
||||||
h[1] -= carry[1] << 25
|
|
||||||
carry[2] = h[2] >> 26
|
|
||||||
h[3] += carry[2]
|
|
||||||
h[2] -= carry[2] << 26
|
|
||||||
carry[3] = h[3] >> 25
|
|
||||||
h[4] += carry[3]
|
|
||||||
h[3] -= carry[3] << 25
|
|
||||||
carry[4] = h[4] >> 26
|
|
||||||
h[5] += carry[4]
|
|
||||||
h[4] -= carry[4] << 26
|
|
||||||
carry[5] = h[5] >> 25
|
|
||||||
h[6] += carry[5]
|
|
||||||
h[5] -= carry[5] << 25
|
|
||||||
carry[6] = h[6] >> 26
|
|
||||||
h[7] += carry[6]
|
|
||||||
h[6] -= carry[6] << 26
|
|
||||||
carry[7] = h[7] >> 25
|
|
||||||
h[8] += carry[7]
|
|
||||||
h[7] -= carry[7] << 25
|
|
||||||
carry[8] = h[8] >> 26
|
|
||||||
h[9] += carry[8]
|
|
||||||
h[8] -= carry[8] << 26
|
|
||||||
carry[9] = h[9] >> 25
|
|
||||||
h[9] -= carry[9] << 25
|
|
||||||
// h10 = carry9
|
|
||||||
|
|
||||||
// Goal: Output h[0]+...+2^255 h10-2^255 q, which is between 0 and 2^255-20.
|
|
||||||
// Have h[0]+...+2^230 h[9] between 0 and 2^255-1;
|
|
||||||
// evidently 2^255 h10-2^255 q = 0.
|
|
||||||
// Goal: Output h[0]+...+2^230 h[9].
|
|
||||||
|
|
||||||
s[0] = byte(h[0] >> 0)
|
|
||||||
s[1] = byte(h[0] >> 8)
|
|
||||||
s[2] = byte(h[0] >> 16)
|
|
||||||
s[3] = byte((h[0] >> 24) | (h[1] << 2))
|
|
||||||
s[4] = byte(h[1] >> 6)
|
|
||||||
s[5] = byte(h[1] >> 14)
|
|
||||||
s[6] = byte((h[1] >> 22) | (h[2] << 3))
|
|
||||||
s[7] = byte(h[2] >> 5)
|
|
||||||
s[8] = byte(h[2] >> 13)
|
|
||||||
s[9] = byte((h[2] >> 21) | (h[3] << 5))
|
|
||||||
s[10] = byte(h[3] >> 3)
|
|
||||||
s[11] = byte(h[3] >> 11)
|
|
||||||
s[12] = byte((h[3] >> 19) | (h[4] << 6))
|
|
||||||
s[13] = byte(h[4] >> 2)
|
|
||||||
s[14] = byte(h[4] >> 10)
|
|
||||||
s[15] = byte(h[4] >> 18)
|
|
||||||
s[16] = byte(h[5] >> 0)
|
|
||||||
s[17] = byte(h[5] >> 8)
|
|
||||||
s[18] = byte(h[5] >> 16)
|
|
||||||
s[19] = byte((h[5] >> 24) | (h[6] << 1))
|
|
||||||
s[20] = byte(h[6] >> 7)
|
|
||||||
s[21] = byte(h[6] >> 15)
|
|
||||||
s[22] = byte((h[6] >> 23) | (h[7] << 3))
|
|
||||||
s[23] = byte(h[7] >> 5)
|
|
||||||
s[24] = byte(h[7] >> 13)
|
|
||||||
s[25] = byte((h[7] >> 21) | (h[8] << 4))
|
|
||||||
s[26] = byte(h[8] >> 4)
|
|
||||||
s[27] = byte(h[8] >> 12)
|
|
||||||
s[28] = byte((h[8] >> 20) | (h[9] << 6))
|
|
||||||
s[29] = byte(h[9] >> 2)
|
|
||||||
s[30] = byte(h[9] >> 10)
|
|
||||||
s[31] = byte(h[9] >> 18)
|
|
||||||
}
|
|
||||||
|
|
||||||
// feMul calculates h = f * g
|
|
||||||
// Can overlap h with f or g.
|
|
||||||
//
|
|
||||||
// Preconditions:
|
|
||||||
// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
|
|
||||||
// |g| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
|
|
||||||
//
|
|
||||||
// Postconditions:
|
|
||||||
// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
|
|
||||||
//
|
|
||||||
// Notes on implementation strategy:
|
|
||||||
//
|
|
||||||
// Using schoolbook multiplication.
|
|
||||||
// Karatsuba would save a little in some cost models.
|
|
||||||
//
|
|
||||||
// Most multiplications by 2 and 19 are 32-bit precomputations;
|
|
||||||
// cheaper than 64-bit postcomputations.
|
|
||||||
//
|
|
||||||
// There is one remaining multiplication by 19 in the carry chain;
|
|
||||||
// one *19 precomputation can be merged into this,
|
|
||||||
// but the resulting data flow is considerably less clean.
|
|
||||||
//
|
|
||||||
// There are 12 carries below.
|
|
||||||
// 10 of them are 2-way parallelizable and vectorizable.
|
|
||||||
// Can get away with 11 carries, but then data flow is much deeper.
|
|
||||||
//
|
|
||||||
// With tighter constraints on inputs can squeeze carries into int32.
|
|
||||||
func feMul(h, f, g *fieldElement) {
|
|
||||||
f0 := f[0]
|
|
||||||
f1 := f[1]
|
|
||||||
f2 := f[2]
|
|
||||||
f3 := f[3]
|
|
||||||
f4 := f[4]
|
|
||||||
f5 := f[5]
|
|
||||||
f6 := f[6]
|
|
||||||
f7 := f[7]
|
|
||||||
f8 := f[8]
|
|
||||||
f9 := f[9]
|
|
||||||
g0 := g[0]
|
|
||||||
g1 := g[1]
|
|
||||||
g2 := g[2]
|
|
||||||
g3 := g[3]
|
|
||||||
g4 := g[4]
|
|
||||||
g5 := g[5]
|
|
||||||
g6 := g[6]
|
|
||||||
g7 := g[7]
|
|
||||||
g8 := g[8]
|
|
||||||
g9 := g[9]
|
|
||||||
g1_19 := 19 * g1 // 1.4*2^29
|
|
||||||
g2_19 := 19 * g2 // 1.4*2^30; still ok
|
|
||||||
g3_19 := 19 * g3
|
|
||||||
g4_19 := 19 * g4
|
|
||||||
g5_19 := 19 * g5
|
|
||||||
g6_19 := 19 * g6
|
|
||||||
g7_19 := 19 * g7
|
|
||||||
g8_19 := 19 * g8
|
|
||||||
g9_19 := 19 * g9
|
|
||||||
f1_2 := 2 * f1
|
|
||||||
f3_2 := 2 * f3
|
|
||||||
f5_2 := 2 * f5
|
|
||||||
f7_2 := 2 * f7
|
|
||||||
f9_2 := 2 * f9
|
|
||||||
f0g0 := int64(f0) * int64(g0)
|
|
||||||
f0g1 := int64(f0) * int64(g1)
|
|
||||||
f0g2 := int64(f0) * int64(g2)
|
|
||||||
f0g3 := int64(f0) * int64(g3)
|
|
||||||
f0g4 := int64(f0) * int64(g4)
|
|
||||||
f0g5 := int64(f0) * int64(g5)
|
|
||||||
f0g6 := int64(f0) * int64(g6)
|
|
||||||
f0g7 := int64(f0) * int64(g7)
|
|
||||||
f0g8 := int64(f0) * int64(g8)
|
|
||||||
f0g9 := int64(f0) * int64(g9)
|
|
||||||
f1g0 := int64(f1) * int64(g0)
|
|
||||||
f1g1_2 := int64(f1_2) * int64(g1)
|
|
||||||
f1g2 := int64(f1) * int64(g2)
|
|
||||||
f1g3_2 := int64(f1_2) * int64(g3)
|
|
||||||
f1g4 := int64(f1) * int64(g4)
|
|
||||||
f1g5_2 := int64(f1_2) * int64(g5)
|
|
||||||
f1g6 := int64(f1) * int64(g6)
|
|
||||||
f1g7_2 := int64(f1_2) * int64(g7)
|
|
||||||
f1g8 := int64(f1) * int64(g8)
|
|
||||||
f1g9_38 := int64(f1_2) * int64(g9_19)
|
|
||||||
f2g0 := int64(f2) * int64(g0)
|
|
||||||
f2g1 := int64(f2) * int64(g1)
|
|
||||||
f2g2 := int64(f2) * int64(g2)
|
|
||||||
f2g3 := int64(f2) * int64(g3)
|
|
||||||
f2g4 := int64(f2) * int64(g4)
|
|
||||||
f2g5 := int64(f2) * int64(g5)
|
|
||||||
f2g6 := int64(f2) * int64(g6)
|
|
||||||
f2g7 := int64(f2) * int64(g7)
|
|
||||||
f2g8_19 := int64(f2) * int64(g8_19)
|
|
||||||
f2g9_19 := int64(f2) * int64(g9_19)
|
|
||||||
f3g0 := int64(f3) * int64(g0)
|
|
||||||
f3g1_2 := int64(f3_2) * int64(g1)
|
|
||||||
f3g2 := int64(f3) * int64(g2)
|
|
||||||
f3g3_2 := int64(f3_2) * int64(g3)
|
|
||||||
f3g4 := int64(f3) * int64(g4)
|
|
||||||
f3g5_2 := int64(f3_2) * int64(g5)
|
|
||||||
f3g6 := int64(f3) * int64(g6)
|
|
||||||
f3g7_38 := int64(f3_2) * int64(g7_19)
|
|
||||||
f3g8_19 := int64(f3) * int64(g8_19)
|
|
||||||
f3g9_38 := int64(f3_2) * int64(g9_19)
|
|
||||||
f4g0 := int64(f4) * int64(g0)
|
|
||||||
f4g1 := int64(f4) * int64(g1)
|
|
||||||
f4g2 := int64(f4) * int64(g2)
|
|
||||||
f4g3 := int64(f4) * int64(g3)
|
|
||||||
f4g4 := int64(f4) * int64(g4)
|
|
||||||
f4g5 := int64(f4) * int64(g5)
|
|
||||||
f4g6_19 := int64(f4) * int64(g6_19)
|
|
||||||
f4g7_19 := int64(f4) * int64(g7_19)
|
|
||||||
f4g8_19 := int64(f4) * int64(g8_19)
|
|
||||||
f4g9_19 := int64(f4) * int64(g9_19)
|
|
||||||
f5g0 := int64(f5) * int64(g0)
|
|
||||||
f5g1_2 := int64(f5_2) * int64(g1)
|
|
||||||
f5g2 := int64(f5) * int64(g2)
|
|
||||||
f5g3_2 := int64(f5_2) * int64(g3)
|
|
||||||
f5g4 := int64(f5) * int64(g4)
|
|
||||||
f5g5_38 := int64(f5_2) * int64(g5_19)
|
|
||||||
f5g6_19 := int64(f5) * int64(g6_19)
|
|
||||||
f5g7_38 := int64(f5_2) * int64(g7_19)
|
|
||||||
f5g8_19 := int64(f5) * int64(g8_19)
|
|
||||||
f5g9_38 := int64(f5_2) * int64(g9_19)
|
|
||||||
f6g0 := int64(f6) * int64(g0)
|
|
||||||
f6g1 := int64(f6) * int64(g1)
|
|
||||||
f6g2 := int64(f6) * int64(g2)
|
|
||||||
f6g3 := int64(f6) * int64(g3)
|
|
||||||
f6g4_19 := int64(f6) * int64(g4_19)
|
|
||||||
f6g5_19 := int64(f6) * int64(g5_19)
|
|
||||||
f6g6_19 := int64(f6) * int64(g6_19)
|
|
||||||
f6g7_19 := int64(f6) * int64(g7_19)
|
|
||||||
f6g8_19 := int64(f6) * int64(g8_19)
|
|
||||||
f6g9_19 := int64(f6) * int64(g9_19)
|
|
||||||
f7g0 := int64(f7) * int64(g0)
|
|
||||||
f7g1_2 := int64(f7_2) * int64(g1)
|
|
||||||
f7g2 := int64(f7) * int64(g2)
|
|
||||||
f7g3_38 := int64(f7_2) * int64(g3_19)
|
|
||||||
f7g4_19 := int64(f7) * int64(g4_19)
|
|
||||||
f7g5_38 := int64(f7_2) * int64(g5_19)
|
|
||||||
f7g6_19 := int64(f7) * int64(g6_19)
|
|
||||||
f7g7_38 := int64(f7_2) * int64(g7_19)
|
|
||||||
f7g8_19 := int64(f7) * int64(g8_19)
|
|
||||||
f7g9_38 := int64(f7_2) * int64(g9_19)
|
|
||||||
f8g0 := int64(f8) * int64(g0)
|
|
||||||
f8g1 := int64(f8) * int64(g1)
|
|
||||||
f8g2_19 := int64(f8) * int64(g2_19)
|
|
||||||
f8g3_19 := int64(f8) * int64(g3_19)
|
|
||||||
f8g4_19 := int64(f8) * int64(g4_19)
|
|
||||||
f8g5_19 := int64(f8) * int64(g5_19)
|
|
||||||
f8g6_19 := int64(f8) * int64(g6_19)
|
|
||||||
f8g7_19 := int64(f8) * int64(g7_19)
|
|
||||||
f8g8_19 := int64(f8) * int64(g8_19)
|
|
||||||
f8g9_19 := int64(f8) * int64(g9_19)
|
|
||||||
f9g0 := int64(f9) * int64(g0)
|
|
||||||
f9g1_38 := int64(f9_2) * int64(g1_19)
|
|
||||||
f9g2_19 := int64(f9) * int64(g2_19)
|
|
||||||
f9g3_38 := int64(f9_2) * int64(g3_19)
|
|
||||||
f9g4_19 := int64(f9) * int64(g4_19)
|
|
||||||
f9g5_38 := int64(f9_2) * int64(g5_19)
|
|
||||||
f9g6_19 := int64(f9) * int64(g6_19)
|
|
||||||
f9g7_38 := int64(f9_2) * int64(g7_19)
|
|
||||||
f9g8_19 := int64(f9) * int64(g8_19)
|
|
||||||
f9g9_38 := int64(f9_2) * int64(g9_19)
|
|
||||||
h0 := f0g0 + f1g9_38 + f2g8_19 + f3g7_38 + f4g6_19 + f5g5_38 + f6g4_19 + f7g3_38 + f8g2_19 + f9g1_38
|
|
||||||
h1 := f0g1 + f1g0 + f2g9_19 + f3g8_19 + f4g7_19 + f5g6_19 + f6g5_19 + f7g4_19 + f8g3_19 + f9g2_19
|
|
||||||
h2 := f0g2 + f1g1_2 + f2g0 + f3g9_38 + f4g8_19 + f5g7_38 + f6g6_19 + f7g5_38 + f8g4_19 + f9g3_38
|
|
||||||
h3 := f0g3 + f1g2 + f2g1 + f3g0 + f4g9_19 + f5g8_19 + f6g7_19 + f7g6_19 + f8g5_19 + f9g4_19
|
|
||||||
h4 := f0g4 + f1g3_2 + f2g2 + f3g1_2 + f4g0 + f5g9_38 + f6g8_19 + f7g7_38 + f8g6_19 + f9g5_38
|
|
||||||
h5 := f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + f6g9_19 + f7g8_19 + f8g7_19 + f9g6_19
|
|
||||||
h6 := f0g6 + f1g5_2 + f2g4 + f3g3_2 + f4g2 + f5g1_2 + f6g0 + f7g9_38 + f8g8_19 + f9g7_38
|
|
||||||
h7 := f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 + f8g9_19 + f9g8_19
|
|
||||||
h8 := f0g8 + f1g7_2 + f2g6 + f3g5_2 + f4g4 + f5g3_2 + f6g2 + f7g1_2 + f8g0 + f9g9_38
|
|
||||||
h9 := f0g9 + f1g8 + f2g7 + f3g6 + f4g5 + f5g4 + f6g3 + f7g2 + f8g1 + f9g0
|
|
||||||
var carry [10]int64
|
|
||||||
|
|
||||||
// |h0| <= (1.1*1.1*2^52*(1+19+19+19+19)+1.1*1.1*2^50*(38+38+38+38+38))
|
|
||||||
// i.e. |h0| <= 1.2*2^59; narrower ranges for h2, h4, h6, h8
|
|
||||||
// |h1| <= (1.1*1.1*2^51*(1+1+19+19+19+19+19+19+19+19))
|
|
||||||
// i.e. |h1| <= 1.5*2^58; narrower ranges for h3, h5, h7, h9
|
|
||||||
|
|
||||||
carry[0] = (h0 + (1 << 25)) >> 26
|
|
||||||
h1 += carry[0]
|
|
||||||
h0 -= carry[0] << 26
|
|
||||||
carry[4] = (h4 + (1 << 25)) >> 26
|
|
||||||
h5 += carry[4]
|
|
||||||
h4 -= carry[4] << 26
|
|
||||||
// |h0| <= 2^25
|
|
||||||
// |h4| <= 2^25
|
|
||||||
// |h1| <= 1.51*2^58
|
|
||||||
// |h5| <= 1.51*2^58
|
|
||||||
|
|
||||||
carry[1] = (h1 + (1 << 24)) >> 25
|
|
||||||
h2 += carry[1]
|
|
||||||
h1 -= carry[1] << 25
|
|
||||||
carry[5] = (h5 + (1 << 24)) >> 25
|
|
||||||
h6 += carry[5]
|
|
||||||
h5 -= carry[5] << 25
|
|
||||||
// |h1| <= 2^24; from now on fits into int32
|
|
||||||
// |h5| <= 2^24; from now on fits into int32
|
|
||||||
// |h2| <= 1.21*2^59
|
|
||||||
// |h6| <= 1.21*2^59
|
|
||||||
|
|
||||||
carry[2] = (h2 + (1 << 25)) >> 26
|
|
||||||
h3 += carry[2]
|
|
||||||
h2 -= carry[2] << 26
|
|
||||||
carry[6] = (h6 + (1 << 25)) >> 26
|
|
||||||
h7 += carry[6]
|
|
||||||
h6 -= carry[6] << 26
|
|
||||||
// |h2| <= 2^25; from now on fits into int32 unchanged
|
|
||||||
// |h6| <= 2^25; from now on fits into int32 unchanged
|
|
||||||
// |h3| <= 1.51*2^58
|
|
||||||
// |h7| <= 1.51*2^58
|
|
||||||
|
|
||||||
carry[3] = (h3 + (1 << 24)) >> 25
|
|
||||||
h4 += carry[3]
|
|
||||||
h3 -= carry[3] << 25
|
|
||||||
carry[7] = (h7 + (1 << 24)) >> 25
|
|
||||||
h8 += carry[7]
|
|
||||||
h7 -= carry[7] << 25
|
|
||||||
// |h3| <= 2^24; from now on fits into int32 unchanged
|
|
||||||
// |h7| <= 2^24; from now on fits into int32 unchanged
|
|
||||||
// |h4| <= 1.52*2^33
|
|
||||||
// |h8| <= 1.52*2^33
|
|
||||||
|
|
||||||
carry[4] = (h4 + (1 << 25)) >> 26
|
|
||||||
h5 += carry[4]
|
|
||||||
h4 -= carry[4] << 26
|
|
||||||
carry[8] = (h8 + (1 << 25)) >> 26
|
|
||||||
h9 += carry[8]
|
|
||||||
h8 -= carry[8] << 26
|
|
||||||
// |h4| <= 2^25; from now on fits into int32 unchanged
|
|
||||||
// |h8| <= 2^25; from now on fits into int32 unchanged
|
|
||||||
// |h5| <= 1.01*2^24
|
|
||||||
// |h9| <= 1.51*2^58
|
|
||||||
|
|
||||||
carry[9] = (h9 + (1 << 24)) >> 25
|
|
||||||
h0 += carry[9] * 19
|
|
||||||
h9 -= carry[9] << 25
|
|
||||||
// |h9| <= 2^24; from now on fits into int32 unchanged
|
|
||||||
// |h0| <= 1.8*2^37
|
|
||||||
|
|
||||||
carry[0] = (h0 + (1 << 25)) >> 26
|
|
||||||
h1 += carry[0]
|
|
||||||
h0 -= carry[0] << 26
|
|
||||||
// |h0| <= 2^25; from now on fits into int32 unchanged
|
|
||||||
// |h1| <= 1.01*2^24
|
|
||||||
|
|
||||||
h[0] = int32(h0)
|
|
||||||
h[1] = int32(h1)
|
|
||||||
h[2] = int32(h2)
|
|
||||||
h[3] = int32(h3)
|
|
||||||
h[4] = int32(h4)
|
|
||||||
h[5] = int32(h5)
|
|
||||||
h[6] = int32(h6)
|
|
||||||
h[7] = int32(h7)
|
|
||||||
h[8] = int32(h8)
|
|
||||||
h[9] = int32(h9)
|
|
||||||
}
|
|
||||||
|
|
||||||
// feSquare calculates h = f*f. Can overlap h with f.
|
|
||||||
//
|
|
||||||
// Preconditions:
|
|
||||||
// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
|
|
||||||
//
|
|
||||||
// Postconditions:
|
|
||||||
// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
|
|
||||||
func feSquare(h, f *fieldElement) {
|
|
||||||
f0 := f[0]
|
|
||||||
f1 := f[1]
|
|
||||||
f2 := f[2]
|
|
||||||
f3 := f[3]
|
|
||||||
f4 := f[4]
|
|
||||||
f5 := f[5]
|
|
||||||
f6 := f[6]
|
|
||||||
f7 := f[7]
|
|
||||||
f8 := f[8]
|
|
||||||
f9 := f[9]
|
|
||||||
f0_2 := 2 * f0
|
|
||||||
f1_2 := 2 * f1
|
|
||||||
f2_2 := 2 * f2
|
|
||||||
f3_2 := 2 * f3
|
|
||||||
f4_2 := 2 * f4
|
|
||||||
f5_2 := 2 * f5
|
|
||||||
f6_2 := 2 * f6
|
|
||||||
f7_2 := 2 * f7
|
|
||||||
f5_38 := 38 * f5 // 1.31*2^30
|
|
||||||
f6_19 := 19 * f6 // 1.31*2^30
|
|
||||||
f7_38 := 38 * f7 // 1.31*2^30
|
|
||||||
f8_19 := 19 * f8 // 1.31*2^30
|
|
||||||
f9_38 := 38 * f9 // 1.31*2^30
|
|
||||||
f0f0 := int64(f0) * int64(f0)
|
|
||||||
f0f1_2 := int64(f0_2) * int64(f1)
|
|
||||||
f0f2_2 := int64(f0_2) * int64(f2)
|
|
||||||
f0f3_2 := int64(f0_2) * int64(f3)
|
|
||||||
f0f4_2 := int64(f0_2) * int64(f4)
|
|
||||||
f0f5_2 := int64(f0_2) * int64(f5)
|
|
||||||
f0f6_2 := int64(f0_2) * int64(f6)
|
|
||||||
f0f7_2 := int64(f0_2) * int64(f7)
|
|
||||||
f0f8_2 := int64(f0_2) * int64(f8)
|
|
||||||
f0f9_2 := int64(f0_2) * int64(f9)
|
|
||||||
f1f1_2 := int64(f1_2) * int64(f1)
|
|
||||||
f1f2_2 := int64(f1_2) * int64(f2)
|
|
||||||
f1f3_4 := int64(f1_2) * int64(f3_2)
|
|
||||||
f1f4_2 := int64(f1_2) * int64(f4)
|
|
||||||
f1f5_4 := int64(f1_2) * int64(f5_2)
|
|
||||||
f1f6_2 := int64(f1_2) * int64(f6)
|
|
||||||
f1f7_4 := int64(f1_2) * int64(f7_2)
|
|
||||||
f1f8_2 := int64(f1_2) * int64(f8)
|
|
||||||
f1f9_76 := int64(f1_2) * int64(f9_38)
|
|
||||||
f2f2 := int64(f2) * int64(f2)
|
|
||||||
f2f3_2 := int64(f2_2) * int64(f3)
|
|
||||||
f2f4_2 := int64(f2_2) * int64(f4)
|
|
||||||
f2f5_2 := int64(f2_2) * int64(f5)
|
|
||||||
f2f6_2 := int64(f2_2) * int64(f6)
|
|
||||||
f2f7_2 := int64(f2_2) * int64(f7)
|
|
||||||
f2f8_38 := int64(f2_2) * int64(f8_19)
|
|
||||||
f2f9_38 := int64(f2) * int64(f9_38)
|
|
||||||
f3f3_2 := int64(f3_2) * int64(f3)
|
|
||||||
f3f4_2 := int64(f3_2) * int64(f4)
|
|
||||||
f3f5_4 := int64(f3_2) * int64(f5_2)
|
|
||||||
f3f6_2 := int64(f3_2) * int64(f6)
|
|
||||||
f3f7_76 := int64(f3_2) * int64(f7_38)
|
|
||||||
f3f8_38 := int64(f3_2) * int64(f8_19)
|
|
||||||
f3f9_76 := int64(f3_2) * int64(f9_38)
|
|
||||||
f4f4 := int64(f4) * int64(f4)
|
|
||||||
f4f5_2 := int64(f4_2) * int64(f5)
|
|
||||||
f4f6_38 := int64(f4_2) * int64(f6_19)
|
|
||||||
f4f7_38 := int64(f4) * int64(f7_38)
|
|
||||||
f4f8_38 := int64(f4_2) * int64(f8_19)
|
|
||||||
f4f9_38 := int64(f4) * int64(f9_38)
|
|
||||||
f5f5_38 := int64(f5) * int64(f5_38)
|
|
||||||
f5f6_38 := int64(f5_2) * int64(f6_19)
|
|
||||||
f5f7_76 := int64(f5_2) * int64(f7_38)
|
|
||||||
f5f8_38 := int64(f5_2) * int64(f8_19)
|
|
||||||
f5f9_76 := int64(f5_2) * int64(f9_38)
|
|
||||||
f6f6_19 := int64(f6) * int64(f6_19)
|
|
||||||
f6f7_38 := int64(f6) * int64(f7_38)
|
|
||||||
f6f8_38 := int64(f6_2) * int64(f8_19)
|
|
||||||
f6f9_38 := int64(f6) * int64(f9_38)
|
|
||||||
f7f7_38 := int64(f7) * int64(f7_38)
|
|
||||||
f7f8_38 := int64(f7_2) * int64(f8_19)
|
|
||||||
f7f9_76 := int64(f7_2) * int64(f9_38)
|
|
||||||
f8f8_19 := int64(f8) * int64(f8_19)
|
|
||||||
f8f9_38 := int64(f8) * int64(f9_38)
|
|
||||||
f9f9_38 := int64(f9) * int64(f9_38)
|
|
||||||
h0 := f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38
|
|
||||||
h1 := f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38
|
|
||||||
h2 := f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19
|
|
||||||
h3 := f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38
|
|
||||||
h4 := f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38
|
|
||||||
h5 := f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38
|
|
||||||
h6 := f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19
|
|
||||||
h7 := f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38
|
|
||||||
h8 := f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38
|
|
||||||
h9 := f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2
|
|
||||||
var carry [10]int64
|
|
||||||
|
|
||||||
carry[0] = (h0 + (1 << 25)) >> 26
|
|
||||||
h1 += carry[0]
|
|
||||||
h0 -= carry[0] << 26
|
|
||||||
carry[4] = (h4 + (1 << 25)) >> 26
|
|
||||||
h5 += carry[4]
|
|
||||||
h4 -= carry[4] << 26
|
|
||||||
|
|
||||||
carry[1] = (h1 + (1 << 24)) >> 25
|
|
||||||
h2 += carry[1]
|
|
||||||
h1 -= carry[1] << 25
|
|
||||||
carry[5] = (h5 + (1 << 24)) >> 25
|
|
||||||
h6 += carry[5]
|
|
||||||
h5 -= carry[5] << 25
|
|
||||||
|
|
||||||
carry[2] = (h2 + (1 << 25)) >> 26
|
|
||||||
h3 += carry[2]
|
|
||||||
h2 -= carry[2] << 26
|
|
||||||
carry[6] = (h6 + (1 << 25)) >> 26
|
|
||||||
h7 += carry[6]
|
|
||||||
h6 -= carry[6] << 26
|
|
||||||
|
|
||||||
carry[3] = (h3 + (1 << 24)) >> 25
|
|
||||||
h4 += carry[3]
|
|
||||||
h3 -= carry[3] << 25
|
|
||||||
carry[7] = (h7 + (1 << 24)) >> 25
|
|
||||||
h8 += carry[7]
|
|
||||||
h7 -= carry[7] << 25
|
|
||||||
|
|
||||||
carry[4] = (h4 + (1 << 25)) >> 26
|
|
||||||
h5 += carry[4]
|
|
||||||
h4 -= carry[4] << 26
|
|
||||||
carry[8] = (h8 + (1 << 25)) >> 26
|
|
||||||
h9 += carry[8]
|
|
||||||
h8 -= carry[8] << 26
|
|
||||||
|
|
||||||
carry[9] = (h9 + (1 << 24)) >> 25
|
|
||||||
h0 += carry[9] * 19
|
|
||||||
h9 -= carry[9] << 25
|
|
||||||
|
|
||||||
carry[0] = (h0 + (1 << 25)) >> 26
|
|
||||||
h1 += carry[0]
|
|
||||||
h0 -= carry[0] << 26
|
|
||||||
|
|
||||||
h[0] = int32(h0)
|
|
||||||
h[1] = int32(h1)
|
|
||||||
h[2] = int32(h2)
|
|
||||||
h[3] = int32(h3)
|
|
||||||
h[4] = int32(h4)
|
|
||||||
h[5] = int32(h5)
|
|
||||||
h[6] = int32(h6)
|
|
||||||
h[7] = int32(h7)
|
|
||||||
h[8] = int32(h8)
|
|
||||||
h[9] = int32(h9)
|
|
||||||
}
|
|
||||||
|
|
||||||
// feMul121666 calculates h = f * 121666. Can overlap h with f.
|
|
||||||
//
|
|
||||||
// Preconditions:
|
|
||||||
// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
|
|
||||||
//
|
|
||||||
// Postconditions:
|
|
||||||
// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
|
|
||||||
func feMul121666(h, f *fieldElement) {
|
|
||||||
h0 := int64(f[0]) * 121666
|
|
||||||
h1 := int64(f[1]) * 121666
|
|
||||||
h2 := int64(f[2]) * 121666
|
|
||||||
h3 := int64(f[3]) * 121666
|
|
||||||
h4 := int64(f[4]) * 121666
|
|
||||||
h5 := int64(f[5]) * 121666
|
|
||||||
h6 := int64(f[6]) * 121666
|
|
||||||
h7 := int64(f[7]) * 121666
|
|
||||||
h8 := int64(f[8]) * 121666
|
|
||||||
h9 := int64(f[9]) * 121666
|
|
||||||
var carry [10]int64
|
|
||||||
|
|
||||||
carry[9] = (h9 + (1 << 24)) >> 25
|
|
||||||
h0 += carry[9] * 19
|
|
||||||
h9 -= carry[9] << 25
|
|
||||||
carry[1] = (h1 + (1 << 24)) >> 25
|
|
||||||
h2 += carry[1]
|
|
||||||
h1 -= carry[1] << 25
|
|
||||||
carry[3] = (h3 + (1 << 24)) >> 25
|
|
||||||
h4 += carry[3]
|
|
||||||
h3 -= carry[3] << 25
|
|
||||||
carry[5] = (h5 + (1 << 24)) >> 25
|
|
||||||
h6 += carry[5]
|
|
||||||
h5 -= carry[5] << 25
|
|
||||||
carry[7] = (h7 + (1 << 24)) >> 25
|
|
||||||
h8 += carry[7]
|
|
||||||
h7 -= carry[7] << 25
|
|
||||||
|
|
||||||
carry[0] = (h0 + (1 << 25)) >> 26
|
|
||||||
h1 += carry[0]
|
|
||||||
h0 -= carry[0] << 26
|
|
||||||
carry[2] = (h2 + (1 << 25)) >> 26
|
|
||||||
h3 += carry[2]
|
|
||||||
h2 -= carry[2] << 26
|
|
||||||
carry[4] = (h4 + (1 << 25)) >> 26
|
|
||||||
h5 += carry[4]
|
|
||||||
h4 -= carry[4] << 26
|
|
||||||
carry[6] = (h6 + (1 << 25)) >> 26
|
|
||||||
h7 += carry[6]
|
|
||||||
h6 -= carry[6] << 26
|
|
||||||
carry[8] = (h8 + (1 << 25)) >> 26
|
|
||||||
h9 += carry[8]
|
|
||||||
h8 -= carry[8] << 26
|
|
||||||
|
|
||||||
h[0] = int32(h0)
|
|
||||||
h[1] = int32(h1)
|
|
||||||
h[2] = int32(h2)
|
|
||||||
h[3] = int32(h3)
|
|
||||||
h[4] = int32(h4)
|
|
||||||
h[5] = int32(h5)
|
|
||||||
h[6] = int32(h6)
|
|
||||||
h[7] = int32(h7)
|
|
||||||
h[8] = int32(h8)
|
|
||||||
h[9] = int32(h9)
|
|
||||||
}
|
|
||||||
|
|
||||||
// feInvert sets out = z^-1.
|
|
||||||
func feInvert(out, z *fieldElement) {
|
|
||||||
var t0, t1, t2, t3 fieldElement
|
|
||||||
var i int
|
|
||||||
|
|
||||||
feSquare(&t0, z)
|
|
||||||
for i = 1; i < 1; i++ {
|
|
||||||
feSquare(&t0, &t0)
|
|
||||||
}
|
|
||||||
feSquare(&t1, &t0)
|
|
||||||
for i = 1; i < 2; i++ {
|
|
||||||
feSquare(&t1, &t1)
|
|
||||||
}
|
|
||||||
feMul(&t1, z, &t1)
|
|
||||||
feMul(&t0, &t0, &t1)
|
|
||||||
feSquare(&t2, &t0)
|
|
||||||
for i = 1; i < 1; i++ {
|
|
||||||
feSquare(&t2, &t2)
|
|
||||||
}
|
|
||||||
feMul(&t1, &t1, &t2)
|
|
||||||
feSquare(&t2, &t1)
|
|
||||||
for i = 1; i < 5; i++ {
|
|
||||||
feSquare(&t2, &t2)
|
|
||||||
}
|
|
||||||
feMul(&t1, &t2, &t1)
|
|
||||||
feSquare(&t2, &t1)
|
|
||||||
for i = 1; i < 10; i++ {
|
|
||||||
feSquare(&t2, &t2)
|
|
||||||
}
|
|
||||||
feMul(&t2, &t2, &t1)
|
|
||||||
feSquare(&t3, &t2)
|
|
||||||
for i = 1; i < 20; i++ {
|
|
||||||
feSquare(&t3, &t3)
|
|
||||||
}
|
|
||||||
feMul(&t2, &t3, &t2)
|
|
||||||
feSquare(&t2, &t2)
|
|
||||||
for i = 1; i < 10; i++ {
|
|
||||||
feSquare(&t2, &t2)
|
|
||||||
}
|
|
||||||
feMul(&t1, &t2, &t1)
|
|
||||||
feSquare(&t2, &t1)
|
|
||||||
for i = 1; i < 50; i++ {
|
|
||||||
feSquare(&t2, &t2)
|
|
||||||
}
|
|
||||||
feMul(&t2, &t2, &t1)
|
|
||||||
feSquare(&t3, &t2)
|
|
||||||
for i = 1; i < 100; i++ {
|
|
||||||
feSquare(&t3, &t3)
|
|
||||||
}
|
|
||||||
feMul(&t2, &t3, &t2)
|
|
||||||
feSquare(&t2, &t2)
|
|
||||||
for i = 1; i < 50; i++ {
|
|
||||||
feSquare(&t2, &t2)
|
|
||||||
}
|
|
||||||
feMul(&t1, &t2, &t1)
|
|
||||||
feSquare(&t1, &t1)
|
|
||||||
for i = 1; i < 5; i++ {
|
|
||||||
feSquare(&t1, &t1)
|
|
||||||
}
|
|
||||||
feMul(out, &t1, &t0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func scalarMultGeneric(out, in, base *[32]byte) {
|
|
||||||
var e [32]byte
|
|
||||||
|
|
||||||
copy(e[:], in[:])
|
|
||||||
e[0] &= 248
|
|
||||||
e[31] &= 127
|
|
||||||
e[31] |= 64
|
|
||||||
|
|
||||||
var x1, x2, z2, x3, z3, tmp0, tmp1 fieldElement
|
|
||||||
feFromBytes(&x1, base)
|
|
||||||
feOne(&x2)
|
|
||||||
feCopy(&x3, &x1)
|
|
||||||
feOne(&z3)
|
|
||||||
|
|
||||||
swap := int32(0)
|
|
||||||
for pos := 254; pos >= 0; pos-- {
|
|
||||||
b := e[pos/8] >> uint(pos&7)
|
|
||||||
b &= 1
|
|
||||||
swap ^= int32(b)
|
|
||||||
feCSwap(&x2, &x3, swap)
|
|
||||||
feCSwap(&z2, &z3, swap)
|
|
||||||
swap = int32(b)
|
|
||||||
|
|
||||||
feSub(&tmp0, &x3, &z3)
|
|
||||||
feSub(&tmp1, &x2, &z2)
|
|
||||||
feAdd(&x2, &x2, &z2)
|
|
||||||
feAdd(&z2, &x3, &z3)
|
|
||||||
feMul(&z3, &tmp0, &x2)
|
|
||||||
feMul(&z2, &z2, &tmp1)
|
|
||||||
feSquare(&tmp0, &tmp1)
|
|
||||||
feSquare(&tmp1, &x2)
|
|
||||||
feAdd(&x3, &z3, &z2)
|
|
||||||
feSub(&z2, &z3, &z2)
|
|
||||||
feMul(&x2, &tmp1, &tmp0)
|
|
||||||
feSub(&tmp1, &tmp1, &tmp0)
|
|
||||||
feSquare(&z2, &z2)
|
|
||||||
feMul121666(&z3, &tmp1)
|
|
||||||
feSquare(&x3, &x3)
|
|
||||||
feAdd(&tmp0, &tmp0, &z3)
|
|
||||||
feMul(&z3, &x1, &z2)
|
|
||||||
feMul(&z2, &tmp1, &tmp0)
|
|
||||||
}
|
|
||||||
|
|
||||||
feCSwap(&x2, &x3, swap)
|
|
||||||
feCSwap(&z2, &z3, swap)
|
|
||||||
|
|
||||||
feInvert(&z2, &z2)
|
|
||||||
feMul(&x2, &x2, &z2)
|
|
||||||
feToBytes(out, &x2)
|
|
||||||
}
|
|
11
vendor/golang.org/x/crypto/curve25519/curve25519_noasm.go
generated
vendored
11
vendor/golang.org/x/crypto/curve25519/curve25519_noasm.go
generated
vendored
@ -1,11 +0,0 @@
|
|||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build !amd64 gccgo appengine purego
|
|
||||||
|
|
||||||
package curve25519
|
|
||||||
|
|
||||||
func scalarMult(out, in, base *[32]byte) {
|
|
||||||
scalarMultGeneric(out, in, base)
|
|
||||||
}
|
|
23
vendor/golang.org/x/crypto/curve25519/doc.go
generated
vendored
Normal file
23
vendor/golang.org/x/crypto/curve25519/doc.go
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package curve25519 provides an implementation of scalar multiplication on
|
||||||
|
// the elliptic curve known as curve25519. See https://cr.yp.to/ecdh.html
|
||||||
|
package curve25519 // import "golang.org/x/crypto/curve25519"
|
||||||
|
|
||||||
|
// basePoint is the x coordinate of the generator of the curve.
|
||||||
|
var basePoint = [32]byte{9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
|
|
||||||
|
// ScalarMult sets dst to the product in*base where dst and base are the x
|
||||||
|
// coordinates of group points and all values are in little-endian form.
|
||||||
|
func ScalarMult(dst, in, base *[32]byte) {
|
||||||
|
scalarMult(dst, in, base)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ScalarBaseMult sets dst to the product in*base where dst and base are the x
|
||||||
|
// coordinates of group points, base is the standard generator and all values
|
||||||
|
// are in little-endian form.
|
||||||
|
func ScalarBaseMult(dst, in *[32]byte) {
|
||||||
|
ScalarMult(dst, in, &basePoint)
|
||||||
|
}
|
73
vendor/golang.org/x/crypto/curve25519/freeze_amd64.s
generated
vendored
Normal file
73
vendor/golang.org/x/crypto/curve25519/freeze_amd64.s
generated
vendored
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// This code was translated into a form compatible with 6a from the public
|
||||||
|
// domain sources in SUPERCOP: https://bench.cr.yp.to/supercop.html
|
||||||
|
|
||||||
|
// +build amd64,!gccgo,!appengine
|
||||||
|
|
||||||
|
#include "const_amd64.h"
|
||||||
|
|
||||||
|
// func freeze(inout *[5]uint64)
|
||||||
|
TEXT ·freeze(SB),7,$0-8
|
||||||
|
MOVQ inout+0(FP), DI
|
||||||
|
|
||||||
|
MOVQ 0(DI),SI
|
||||||
|
MOVQ 8(DI),DX
|
||||||
|
MOVQ 16(DI),CX
|
||||||
|
MOVQ 24(DI),R8
|
||||||
|
MOVQ 32(DI),R9
|
||||||
|
MOVQ $REDMASK51,AX
|
||||||
|
MOVQ AX,R10
|
||||||
|
SUBQ $18,R10
|
||||||
|
MOVQ $3,R11
|
||||||
|
REDUCELOOP:
|
||||||
|
MOVQ SI,R12
|
||||||
|
SHRQ $51,R12
|
||||||
|
ANDQ AX,SI
|
||||||
|
ADDQ R12,DX
|
||||||
|
MOVQ DX,R12
|
||||||
|
SHRQ $51,R12
|
||||||
|
ANDQ AX,DX
|
||||||
|
ADDQ R12,CX
|
||||||
|
MOVQ CX,R12
|
||||||
|
SHRQ $51,R12
|
||||||
|
ANDQ AX,CX
|
||||||
|
ADDQ R12,R8
|
||||||
|
MOVQ R8,R12
|
||||||
|
SHRQ $51,R12
|
||||||
|
ANDQ AX,R8
|
||||||
|
ADDQ R12,R9
|
||||||
|
MOVQ R9,R12
|
||||||
|
SHRQ $51,R12
|
||||||
|
ANDQ AX,R9
|
||||||
|
IMUL3Q $19,R12,R12
|
||||||
|
ADDQ R12,SI
|
||||||
|
SUBQ $1,R11
|
||||||
|
JA REDUCELOOP
|
||||||
|
MOVQ $1,R12
|
||||||
|
CMPQ R10,SI
|
||||||
|
CMOVQLT R11,R12
|
||||||
|
CMPQ AX,DX
|
||||||
|
CMOVQNE R11,R12
|
||||||
|
CMPQ AX,CX
|
||||||
|
CMOVQNE R11,R12
|
||||||
|
CMPQ AX,R8
|
||||||
|
CMOVQNE R11,R12
|
||||||
|
CMPQ AX,R9
|
||||||
|
CMOVQNE R11,R12
|
||||||
|
NEGQ R12
|
||||||
|
ANDQ R12,AX
|
||||||
|
ANDQ R12,R10
|
||||||
|
SUBQ R10,SI
|
||||||
|
SUBQ AX,DX
|
||||||
|
SUBQ AX,CX
|
||||||
|
SUBQ AX,R8
|
||||||
|
SUBQ AX,R9
|
||||||
|
MOVQ SI,0(DI)
|
||||||
|
MOVQ DX,8(DI)
|
||||||
|
MOVQ CX,16(DI)
|
||||||
|
MOVQ R8,24(DI)
|
||||||
|
MOVQ R9,32(DI)
|
||||||
|
RET
|
@ -5,84 +5,9 @@
|
|||||||
// This code was translated into a form compatible with 6a from the public
|
// This code was translated into a form compatible with 6a from the public
|
||||||
// domain sources in SUPERCOP: https://bench.cr.yp.to/supercop.html
|
// domain sources in SUPERCOP: https://bench.cr.yp.to/supercop.html
|
||||||
|
|
||||||
// +build amd64,!gccgo,!appengine,!purego
|
// +build amd64,!gccgo,!appengine
|
||||||
|
|
||||||
#define REDMASK51 0x0007FFFFFFFFFFFF
|
#include "const_amd64.h"
|
||||||
|
|
||||||
// These constants cannot be encoded in non-MOVQ immediates.
|
|
||||||
// We access them directly from memory instead.
|
|
||||||
|
|
||||||
DATA ·_121666_213(SB)/8, $996687872
|
|
||||||
GLOBL ·_121666_213(SB), 8, $8
|
|
||||||
|
|
||||||
DATA ·_2P0(SB)/8, $0xFFFFFFFFFFFDA
|
|
||||||
GLOBL ·_2P0(SB), 8, $8
|
|
||||||
|
|
||||||
DATA ·_2P1234(SB)/8, $0xFFFFFFFFFFFFE
|
|
||||||
GLOBL ·_2P1234(SB), 8, $8
|
|
||||||
|
|
||||||
// func freeze(inout *[5]uint64)
|
|
||||||
TEXT ·freeze(SB),7,$0-8
|
|
||||||
MOVQ inout+0(FP), DI
|
|
||||||
|
|
||||||
MOVQ 0(DI),SI
|
|
||||||
MOVQ 8(DI),DX
|
|
||||||
MOVQ 16(DI),CX
|
|
||||||
MOVQ 24(DI),R8
|
|
||||||
MOVQ 32(DI),R9
|
|
||||||
MOVQ $REDMASK51,AX
|
|
||||||
MOVQ AX,R10
|
|
||||||
SUBQ $18,R10
|
|
||||||
MOVQ $3,R11
|
|
||||||
REDUCELOOP:
|
|
||||||
MOVQ SI,R12
|
|
||||||
SHRQ $51,R12
|
|
||||||
ANDQ AX,SI
|
|
||||||
ADDQ R12,DX
|
|
||||||
MOVQ DX,R12
|
|
||||||
SHRQ $51,R12
|
|
||||||
ANDQ AX,DX
|
|
||||||
ADDQ R12,CX
|
|
||||||
MOVQ CX,R12
|
|
||||||
SHRQ $51,R12
|
|
||||||
ANDQ AX,CX
|
|
||||||
ADDQ R12,R8
|
|
||||||
MOVQ R8,R12
|
|
||||||
SHRQ $51,R12
|
|
||||||
ANDQ AX,R8
|
|
||||||
ADDQ R12,R9
|
|
||||||
MOVQ R9,R12
|
|
||||||
SHRQ $51,R12
|
|
||||||
ANDQ AX,R9
|
|
||||||
IMUL3Q $19,R12,R12
|
|
||||||
ADDQ R12,SI
|
|
||||||
SUBQ $1,R11
|
|
||||||
JA REDUCELOOP
|
|
||||||
MOVQ $1,R12
|
|
||||||
CMPQ R10,SI
|
|
||||||
CMOVQLT R11,R12
|
|
||||||
CMPQ AX,DX
|
|
||||||
CMOVQNE R11,R12
|
|
||||||
CMPQ AX,CX
|
|
||||||
CMOVQNE R11,R12
|
|
||||||
CMPQ AX,R8
|
|
||||||
CMOVQNE R11,R12
|
|
||||||
CMPQ AX,R9
|
|
||||||
CMOVQNE R11,R12
|
|
||||||
NEGQ R12
|
|
||||||
ANDQ R12,AX
|
|
||||||
ANDQ R12,R10
|
|
||||||
SUBQ R10,SI
|
|
||||||
SUBQ AX,DX
|
|
||||||
SUBQ AX,CX
|
|
||||||
SUBQ AX,R8
|
|
||||||
SUBQ AX,R9
|
|
||||||
MOVQ SI,0(DI)
|
|
||||||
MOVQ DX,8(DI)
|
|
||||||
MOVQ CX,16(DI)
|
|
||||||
MOVQ R8,24(DI)
|
|
||||||
MOVQ R9,32(DI)
|
|
||||||
RET
|
|
||||||
|
|
||||||
// func ladderstep(inout *[5][5]uint64)
|
// func ladderstep(inout *[5][5]uint64)
|
||||||
TEXT ·ladderstep(SB),0,$296-8
|
TEXT ·ladderstep(SB),0,$296-8
|
||||||
@ -196,18 +121,18 @@ TEXT ·ladderstep(SB),0,$296-8
|
|||||||
ADDQ AX,R12
|
ADDQ AX,R12
|
||||||
ADCQ DX,R13
|
ADCQ DX,R13
|
||||||
MOVQ $REDMASK51,DX
|
MOVQ $REDMASK51,DX
|
||||||
SHLQ $13,SI,CX
|
SHLQ $13,CX:SI
|
||||||
ANDQ DX,SI
|
ANDQ DX,SI
|
||||||
SHLQ $13,R8,R9
|
SHLQ $13,R9:R8
|
||||||
ANDQ DX,R8
|
ANDQ DX,R8
|
||||||
ADDQ CX,R8
|
ADDQ CX,R8
|
||||||
SHLQ $13,R10,R11
|
SHLQ $13,R11:R10
|
||||||
ANDQ DX,R10
|
ANDQ DX,R10
|
||||||
ADDQ R9,R10
|
ADDQ R9,R10
|
||||||
SHLQ $13,R12,R13
|
SHLQ $13,R13:R12
|
||||||
ANDQ DX,R12
|
ANDQ DX,R12
|
||||||
ADDQ R11,R12
|
ADDQ R11,R12
|
||||||
SHLQ $13,R14,R15
|
SHLQ $13,R15:R14
|
||||||
ANDQ DX,R14
|
ANDQ DX,R14
|
||||||
ADDQ R13,R14
|
ADDQ R13,R14
|
||||||
IMUL3Q $19,R15,CX
|
IMUL3Q $19,R15,CX
|
||||||
@ -311,18 +236,18 @@ TEXT ·ladderstep(SB),0,$296-8
|
|||||||
ADDQ AX,R12
|
ADDQ AX,R12
|
||||||
ADCQ DX,R13
|
ADCQ DX,R13
|
||||||
MOVQ $REDMASK51,DX
|
MOVQ $REDMASK51,DX
|
||||||
SHLQ $13,SI,CX
|
SHLQ $13,CX:SI
|
||||||
ANDQ DX,SI
|
ANDQ DX,SI
|
||||||
SHLQ $13,R8,R9
|
SHLQ $13,R9:R8
|
||||||
ANDQ DX,R8
|
ANDQ DX,R8
|
||||||
ADDQ CX,R8
|
ADDQ CX,R8
|
||||||
SHLQ $13,R10,R11
|
SHLQ $13,R11:R10
|
||||||
ANDQ DX,R10
|
ANDQ DX,R10
|
||||||
ADDQ R9,R10
|
ADDQ R9,R10
|
||||||
SHLQ $13,R12,R13
|
SHLQ $13,R13:R12
|
||||||
ANDQ DX,R12
|
ANDQ DX,R12
|
||||||
ADDQ R11,R12
|
ADDQ R11,R12
|
||||||
SHLQ $13,R14,R15
|
SHLQ $13,R15:R14
|
||||||
ANDQ DX,R14
|
ANDQ DX,R14
|
||||||
ADDQ R13,R14
|
ADDQ R13,R14
|
||||||
IMUL3Q $19,R15,CX
|
IMUL3Q $19,R15,CX
|
||||||
@ -516,18 +441,18 @@ TEXT ·ladderstep(SB),0,$296-8
|
|||||||
ADDQ AX,R12
|
ADDQ AX,R12
|
||||||
ADCQ DX,R13
|
ADCQ DX,R13
|
||||||
MOVQ $REDMASK51,DX
|
MOVQ $REDMASK51,DX
|
||||||
SHLQ $13,SI,CX
|
SHLQ $13,CX:SI
|
||||||
ANDQ DX,SI
|
ANDQ DX,SI
|
||||||
SHLQ $13,R8,R9
|
SHLQ $13,R9:R8
|
||||||
ANDQ DX,R8
|
ANDQ DX,R8
|
||||||
ADDQ CX,R8
|
ADDQ CX,R8
|
||||||
SHLQ $13,R10,R11
|
SHLQ $13,R11:R10
|
||||||
ANDQ DX,R10
|
ANDQ DX,R10
|
||||||
ADDQ R9,R10
|
ADDQ R9,R10
|
||||||
SHLQ $13,R12,R13
|
SHLQ $13,R13:R12
|
||||||
ANDQ DX,R12
|
ANDQ DX,R12
|
||||||
ADDQ R11,R12
|
ADDQ R11,R12
|
||||||
SHLQ $13,R14,R15
|
SHLQ $13,R15:R14
|
||||||
ANDQ DX,R14
|
ANDQ DX,R14
|
||||||
ADDQ R13,R14
|
ADDQ R13,R14
|
||||||
IMUL3Q $19,R15,CX
|
IMUL3Q $19,R15,CX
|
||||||
@ -666,18 +591,18 @@ TEXT ·ladderstep(SB),0,$296-8
|
|||||||
ADDQ AX,R12
|
ADDQ AX,R12
|
||||||
ADCQ DX,R13
|
ADCQ DX,R13
|
||||||
MOVQ $REDMASK51,DX
|
MOVQ $REDMASK51,DX
|
||||||
SHLQ $13,SI,CX
|
SHLQ $13,CX:SI
|
||||||
ANDQ DX,SI
|
ANDQ DX,SI
|
||||||
SHLQ $13,R8,R9
|
SHLQ $13,R9:R8
|
||||||
ANDQ DX,R8
|
ANDQ DX,R8
|
||||||
ADDQ CX,R8
|
ADDQ CX,R8
|
||||||
SHLQ $13,R10,R11
|
SHLQ $13,R11:R10
|
||||||
ANDQ DX,R10
|
ANDQ DX,R10
|
||||||
ADDQ R9,R10
|
ADDQ R9,R10
|
||||||
SHLQ $13,R12,R13
|
SHLQ $13,R13:R12
|
||||||
ANDQ DX,R12
|
ANDQ DX,R12
|
||||||
ADDQ R11,R12
|
ADDQ R11,R12
|
||||||
SHLQ $13,R14,R15
|
SHLQ $13,R15:R14
|
||||||
ANDQ DX,R14
|
ANDQ DX,R14
|
||||||
ADDQ R13,R14
|
ADDQ R13,R14
|
||||||
IMUL3Q $19,R15,CX
|
IMUL3Q $19,R15,CX
|
||||||
@ -806,18 +731,18 @@ TEXT ·ladderstep(SB),0,$296-8
|
|||||||
ADDQ AX,R12
|
ADDQ AX,R12
|
||||||
ADCQ DX,R13
|
ADCQ DX,R13
|
||||||
MOVQ $REDMASK51,DX
|
MOVQ $REDMASK51,DX
|
||||||
SHLQ $13,SI,CX
|
SHLQ $13,CX:SI
|
||||||
ANDQ DX,SI
|
ANDQ DX,SI
|
||||||
SHLQ $13,R8,R9
|
SHLQ $13,R9:R8
|
||||||
ANDQ DX,R8
|
ANDQ DX,R8
|
||||||
ADDQ CX,R8
|
ADDQ CX,R8
|
||||||
SHLQ $13,R10,R11
|
SHLQ $13,R11:R10
|
||||||
ANDQ DX,R10
|
ANDQ DX,R10
|
||||||
ADDQ R9,R10
|
ADDQ R9,R10
|
||||||
SHLQ $13,R12,R13
|
SHLQ $13,R13:R12
|
||||||
ANDQ DX,R12
|
ANDQ DX,R12
|
||||||
ADDQ R11,R12
|
ADDQ R11,R12
|
||||||
SHLQ $13,R14,R15
|
SHLQ $13,R15:R14
|
||||||
ANDQ DX,R14
|
ANDQ DX,R14
|
||||||
ADDQ R13,R14
|
ADDQ R13,R14
|
||||||
IMUL3Q $19,R15,CX
|
IMUL3Q $19,R15,CX
|
||||||
@ -921,18 +846,18 @@ TEXT ·ladderstep(SB),0,$296-8
|
|||||||
ADDQ AX,R12
|
ADDQ AX,R12
|
||||||
ADCQ DX,R13
|
ADCQ DX,R13
|
||||||
MOVQ $REDMASK51,DX
|
MOVQ $REDMASK51,DX
|
||||||
SHLQ $13,SI,CX
|
SHLQ $13,CX:SI
|
||||||
ANDQ DX,SI
|
ANDQ DX,SI
|
||||||
SHLQ $13,R8,R9
|
SHLQ $13,R9:R8
|
||||||
ANDQ DX,R8
|
ANDQ DX,R8
|
||||||
ADDQ CX,R8
|
ADDQ CX,R8
|
||||||
SHLQ $13,R10,R11
|
SHLQ $13,R11:R10
|
||||||
ANDQ DX,R10
|
ANDQ DX,R10
|
||||||
ADDQ R9,R10
|
ADDQ R9,R10
|
||||||
SHLQ $13,R12,R13
|
SHLQ $13,R13:R12
|
||||||
ANDQ DX,R12
|
ANDQ DX,R12
|
||||||
ADDQ R11,R12
|
ADDQ R11,R12
|
||||||
SHLQ $13,R14,R15
|
SHLQ $13,R15:R14
|
||||||
ANDQ DX,R14
|
ANDQ DX,R14
|
||||||
ADDQ R13,R14
|
ADDQ R13,R14
|
||||||
IMUL3Q $19,R15,CX
|
IMUL3Q $19,R15,CX
|
||||||
@ -1071,18 +996,18 @@ TEXT ·ladderstep(SB),0,$296-8
|
|||||||
ADDQ AX,R12
|
ADDQ AX,R12
|
||||||
ADCQ DX,R13
|
ADCQ DX,R13
|
||||||
MOVQ $REDMASK51,DX
|
MOVQ $REDMASK51,DX
|
||||||
SHLQ $13,SI,CX
|
SHLQ $13,CX:SI
|
||||||
ANDQ DX,SI
|
ANDQ DX,SI
|
||||||
SHLQ $13,R8,R9
|
SHLQ $13,R9:R8
|
||||||
ANDQ DX,R8
|
ANDQ DX,R8
|
||||||
ADDQ CX,R8
|
ADDQ CX,R8
|
||||||
SHLQ $13,R10,R11
|
SHLQ $13,R11:R10
|
||||||
ANDQ DX,R10
|
ANDQ DX,R10
|
||||||
ADDQ R9,R10
|
ADDQ R9,R10
|
||||||
SHLQ $13,R12,R13
|
SHLQ $13,R13:R12
|
||||||
ANDQ DX,R12
|
ANDQ DX,R12
|
||||||
ADDQ R11,R12
|
ADDQ R11,R12
|
||||||
SHLQ $13,R14,R15
|
SHLQ $13,R15:R14
|
||||||
ANDQ DX,R14
|
ANDQ DX,R14
|
||||||
ADDQ R13,R14
|
ADDQ R13,R14
|
||||||
IMUL3Q $19,R15,CX
|
IMUL3Q $19,R15,CX
|
||||||
@ -1221,18 +1146,18 @@ TEXT ·ladderstep(SB),0,$296-8
|
|||||||
ADDQ AX,R12
|
ADDQ AX,R12
|
||||||
ADCQ DX,R13
|
ADCQ DX,R13
|
||||||
MOVQ $REDMASK51,DX
|
MOVQ $REDMASK51,DX
|
||||||
SHLQ $13,SI,CX
|
SHLQ $13,CX:SI
|
||||||
ANDQ DX,SI
|
ANDQ DX,SI
|
||||||
SHLQ $13,R8,R9
|
SHLQ $13,R9:R8
|
||||||
ANDQ DX,R8
|
ANDQ DX,R8
|
||||||
ADDQ CX,R8
|
ADDQ CX,R8
|
||||||
SHLQ $13,R10,R11
|
SHLQ $13,R11:R10
|
||||||
ANDQ DX,R10
|
ANDQ DX,R10
|
||||||
ADDQ R9,R10
|
ADDQ R9,R10
|
||||||
SHLQ $13,R12,R13
|
SHLQ $13,R13:R12
|
||||||
ANDQ DX,R12
|
ANDQ DX,R12
|
||||||
ADDQ R11,R12
|
ADDQ R11,R12
|
||||||
SHLQ $13,R14,R15
|
SHLQ $13,R15:R14
|
||||||
ANDQ DX,R14
|
ANDQ DX,R14
|
||||||
ADDQ R13,R14
|
ADDQ R13,R14
|
||||||
IMUL3Q $19,R15,CX
|
IMUL3Q $19,R15,CX
|
||||||
@ -1407,18 +1332,18 @@ TEXT ·ladderstep(SB),0,$296-8
|
|||||||
ADDQ AX,R12
|
ADDQ AX,R12
|
||||||
ADCQ DX,R13
|
ADCQ DX,R13
|
||||||
MOVQ $REDMASK51,DX
|
MOVQ $REDMASK51,DX
|
||||||
SHLQ $13,SI,CX
|
SHLQ $13,CX:SI
|
||||||
ANDQ DX,SI
|
ANDQ DX,SI
|
||||||
SHLQ $13,R8,R9
|
SHLQ $13,R9:R8
|
||||||
ANDQ DX,R8
|
ANDQ DX,R8
|
||||||
ADDQ CX,R8
|
ADDQ CX,R8
|
||||||
SHLQ $13,R10,R11
|
SHLQ $13,R11:R10
|
||||||
ANDQ DX,R10
|
ANDQ DX,R10
|
||||||
ADDQ R9,R10
|
ADDQ R9,R10
|
||||||
SHLQ $13,R12,R13
|
SHLQ $13,R13:R12
|
||||||
ANDQ DX,R12
|
ANDQ DX,R12
|
||||||
ADDQ R11,R12
|
ADDQ R11,R12
|
||||||
SHLQ $13,R14,R15
|
SHLQ $13,R15:R14
|
||||||
ANDQ DX,R14
|
ANDQ DX,R14
|
||||||
ADDQ R13,R14
|
ADDQ R13,R14
|
||||||
IMUL3Q $19,R15,CX
|
IMUL3Q $19,R15,CX
|
||||||
@ -1450,344 +1375,3 @@ TEXT ·ladderstep(SB),0,$296-8
|
|||||||
MOVQ AX,104(DI)
|
MOVQ AX,104(DI)
|
||||||
MOVQ R10,112(DI)
|
MOVQ R10,112(DI)
|
||||||
RET
|
RET
|
||||||
|
|
||||||
// func cswap(inout *[4][5]uint64, v uint64)
|
|
||||||
TEXT ·cswap(SB),7,$0
|
|
||||||
MOVQ inout+0(FP),DI
|
|
||||||
MOVQ v+8(FP),SI
|
|
||||||
|
|
||||||
SUBQ $1, SI
|
|
||||||
NOTQ SI
|
|
||||||
MOVQ SI, X15
|
|
||||||
PSHUFD $0x44, X15, X15
|
|
||||||
|
|
||||||
MOVOU 0(DI), X0
|
|
||||||
MOVOU 16(DI), X2
|
|
||||||
MOVOU 32(DI), X4
|
|
||||||
MOVOU 48(DI), X6
|
|
||||||
MOVOU 64(DI), X8
|
|
||||||
MOVOU 80(DI), X1
|
|
||||||
MOVOU 96(DI), X3
|
|
||||||
MOVOU 112(DI), X5
|
|
||||||
MOVOU 128(DI), X7
|
|
||||||
MOVOU 144(DI), X9
|
|
||||||
|
|
||||||
MOVO X1, X10
|
|
||||||
MOVO X3, X11
|
|
||||||
MOVO X5, X12
|
|
||||||
MOVO X7, X13
|
|
||||||
MOVO X9, X14
|
|
||||||
|
|
||||||
PXOR X0, X10
|
|
||||||
PXOR X2, X11
|
|
||||||
PXOR X4, X12
|
|
||||||
PXOR X6, X13
|
|
||||||
PXOR X8, X14
|
|
||||||
PAND X15, X10
|
|
||||||
PAND X15, X11
|
|
||||||
PAND X15, X12
|
|
||||||
PAND X15, X13
|
|
||||||
PAND X15, X14
|
|
||||||
PXOR X10, X0
|
|
||||||
PXOR X10, X1
|
|
||||||
PXOR X11, X2
|
|
||||||
PXOR X11, X3
|
|
||||||
PXOR X12, X4
|
|
||||||
PXOR X12, X5
|
|
||||||
PXOR X13, X6
|
|
||||||
PXOR X13, X7
|
|
||||||
PXOR X14, X8
|
|
||||||
PXOR X14, X9
|
|
||||||
|
|
||||||
MOVOU X0, 0(DI)
|
|
||||||
MOVOU X2, 16(DI)
|
|
||||||
MOVOU X4, 32(DI)
|
|
||||||
MOVOU X6, 48(DI)
|
|
||||||
MOVOU X8, 64(DI)
|
|
||||||
MOVOU X1, 80(DI)
|
|
||||||
MOVOU X3, 96(DI)
|
|
||||||
MOVOU X5, 112(DI)
|
|
||||||
MOVOU X7, 128(DI)
|
|
||||||
MOVOU X9, 144(DI)
|
|
||||||
RET
|
|
||||||
|
|
||||||
// func mul(dest, a, b *[5]uint64)
|
|
||||||
TEXT ·mul(SB),0,$16-24
|
|
||||||
MOVQ dest+0(FP), DI
|
|
||||||
MOVQ a+8(FP), SI
|
|
||||||
MOVQ b+16(FP), DX
|
|
||||||
|
|
||||||
MOVQ DX,CX
|
|
||||||
MOVQ 24(SI),DX
|
|
||||||
IMUL3Q $19,DX,AX
|
|
||||||
MOVQ AX,0(SP)
|
|
||||||
MULQ 16(CX)
|
|
||||||
MOVQ AX,R8
|
|
||||||
MOVQ DX,R9
|
|
||||||
MOVQ 32(SI),DX
|
|
||||||
IMUL3Q $19,DX,AX
|
|
||||||
MOVQ AX,8(SP)
|
|
||||||
MULQ 8(CX)
|
|
||||||
ADDQ AX,R8
|
|
||||||
ADCQ DX,R9
|
|
||||||
MOVQ 0(SI),AX
|
|
||||||
MULQ 0(CX)
|
|
||||||
ADDQ AX,R8
|
|
||||||
ADCQ DX,R9
|
|
||||||
MOVQ 0(SI),AX
|
|
||||||
MULQ 8(CX)
|
|
||||||
MOVQ AX,R10
|
|
||||||
MOVQ DX,R11
|
|
||||||
MOVQ 0(SI),AX
|
|
||||||
MULQ 16(CX)
|
|
||||||
MOVQ AX,R12
|
|
||||||
MOVQ DX,R13
|
|
||||||
MOVQ 0(SI),AX
|
|
||||||
MULQ 24(CX)
|
|
||||||
MOVQ AX,R14
|
|
||||||
MOVQ DX,R15
|
|
||||||
MOVQ 0(SI),AX
|
|
||||||
MULQ 32(CX)
|
|
||||||
MOVQ AX,BX
|
|
||||||
MOVQ DX,BP
|
|
||||||
MOVQ 8(SI),AX
|
|
||||||
MULQ 0(CX)
|
|
||||||
ADDQ AX,R10
|
|
||||||
ADCQ DX,R11
|
|
||||||
MOVQ 8(SI),AX
|
|
||||||
MULQ 8(CX)
|
|
||||||
ADDQ AX,R12
|
|
||||||
ADCQ DX,R13
|
|
||||||
MOVQ 8(SI),AX
|
|
||||||
MULQ 16(CX)
|
|
||||||
ADDQ AX,R14
|
|
||||||
ADCQ DX,R15
|
|
||||||
MOVQ 8(SI),AX
|
|
||||||
MULQ 24(CX)
|
|
||||||
ADDQ AX,BX
|
|
||||||
ADCQ DX,BP
|
|
||||||
MOVQ 8(SI),DX
|
|
||||||
IMUL3Q $19,DX,AX
|
|
||||||
MULQ 32(CX)
|
|
||||||
ADDQ AX,R8
|
|
||||||
ADCQ DX,R9
|
|
||||||
MOVQ 16(SI),AX
|
|
||||||
MULQ 0(CX)
|
|
||||||
ADDQ AX,R12
|
|
||||||
ADCQ DX,R13
|
|
||||||
MOVQ 16(SI),AX
|
|
||||||
MULQ 8(CX)
|
|
||||||
ADDQ AX,R14
|
|
||||||
ADCQ DX,R15
|
|
||||||
MOVQ 16(SI),AX
|
|
||||||
MULQ 16(CX)
|
|
||||||
ADDQ AX,BX
|
|
||||||
ADCQ DX,BP
|
|
||||||
MOVQ 16(SI),DX
|
|
||||||
IMUL3Q $19,DX,AX
|
|
||||||
MULQ 24(CX)
|
|
||||||
ADDQ AX,R8
|
|
||||||
ADCQ DX,R9
|
|
||||||
MOVQ 16(SI),DX
|
|
||||||
IMUL3Q $19,DX,AX
|
|
||||||
MULQ 32(CX)
|
|
||||||
ADDQ AX,R10
|
|
||||||
ADCQ DX,R11
|
|
||||||
MOVQ 24(SI),AX
|
|
||||||
MULQ 0(CX)
|
|
||||||
ADDQ AX,R14
|
|
||||||
ADCQ DX,R15
|
|
||||||
MOVQ 24(SI),AX
|
|
||||||
MULQ 8(CX)
|
|
||||||
ADDQ AX,BX
|
|
||||||
ADCQ DX,BP
|
|
||||||
MOVQ 0(SP),AX
|
|
||||||
MULQ 24(CX)
|
|
||||||
ADDQ AX,R10
|
|
||||||
ADCQ DX,R11
|
|
||||||
MOVQ 0(SP),AX
|
|
||||||
MULQ 32(CX)
|
|
||||||
ADDQ AX,R12
|
|
||||||
ADCQ DX,R13
|
|
||||||
MOVQ 32(SI),AX
|
|
||||||
MULQ 0(CX)
|
|
||||||
ADDQ AX,BX
|
|
||||||
ADCQ DX,BP
|
|
||||||
MOVQ 8(SP),AX
|
|
||||||
MULQ 16(CX)
|
|
||||||
ADDQ AX,R10
|
|
||||||
ADCQ DX,R11
|
|
||||||
MOVQ 8(SP),AX
|
|
||||||
MULQ 24(CX)
|
|
||||||
ADDQ AX,R12
|
|
||||||
ADCQ DX,R13
|
|
||||||
MOVQ 8(SP),AX
|
|
||||||
MULQ 32(CX)
|
|
||||||
ADDQ AX,R14
|
|
||||||
ADCQ DX,R15
|
|
||||||
MOVQ $REDMASK51,SI
|
|
||||||
SHLQ $13,R8,R9
|
|
||||||
ANDQ SI,R8
|
|
||||||
SHLQ $13,R10,R11
|
|
||||||
ANDQ SI,R10
|
|
||||||
ADDQ R9,R10
|
|
||||||
SHLQ $13,R12,R13
|
|
||||||
ANDQ SI,R12
|
|
||||||
ADDQ R11,R12
|
|
||||||
SHLQ $13,R14,R15
|
|
||||||
ANDQ SI,R14
|
|
||||||
ADDQ R13,R14
|
|
||||||
SHLQ $13,BX,BP
|
|
||||||
ANDQ SI,BX
|
|
||||||
ADDQ R15,BX
|
|
||||||
IMUL3Q $19,BP,DX
|
|
||||||
ADDQ DX,R8
|
|
||||||
MOVQ R8,DX
|
|
||||||
SHRQ $51,DX
|
|
||||||
ADDQ R10,DX
|
|
||||||
MOVQ DX,CX
|
|
||||||
SHRQ $51,DX
|
|
||||||
ANDQ SI,R8
|
|
||||||
ADDQ R12,DX
|
|
||||||
MOVQ DX,R9
|
|
||||||
SHRQ $51,DX
|
|
||||||
ANDQ SI,CX
|
|
||||||
ADDQ R14,DX
|
|
||||||
MOVQ DX,AX
|
|
||||||
SHRQ $51,DX
|
|
||||||
ANDQ SI,R9
|
|
||||||
ADDQ BX,DX
|
|
||||||
MOVQ DX,R10
|
|
||||||
SHRQ $51,DX
|
|
||||||
ANDQ SI,AX
|
|
||||||
IMUL3Q $19,DX,DX
|
|
||||||
ADDQ DX,R8
|
|
||||||
ANDQ SI,R10
|
|
||||||
MOVQ R8,0(DI)
|
|
||||||
MOVQ CX,8(DI)
|
|
||||||
MOVQ R9,16(DI)
|
|
||||||
MOVQ AX,24(DI)
|
|
||||||
MOVQ R10,32(DI)
|
|
||||||
RET
|
|
||||||
|
|
||||||
// func square(out, in *[5]uint64)
|
|
||||||
TEXT ·square(SB),7,$0-16
|
|
||||||
MOVQ out+0(FP), DI
|
|
||||||
MOVQ in+8(FP), SI
|
|
||||||
|
|
||||||
MOVQ 0(SI),AX
|
|
||||||
MULQ 0(SI)
|
|
||||||
MOVQ AX,CX
|
|
||||||
MOVQ DX,R8
|
|
||||||
MOVQ 0(SI),AX
|
|
||||||
SHLQ $1,AX
|
|
||||||
MULQ 8(SI)
|
|
||||||
MOVQ AX,R9
|
|
||||||
MOVQ DX,R10
|
|
||||||
MOVQ 0(SI),AX
|
|
||||||
SHLQ $1,AX
|
|
||||||
MULQ 16(SI)
|
|
||||||
MOVQ AX,R11
|
|
||||||
MOVQ DX,R12
|
|
||||||
MOVQ 0(SI),AX
|
|
||||||
SHLQ $1,AX
|
|
||||||
MULQ 24(SI)
|
|
||||||
MOVQ AX,R13
|
|
||||||
MOVQ DX,R14
|
|
||||||
MOVQ 0(SI),AX
|
|
||||||
SHLQ $1,AX
|
|
||||||
MULQ 32(SI)
|
|
||||||
MOVQ AX,R15
|
|
||||||
MOVQ DX,BX
|
|
||||||
MOVQ 8(SI),AX
|
|
||||||
MULQ 8(SI)
|
|
||||||
ADDQ AX,R11
|
|
||||||
ADCQ DX,R12
|
|
||||||
MOVQ 8(SI),AX
|
|
||||||
SHLQ $1,AX
|
|
||||||
MULQ 16(SI)
|
|
||||||
ADDQ AX,R13
|
|
||||||
ADCQ DX,R14
|
|
||||||
MOVQ 8(SI),AX
|
|
||||||
SHLQ $1,AX
|
|
||||||
MULQ 24(SI)
|
|
||||||
ADDQ AX,R15
|
|
||||||
ADCQ DX,BX
|
|
||||||
MOVQ 8(SI),DX
|
|
||||||
IMUL3Q $38,DX,AX
|
|
||||||
MULQ 32(SI)
|
|
||||||
ADDQ AX,CX
|
|
||||||
ADCQ DX,R8
|
|
||||||
MOVQ 16(SI),AX
|
|
||||||
MULQ 16(SI)
|
|
||||||
ADDQ AX,R15
|
|
||||||
ADCQ DX,BX
|
|
||||||
MOVQ 16(SI),DX
|
|
||||||
IMUL3Q $38,DX,AX
|
|
||||||
MULQ 24(SI)
|
|
||||||
ADDQ AX,CX
|
|
||||||
ADCQ DX,R8
|
|
||||||
MOVQ 16(SI),DX
|
|
||||||
IMUL3Q $38,DX,AX
|
|
||||||
MULQ 32(SI)
|
|
||||||
ADDQ AX,R9
|
|
||||||
ADCQ DX,R10
|
|
||||||
MOVQ 24(SI),DX
|
|
||||||
IMUL3Q $19,DX,AX
|
|
||||||
MULQ 24(SI)
|
|
||||||
ADDQ AX,R9
|
|
||||||
ADCQ DX,R10
|
|
||||||
MOVQ 24(SI),DX
|
|
||||||
IMUL3Q $38,DX,AX
|
|
||||||
MULQ 32(SI)
|
|
||||||
ADDQ AX,R11
|
|
||||||
ADCQ DX,R12
|
|
||||||
MOVQ 32(SI),DX
|
|
||||||
IMUL3Q $19,DX,AX
|
|
||||||
MULQ 32(SI)
|
|
||||||
ADDQ AX,R13
|
|
||||||
ADCQ DX,R14
|
|
||||||
MOVQ $REDMASK51,SI
|
|
||||||
SHLQ $13,CX,R8
|
|
||||||
ANDQ SI,CX
|
|
||||||
SHLQ $13,R9,R10
|
|
||||||
ANDQ SI,R9
|
|
||||||
ADDQ R8,R9
|
|
||||||
SHLQ $13,R11,R12
|
|
||||||
ANDQ SI,R11
|
|
||||||
ADDQ R10,R11
|
|
||||||
SHLQ $13,R13,R14
|
|
||||||
ANDQ SI,R13
|
|
||||||
ADDQ R12,R13
|
|
||||||
SHLQ $13,R15,BX
|
|
||||||
ANDQ SI,R15
|
|
||||||
ADDQ R14,R15
|
|
||||||
IMUL3Q $19,BX,DX
|
|
||||||
ADDQ DX,CX
|
|
||||||
MOVQ CX,DX
|
|
||||||
SHRQ $51,DX
|
|
||||||
ADDQ R9,DX
|
|
||||||
ANDQ SI,CX
|
|
||||||
MOVQ DX,R8
|
|
||||||
SHRQ $51,DX
|
|
||||||
ADDQ R11,DX
|
|
||||||
ANDQ SI,R8
|
|
||||||
MOVQ DX,R9
|
|
||||||
SHRQ $51,DX
|
|
||||||
ADDQ R13,DX
|
|
||||||
ANDQ SI,R9
|
|
||||||
MOVQ DX,AX
|
|
||||||
SHRQ $51,DX
|
|
||||||
ADDQ R15,DX
|
|
||||||
ANDQ SI,AX
|
|
||||||
MOVQ DX,R10
|
|
||||||
SHRQ $51,DX
|
|
||||||
IMUL3Q $19,DX,DX
|
|
||||||
ADDQ DX,CX
|
|
||||||
ANDQ SI,R10
|
|
||||||
MOVQ CX,0(DI)
|
|
||||||
MOVQ R8,8(DI)
|
|
||||||
MOVQ R9,16(DI)
|
|
||||||
MOVQ AX,24(DI)
|
|
||||||
MOVQ R10,32(DI)
|
|
||||||
RET
|
|
@ -2,7 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build amd64,!gccgo,!appengine,!purego
|
// +build amd64,!gccgo,!appengine
|
||||||
|
|
||||||
package curve25519
|
package curve25519
|
||||||
|
|
169
vendor/golang.org/x/crypto/curve25519/mul_amd64.s
generated
vendored
Normal file
169
vendor/golang.org/x/crypto/curve25519/mul_amd64.s
generated
vendored
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// This code was translated into a form compatible with 6a from the public
|
||||||
|
// domain sources in SUPERCOP: https://bench.cr.yp.to/supercop.html
|
||||||
|
|
||||||
|
// +build amd64,!gccgo,!appengine
|
||||||
|
|
||||||
|
#include "const_amd64.h"
|
||||||
|
|
||||||
|
// func mul(dest, a, b *[5]uint64)
|
||||||
|
TEXT ·mul(SB),0,$16-24
|
||||||
|
MOVQ dest+0(FP), DI
|
||||||
|
MOVQ a+8(FP), SI
|
||||||
|
MOVQ b+16(FP), DX
|
||||||
|
|
||||||
|
MOVQ DX,CX
|
||||||
|
MOVQ 24(SI),DX
|
||||||
|
IMUL3Q $19,DX,AX
|
||||||
|
MOVQ AX,0(SP)
|
||||||
|
MULQ 16(CX)
|
||||||
|
MOVQ AX,R8
|
||||||
|
MOVQ DX,R9
|
||||||
|
MOVQ 32(SI),DX
|
||||||
|
IMUL3Q $19,DX,AX
|
||||||
|
MOVQ AX,8(SP)
|
||||||
|
MULQ 8(CX)
|
||||||
|
ADDQ AX,R8
|
||||||
|
ADCQ DX,R9
|
||||||
|
MOVQ 0(SI),AX
|
||||||
|
MULQ 0(CX)
|
||||||
|
ADDQ AX,R8
|
||||||
|
ADCQ DX,R9
|
||||||
|
MOVQ 0(SI),AX
|
||||||
|
MULQ 8(CX)
|
||||||
|
MOVQ AX,R10
|
||||||
|
MOVQ DX,R11
|
||||||
|
MOVQ 0(SI),AX
|
||||||
|
MULQ 16(CX)
|
||||||
|
MOVQ AX,R12
|
||||||
|
MOVQ DX,R13
|
||||||
|
MOVQ 0(SI),AX
|
||||||
|
MULQ 24(CX)
|
||||||
|
MOVQ AX,R14
|
||||||
|
MOVQ DX,R15
|
||||||
|
MOVQ 0(SI),AX
|
||||||
|
MULQ 32(CX)
|
||||||
|
MOVQ AX,BX
|
||||||
|
MOVQ DX,BP
|
||||||
|
MOVQ 8(SI),AX
|
||||||
|
MULQ 0(CX)
|
||||||
|
ADDQ AX,R10
|
||||||
|
ADCQ DX,R11
|
||||||
|
MOVQ 8(SI),AX
|
||||||
|
MULQ 8(CX)
|
||||||
|
ADDQ AX,R12
|
||||||
|
ADCQ DX,R13
|
||||||
|
MOVQ 8(SI),AX
|
||||||
|
MULQ 16(CX)
|
||||||
|
ADDQ AX,R14
|
||||||
|
ADCQ DX,R15
|
||||||
|
MOVQ 8(SI),AX
|
||||||
|
MULQ 24(CX)
|
||||||
|
ADDQ AX,BX
|
||||||
|
ADCQ DX,BP
|
||||||
|
MOVQ 8(SI),DX
|
||||||
|
IMUL3Q $19,DX,AX
|
||||||
|
MULQ 32(CX)
|
||||||
|
ADDQ AX,R8
|
||||||
|
ADCQ DX,R9
|
||||||
|
MOVQ 16(SI),AX
|
||||||
|
MULQ 0(CX)
|
||||||
|
ADDQ AX,R12
|
||||||
|
ADCQ DX,R13
|
||||||
|
MOVQ 16(SI),AX
|
||||||
|
MULQ 8(CX)
|
||||||
|
ADDQ AX,R14
|
||||||
|
ADCQ DX,R15
|
||||||
|
MOVQ 16(SI),AX
|
||||||
|
MULQ 16(CX)
|
||||||
|
ADDQ AX,BX
|
||||||
|
ADCQ DX,BP
|
||||||
|
MOVQ 16(SI),DX
|
||||||
|
IMUL3Q $19,DX,AX
|
||||||
|
MULQ 24(CX)
|
||||||
|
ADDQ AX,R8
|
||||||
|
ADCQ DX,R9
|
||||||
|
MOVQ 16(SI),DX
|
||||||
|
IMUL3Q $19,DX,AX
|
||||||
|
MULQ 32(CX)
|
||||||
|
ADDQ AX,R10
|
||||||
|
ADCQ DX,R11
|
||||||
|
MOVQ 24(SI),AX
|
||||||
|
MULQ 0(CX)
|
||||||
|
ADDQ AX,R14
|
||||||
|
ADCQ DX,R15
|
||||||
|
MOVQ 24(SI),AX
|
||||||
|
MULQ 8(CX)
|
||||||
|
ADDQ AX,BX
|
||||||
|
ADCQ DX,BP
|
||||||
|
MOVQ 0(SP),AX
|
||||||
|
MULQ 24(CX)
|
||||||
|
ADDQ AX,R10
|
||||||
|
ADCQ DX,R11
|
||||||
|
MOVQ 0(SP),AX
|
||||||
|
MULQ 32(CX)
|
||||||
|
ADDQ AX,R12
|
||||||
|
ADCQ DX,R13
|
||||||
|
MOVQ 32(SI),AX
|
||||||
|
MULQ 0(CX)
|
||||||
|
ADDQ AX,BX
|
||||||
|
ADCQ DX,BP
|
||||||
|
MOVQ 8(SP),AX
|
||||||
|
MULQ 16(CX)
|
||||||
|
ADDQ AX,R10
|
||||||
|
ADCQ DX,R11
|
||||||
|
MOVQ 8(SP),AX
|
||||||
|
MULQ 24(CX)
|
||||||
|
ADDQ AX,R12
|
||||||
|
ADCQ DX,R13
|
||||||
|
MOVQ 8(SP),AX
|
||||||
|
MULQ 32(CX)
|
||||||
|
ADDQ AX,R14
|
||||||
|
ADCQ DX,R15
|
||||||
|
MOVQ $REDMASK51,SI
|
||||||
|
SHLQ $13,R9:R8
|
||||||
|
ANDQ SI,R8
|
||||||
|
SHLQ $13,R11:R10
|
||||||
|
ANDQ SI,R10
|
||||||
|
ADDQ R9,R10
|
||||||
|
SHLQ $13,R13:R12
|
||||||
|
ANDQ SI,R12
|
||||||
|
ADDQ R11,R12
|
||||||
|
SHLQ $13,R15:R14
|
||||||
|
ANDQ SI,R14
|
||||||
|
ADDQ R13,R14
|
||||||
|
SHLQ $13,BP:BX
|
||||||
|
ANDQ SI,BX
|
||||||
|
ADDQ R15,BX
|
||||||
|
IMUL3Q $19,BP,DX
|
||||||
|
ADDQ DX,R8
|
||||||
|
MOVQ R8,DX
|
||||||
|
SHRQ $51,DX
|
||||||
|
ADDQ R10,DX
|
||||||
|
MOVQ DX,CX
|
||||||
|
SHRQ $51,DX
|
||||||
|
ANDQ SI,R8
|
||||||
|
ADDQ R12,DX
|
||||||
|
MOVQ DX,R9
|
||||||
|
SHRQ $51,DX
|
||||||
|
ANDQ SI,CX
|
||||||
|
ADDQ R14,DX
|
||||||
|
MOVQ DX,AX
|
||||||
|
SHRQ $51,DX
|
||||||
|
ANDQ SI,R9
|
||||||
|
ADDQ BX,DX
|
||||||
|
MOVQ DX,R10
|
||||||
|
SHRQ $51,DX
|
||||||
|
ANDQ SI,AX
|
||||||
|
IMUL3Q $19,DX,DX
|
||||||
|
ADDQ DX,R8
|
||||||
|
ANDQ SI,R10
|
||||||
|
MOVQ R8,0(DI)
|
||||||
|
MOVQ CX,8(DI)
|
||||||
|
MOVQ R9,16(DI)
|
||||||
|
MOVQ AX,24(DI)
|
||||||
|
MOVQ R10,32(DI)
|
||||||
|
RET
|
132
vendor/golang.org/x/crypto/curve25519/square_amd64.s
generated
vendored
Normal file
132
vendor/golang.org/x/crypto/curve25519/square_amd64.s
generated
vendored
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// This code was translated into a form compatible with 6a from the public
|
||||||
|
// domain sources in SUPERCOP: https://bench.cr.yp.to/supercop.html
|
||||||
|
|
||||||
|
// +build amd64,!gccgo,!appengine
|
||||||
|
|
||||||
|
#include "const_amd64.h"
|
||||||
|
|
||||||
|
// func square(out, in *[5]uint64)
|
||||||
|
TEXT ·square(SB),7,$0-16
|
||||||
|
MOVQ out+0(FP), DI
|
||||||
|
MOVQ in+8(FP), SI
|
||||||
|
|
||||||
|
MOVQ 0(SI),AX
|
||||||
|
MULQ 0(SI)
|
||||||
|
MOVQ AX,CX
|
||||||
|
MOVQ DX,R8
|
||||||
|
MOVQ 0(SI),AX
|
||||||
|
SHLQ $1,AX
|
||||||
|
MULQ 8(SI)
|
||||||
|
MOVQ AX,R9
|
||||||
|
MOVQ DX,R10
|
||||||
|
MOVQ 0(SI),AX
|
||||||
|
SHLQ $1,AX
|
||||||
|
MULQ 16(SI)
|
||||||
|
MOVQ AX,R11
|
||||||
|
MOVQ DX,R12
|
||||||
|
MOVQ 0(SI),AX
|
||||||
|
SHLQ $1,AX
|
||||||
|
MULQ 24(SI)
|
||||||
|
MOVQ AX,R13
|
||||||
|
MOVQ DX,R14
|
||||||
|
MOVQ 0(SI),AX
|
||||||
|
SHLQ $1,AX
|
||||||
|
MULQ 32(SI)
|
||||||
|
MOVQ AX,R15
|
||||||
|
MOVQ DX,BX
|
||||||
|
MOVQ 8(SI),AX
|
||||||
|
MULQ 8(SI)
|
||||||
|
ADDQ AX,R11
|
||||||
|
ADCQ DX,R12
|
||||||
|
MOVQ 8(SI),AX
|
||||||
|
SHLQ $1,AX
|
||||||
|
MULQ 16(SI)
|
||||||
|
ADDQ AX,R13
|
||||||
|
ADCQ DX,R14
|
||||||
|
MOVQ 8(SI),AX
|
||||||
|
SHLQ $1,AX
|
||||||
|
MULQ 24(SI)
|
||||||
|
ADDQ AX,R15
|
||||||
|
ADCQ DX,BX
|
||||||
|
MOVQ 8(SI),DX
|
||||||
|
IMUL3Q $38,DX,AX
|
||||||
|
MULQ 32(SI)
|
||||||
|
ADDQ AX,CX
|
||||||
|
ADCQ DX,R8
|
||||||
|
MOVQ 16(SI),AX
|
||||||
|
MULQ 16(SI)
|
||||||
|
ADDQ AX,R15
|
||||||
|
ADCQ DX,BX
|
||||||
|
MOVQ 16(SI),DX
|
||||||
|
IMUL3Q $38,DX,AX
|
||||||
|
MULQ 24(SI)
|
||||||
|
ADDQ AX,CX
|
||||||
|
ADCQ DX,R8
|
||||||
|
MOVQ 16(SI),DX
|
||||||
|
IMUL3Q $38,DX,AX
|
||||||
|
MULQ 32(SI)
|
||||||
|
ADDQ AX,R9
|
||||||
|
ADCQ DX,R10
|
||||||
|
MOVQ 24(SI),DX
|
||||||
|
IMUL3Q $19,DX,AX
|
||||||
|
MULQ 24(SI)
|
||||||
|
ADDQ AX,R9
|
||||||
|
ADCQ DX,R10
|
||||||
|
MOVQ 24(SI),DX
|
||||||
|
IMUL3Q $38,DX,AX
|
||||||
|
MULQ 32(SI)
|
||||||
|
ADDQ AX,R11
|
||||||
|
ADCQ DX,R12
|
||||||
|
MOVQ 32(SI),DX
|
||||||
|
IMUL3Q $19,DX,AX
|
||||||
|
MULQ 32(SI)
|
||||||
|
ADDQ AX,R13
|
||||||
|
ADCQ DX,R14
|
||||||
|
MOVQ $REDMASK51,SI
|
||||||
|
SHLQ $13,R8:CX
|
||||||
|
ANDQ SI,CX
|
||||||
|
SHLQ $13,R10:R9
|
||||||
|
ANDQ SI,R9
|
||||||
|
ADDQ R8,R9
|
||||||
|
SHLQ $13,R12:R11
|
||||||
|
ANDQ SI,R11
|
||||||
|
ADDQ R10,R11
|
||||||
|
SHLQ $13,R14:R13
|
||||||
|
ANDQ SI,R13
|
||||||
|
ADDQ R12,R13
|
||||||
|
SHLQ $13,BX:R15
|
||||||
|
ANDQ SI,R15
|
||||||
|
ADDQ R14,R15
|
||||||
|
IMUL3Q $19,BX,DX
|
||||||
|
ADDQ DX,CX
|
||||||
|
MOVQ CX,DX
|
||||||
|
SHRQ $51,DX
|
||||||
|
ADDQ R9,DX
|
||||||
|
ANDQ SI,CX
|
||||||
|
MOVQ DX,R8
|
||||||
|
SHRQ $51,DX
|
||||||
|
ADDQ R11,DX
|
||||||
|
ANDQ SI,R8
|
||||||
|
MOVQ DX,R9
|
||||||
|
SHRQ $51,DX
|
||||||
|
ADDQ R13,DX
|
||||||
|
ANDQ SI,R9
|
||||||
|
MOVQ DX,AX
|
||||||
|
SHRQ $51,DX
|
||||||
|
ADDQ R15,DX
|
||||||
|
ANDQ SI,AX
|
||||||
|
MOVQ DX,R10
|
||||||
|
SHRQ $51,DX
|
||||||
|
IMUL3Q $19,DX,DX
|
||||||
|
ADDQ DX,CX
|
||||||
|
ANDQ SI,R10
|
||||||
|
MOVQ CX,0(DI)
|
||||||
|
MOVQ R8,8(DI)
|
||||||
|
MOVQ R9,16(DI)
|
||||||
|
MOVQ AX,24(DI)
|
||||||
|
MOVQ R10,32(DI)
|
||||||
|
RET
|
5
vendor/golang.org/x/crypto/ed25519/ed25519.go
generated
vendored
5
vendor/golang.org/x/crypto/ed25519/ed25519.go
generated
vendored
@ -2,11 +2,6 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// In Go 1.13, the ed25519 package was promoted to the standard library as
|
|
||||||
// crypto/ed25519, and this package became a wrapper for the standard library one.
|
|
||||||
//
|
|
||||||
// +build !go1.13
|
|
||||||
|
|
||||||
// Package ed25519 implements the Ed25519 signature algorithm. See
|
// Package ed25519 implements the Ed25519 signature algorithm. See
|
||||||
// https://ed25519.cr.yp.to/.
|
// https://ed25519.cr.yp.to/.
|
||||||
//
|
//
|
||||||
|
73
vendor/golang.org/x/crypto/ed25519/ed25519_go113.go
generated
vendored
73
vendor/golang.org/x/crypto/ed25519/ed25519_go113.go
generated
vendored
@ -1,73 +0,0 @@
|
|||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build go1.13
|
|
||||||
|
|
||||||
// Package ed25519 implements the Ed25519 signature algorithm. See
|
|
||||||
// https://ed25519.cr.yp.to/.
|
|
||||||
//
|
|
||||||
// These functions are also compatible with the “Ed25519” function defined in
|
|
||||||
// RFC 8032. However, unlike RFC 8032's formulation, this package's private key
|
|
||||||
// representation includes a public key suffix to make multiple signing
|
|
||||||
// operations with the same key more efficient. This package refers to the RFC
|
|
||||||
// 8032 private key as the “seed”.
|
|
||||||
//
|
|
||||||
// Beginning with Go 1.13, the functionality of this package was moved to the
|
|
||||||
// standard library as crypto/ed25519. This package only acts as a compatibility
|
|
||||||
// wrapper.
|
|
||||||
package ed25519
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/ed25519"
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// PublicKeySize is the size, in bytes, of public keys as used in this package.
|
|
||||||
PublicKeySize = 32
|
|
||||||
// PrivateKeySize is the size, in bytes, of private keys as used in this package.
|
|
||||||
PrivateKeySize = 64
|
|
||||||
// SignatureSize is the size, in bytes, of signatures generated and verified by this package.
|
|
||||||
SignatureSize = 64
|
|
||||||
// SeedSize is the size, in bytes, of private key seeds. These are the private key representations used by RFC 8032.
|
|
||||||
SeedSize = 32
|
|
||||||
)
|
|
||||||
|
|
||||||
// PublicKey is the type of Ed25519 public keys.
|
|
||||||
//
|
|
||||||
// This type is an alias for crypto/ed25519's PublicKey type.
|
|
||||||
// See the crypto/ed25519 package for the methods on this type.
|
|
||||||
type PublicKey = ed25519.PublicKey
|
|
||||||
|
|
||||||
// PrivateKey is the type of Ed25519 private keys. It implements crypto.Signer.
|
|
||||||
//
|
|
||||||
// This type is an alias for crypto/ed25519's PrivateKey type.
|
|
||||||
// See the crypto/ed25519 package for the methods on this type.
|
|
||||||
type PrivateKey = ed25519.PrivateKey
|
|
||||||
|
|
||||||
// GenerateKey generates a public/private key pair using entropy from rand.
|
|
||||||
// If rand is nil, crypto/rand.Reader will be used.
|
|
||||||
func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) {
|
|
||||||
return ed25519.GenerateKey(rand)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewKeyFromSeed calculates a private key from a seed. It will panic if
|
|
||||||
// len(seed) is not SeedSize. This function is provided for interoperability
|
|
||||||
// with RFC 8032. RFC 8032's private keys correspond to seeds in this
|
|
||||||
// package.
|
|
||||||
func NewKeyFromSeed(seed []byte) PrivateKey {
|
|
||||||
return ed25519.NewKeyFromSeed(seed)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sign signs the message with privateKey and returns a signature. It will
|
|
||||||
// panic if len(privateKey) is not PrivateKeySize.
|
|
||||||
func Sign(privateKey PrivateKey, message []byte) []byte {
|
|
||||||
return ed25519.Sign(privateKey, message)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify reports whether sig is a valid signature of message by publicKey. It
|
|
||||||
// will panic if len(publicKey) is not PublicKeySize.
|
|
||||||
func Verify(publicKey PublicKey, message, sig []byte) bool {
|
|
||||||
return ed25519.Verify(publicKey, message, sig)
|
|
||||||
}
|
|
@ -2,7 +2,8 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build go1.11,!gccgo,!purego
|
// +build go1.11
|
||||||
|
// +build !gccgo,!appengine
|
||||||
|
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
|
|
31
vendor/golang.org/x/crypto/internal/chacha20/chacha_arm64.go
generated
vendored
Normal file
31
vendor/golang.org/x/crypto/internal/chacha20/chacha_arm64.go
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build go1.11
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
package chacha20
|
||||||
|
|
||||||
|
const (
|
||||||
|
haveAsm = true
|
||||||
|
bufSize = 256
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32)
|
||||||
|
|
||||||
|
func (c *Cipher) xorKeyStreamAsm(dst, src []byte) {
|
||||||
|
|
||||||
|
if len(src) >= bufSize {
|
||||||
|
xorKeyStreamVX(dst, src, &c.key, &c.nonce, &c.counter)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(src)%bufSize != 0 {
|
||||||
|
i := len(src) - len(src)%bufSize
|
||||||
|
c.buf = [bufSize]byte{}
|
||||||
|
copy(c.buf[:], src[i:])
|
||||||
|
xorKeyStreamVX(c.buf[:], c.buf[:], &c.key, &c.nonce, &c.counter)
|
||||||
|
c.len = bufSize - copy(dst[i:], c.buf[:len(src)%bufSize])
|
||||||
|
}
|
||||||
|
}
|
264
vendor/golang.org/x/crypto/internal/chacha20/chacha_generic.go
generated
vendored
Normal file
264
vendor/golang.org/x/crypto/internal/chacha20/chacha_generic.go
generated
vendored
Normal file
@ -0,0 +1,264 @@
|
|||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package ChaCha20 implements the core ChaCha20 function as specified
|
||||||
|
// in https://tools.ietf.org/html/rfc7539#section-2.3.
|
||||||
|
package chacha20
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/cipher"
|
||||||
|
"encoding/binary"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/internal/subtle"
|
||||||
|
)
|
||||||
|
|
||||||
|
// assert that *Cipher implements cipher.Stream
|
||||||
|
var _ cipher.Stream = (*Cipher)(nil)
|
||||||
|
|
||||||
|
// Cipher is a stateful instance of ChaCha20 using a particular key
|
||||||
|
// and nonce. A *Cipher implements the cipher.Stream interface.
|
||||||
|
type Cipher struct {
|
||||||
|
key [8]uint32
|
||||||
|
counter uint32 // incremented after each block
|
||||||
|
nonce [3]uint32
|
||||||
|
buf [bufSize]byte // buffer for unused keystream bytes
|
||||||
|
len int // number of unused keystream bytes at end of buf
|
||||||
|
}
|
||||||
|
|
||||||
|
// New creates a new ChaCha20 stream cipher with the given key and nonce.
|
||||||
|
// The initial counter value is set to 0.
|
||||||
|
func New(key [8]uint32, nonce [3]uint32) *Cipher {
|
||||||
|
return &Cipher{key: key, nonce: nonce}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChaCha20 constants spelling "expand 32-byte k"
|
||||||
|
const (
|
||||||
|
j0 uint32 = 0x61707865
|
||||||
|
j1 uint32 = 0x3320646e
|
||||||
|
j2 uint32 = 0x79622d32
|
||||||
|
j3 uint32 = 0x6b206574
|
||||||
|
)
|
||||||
|
|
||||||
|
func quarterRound(a, b, c, d uint32) (uint32, uint32, uint32, uint32) {
|
||||||
|
a += b
|
||||||
|
d ^= a
|
||||||
|
d = (d << 16) | (d >> 16)
|
||||||
|
c += d
|
||||||
|
b ^= c
|
||||||
|
b = (b << 12) | (b >> 20)
|
||||||
|
a += b
|
||||||
|
d ^= a
|
||||||
|
d = (d << 8) | (d >> 24)
|
||||||
|
c += d
|
||||||
|
b ^= c
|
||||||
|
b = (b << 7) | (b >> 25)
|
||||||
|
return a, b, c, d
|
||||||
|
}
|
||||||
|
|
||||||
|
// XORKeyStream XORs each byte in the given slice with a byte from the
|
||||||
|
// cipher's key stream. Dst and src must overlap entirely or not at all.
|
||||||
|
//
|
||||||
|
// If len(dst) < len(src), XORKeyStream will panic. It is acceptable
|
||||||
|
// to pass a dst bigger than src, and in that case, XORKeyStream will
|
||||||
|
// only update dst[:len(src)] and will not touch the rest of dst.
|
||||||
|
//
|
||||||
|
// Multiple calls to XORKeyStream behave as if the concatenation of
|
||||||
|
// the src buffers was passed in a single run. That is, Cipher
|
||||||
|
// maintains state and does not reset at each XORKeyStream call.
|
||||||
|
func (s *Cipher) XORKeyStream(dst, src []byte) {
|
||||||
|
if len(dst) < len(src) {
|
||||||
|
panic("chacha20: output smaller than input")
|
||||||
|
}
|
||||||
|
if subtle.InexactOverlap(dst[:len(src)], src) {
|
||||||
|
panic("chacha20: invalid buffer overlap")
|
||||||
|
}
|
||||||
|
|
||||||
|
// xor src with buffered keystream first
|
||||||
|
if s.len != 0 {
|
||||||
|
buf := s.buf[len(s.buf)-s.len:]
|
||||||
|
if len(src) < len(buf) {
|
||||||
|
buf = buf[:len(src)]
|
||||||
|
}
|
||||||
|
td, ts := dst[:len(buf)], src[:len(buf)] // BCE hint
|
||||||
|
for i, b := range buf {
|
||||||
|
td[i] = ts[i] ^ b
|
||||||
|
}
|
||||||
|
s.len -= len(buf)
|
||||||
|
if s.len != 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.buf = [len(s.buf)]byte{} // zero the empty buffer
|
||||||
|
src = src[len(buf):]
|
||||||
|
dst = dst[len(buf):]
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(src) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if haveAsm {
|
||||||
|
if uint64(len(src))+uint64(s.counter)*64 > (1<<38)-64 {
|
||||||
|
panic("chacha20: counter overflow")
|
||||||
|
}
|
||||||
|
s.xorKeyStreamAsm(dst, src)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up a 64-byte buffer to pad out the final block if needed
|
||||||
|
// (hoisted out of the main loop to avoid spills)
|
||||||
|
rem := len(src) % 64 // length of final block
|
||||||
|
fin := len(src) - rem // index of final block
|
||||||
|
if rem > 0 {
|
||||||
|
copy(s.buf[len(s.buf)-64:], src[fin:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// pre-calculate most of the first round
|
||||||
|
s1, s5, s9, s13 := quarterRound(j1, s.key[1], s.key[5], s.nonce[0])
|
||||||
|
s2, s6, s10, s14 := quarterRound(j2, s.key[2], s.key[6], s.nonce[1])
|
||||||
|
s3, s7, s11, s15 := quarterRound(j3, s.key[3], s.key[7], s.nonce[2])
|
||||||
|
|
||||||
|
n := len(src)
|
||||||
|
src, dst = src[:n:n], dst[:n:n] // BCE hint
|
||||||
|
for i := 0; i < n; i += 64 {
|
||||||
|
// calculate the remainder of the first round
|
||||||
|
s0, s4, s8, s12 := quarterRound(j0, s.key[0], s.key[4], s.counter)
|
||||||
|
|
||||||
|
// execute the second round
|
||||||
|
x0, x5, x10, x15 := quarterRound(s0, s5, s10, s15)
|
||||||
|
x1, x6, x11, x12 := quarterRound(s1, s6, s11, s12)
|
||||||
|
x2, x7, x8, x13 := quarterRound(s2, s7, s8, s13)
|
||||||
|
x3, x4, x9, x14 := quarterRound(s3, s4, s9, s14)
|
||||||
|
|
||||||
|
// execute the remaining 18 rounds
|
||||||
|
for i := 0; i < 9; i++ {
|
||||||
|
x0, x4, x8, x12 = quarterRound(x0, x4, x8, x12)
|
||||||
|
x1, x5, x9, x13 = quarterRound(x1, x5, x9, x13)
|
||||||
|
x2, x6, x10, x14 = quarterRound(x2, x6, x10, x14)
|
||||||
|
x3, x7, x11, x15 = quarterRound(x3, x7, x11, x15)
|
||||||
|
|
||||||
|
x0, x5, x10, x15 = quarterRound(x0, x5, x10, x15)
|
||||||
|
x1, x6, x11, x12 = quarterRound(x1, x6, x11, x12)
|
||||||
|
x2, x7, x8, x13 = quarterRound(x2, x7, x8, x13)
|
||||||
|
x3, x4, x9, x14 = quarterRound(x3, x4, x9, x14)
|
||||||
|
}
|
||||||
|
|
||||||
|
x0 += j0
|
||||||
|
x1 += j1
|
||||||
|
x2 += j2
|
||||||
|
x3 += j3
|
||||||
|
|
||||||
|
x4 += s.key[0]
|
||||||
|
x5 += s.key[1]
|
||||||
|
x6 += s.key[2]
|
||||||
|
x7 += s.key[3]
|
||||||
|
x8 += s.key[4]
|
||||||
|
x9 += s.key[5]
|
||||||
|
x10 += s.key[6]
|
||||||
|
x11 += s.key[7]
|
||||||
|
|
||||||
|
x12 += s.counter
|
||||||
|
x13 += s.nonce[0]
|
||||||
|
x14 += s.nonce[1]
|
||||||
|
x15 += s.nonce[2]
|
||||||
|
|
||||||
|
// increment the counter
|
||||||
|
s.counter += 1
|
||||||
|
if s.counter == 0 {
|
||||||
|
panic("chacha20: counter overflow")
|
||||||
|
}
|
||||||
|
|
||||||
|
// pad to 64 bytes if needed
|
||||||
|
in, out := src[i:], dst[i:]
|
||||||
|
if i == fin {
|
||||||
|
// src[fin:] has already been copied into s.buf before
|
||||||
|
// the main loop
|
||||||
|
in, out = s.buf[len(s.buf)-64:], s.buf[len(s.buf)-64:]
|
||||||
|
}
|
||||||
|
in, out = in[:64], out[:64] // BCE hint
|
||||||
|
|
||||||
|
// XOR the key stream with the source and write out the result
|
||||||
|
xor(out[0:], in[0:], x0)
|
||||||
|
xor(out[4:], in[4:], x1)
|
||||||
|
xor(out[8:], in[8:], x2)
|
||||||
|
xor(out[12:], in[12:], x3)
|
||||||
|
xor(out[16:], in[16:], x4)
|
||||||
|
xor(out[20:], in[20:], x5)
|
||||||
|
xor(out[24:], in[24:], x6)
|
||||||
|
xor(out[28:], in[28:], x7)
|
||||||
|
xor(out[32:], in[32:], x8)
|
||||||
|
xor(out[36:], in[36:], x9)
|
||||||
|
xor(out[40:], in[40:], x10)
|
||||||
|
xor(out[44:], in[44:], x11)
|
||||||
|
xor(out[48:], in[48:], x12)
|
||||||
|
xor(out[52:], in[52:], x13)
|
||||||
|
xor(out[56:], in[56:], x14)
|
||||||
|
xor(out[60:], in[60:], x15)
|
||||||
|
}
|
||||||
|
// copy any trailing bytes out of the buffer and into dst
|
||||||
|
if rem != 0 {
|
||||||
|
s.len = 64 - rem
|
||||||
|
copy(dst[fin:], s.buf[len(s.buf)-64:])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Advance discards bytes in the key stream until the next 64 byte block
|
||||||
|
// boundary is reached and updates the counter accordingly. If the key
|
||||||
|
// stream is already at a block boundary no bytes will be discarded and
|
||||||
|
// the counter will be unchanged.
|
||||||
|
func (s *Cipher) Advance() {
|
||||||
|
s.len -= s.len % 64
|
||||||
|
if s.len == 0 {
|
||||||
|
s.buf = [len(s.buf)]byte{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// XORKeyStream crypts bytes from in to out using the given key and counters.
|
||||||
|
// In and out must overlap entirely or not at all. Counter contains the raw
|
||||||
|
// ChaCha20 counter bytes (i.e. block counter followed by nonce).
|
||||||
|
func XORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) {
|
||||||
|
s := Cipher{
|
||||||
|
key: [8]uint32{
|
||||||
|
binary.LittleEndian.Uint32(key[0:4]),
|
||||||
|
binary.LittleEndian.Uint32(key[4:8]),
|
||||||
|
binary.LittleEndian.Uint32(key[8:12]),
|
||||||
|
binary.LittleEndian.Uint32(key[12:16]),
|
||||||
|
binary.LittleEndian.Uint32(key[16:20]),
|
||||||
|
binary.LittleEndian.Uint32(key[20:24]),
|
||||||
|
binary.LittleEndian.Uint32(key[24:28]),
|
||||||
|
binary.LittleEndian.Uint32(key[28:32]),
|
||||||
|
},
|
||||||
|
nonce: [3]uint32{
|
||||||
|
binary.LittleEndian.Uint32(counter[4:8]),
|
||||||
|
binary.LittleEndian.Uint32(counter[8:12]),
|
||||||
|
binary.LittleEndian.Uint32(counter[12:16]),
|
||||||
|
},
|
||||||
|
counter: binary.LittleEndian.Uint32(counter[0:4]),
|
||||||
|
}
|
||||||
|
s.XORKeyStream(out, in)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HChaCha20 uses the ChaCha20 core to generate a derived key from a key and a
|
||||||
|
// nonce. It should only be used as part of the XChaCha20 construction.
|
||||||
|
func HChaCha20(key *[8]uint32, nonce *[4]uint32) [8]uint32 {
|
||||||
|
x0, x1, x2, x3 := j0, j1, j2, j3
|
||||||
|
x4, x5, x6, x7 := key[0], key[1], key[2], key[3]
|
||||||
|
x8, x9, x10, x11 := key[4], key[5], key[6], key[7]
|
||||||
|
x12, x13, x14, x15 := nonce[0], nonce[1], nonce[2], nonce[3]
|
||||||
|
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
x0, x4, x8, x12 = quarterRound(x0, x4, x8, x12)
|
||||||
|
x1, x5, x9, x13 = quarterRound(x1, x5, x9, x13)
|
||||||
|
x2, x6, x10, x14 = quarterRound(x2, x6, x10, x14)
|
||||||
|
x3, x7, x11, x15 = quarterRound(x3, x7, x11, x15)
|
||||||
|
|
||||||
|
x0, x5, x10, x15 = quarterRound(x0, x5, x10, x15)
|
||||||
|
x1, x6, x11, x12 = quarterRound(x1, x6, x11, x12)
|
||||||
|
x2, x7, x8, x13 = quarterRound(x2, x7, x8, x13)
|
||||||
|
x3, x4, x9, x14 = quarterRound(x3, x4, x9, x14)
|
||||||
|
}
|
||||||
|
|
||||||
|
var out [8]uint32
|
||||||
|
out[0], out[1], out[2], out[3] = x0, x1, x2, x3
|
||||||
|
out[4], out[5], out[6], out[7] = x12, x13, x14, x15
|
||||||
|
return out
|
||||||
|
}
|
@ -2,12 +2,15 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build !arm64,!s390x,!ppc64le arm64,!go1.11 gccgo purego
|
// +build !arm64,!s390x arm64,!go1.11 gccgo appengine
|
||||||
|
|
||||||
package chacha20
|
package chacha20
|
||||||
|
|
||||||
const bufSize = blockSize
|
const (
|
||||||
|
bufSize = 64
|
||||||
|
haveAsm = false
|
||||||
|
)
|
||||||
|
|
||||||
func (s *Cipher) xorKeyStreamBlocks(dst, src []byte) {
|
func (*Cipher) xorKeyStreamAsm(dst, src []byte) {
|
||||||
s.xorKeyStreamBlocksGeneric(dst, src)
|
panic("not implemented")
|
||||||
}
|
}
|
29
vendor/golang.org/x/crypto/internal/chacha20/chacha_s390x.go
generated
vendored
Normal file
29
vendor/golang.org/x/crypto/internal/chacha20/chacha_s390x.go
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build s390x,!gccgo,!appengine
|
||||||
|
|
||||||
|
package chacha20
|
||||||
|
|
||||||
|
import (
|
||||||
|
"golang.org/x/sys/cpu"
|
||||||
|
)
|
||||||
|
|
||||||
|
var haveAsm = cpu.S390X.HasVX
|
||||||
|
|
||||||
|
const bufSize = 256
|
||||||
|
|
||||||
|
// xorKeyStreamVX is an assembly implementation of XORKeyStream. It must only
|
||||||
|
// be called when the vector facility is available.
|
||||||
|
// Implementation in asm_s390x.s.
|
||||||
|
//go:noescape
|
||||||
|
func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32, buf *[256]byte, len *int)
|
||||||
|
|
||||||
|
func (c *Cipher) xorKeyStreamAsm(dst, src []byte) {
|
||||||
|
xorKeyStreamVX(dst, src, &c.key, &c.nonce, &c.counter, &c.buf, &c.len)
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXRL targets, DO NOT CALL!
|
||||||
|
func mvcSrcToBuf()
|
||||||
|
func mvcBufToDst()
|
@ -2,7 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build !gccgo,!purego
|
// +build s390x,!gccgo,!appengine
|
||||||
|
|
||||||
#include "go_asm.h"
|
#include "go_asm.h"
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
@ -24,6 +24,15 @@ DATA ·constants<>+0x14(SB)/4, $0x3320646e
|
|||||||
DATA ·constants<>+0x18(SB)/4, $0x79622d32
|
DATA ·constants<>+0x18(SB)/4, $0x79622d32
|
||||||
DATA ·constants<>+0x1c(SB)/4, $0x6b206574
|
DATA ·constants<>+0x1c(SB)/4, $0x6b206574
|
||||||
|
|
||||||
|
// EXRL targets:
|
||||||
|
TEXT ·mvcSrcToBuf(SB), NOFRAME|NOSPLIT, $0
|
||||||
|
MVC $1, (R1), (R8)
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT ·mvcBufToDst(SB), NOFRAME|NOSPLIT, $0
|
||||||
|
MVC $1, (R8), (R9)
|
||||||
|
RET
|
||||||
|
|
||||||
#define BSWAP V5
|
#define BSWAP V5
|
||||||
#define J0 V6
|
#define J0 V6
|
||||||
#define KEY0 V7
|
#define KEY0 V7
|
||||||
@ -135,7 +144,7 @@ DATA ·constants<>+0x1c(SB)/4, $0x6b206574
|
|||||||
VMRHF v, w, c \ // c = {a[2], b[2], c[2], d[2]}
|
VMRHF v, w, c \ // c = {a[2], b[2], c[2], d[2]}
|
||||||
VMRLF v, w, d // d = {a[3], b[3], c[3], d[3]}
|
VMRLF v, w, d // d = {a[3], b[3], c[3], d[3]}
|
||||||
|
|
||||||
// func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32)
|
// func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32, buf *[256]byte, len *int)
|
||||||
TEXT ·xorKeyStreamVX(SB), NOSPLIT, $0
|
TEXT ·xorKeyStreamVX(SB), NOSPLIT, $0
|
||||||
MOVD $·constants<>(SB), R1
|
MOVD $·constants<>(SB), R1
|
||||||
MOVD dst+0(FP), R2 // R2=&dst[0]
|
MOVD dst+0(FP), R2 // R2=&dst[0]
|
||||||
@ -143,10 +152,25 @@ TEXT ·xorKeyStreamVX(SB), NOSPLIT, $0
|
|||||||
MOVD key+48(FP), R5 // R5=key
|
MOVD key+48(FP), R5 // R5=key
|
||||||
MOVD nonce+56(FP), R6 // R6=nonce
|
MOVD nonce+56(FP), R6 // R6=nonce
|
||||||
MOVD counter+64(FP), R7 // R7=counter
|
MOVD counter+64(FP), R7 // R7=counter
|
||||||
|
MOVD buf+72(FP), R8 // R8=buf
|
||||||
|
MOVD len+80(FP), R9 // R9=len
|
||||||
|
|
||||||
// load BSWAP and J0
|
// load BSWAP and J0
|
||||||
VLM (R1), BSWAP, J0
|
VLM (R1), BSWAP, J0
|
||||||
|
|
||||||
|
// set up tail buffer
|
||||||
|
ADD $-1, R4, R12
|
||||||
|
MOVBZ R12, R12
|
||||||
|
CMPUBEQ R12, $255, aligned
|
||||||
|
MOVD R4, R1
|
||||||
|
AND $~255, R1
|
||||||
|
MOVD $(R3)(R1*1), R1
|
||||||
|
EXRL $·mvcSrcToBuf(SB), R12
|
||||||
|
MOVD $255, R0
|
||||||
|
SUB R12, R0
|
||||||
|
MOVD R0, (R9) // update len
|
||||||
|
|
||||||
|
aligned:
|
||||||
// setup
|
// setup
|
||||||
MOVD $95, R0
|
MOVD $95, R0
|
||||||
VLM (R5), KEY0, KEY1
|
VLM (R5), KEY0, KEY1
|
||||||
@ -193,7 +217,9 @@ loop:
|
|||||||
|
|
||||||
// decrement length
|
// decrement length
|
||||||
ADD $-256, R4
|
ADD $-256, R4
|
||||||
|
BLT tail
|
||||||
|
|
||||||
|
continue:
|
||||||
// rearrange vectors
|
// rearrange vectors
|
||||||
SHUFFLE(X0, X1, X2, X3, M0, M1, M2, M3)
|
SHUFFLE(X0, X1, X2, X3, M0, M1, M2, M3)
|
||||||
ADDV(J0, X0, X1, X2, X3)
|
ADDV(J0, X0, X1, X2, X3)
|
||||||
@ -219,6 +245,16 @@ loop:
|
|||||||
MOVD $256(R3), R3
|
MOVD $256(R3), R3
|
||||||
|
|
||||||
CMPBNE R4, $0, chacha
|
CMPBNE R4, $0, chacha
|
||||||
|
CMPUBEQ R12, $255, return
|
||||||
|
EXRL $·mvcBufToDst(SB), R12 // len was updated during setup
|
||||||
|
|
||||||
|
return:
|
||||||
VSTEF $0, CTR, (R7)
|
VSTEF $0, CTR, (R7)
|
||||||
RET
|
RET
|
||||||
|
|
||||||
|
tail:
|
||||||
|
MOVD R2, R9
|
||||||
|
MOVD R8, R2
|
||||||
|
MOVD R8, R3
|
||||||
|
MOVD $0, R4
|
||||||
|
JMP continue
|
@ -4,7 +4,9 @@
|
|||||||
|
|
||||||
package chacha20
|
package chacha20
|
||||||
|
|
||||||
import "runtime"
|
import (
|
||||||
|
"runtime"
|
||||||
|
)
|
||||||
|
|
||||||
// Platforms that have fast unaligned 32-bit little endian accesses.
|
// Platforms that have fast unaligned 32-bit little endian accesses.
|
||||||
const unaligned = runtime.GOARCH == "386" ||
|
const unaligned = runtime.GOARCH == "386" ||
|
||||||
@ -13,10 +15,10 @@ const unaligned = runtime.GOARCH == "386" ||
|
|||||||
runtime.GOARCH == "ppc64le" ||
|
runtime.GOARCH == "ppc64le" ||
|
||||||
runtime.GOARCH == "s390x"
|
runtime.GOARCH == "s390x"
|
||||||
|
|
||||||
// addXor reads a little endian uint32 from src, XORs it with (a + b) and
|
// xor reads a little endian uint32 from src, XORs it with u and
|
||||||
// places the result in little endian byte order in dst.
|
// places the result in little endian byte order in dst.
|
||||||
func addXor(dst, src []byte, a, b uint32) {
|
func xor(dst, src []byte, u uint32) {
|
||||||
_, _ = src[3], dst[3] // bounds check elimination hint
|
_, _ = src[3], dst[3] // eliminate bounds checks
|
||||||
if unaligned {
|
if unaligned {
|
||||||
// The compiler should optimize this code into
|
// The compiler should optimize this code into
|
||||||
// 32-bit unaligned little endian loads and stores.
|
// 32-bit unaligned little endian loads and stores.
|
||||||
@ -27,16 +29,15 @@ func addXor(dst, src []byte, a, b uint32) {
|
|||||||
v |= uint32(src[1]) << 8
|
v |= uint32(src[1]) << 8
|
||||||
v |= uint32(src[2]) << 16
|
v |= uint32(src[2]) << 16
|
||||||
v |= uint32(src[3]) << 24
|
v |= uint32(src[3]) << 24
|
||||||
v ^= a + b
|
v ^= u
|
||||||
dst[0] = byte(v)
|
dst[0] = byte(v)
|
||||||
dst[1] = byte(v >> 8)
|
dst[1] = byte(v >> 8)
|
||||||
dst[2] = byte(v >> 16)
|
dst[2] = byte(v >> 16)
|
||||||
dst[3] = byte(v >> 24)
|
dst[3] = byte(v >> 24)
|
||||||
} else {
|
} else {
|
||||||
a += b
|
dst[0] = src[0] ^ byte(u)
|
||||||
dst[0] = src[0] ^ byte(a)
|
dst[1] = src[1] ^ byte(u>>8)
|
||||||
dst[1] = src[1] ^ byte(a>>8)
|
dst[2] = src[2] ^ byte(u>>16)
|
||||||
dst[2] = src[2] ^ byte(a>>16)
|
dst[3] = src[3] ^ byte(u>>24)
|
||||||
dst[3] = src[3] ^ byte(a>>24)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
21
vendor/golang.org/x/crypto/openpgp/armor/armor.go
generated
vendored
21
vendor/golang.org/x/crypto/openpgp/armor/armor.go
generated
vendored
@ -62,11 +62,10 @@ var armorEndOfLine = []byte("-----")
|
|||||||
// lineReader wraps a line based reader. It watches for the end of an armor
|
// lineReader wraps a line based reader. It watches for the end of an armor
|
||||||
// block and records the expected CRC value.
|
// block and records the expected CRC value.
|
||||||
type lineReader struct {
|
type lineReader struct {
|
||||||
in *bufio.Reader
|
in *bufio.Reader
|
||||||
buf []byte
|
buf []byte
|
||||||
eof bool
|
eof bool
|
||||||
crc uint32
|
crc uint32
|
||||||
crcSet bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *lineReader) Read(p []byte) (n int, err error) {
|
func (l *lineReader) Read(p []byte) (n int, err error) {
|
||||||
@ -88,11 +87,6 @@ func (l *lineReader) Read(p []byte) (n int, err error) {
|
|||||||
return 0, ArmorCorrupt
|
return 0, ArmorCorrupt
|
||||||
}
|
}
|
||||||
|
|
||||||
if bytes.HasPrefix(line, armorEnd) {
|
|
||||||
l.eof = true
|
|
||||||
return 0, io.EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(line) == 5 && line[0] == '=' {
|
if len(line) == 5 && line[0] == '=' {
|
||||||
// This is the checksum line
|
// This is the checksum line
|
||||||
var expectedBytes [3]byte
|
var expectedBytes [3]byte
|
||||||
@ -114,7 +108,6 @@ func (l *lineReader) Read(p []byte) (n int, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
l.eof = true
|
l.eof = true
|
||||||
l.crcSet = true
|
|
||||||
return 0, io.EOF
|
return 0, io.EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,8 +141,10 @@ func (r *openpgpReader) Read(p []byte) (n int, err error) {
|
|||||||
n, err = r.b64Reader.Read(p)
|
n, err = r.b64Reader.Read(p)
|
||||||
r.currentCRC = crc24(r.currentCRC, p[:n])
|
r.currentCRC = crc24(r.currentCRC, p[:n])
|
||||||
|
|
||||||
if err == io.EOF && r.lReader.crcSet && r.lReader.crc != uint32(r.currentCRC&crc24Mask) {
|
if err == io.EOF {
|
||||||
return 0, ArmorCorrupt
|
if r.lReader.crc != uint32(r.currentCRC&crc24Mask) {
|
||||||
|
return 0, ArmorCorrupt
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
|
4
vendor/golang.org/x/crypto/openpgp/elgamal/elgamal.go
generated
vendored
4
vendor/golang.org/x/crypto/openpgp/elgamal/elgamal.go
generated
vendored
@ -76,9 +76,7 @@ func Encrypt(random io.Reader, pub *PublicKey, msg []byte) (c1, c2 *big.Int, err
|
|||||||
// Bleichenbacher, Advances in Cryptology (Crypto '98),
|
// Bleichenbacher, Advances in Cryptology (Crypto '98),
|
||||||
func Decrypt(priv *PrivateKey, c1, c2 *big.Int) (msg []byte, err error) {
|
func Decrypt(priv *PrivateKey, c1, c2 *big.Int) (msg []byte, err error) {
|
||||||
s := new(big.Int).Exp(c1, priv.X, priv.P)
|
s := new(big.Int).Exp(c1, priv.X, priv.P)
|
||||||
if s.ModInverse(s, priv.P) == nil {
|
s.ModInverse(s, priv.P)
|
||||||
return nil, errors.New("elgamal: invalid private key")
|
|
||||||
}
|
|
||||||
s.Mul(s, c2)
|
s.Mul(s, c2)
|
||||||
s.Mod(s, priv.P)
|
s.Mod(s, priv.P)
|
||||||
em := s.Bytes()
|
em := s.Bytes()
|
||||||
|
14
vendor/golang.org/x/crypto/openpgp/keys.go
generated
vendored
14
vendor/golang.org/x/crypto/openpgp/keys.go
generated
vendored
@ -504,7 +504,7 @@ const defaultRSAKeyBits = 2048
|
|||||||
// which may be empty but must not contain any of "()<>\x00".
|
// which may be empty but must not contain any of "()<>\x00".
|
||||||
// If config is nil, sensible defaults will be used.
|
// If config is nil, sensible defaults will be used.
|
||||||
func NewEntity(name, comment, email string, config *packet.Config) (*Entity, error) {
|
func NewEntity(name, comment, email string, config *packet.Config) (*Entity, error) {
|
||||||
creationTime := config.Now()
|
currentTime := config.Now()
|
||||||
|
|
||||||
bits := defaultRSAKeyBits
|
bits := defaultRSAKeyBits
|
||||||
if config != nil && config.RSABits != 0 {
|
if config != nil && config.RSABits != 0 {
|
||||||
@ -525,8 +525,8 @@ func NewEntity(name, comment, email string, config *packet.Config) (*Entity, err
|
|||||||
}
|
}
|
||||||
|
|
||||||
e := &Entity{
|
e := &Entity{
|
||||||
PrimaryKey: packet.NewRSAPublicKey(creationTime, &signingPriv.PublicKey),
|
PrimaryKey: packet.NewRSAPublicKey(currentTime, &signingPriv.PublicKey),
|
||||||
PrivateKey: packet.NewRSAPrivateKey(creationTime, signingPriv),
|
PrivateKey: packet.NewRSAPrivateKey(currentTime, signingPriv),
|
||||||
Identities: make(map[string]*Identity),
|
Identities: make(map[string]*Identity),
|
||||||
}
|
}
|
||||||
isPrimaryId := true
|
isPrimaryId := true
|
||||||
@ -534,7 +534,7 @@ func NewEntity(name, comment, email string, config *packet.Config) (*Entity, err
|
|||||||
Name: uid.Id,
|
Name: uid.Id,
|
||||||
UserId: uid,
|
UserId: uid,
|
||||||
SelfSignature: &packet.Signature{
|
SelfSignature: &packet.Signature{
|
||||||
CreationTime: creationTime,
|
CreationTime: currentTime,
|
||||||
SigType: packet.SigTypePositiveCert,
|
SigType: packet.SigTypePositiveCert,
|
||||||
PubKeyAlgo: packet.PubKeyAlgoRSA,
|
PubKeyAlgo: packet.PubKeyAlgoRSA,
|
||||||
Hash: config.Hash(),
|
Hash: config.Hash(),
|
||||||
@ -563,10 +563,10 @@ func NewEntity(name, comment, email string, config *packet.Config) (*Entity, err
|
|||||||
|
|
||||||
e.Subkeys = make([]Subkey, 1)
|
e.Subkeys = make([]Subkey, 1)
|
||||||
e.Subkeys[0] = Subkey{
|
e.Subkeys[0] = Subkey{
|
||||||
PublicKey: packet.NewRSAPublicKey(creationTime, &encryptingPriv.PublicKey),
|
PublicKey: packet.NewRSAPublicKey(currentTime, &encryptingPriv.PublicKey),
|
||||||
PrivateKey: packet.NewRSAPrivateKey(creationTime, encryptingPriv),
|
PrivateKey: packet.NewRSAPrivateKey(currentTime, encryptingPriv),
|
||||||
Sig: &packet.Signature{
|
Sig: &packet.Signature{
|
||||||
CreationTime: creationTime,
|
CreationTime: currentTime,
|
||||||
SigType: packet.SigTypeSubkeyBinding,
|
SigType: packet.SigTypeSubkeyBinding,
|
||||||
PubKeyAlgo: packet.PubKeyAlgoRSA,
|
PubKeyAlgo: packet.PubKeyAlgoRSA,
|
||||||
Hash: config.Hash(),
|
Hash: config.Hash(),
|
||||||
|
6
vendor/golang.org/x/crypto/openpgp/packet/encrypted_key.go
generated
vendored
6
vendor/golang.org/x/crypto/openpgp/packet/encrypted_key.go
generated
vendored
@ -5,7 +5,6 @@
|
|||||||
package packet
|
package packet
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto"
|
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"io"
|
"io"
|
||||||
@ -79,9 +78,8 @@ func (e *EncryptedKey) Decrypt(priv *PrivateKey, config *Config) error {
|
|||||||
// padding oracle attacks.
|
// padding oracle attacks.
|
||||||
switch priv.PubKeyAlgo {
|
switch priv.PubKeyAlgo {
|
||||||
case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly:
|
case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly:
|
||||||
// Supports both *rsa.PrivateKey and crypto.Decrypter
|
k := priv.PrivateKey.(*rsa.PrivateKey)
|
||||||
k := priv.PrivateKey.(crypto.Decrypter)
|
b, err = rsa.DecryptPKCS1v15(config.Random(), k, padToKeySize(&k.PublicKey, e.encryptedMPI1.bytes))
|
||||||
b, err = k.Decrypt(config.Random(), padToKeySize(k.Public().(*rsa.PublicKey), e.encryptedMPI1.bytes), nil)
|
|
||||||
case PubKeyAlgoElGamal:
|
case PubKeyAlgoElGamal:
|
||||||
c1 := new(big.Int).SetBytes(e.encryptedMPI1.bytes)
|
c1 := new(big.Int).SetBytes(e.encryptedMPI1.bytes)
|
||||||
c2 := new(big.Int).SetBytes(e.encryptedMPI2.bytes)
|
c2 := new(big.Int).SetBytes(e.encryptedMPI2.bytes)
|
||||||
|
67
vendor/golang.org/x/crypto/openpgp/packet/packet.go
generated
vendored
67
vendor/golang.org/x/crypto/openpgp/packet/packet.go
generated
vendored
@ -14,7 +14,6 @@ import (
|
|||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"io"
|
"io"
|
||||||
"math/big"
|
"math/big"
|
||||||
"math/bits"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/cast5"
|
"golang.org/x/crypto/cast5"
|
||||||
"golang.org/x/crypto/openpgp/errors"
|
"golang.org/x/crypto/openpgp/errors"
|
||||||
@ -101,65 +100,33 @@ func (r *partialLengthReader) Read(p []byte) (n int, err error) {
|
|||||||
type partialLengthWriter struct {
|
type partialLengthWriter struct {
|
||||||
w io.WriteCloser
|
w io.WriteCloser
|
||||||
lengthByte [1]byte
|
lengthByte [1]byte
|
||||||
sentFirst bool
|
|
||||||
buf []byte
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RFC 4880 4.2.2.4: the first partial length MUST be at least 512 octets long.
|
|
||||||
const minFirstPartialWrite = 512
|
|
||||||
|
|
||||||
func (w *partialLengthWriter) Write(p []byte) (n int, err error) {
|
func (w *partialLengthWriter) Write(p []byte) (n int, err error) {
|
||||||
off := 0
|
|
||||||
if !w.sentFirst {
|
|
||||||
if len(w.buf) > 0 || len(p) < minFirstPartialWrite {
|
|
||||||
off = len(w.buf)
|
|
||||||
w.buf = append(w.buf, p...)
|
|
||||||
if len(w.buf) < minFirstPartialWrite {
|
|
||||||
return len(p), nil
|
|
||||||
}
|
|
||||||
p = w.buf
|
|
||||||
w.buf = nil
|
|
||||||
}
|
|
||||||
w.sentFirst = true
|
|
||||||
}
|
|
||||||
|
|
||||||
power := uint8(30)
|
|
||||||
for len(p) > 0 {
|
for len(p) > 0 {
|
||||||
l := 1 << power
|
for power := uint(14); power < 32; power-- {
|
||||||
if len(p) < l {
|
l := 1 << power
|
||||||
power = uint8(bits.Len32(uint32(len(p)))) - 1
|
if len(p) >= l {
|
||||||
l = 1 << power
|
w.lengthByte[0] = 224 + uint8(power)
|
||||||
}
|
_, err = w.w.Write(w.lengthByte[:])
|
||||||
w.lengthByte[0] = 224 + power
|
if err != nil {
|
||||||
_, err = w.w.Write(w.lengthByte[:])
|
return
|
||||||
if err == nil {
|
}
|
||||||
var m int
|
var m int
|
||||||
m, err = w.w.Write(p[:l])
|
m, err = w.w.Write(p[:l])
|
||||||
n += m
|
n += m
|
||||||
}
|
if err != nil {
|
||||||
if err != nil {
|
return
|
||||||
if n < off {
|
}
|
||||||
return 0, err
|
p = p[l:]
|
||||||
|
break
|
||||||
}
|
}
|
||||||
return n - off, err
|
|
||||||
}
|
}
|
||||||
p = p[l:]
|
|
||||||
}
|
}
|
||||||
return n - off, nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *partialLengthWriter) Close() error {
|
func (w *partialLengthWriter) Close() error {
|
||||||
if len(w.buf) > 0 {
|
|
||||||
// In this case we can't send a 512 byte packet.
|
|
||||||
// Just send what we have.
|
|
||||||
p := w.buf
|
|
||||||
w.sentFirst = true
|
|
||||||
w.buf = nil
|
|
||||||
if _, err := w.Write(p); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
w.lengthByte[0] = 0
|
w.lengthByte[0] = 0
|
||||||
_, err := w.w.Write(w.lengthByte[:])
|
_, err := w.w.Write(w.lengthByte[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
28
vendor/golang.org/x/crypto/openpgp/packet/private_key.go
generated
vendored
28
vendor/golang.org/x/crypto/openpgp/packet/private_key.go
generated
vendored
@ -31,54 +31,54 @@ type PrivateKey struct {
|
|||||||
encryptedData []byte
|
encryptedData []byte
|
||||||
cipher CipherFunction
|
cipher CipherFunction
|
||||||
s2k func(out, in []byte)
|
s2k func(out, in []byte)
|
||||||
PrivateKey interface{} // An *{rsa|dsa|ecdsa}.PrivateKey or crypto.Signer/crypto.Decrypter (Decryptor RSA only).
|
PrivateKey interface{} // An *{rsa|dsa|ecdsa}.PrivateKey or a crypto.Signer.
|
||||||
sha1Checksum bool
|
sha1Checksum bool
|
||||||
iv []byte
|
iv []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRSAPrivateKey(creationTime time.Time, priv *rsa.PrivateKey) *PrivateKey {
|
func NewRSAPrivateKey(currentTime time.Time, priv *rsa.PrivateKey) *PrivateKey {
|
||||||
pk := new(PrivateKey)
|
pk := new(PrivateKey)
|
||||||
pk.PublicKey = *NewRSAPublicKey(creationTime, &priv.PublicKey)
|
pk.PublicKey = *NewRSAPublicKey(currentTime, &priv.PublicKey)
|
||||||
pk.PrivateKey = priv
|
pk.PrivateKey = priv
|
||||||
return pk
|
return pk
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDSAPrivateKey(creationTime time.Time, priv *dsa.PrivateKey) *PrivateKey {
|
func NewDSAPrivateKey(currentTime time.Time, priv *dsa.PrivateKey) *PrivateKey {
|
||||||
pk := new(PrivateKey)
|
pk := new(PrivateKey)
|
||||||
pk.PublicKey = *NewDSAPublicKey(creationTime, &priv.PublicKey)
|
pk.PublicKey = *NewDSAPublicKey(currentTime, &priv.PublicKey)
|
||||||
pk.PrivateKey = priv
|
pk.PrivateKey = priv
|
||||||
return pk
|
return pk
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewElGamalPrivateKey(creationTime time.Time, priv *elgamal.PrivateKey) *PrivateKey {
|
func NewElGamalPrivateKey(currentTime time.Time, priv *elgamal.PrivateKey) *PrivateKey {
|
||||||
pk := new(PrivateKey)
|
pk := new(PrivateKey)
|
||||||
pk.PublicKey = *NewElGamalPublicKey(creationTime, &priv.PublicKey)
|
pk.PublicKey = *NewElGamalPublicKey(currentTime, &priv.PublicKey)
|
||||||
pk.PrivateKey = priv
|
pk.PrivateKey = priv
|
||||||
return pk
|
return pk
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewECDSAPrivateKey(creationTime time.Time, priv *ecdsa.PrivateKey) *PrivateKey {
|
func NewECDSAPrivateKey(currentTime time.Time, priv *ecdsa.PrivateKey) *PrivateKey {
|
||||||
pk := new(PrivateKey)
|
pk := new(PrivateKey)
|
||||||
pk.PublicKey = *NewECDSAPublicKey(creationTime, &priv.PublicKey)
|
pk.PublicKey = *NewECDSAPublicKey(currentTime, &priv.PublicKey)
|
||||||
pk.PrivateKey = priv
|
pk.PrivateKey = priv
|
||||||
return pk
|
return pk
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSignerPrivateKey creates a PrivateKey from a crypto.Signer that
|
// NewSignerPrivateKey creates a PrivateKey from a crypto.Signer that
|
||||||
// implements RSA or ECDSA.
|
// implements RSA or ECDSA.
|
||||||
func NewSignerPrivateKey(creationTime time.Time, signer crypto.Signer) *PrivateKey {
|
func NewSignerPrivateKey(currentTime time.Time, signer crypto.Signer) *PrivateKey {
|
||||||
pk := new(PrivateKey)
|
pk := new(PrivateKey)
|
||||||
// In general, the public Keys should be used as pointers. We still
|
// In general, the public Keys should be used as pointers. We still
|
||||||
// type-switch on the values, for backwards-compatibility.
|
// type-switch on the values, for backwards-compatibility.
|
||||||
switch pubkey := signer.Public().(type) {
|
switch pubkey := signer.Public().(type) {
|
||||||
case *rsa.PublicKey:
|
case *rsa.PublicKey:
|
||||||
pk.PublicKey = *NewRSAPublicKey(creationTime, pubkey)
|
pk.PublicKey = *NewRSAPublicKey(currentTime, pubkey)
|
||||||
case rsa.PublicKey:
|
case rsa.PublicKey:
|
||||||
pk.PublicKey = *NewRSAPublicKey(creationTime, &pubkey)
|
pk.PublicKey = *NewRSAPublicKey(currentTime, &pubkey)
|
||||||
case *ecdsa.PublicKey:
|
case *ecdsa.PublicKey:
|
||||||
pk.PublicKey = *NewECDSAPublicKey(creationTime, pubkey)
|
pk.PublicKey = *NewECDSAPublicKey(currentTime, pubkey)
|
||||||
case ecdsa.PublicKey:
|
case ecdsa.PublicKey:
|
||||||
pk.PublicKey = *NewECDSAPublicKey(creationTime, &pubkey)
|
pk.PublicKey = *NewECDSAPublicKey(currentTime, &pubkey)
|
||||||
default:
|
default:
|
||||||
panic("openpgp: unknown crypto.Signer type in NewSignerPrivateKey")
|
panic("openpgp: unknown crypto.Signer type in NewSignerPrivateKey")
|
||||||
}
|
}
|
||||||
|
1
vendor/golang.org/x/crypto/pkcs12/pkcs12.go
generated
vendored
1
vendor/golang.org/x/crypto/pkcs12/pkcs12.go
generated
vendored
@ -252,7 +252,6 @@ func Decode(pfxData []byte, password string) (privateKey interface{}, certificat
|
|||||||
case bag.Id.Equal(oidPKCS8ShroundedKeyBag):
|
case bag.Id.Equal(oidPKCS8ShroundedKeyBag):
|
||||||
if privateKey != nil {
|
if privateKey != nil {
|
||||||
err = errors.New("pkcs12: expected exactly one key bag")
|
err = errors.New("pkcs12: expected exactly one key bag")
|
||||||
return nil, nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if privateKey, err = decodePkcs8ShroudedKeyBag(bag.Value.Bytes, encodedPassword); err != nil {
|
if privateKey, err = decodePkcs8ShroudedKeyBag(bag.Value.Bytes, encodedPassword); err != nil {
|
||||||
|
39
vendor/golang.org/x/crypto/poly1305/bits_compat.go
generated
vendored
39
vendor/golang.org/x/crypto/poly1305/bits_compat.go
generated
vendored
@ -1,39 +0,0 @@
|
|||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build !go1.13
|
|
||||||
|
|
||||||
package poly1305
|
|
||||||
|
|
||||||
// Generic fallbacks for the math/bits intrinsics, copied from
|
|
||||||
// src/math/bits/bits.go. They were added in Go 1.12, but Add64 and Sum64 had
|
|
||||||
// variable time fallbacks until Go 1.13.
|
|
||||||
|
|
||||||
func bitsAdd64(x, y, carry uint64) (sum, carryOut uint64) {
|
|
||||||
sum = x + y + carry
|
|
||||||
carryOut = ((x & y) | ((x | y) &^ sum)) >> 63
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func bitsSub64(x, y, borrow uint64) (diff, borrowOut uint64) {
|
|
||||||
diff = x - y - borrow
|
|
||||||
borrowOut = ((^x & y) | (^(x ^ y) & diff)) >> 63
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func bitsMul64(x, y uint64) (hi, lo uint64) {
|
|
||||||
const mask32 = 1<<32 - 1
|
|
||||||
x0 := x & mask32
|
|
||||||
x1 := x >> 32
|
|
||||||
y0 := y & mask32
|
|
||||||
y1 := y >> 32
|
|
||||||
w0 := x0 * y0
|
|
||||||
t := x1*y0 + w0>>32
|
|
||||||
w1 := t & mask32
|
|
||||||
w2 := t >> 32
|
|
||||||
w1 += x0 * y1
|
|
||||||
hi = x1*y1 + w2 + w1>>32
|
|
||||||
lo = x * y
|
|
||||||
return
|
|
||||||
}
|
|
21
vendor/golang.org/x/crypto/poly1305/bits_go1.13.go
generated
vendored
21
vendor/golang.org/x/crypto/poly1305/bits_go1.13.go
generated
vendored
@ -1,21 +0,0 @@
|
|||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build go1.13
|
|
||||||
|
|
||||||
package poly1305
|
|
||||||
|
|
||||||
import "math/bits"
|
|
||||||
|
|
||||||
func bitsAdd64(x, y, carry uint64) (sum, carryOut uint64) {
|
|
||||||
return bits.Add64(x, y, carry)
|
|
||||||
}
|
|
||||||
|
|
||||||
func bitsSub64(x, y, borrow uint64) (diff, borrowOut uint64) {
|
|
||||||
return bits.Sub64(x, y, borrow)
|
|
||||||
}
|
|
||||||
|
|
||||||
func bitsMul64(x, y uint64) (hi, lo uint64) {
|
|
||||||
return bits.Mul64(x, y)
|
|
||||||
}
|
|
4
vendor/golang.org/x/crypto/poly1305/mac_noasm.go
generated
vendored
4
vendor/golang.org/x/crypto/poly1305/mac_noasm.go
generated
vendored
@ -2,8 +2,10 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build !amd64,!ppc64le,!s390x gccgo purego
|
// +build !amd64 gccgo appengine
|
||||||
|
|
||||||
package poly1305
|
package poly1305
|
||||||
|
|
||||||
type mac struct{ macGeneric }
|
type mac struct{ macGeneric }
|
||||||
|
|
||||||
|
func newMAC(key *[32]byte) mac { return mac{newMACGeneric(key)} }
|
||||||
|
34
vendor/golang.org/x/crypto/poly1305/poly1305.go
generated
vendored
34
vendor/golang.org/x/crypto/poly1305/poly1305.go
generated
vendored
@ -22,16 +22,8 @@ import "crypto/subtle"
|
|||||||
// TagSize is the size, in bytes, of a poly1305 authenticator.
|
// TagSize is the size, in bytes, of a poly1305 authenticator.
|
||||||
const TagSize = 16
|
const TagSize = 16
|
||||||
|
|
||||||
// Sum generates an authenticator for msg using a one-time key and puts the
|
// Verify returns true if mac is a valid authenticator for m with the given
|
||||||
// 16-byte result into out. Authenticating two different messages with the same
|
// key.
|
||||||
// key allows an attacker to forge messages at will.
|
|
||||||
func Sum(out *[16]byte, m []byte, key *[32]byte) {
|
|
||||||
h := New(key)
|
|
||||||
h.Write(m)
|
|
||||||
h.Sum(out[:0])
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify returns true if mac is a valid authenticator for m with the given key.
|
|
||||||
func Verify(mac *[16]byte, m []byte, key *[32]byte) bool {
|
func Verify(mac *[16]byte, m []byte, key *[32]byte) bool {
|
||||||
var tmp [16]byte
|
var tmp [16]byte
|
||||||
Sum(&tmp, m, key)
|
Sum(&tmp, m, key)
|
||||||
@ -48,9 +40,10 @@ func Verify(mac *[16]byte, m []byte, key *[32]byte) bool {
|
|||||||
// two different messages with the same key allows an attacker
|
// two different messages with the same key allows an attacker
|
||||||
// to forge messages at will.
|
// to forge messages at will.
|
||||||
func New(key *[32]byte) *MAC {
|
func New(key *[32]byte) *MAC {
|
||||||
m := &MAC{}
|
return &MAC{
|
||||||
initialize(key, &m.macState)
|
mac: newMAC(key),
|
||||||
return m
|
finalized: false,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MAC is an io.Writer computing an authentication tag
|
// MAC is an io.Writer computing an authentication tag
|
||||||
@ -59,7 +52,7 @@ func New(key *[32]byte) *MAC {
|
|||||||
// MAC cannot be used like common hash.Hash implementations,
|
// MAC cannot be used like common hash.Hash implementations,
|
||||||
// because using a poly1305 key twice breaks its security.
|
// because using a poly1305 key twice breaks its security.
|
||||||
// Therefore writing data to a running MAC after calling
|
// Therefore writing data to a running MAC after calling
|
||||||
// Sum or Verify causes it to panic.
|
// Sum causes it to panic.
|
||||||
type MAC struct {
|
type MAC struct {
|
||||||
mac // platform-dependent implementation
|
mac // platform-dependent implementation
|
||||||
|
|
||||||
@ -72,10 +65,10 @@ func (h *MAC) Size() int { return TagSize }
|
|||||||
// Write adds more data to the running message authentication code.
|
// Write adds more data to the running message authentication code.
|
||||||
// It never returns an error.
|
// It never returns an error.
|
||||||
//
|
//
|
||||||
// It must not be called after the first call of Sum or Verify.
|
// It must not be called after the first call of Sum.
|
||||||
func (h *MAC) Write(p []byte) (n int, err error) {
|
func (h *MAC) Write(p []byte) (n int, err error) {
|
||||||
if h.finalized {
|
if h.finalized {
|
||||||
panic("poly1305: write to MAC after Sum or Verify")
|
panic("poly1305: write to MAC after Sum")
|
||||||
}
|
}
|
||||||
return h.mac.Write(p)
|
return h.mac.Write(p)
|
||||||
}
|
}
|
||||||
@ -88,12 +81,3 @@ func (h *MAC) Sum(b []byte) []byte {
|
|||||||
h.finalized = true
|
h.finalized = true
|
||||||
return append(b, mac[:]...)
|
return append(b, mac[:]...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify returns whether the authenticator of all data written to
|
|
||||||
// the message authentication code matches the expected value.
|
|
||||||
func (h *MAC) Verify(expected []byte) bool {
|
|
||||||
var mac [TagSize]byte
|
|
||||||
h.mac.Sum(&mac)
|
|
||||||
h.finalized = true
|
|
||||||
return subtle.ConstantTimeCompare(expected, mac[:]) == 1
|
|
||||||
}
|
|
||||||
|
65
vendor/golang.org/x/crypto/poly1305/sum_amd64.go
generated
vendored
65
vendor/golang.org/x/crypto/poly1305/sum_amd64.go
generated
vendored
@ -2,46 +2,67 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build !gccgo,!purego
|
// +build amd64,!gccgo,!appengine
|
||||||
|
|
||||||
package poly1305
|
package poly1305
|
||||||
|
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func update(state *macState, msg []byte)
|
func initialize(state *[7]uint64, key *[32]byte)
|
||||||
|
|
||||||
// mac is a wrapper for macGeneric that redirects calls that would have gone to
|
//go:noescape
|
||||||
// updateGeneric to update.
|
func update(state *[7]uint64, msg []byte)
|
||||||
//
|
|
||||||
// Its Write and Sum methods are otherwise identical to the macGeneric ones, but
|
|
||||||
// using function pointers would carry a major performance cost.
|
|
||||||
type mac struct{ macGeneric }
|
|
||||||
|
|
||||||
func (h *mac) Write(p []byte) (int, error) {
|
//go:noescape
|
||||||
nn := len(p)
|
func finalize(tag *[TagSize]byte, state *[7]uint64)
|
||||||
|
|
||||||
|
// Sum generates an authenticator for m using a one-time key and puts the
|
||||||
|
// 16-byte result into out. Authenticating two different messages with the same
|
||||||
|
// key allows an attacker to forge messages at will.
|
||||||
|
func Sum(out *[16]byte, m []byte, key *[32]byte) {
|
||||||
|
h := newMAC(key)
|
||||||
|
h.Write(m)
|
||||||
|
h.Sum(out)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newMAC(key *[32]byte) (h mac) {
|
||||||
|
initialize(&h.state, key)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type mac struct {
|
||||||
|
state [7]uint64 // := uint64{ h0, h1, h2, r0, r1, pad0, pad1 }
|
||||||
|
|
||||||
|
buffer [TagSize]byte
|
||||||
|
offset int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *mac) Write(p []byte) (n int, err error) {
|
||||||
|
n = len(p)
|
||||||
if h.offset > 0 {
|
if h.offset > 0 {
|
||||||
n := copy(h.buffer[h.offset:], p)
|
remaining := TagSize - h.offset
|
||||||
if h.offset+n < TagSize {
|
if n < remaining {
|
||||||
h.offset += n
|
h.offset += copy(h.buffer[h.offset:], p)
|
||||||
return nn, nil
|
return n, nil
|
||||||
}
|
}
|
||||||
p = p[n:]
|
copy(h.buffer[h.offset:], p[:remaining])
|
||||||
|
p = p[remaining:]
|
||||||
h.offset = 0
|
h.offset = 0
|
||||||
update(&h.macState, h.buffer[:])
|
update(&h.state, h.buffer[:])
|
||||||
}
|
}
|
||||||
if n := len(p) - (len(p) % TagSize); n > 0 {
|
if nn := len(p) - (len(p) % TagSize); nn > 0 {
|
||||||
update(&h.macState, p[:n])
|
update(&h.state, p[:nn])
|
||||||
p = p[n:]
|
p = p[nn:]
|
||||||
}
|
}
|
||||||
if len(p) > 0 {
|
if len(p) > 0 {
|
||||||
h.offset += copy(h.buffer[h.offset:], p)
|
h.offset += copy(h.buffer[h.offset:], p)
|
||||||
}
|
}
|
||||||
return nn, nil
|
return n, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *mac) Sum(out *[16]byte) {
|
func (h *mac) Sum(out *[16]byte) {
|
||||||
state := h.macState
|
state := h.state
|
||||||
if h.offset > 0 {
|
if h.offset > 0 {
|
||||||
update(&state, h.buffer[:h.offset])
|
update(&state, h.buffer[:h.offset])
|
||||||
}
|
}
|
||||||
finalize(out, &state.h, &state.s)
|
finalize(out, &state)
|
||||||
}
|
}
|
||||||
|
42
vendor/golang.org/x/crypto/poly1305/sum_amd64.s
generated
vendored
42
vendor/golang.org/x/crypto/poly1305/sum_amd64.s
generated
vendored
@ -2,7 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build !gccgo,!purego
|
// +build amd64,!gccgo,!appengine
|
||||||
|
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
|
|
||||||
@ -54,6 +54,10 @@
|
|||||||
ADCQ t3, h1; \
|
ADCQ t3, h1; \
|
||||||
ADCQ $0, h2
|
ADCQ $0, h2
|
||||||
|
|
||||||
|
DATA ·poly1305Mask<>+0x00(SB)/8, $0x0FFFFFFC0FFFFFFF
|
||||||
|
DATA ·poly1305Mask<>+0x08(SB)/8, $0x0FFFFFFC0FFFFFFC
|
||||||
|
GLOBL ·poly1305Mask<>(SB), RODATA, $16
|
||||||
|
|
||||||
// func update(state *[7]uint64, msg []byte)
|
// func update(state *[7]uint64, msg []byte)
|
||||||
TEXT ·update(SB), $0-32
|
TEXT ·update(SB), $0-32
|
||||||
MOVQ state+0(FP), DI
|
MOVQ state+0(FP), DI
|
||||||
@ -106,3 +110,39 @@ done:
|
|||||||
MOVQ R9, 8(DI)
|
MOVQ R9, 8(DI)
|
||||||
MOVQ R10, 16(DI)
|
MOVQ R10, 16(DI)
|
||||||
RET
|
RET
|
||||||
|
|
||||||
|
// func initialize(state *[7]uint64, key *[32]byte)
|
||||||
|
TEXT ·initialize(SB), $0-16
|
||||||
|
MOVQ state+0(FP), DI
|
||||||
|
MOVQ key+8(FP), SI
|
||||||
|
|
||||||
|
// state[0...7] is initialized with zero
|
||||||
|
MOVOU 0(SI), X0
|
||||||
|
MOVOU 16(SI), X1
|
||||||
|
MOVOU ·poly1305Mask<>(SB), X2
|
||||||
|
PAND X2, X0
|
||||||
|
MOVOU X0, 24(DI)
|
||||||
|
MOVOU X1, 40(DI)
|
||||||
|
RET
|
||||||
|
|
||||||
|
// func finalize(tag *[TagSize]byte, state *[7]uint64)
|
||||||
|
TEXT ·finalize(SB), $0-16
|
||||||
|
MOVQ tag+0(FP), DI
|
||||||
|
MOVQ state+8(FP), SI
|
||||||
|
|
||||||
|
MOVQ 0(SI), AX
|
||||||
|
MOVQ 8(SI), BX
|
||||||
|
MOVQ 16(SI), CX
|
||||||
|
MOVQ AX, R8
|
||||||
|
MOVQ BX, R9
|
||||||
|
SUBQ $0xFFFFFFFFFFFFFFFB, AX
|
||||||
|
SBBQ $0xFFFFFFFFFFFFFFFF, BX
|
||||||
|
SBBQ $3, CX
|
||||||
|
CMOVQCS R8, AX
|
||||||
|
CMOVQCS R9, BX
|
||||||
|
ADDQ 40(SI), AX
|
||||||
|
ADCQ 48(SI), BX
|
||||||
|
|
||||||
|
MOVQ AX, 0(DI)
|
||||||
|
MOVQ BX, 8(DI)
|
||||||
|
RET
|
||||||
|
22
vendor/golang.org/x/crypto/poly1305/sum_arm.go
generated
vendored
Normal file
22
vendor/golang.org/x/crypto/poly1305/sum_arm.go
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build arm,!gccgo,!appengine,!nacl
|
||||||
|
|
||||||
|
package poly1305
|
||||||
|
|
||||||
|
// This function is implemented in sum_arm.s
|
||||||
|
//go:noescape
|
||||||
|
func poly1305_auth_armv6(out *[16]byte, m *byte, mlen uint32, key *[32]byte)
|
||||||
|
|
||||||
|
// Sum generates an authenticator for m using a one-time key and puts the
|
||||||
|
// 16-byte result into out. Authenticating two different messages with the same
|
||||||
|
// key allows an attacker to forge messages at will.
|
||||||
|
func Sum(out *[16]byte, m []byte, key *[32]byte) {
|
||||||
|
var mPtr *byte
|
||||||
|
if len(m) > 0 {
|
||||||
|
mPtr = &m[0]
|
||||||
|
}
|
||||||
|
poly1305_auth_armv6(out, mPtr, uint32(len(m)), key)
|
||||||
|
}
|
427
vendor/golang.org/x/crypto/poly1305/sum_arm.s
generated
vendored
Normal file
427
vendor/golang.org/x/crypto/poly1305/sum_arm.s
generated
vendored
Normal file
@ -0,0 +1,427 @@
|
|||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build arm,!gccgo,!appengine,!nacl
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
// This code was translated into a form compatible with 5a from the public
|
||||||
|
// domain source by Andrew Moon: github.com/floodyberry/poly1305-opt/blob/master/app/extensions/poly1305.
|
||||||
|
|
||||||
|
DATA ·poly1305_init_constants_armv6<>+0x00(SB)/4, $0x3ffffff
|
||||||
|
DATA ·poly1305_init_constants_armv6<>+0x04(SB)/4, $0x3ffff03
|
||||||
|
DATA ·poly1305_init_constants_armv6<>+0x08(SB)/4, $0x3ffc0ff
|
||||||
|
DATA ·poly1305_init_constants_armv6<>+0x0c(SB)/4, $0x3f03fff
|
||||||
|
DATA ·poly1305_init_constants_armv6<>+0x10(SB)/4, $0x00fffff
|
||||||
|
GLOBL ·poly1305_init_constants_armv6<>(SB), 8, $20
|
||||||
|
|
||||||
|
// Warning: the linker may use R11 to synthesize certain instructions. Please
|
||||||
|
// take care and verify that no synthetic instructions use it.
|
||||||
|
|
||||||
|
TEXT poly1305_init_ext_armv6<>(SB), NOSPLIT, $0
|
||||||
|
// Needs 16 bytes of stack and 64 bytes of space pointed to by R0. (It
|
||||||
|
// might look like it's only 60 bytes of space but the final four bytes
|
||||||
|
// will be written by another function.) We need to skip over four
|
||||||
|
// bytes of stack because that's saving the value of 'g'.
|
||||||
|
ADD $4, R13, R8
|
||||||
|
MOVM.IB [R4-R7], (R8)
|
||||||
|
MOVM.IA.W (R1), [R2-R5]
|
||||||
|
MOVW $·poly1305_init_constants_armv6<>(SB), R7
|
||||||
|
MOVW R2, R8
|
||||||
|
MOVW R2>>26, R9
|
||||||
|
MOVW R3>>20, g
|
||||||
|
MOVW R4>>14, R11
|
||||||
|
MOVW R5>>8, R12
|
||||||
|
ORR R3<<6, R9, R9
|
||||||
|
ORR R4<<12, g, g
|
||||||
|
ORR R5<<18, R11, R11
|
||||||
|
MOVM.IA (R7), [R2-R6]
|
||||||
|
AND R8, R2, R2
|
||||||
|
AND R9, R3, R3
|
||||||
|
AND g, R4, R4
|
||||||
|
AND R11, R5, R5
|
||||||
|
AND R12, R6, R6
|
||||||
|
MOVM.IA.W [R2-R6], (R0)
|
||||||
|
EOR R2, R2, R2
|
||||||
|
EOR R3, R3, R3
|
||||||
|
EOR R4, R4, R4
|
||||||
|
EOR R5, R5, R5
|
||||||
|
EOR R6, R6, R6
|
||||||
|
MOVM.IA.W [R2-R6], (R0)
|
||||||
|
MOVM.IA.W (R1), [R2-R5]
|
||||||
|
MOVM.IA [R2-R6], (R0)
|
||||||
|
ADD $20, R13, R0
|
||||||
|
MOVM.DA (R0), [R4-R7]
|
||||||
|
RET
|
||||||
|
|
||||||
|
#define MOVW_UNALIGNED(Rsrc, Rdst, Rtmp, offset) \
|
||||||
|
MOVBU (offset+0)(Rsrc), Rtmp; \
|
||||||
|
MOVBU Rtmp, (offset+0)(Rdst); \
|
||||||
|
MOVBU (offset+1)(Rsrc), Rtmp; \
|
||||||
|
MOVBU Rtmp, (offset+1)(Rdst); \
|
||||||
|
MOVBU (offset+2)(Rsrc), Rtmp; \
|
||||||
|
MOVBU Rtmp, (offset+2)(Rdst); \
|
||||||
|
MOVBU (offset+3)(Rsrc), Rtmp; \
|
||||||
|
MOVBU Rtmp, (offset+3)(Rdst)
|
||||||
|
|
||||||
|
TEXT poly1305_blocks_armv6<>(SB), NOSPLIT, $0
|
||||||
|
// Needs 24 bytes of stack for saved registers and then 88 bytes of
|
||||||
|
// scratch space after that. We assume that 24 bytes at (R13) have
|
||||||
|
// already been used: four bytes for the link register saved in the
|
||||||
|
// prelude of poly1305_auth_armv6, four bytes for saving the value of g
|
||||||
|
// in that function and 16 bytes of scratch space used around
|
||||||
|
// poly1305_finish_ext_armv6_skip1.
|
||||||
|
ADD $24, R13, R12
|
||||||
|
MOVM.IB [R4-R8, R14], (R12)
|
||||||
|
MOVW R0, 88(R13)
|
||||||
|
MOVW R1, 92(R13)
|
||||||
|
MOVW R2, 96(R13)
|
||||||
|
MOVW R1, R14
|
||||||
|
MOVW R2, R12
|
||||||
|
MOVW 56(R0), R8
|
||||||
|
WORD $0xe1180008 // TST R8, R8 not working see issue 5921
|
||||||
|
EOR R6, R6, R6
|
||||||
|
MOVW.EQ $(1<<24), R6
|
||||||
|
MOVW R6, 84(R13)
|
||||||
|
ADD $116, R13, g
|
||||||
|
MOVM.IA (R0), [R0-R9]
|
||||||
|
MOVM.IA [R0-R4], (g)
|
||||||
|
CMP $16, R12
|
||||||
|
BLO poly1305_blocks_armv6_done
|
||||||
|
|
||||||
|
poly1305_blocks_armv6_mainloop:
|
||||||
|
WORD $0xe31e0003 // TST R14, #3 not working see issue 5921
|
||||||
|
BEQ poly1305_blocks_armv6_mainloop_aligned
|
||||||
|
ADD $100, R13, g
|
||||||
|
MOVW_UNALIGNED(R14, g, R0, 0)
|
||||||
|
MOVW_UNALIGNED(R14, g, R0, 4)
|
||||||
|
MOVW_UNALIGNED(R14, g, R0, 8)
|
||||||
|
MOVW_UNALIGNED(R14, g, R0, 12)
|
||||||
|
MOVM.IA (g), [R0-R3]
|
||||||
|
ADD $16, R14
|
||||||
|
B poly1305_blocks_armv6_mainloop_loaded
|
||||||
|
|
||||||
|
poly1305_blocks_armv6_mainloop_aligned:
|
||||||
|
MOVM.IA.W (R14), [R0-R3]
|
||||||
|
|
||||||
|
poly1305_blocks_armv6_mainloop_loaded:
|
||||||
|
MOVW R0>>26, g
|
||||||
|
MOVW R1>>20, R11
|
||||||
|
MOVW R2>>14, R12
|
||||||
|
MOVW R14, 92(R13)
|
||||||
|
MOVW R3>>8, R4
|
||||||
|
ORR R1<<6, g, g
|
||||||
|
ORR R2<<12, R11, R11
|
||||||
|
ORR R3<<18, R12, R12
|
||||||
|
BIC $0xfc000000, R0, R0
|
||||||
|
BIC $0xfc000000, g, g
|
||||||
|
MOVW 84(R13), R3
|
||||||
|
BIC $0xfc000000, R11, R11
|
||||||
|
BIC $0xfc000000, R12, R12
|
||||||
|
ADD R0, R5, R5
|
||||||
|
ADD g, R6, R6
|
||||||
|
ORR R3, R4, R4
|
||||||
|
ADD R11, R7, R7
|
||||||
|
ADD $116, R13, R14
|
||||||
|
ADD R12, R8, R8
|
||||||
|
ADD R4, R9, R9
|
||||||
|
MOVM.IA (R14), [R0-R4]
|
||||||
|
MULLU R4, R5, (R11, g)
|
||||||
|
MULLU R3, R5, (R14, R12)
|
||||||
|
MULALU R3, R6, (R11, g)
|
||||||
|
MULALU R2, R6, (R14, R12)
|
||||||
|
MULALU R2, R7, (R11, g)
|
||||||
|
MULALU R1, R7, (R14, R12)
|
||||||
|
ADD R4<<2, R4, R4
|
||||||
|
ADD R3<<2, R3, R3
|
||||||
|
MULALU R1, R8, (R11, g)
|
||||||
|
MULALU R0, R8, (R14, R12)
|
||||||
|
MULALU R0, R9, (R11, g)
|
||||||
|
MULALU R4, R9, (R14, R12)
|
||||||
|
MOVW g, 76(R13)
|
||||||
|
MOVW R11, 80(R13)
|
||||||
|
MOVW R12, 68(R13)
|
||||||
|
MOVW R14, 72(R13)
|
||||||
|
MULLU R2, R5, (R11, g)
|
||||||
|
MULLU R1, R5, (R14, R12)
|
||||||
|
MULALU R1, R6, (R11, g)
|
||||||
|
MULALU R0, R6, (R14, R12)
|
||||||
|
MULALU R0, R7, (R11, g)
|
||||||
|
MULALU R4, R7, (R14, R12)
|
||||||
|
ADD R2<<2, R2, R2
|
||||||
|
ADD R1<<2, R1, R1
|
||||||
|
MULALU R4, R8, (R11, g)
|
||||||
|
MULALU R3, R8, (R14, R12)
|
||||||
|
MULALU R3, R9, (R11, g)
|
||||||
|
MULALU R2, R9, (R14, R12)
|
||||||
|
MOVW g, 60(R13)
|
||||||
|
MOVW R11, 64(R13)
|
||||||
|
MOVW R12, 52(R13)
|
||||||
|
MOVW R14, 56(R13)
|
||||||
|
MULLU R0, R5, (R11, g)
|
||||||
|
MULALU R4, R6, (R11, g)
|
||||||
|
MULALU R3, R7, (R11, g)
|
||||||
|
MULALU R2, R8, (R11, g)
|
||||||
|
MULALU R1, R9, (R11, g)
|
||||||
|
ADD $52, R13, R0
|
||||||
|
MOVM.IA (R0), [R0-R7]
|
||||||
|
MOVW g>>26, R12
|
||||||
|
MOVW R4>>26, R14
|
||||||
|
ORR R11<<6, R12, R12
|
||||||
|
ORR R5<<6, R14, R14
|
||||||
|
BIC $0xfc000000, g, g
|
||||||
|
BIC $0xfc000000, R4, R4
|
||||||
|
ADD.S R12, R0, R0
|
||||||
|
ADC $0, R1, R1
|
||||||
|
ADD.S R14, R6, R6
|
||||||
|
ADC $0, R7, R7
|
||||||
|
MOVW R0>>26, R12
|
||||||
|
MOVW R6>>26, R14
|
||||||
|
ORR R1<<6, R12, R12
|
||||||
|
ORR R7<<6, R14, R14
|
||||||
|
BIC $0xfc000000, R0, R0
|
||||||
|
BIC $0xfc000000, R6, R6
|
||||||
|
ADD R14<<2, R14, R14
|
||||||
|
ADD.S R12, R2, R2
|
||||||
|
ADC $0, R3, R3
|
||||||
|
ADD R14, g, g
|
||||||
|
MOVW R2>>26, R12
|
||||||
|
MOVW g>>26, R14
|
||||||
|
ORR R3<<6, R12, R12
|
||||||
|
BIC $0xfc000000, g, R5
|
||||||
|
BIC $0xfc000000, R2, R7
|
||||||
|
ADD R12, R4, R4
|
||||||
|
ADD R14, R0, R0
|
||||||
|
MOVW R4>>26, R12
|
||||||
|
BIC $0xfc000000, R4, R8
|
||||||
|
ADD R12, R6, R9
|
||||||
|
MOVW 96(R13), R12
|
||||||
|
MOVW 92(R13), R14
|
||||||
|
MOVW R0, R6
|
||||||
|
CMP $32, R12
|
||||||
|
SUB $16, R12, R12
|
||||||
|
MOVW R12, 96(R13)
|
||||||
|
BHS poly1305_blocks_armv6_mainloop
|
||||||
|
|
||||||
|
poly1305_blocks_armv6_done:
|
||||||
|
MOVW 88(R13), R12
|
||||||
|
MOVW R5, 20(R12)
|
||||||
|
MOVW R6, 24(R12)
|
||||||
|
MOVW R7, 28(R12)
|
||||||
|
MOVW R8, 32(R12)
|
||||||
|
MOVW R9, 36(R12)
|
||||||
|
ADD $48, R13, R0
|
||||||
|
MOVM.DA (R0), [R4-R8, R14]
|
||||||
|
RET
|
||||||
|
|
||||||
|
#define MOVHUP_UNALIGNED(Rsrc, Rdst, Rtmp) \
|
||||||
|
MOVBU.P 1(Rsrc), Rtmp; \
|
||||||
|
MOVBU.P Rtmp, 1(Rdst); \
|
||||||
|
MOVBU.P 1(Rsrc), Rtmp; \
|
||||||
|
MOVBU.P Rtmp, 1(Rdst)
|
||||||
|
|
||||||
|
#define MOVWP_UNALIGNED(Rsrc, Rdst, Rtmp) \
|
||||||
|
MOVHUP_UNALIGNED(Rsrc, Rdst, Rtmp); \
|
||||||
|
MOVHUP_UNALIGNED(Rsrc, Rdst, Rtmp)
|
||||||
|
|
||||||
|
// func poly1305_auth_armv6(out *[16]byte, m *byte, mlen uint32, key *[32]key)
|
||||||
|
TEXT ·poly1305_auth_armv6(SB), $196-16
|
||||||
|
// The value 196, just above, is the sum of 64 (the size of the context
|
||||||
|
// structure) and 132 (the amount of stack needed).
|
||||||
|
//
|
||||||
|
// At this point, the stack pointer (R13) has been moved down. It
|
||||||
|
// points to the saved link register and there's 196 bytes of free
|
||||||
|
// space above it.
|
||||||
|
//
|
||||||
|
// The stack for this function looks like:
|
||||||
|
//
|
||||||
|
// +---------------------
|
||||||
|
// |
|
||||||
|
// | 64 bytes of context structure
|
||||||
|
// |
|
||||||
|
// +---------------------
|
||||||
|
// |
|
||||||
|
// | 112 bytes for poly1305_blocks_armv6
|
||||||
|
// |
|
||||||
|
// +---------------------
|
||||||
|
// | 16 bytes of final block, constructed at
|
||||||
|
// | poly1305_finish_ext_armv6_skip8
|
||||||
|
// +---------------------
|
||||||
|
// | four bytes of saved 'g'
|
||||||
|
// +---------------------
|
||||||
|
// | lr, saved by prelude <- R13 points here
|
||||||
|
// +---------------------
|
||||||
|
MOVW g, 4(R13)
|
||||||
|
|
||||||
|
MOVW out+0(FP), R4
|
||||||
|
MOVW m+4(FP), R5
|
||||||
|
MOVW mlen+8(FP), R6
|
||||||
|
MOVW key+12(FP), R7
|
||||||
|
|
||||||
|
ADD $136, R13, R0 // 136 = 4 + 4 + 16 + 112
|
||||||
|
MOVW R7, R1
|
||||||
|
|
||||||
|
// poly1305_init_ext_armv6 will write to the stack from R13+4, but
|
||||||
|
// that's ok because none of the other values have been written yet.
|
||||||
|
BL poly1305_init_ext_armv6<>(SB)
|
||||||
|
BIC.S $15, R6, R2
|
||||||
|
BEQ poly1305_auth_armv6_noblocks
|
||||||
|
ADD $136, R13, R0
|
||||||
|
MOVW R5, R1
|
||||||
|
ADD R2, R5, R5
|
||||||
|
SUB R2, R6, R6
|
||||||
|
BL poly1305_blocks_armv6<>(SB)
|
||||||
|
|
||||||
|
poly1305_auth_armv6_noblocks:
|
||||||
|
ADD $136, R13, R0
|
||||||
|
MOVW R5, R1
|
||||||
|
MOVW R6, R2
|
||||||
|
MOVW R4, R3
|
||||||
|
|
||||||
|
MOVW R0, R5
|
||||||
|
MOVW R1, R6
|
||||||
|
MOVW R2, R7
|
||||||
|
MOVW R3, R8
|
||||||
|
AND.S R2, R2, R2
|
||||||
|
BEQ poly1305_finish_ext_armv6_noremaining
|
||||||
|
EOR R0, R0
|
||||||
|
ADD $8, R13, R9 // 8 = offset to 16 byte scratch space
|
||||||
|
MOVW R0, (R9)
|
||||||
|
MOVW R0, 4(R9)
|
||||||
|
MOVW R0, 8(R9)
|
||||||
|
MOVW R0, 12(R9)
|
||||||
|
WORD $0xe3110003 // TST R1, #3 not working see issue 5921
|
||||||
|
BEQ poly1305_finish_ext_armv6_aligned
|
||||||
|
WORD $0xe3120008 // TST R2, #8 not working see issue 5921
|
||||||
|
BEQ poly1305_finish_ext_armv6_skip8
|
||||||
|
MOVWP_UNALIGNED(R1, R9, g)
|
||||||
|
MOVWP_UNALIGNED(R1, R9, g)
|
||||||
|
|
||||||
|
poly1305_finish_ext_armv6_skip8:
|
||||||
|
WORD $0xe3120004 // TST $4, R2 not working see issue 5921
|
||||||
|
BEQ poly1305_finish_ext_armv6_skip4
|
||||||
|
MOVWP_UNALIGNED(R1, R9, g)
|
||||||
|
|
||||||
|
poly1305_finish_ext_armv6_skip4:
|
||||||
|
WORD $0xe3120002 // TST $2, R2 not working see issue 5921
|
||||||
|
BEQ poly1305_finish_ext_armv6_skip2
|
||||||
|
MOVHUP_UNALIGNED(R1, R9, g)
|
||||||
|
B poly1305_finish_ext_armv6_skip2
|
||||||
|
|
||||||
|
poly1305_finish_ext_armv6_aligned:
|
||||||
|
WORD $0xe3120008 // TST R2, #8 not working see issue 5921
|
||||||
|
BEQ poly1305_finish_ext_armv6_skip8_aligned
|
||||||
|
MOVM.IA.W (R1), [g-R11]
|
||||||
|
MOVM.IA.W [g-R11], (R9)
|
||||||
|
|
||||||
|
poly1305_finish_ext_armv6_skip8_aligned:
|
||||||
|
WORD $0xe3120004 // TST $4, R2 not working see issue 5921
|
||||||
|
BEQ poly1305_finish_ext_armv6_skip4_aligned
|
||||||
|
MOVW.P 4(R1), g
|
||||||
|
MOVW.P g, 4(R9)
|
||||||
|
|
||||||
|
poly1305_finish_ext_armv6_skip4_aligned:
|
||||||
|
WORD $0xe3120002 // TST $2, R2 not working see issue 5921
|
||||||
|
BEQ poly1305_finish_ext_armv6_skip2
|
||||||
|
MOVHU.P 2(R1), g
|
||||||
|
MOVH.P g, 2(R9)
|
||||||
|
|
||||||
|
poly1305_finish_ext_armv6_skip2:
|
||||||
|
WORD $0xe3120001 // TST $1, R2 not working see issue 5921
|
||||||
|
BEQ poly1305_finish_ext_armv6_skip1
|
||||||
|
MOVBU.P 1(R1), g
|
||||||
|
MOVBU.P g, 1(R9)
|
||||||
|
|
||||||
|
poly1305_finish_ext_armv6_skip1:
|
||||||
|
MOVW $1, R11
|
||||||
|
MOVBU R11, 0(R9)
|
||||||
|
MOVW R11, 56(R5)
|
||||||
|
MOVW R5, R0
|
||||||
|
ADD $8, R13, R1
|
||||||
|
MOVW $16, R2
|
||||||
|
BL poly1305_blocks_armv6<>(SB)
|
||||||
|
|
||||||
|
poly1305_finish_ext_armv6_noremaining:
|
||||||
|
MOVW 20(R5), R0
|
||||||
|
MOVW 24(R5), R1
|
||||||
|
MOVW 28(R5), R2
|
||||||
|
MOVW 32(R5), R3
|
||||||
|
MOVW 36(R5), R4
|
||||||
|
MOVW R4>>26, R12
|
||||||
|
BIC $0xfc000000, R4, R4
|
||||||
|
ADD R12<<2, R12, R12
|
||||||
|
ADD R12, R0, R0
|
||||||
|
MOVW R0>>26, R12
|
||||||
|
BIC $0xfc000000, R0, R0
|
||||||
|
ADD R12, R1, R1
|
||||||
|
MOVW R1>>26, R12
|
||||||
|
BIC $0xfc000000, R1, R1
|
||||||
|
ADD R12, R2, R2
|
||||||
|
MOVW R2>>26, R12
|
||||||
|
BIC $0xfc000000, R2, R2
|
||||||
|
ADD R12, R3, R3
|
||||||
|
MOVW R3>>26, R12
|
||||||
|
BIC $0xfc000000, R3, R3
|
||||||
|
ADD R12, R4, R4
|
||||||
|
ADD $5, R0, R6
|
||||||
|
MOVW R6>>26, R12
|
||||||
|
BIC $0xfc000000, R6, R6
|
||||||
|
ADD R12, R1, R7
|
||||||
|
MOVW R7>>26, R12
|
||||||
|
BIC $0xfc000000, R7, R7
|
||||||
|
ADD R12, R2, g
|
||||||
|
MOVW g>>26, R12
|
||||||
|
BIC $0xfc000000, g, g
|
||||||
|
ADD R12, R3, R11
|
||||||
|
MOVW $-(1<<26), R12
|
||||||
|
ADD R11>>26, R12, R12
|
||||||
|
BIC $0xfc000000, R11, R11
|
||||||
|
ADD R12, R4, R9
|
||||||
|
MOVW R9>>31, R12
|
||||||
|
SUB $1, R12
|
||||||
|
AND R12, R6, R6
|
||||||
|
AND R12, R7, R7
|
||||||
|
AND R12, g, g
|
||||||
|
AND R12, R11, R11
|
||||||
|
AND R12, R9, R9
|
||||||
|
MVN R12, R12
|
||||||
|
AND R12, R0, R0
|
||||||
|
AND R12, R1, R1
|
||||||
|
AND R12, R2, R2
|
||||||
|
AND R12, R3, R3
|
||||||
|
AND R12, R4, R4
|
||||||
|
ORR R6, R0, R0
|
||||||
|
ORR R7, R1, R1
|
||||||
|
ORR g, R2, R2
|
||||||
|
ORR R11, R3, R3
|
||||||
|
ORR R9, R4, R4
|
||||||
|
ORR R1<<26, R0, R0
|
||||||
|
MOVW R1>>6, R1
|
||||||
|
ORR R2<<20, R1, R1
|
||||||
|
MOVW R2>>12, R2
|
||||||
|
ORR R3<<14, R2, R2
|
||||||
|
MOVW R3>>18, R3
|
||||||
|
ORR R4<<8, R3, R3
|
||||||
|
MOVW 40(R5), R6
|
||||||
|
MOVW 44(R5), R7
|
||||||
|
MOVW 48(R5), g
|
||||||
|
MOVW 52(R5), R11
|
||||||
|
ADD.S R6, R0, R0
|
||||||
|
ADC.S R7, R1, R1
|
||||||
|
ADC.S g, R2, R2
|
||||||
|
ADC.S R11, R3, R3
|
||||||
|
MOVM.IA [R0-R3], (R8)
|
||||||
|
MOVW R5, R12
|
||||||
|
EOR R0, R0, R0
|
||||||
|
EOR R1, R1, R1
|
||||||
|
EOR R2, R2, R2
|
||||||
|
EOR R3, R3, R3
|
||||||
|
EOR R4, R4, R4
|
||||||
|
EOR R5, R5, R5
|
||||||
|
EOR R6, R6, R6
|
||||||
|
EOR R7, R7, R7
|
||||||
|
MOVM.IA.W [R0-R7], (R12)
|
||||||
|
MOVM.IA [R0-R7], (R12)
|
||||||
|
MOVW 4(R13), g
|
||||||
|
RET
|
374
vendor/golang.org/x/crypto/poly1305/sum_generic.go
generated
vendored
374
vendor/golang.org/x/crypto/poly1305/sum_generic.go
generated
vendored
@ -2,309 +2,171 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// This file provides the generic implementation of Sum and MAC. Other files
|
|
||||||
// might provide optimized assembly implementations of some of this code.
|
|
||||||
|
|
||||||
package poly1305
|
package poly1305
|
||||||
|
|
||||||
import "encoding/binary"
|
import "encoding/binary"
|
||||||
|
|
||||||
// Poly1305 [RFC 7539] is a relatively simple algorithm: the authentication tag
|
const (
|
||||||
// for a 64 bytes message is approximately
|
msgBlock = uint32(1 << 24)
|
||||||
//
|
finalBlock = uint32(0)
|
||||||
// s + m[0:16] * r⁴ + m[16:32] * r³ + m[32:48] * r² + m[48:64] * r mod 2¹³⁰ - 5
|
)
|
||||||
//
|
|
||||||
// for some secret r and s. It can be computed sequentially like
|
|
||||||
//
|
|
||||||
// for len(msg) > 0:
|
|
||||||
// h += read(msg, 16)
|
|
||||||
// h *= r
|
|
||||||
// h %= 2¹³⁰ - 5
|
|
||||||
// return h + s
|
|
||||||
//
|
|
||||||
// All the complexity is about doing performant constant-time math on numbers
|
|
||||||
// larger than any available numeric type.
|
|
||||||
|
|
||||||
|
// sumGeneric generates an authenticator for msg using a one-time key and
|
||||||
|
// puts the 16-byte result into out. This is the generic implementation of
|
||||||
|
// Sum and should be called if no assembly implementation is available.
|
||||||
func sumGeneric(out *[TagSize]byte, msg []byte, key *[32]byte) {
|
func sumGeneric(out *[TagSize]byte, msg []byte, key *[32]byte) {
|
||||||
h := newMACGeneric(key)
|
h := newMACGeneric(key)
|
||||||
h.Write(msg)
|
h.Write(msg)
|
||||||
h.Sum(out)
|
h.Sum(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMACGeneric(key *[32]byte) macGeneric {
|
func newMACGeneric(key *[32]byte) (h macGeneric) {
|
||||||
m := macGeneric{}
|
h.r[0] = binary.LittleEndian.Uint32(key[0:]) & 0x3ffffff
|
||||||
initialize(key, &m.macState)
|
h.r[1] = (binary.LittleEndian.Uint32(key[3:]) >> 2) & 0x3ffff03
|
||||||
return m
|
h.r[2] = (binary.LittleEndian.Uint32(key[6:]) >> 4) & 0x3ffc0ff
|
||||||
}
|
h.r[3] = (binary.LittleEndian.Uint32(key[9:]) >> 6) & 0x3f03fff
|
||||||
|
h.r[4] = (binary.LittleEndian.Uint32(key[12:]) >> 8) & 0x00fffff
|
||||||
|
|
||||||
// macState holds numbers in saturated 64-bit little-endian limbs. That is,
|
h.s[0] = binary.LittleEndian.Uint32(key[16:])
|
||||||
// the value of [x0, x1, x2] is x[0] + x[1] * 2⁶⁴ + x[2] * 2¹²⁸.
|
h.s[1] = binary.LittleEndian.Uint32(key[20:])
|
||||||
type macState struct {
|
h.s[2] = binary.LittleEndian.Uint32(key[24:])
|
||||||
// h is the main accumulator. It is to be interpreted modulo 2¹³⁰ - 5, but
|
h.s[3] = binary.LittleEndian.Uint32(key[28:])
|
||||||
// can grow larger during and after rounds. It must, however, remain below
|
return
|
||||||
// 2 * (2¹³⁰ - 5).
|
|
||||||
h [3]uint64
|
|
||||||
// r and s are the private key components.
|
|
||||||
r [2]uint64
|
|
||||||
s [2]uint64
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type macGeneric struct {
|
type macGeneric struct {
|
||||||
macState
|
h, r [5]uint32
|
||||||
|
s [4]uint32
|
||||||
|
|
||||||
buffer [TagSize]byte
|
buffer [TagSize]byte
|
||||||
offset int
|
offset int
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write splits the incoming message into TagSize chunks, and passes them to
|
func (h *macGeneric) Write(p []byte) (n int, err error) {
|
||||||
// update. It buffers incomplete chunks.
|
n = len(p)
|
||||||
func (h *macGeneric) Write(p []byte) (int, error) {
|
|
||||||
nn := len(p)
|
|
||||||
if h.offset > 0 {
|
if h.offset > 0 {
|
||||||
n := copy(h.buffer[h.offset:], p)
|
remaining := TagSize - h.offset
|
||||||
if h.offset+n < TagSize {
|
if n < remaining {
|
||||||
h.offset += n
|
h.offset += copy(h.buffer[h.offset:], p)
|
||||||
return nn, nil
|
return n, nil
|
||||||
}
|
}
|
||||||
p = p[n:]
|
copy(h.buffer[h.offset:], p[:remaining])
|
||||||
|
p = p[remaining:]
|
||||||
h.offset = 0
|
h.offset = 0
|
||||||
updateGeneric(&h.macState, h.buffer[:])
|
updateGeneric(h.buffer[:], msgBlock, &(h.h), &(h.r))
|
||||||
}
|
}
|
||||||
if n := len(p) - (len(p) % TagSize); n > 0 {
|
if nn := len(p) - (len(p) % TagSize); nn > 0 {
|
||||||
updateGeneric(&h.macState, p[:n])
|
updateGeneric(p, msgBlock, &(h.h), &(h.r))
|
||||||
p = p[n:]
|
p = p[nn:]
|
||||||
}
|
}
|
||||||
if len(p) > 0 {
|
if len(p) > 0 {
|
||||||
h.offset += copy(h.buffer[h.offset:], p)
|
h.offset += copy(h.buffer[h.offset:], p)
|
||||||
}
|
}
|
||||||
return nn, nil
|
return n, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sum flushes the last incomplete chunk from the buffer, if any, and generates
|
func (h *macGeneric) Sum(out *[16]byte) {
|
||||||
// the MAC output. It does not modify its state, in order to allow for multiple
|
H, R := h.h, h.r
|
||||||
// calls to Sum, even if no Write is allowed after Sum.
|
|
||||||
func (h *macGeneric) Sum(out *[TagSize]byte) {
|
|
||||||
state := h.macState
|
|
||||||
if h.offset > 0 {
|
if h.offset > 0 {
|
||||||
updateGeneric(&state, h.buffer[:h.offset])
|
var buffer [TagSize]byte
|
||||||
|
copy(buffer[:], h.buffer[:h.offset])
|
||||||
|
buffer[h.offset] = 1 // invariant: h.offset < TagSize
|
||||||
|
updateGeneric(buffer[:], finalBlock, &H, &R)
|
||||||
}
|
}
|
||||||
finalize(out, &state.h, &state.s)
|
finalizeGeneric(out, &H, &(h.s))
|
||||||
}
|
}
|
||||||
|
|
||||||
// [rMask0, rMask1] is the specified Poly1305 clamping mask in little-endian. It
|
func updateGeneric(msg []byte, flag uint32, h, r *[5]uint32) {
|
||||||
// clears some bits of the secret coefficient to make it possible to implement
|
h0, h1, h2, h3, h4 := h[0], h[1], h[2], h[3], h[4]
|
||||||
// multiplication more efficiently.
|
r0, r1, r2, r3, r4 := uint64(r[0]), uint64(r[1]), uint64(r[2]), uint64(r[3]), uint64(r[4])
|
||||||
const (
|
R1, R2, R3, R4 := r1*5, r2*5, r3*5, r4*5
|
||||||
rMask0 = 0x0FFFFFFC0FFFFFFF
|
|
||||||
rMask1 = 0x0FFFFFFC0FFFFFFC
|
|
||||||
)
|
|
||||||
|
|
||||||
// initialize loads the 256-bit key into the two 128-bit secret values r and s.
|
for len(msg) >= TagSize {
|
||||||
func initialize(key *[32]byte, m *macState) {
|
// h += msg
|
||||||
m.r[0] = binary.LittleEndian.Uint64(key[0:8]) & rMask0
|
h0 += binary.LittleEndian.Uint32(msg[0:]) & 0x3ffffff
|
||||||
m.r[1] = binary.LittleEndian.Uint64(key[8:16]) & rMask1
|
h1 += (binary.LittleEndian.Uint32(msg[3:]) >> 2) & 0x3ffffff
|
||||||
m.s[0] = binary.LittleEndian.Uint64(key[16:24])
|
h2 += (binary.LittleEndian.Uint32(msg[6:]) >> 4) & 0x3ffffff
|
||||||
m.s[1] = binary.LittleEndian.Uint64(key[24:32])
|
h3 += (binary.LittleEndian.Uint32(msg[9:]) >> 6) & 0x3ffffff
|
||||||
}
|
h4 += (binary.LittleEndian.Uint32(msg[12:]) >> 8) | flag
|
||||||
|
|
||||||
// uint128 holds a 128-bit number as two 64-bit limbs, for use with the
|
// h *= r
|
||||||
// bits.Mul64 and bits.Add64 intrinsics.
|
d0 := (uint64(h0) * r0) + (uint64(h1) * R4) + (uint64(h2) * R3) + (uint64(h3) * R2) + (uint64(h4) * R1)
|
||||||
type uint128 struct {
|
d1 := (d0 >> 26) + (uint64(h0) * r1) + (uint64(h1) * r0) + (uint64(h2) * R4) + (uint64(h3) * R3) + (uint64(h4) * R2)
|
||||||
lo, hi uint64
|
d2 := (d1 >> 26) + (uint64(h0) * r2) + (uint64(h1) * r1) + (uint64(h2) * r0) + (uint64(h3) * R4) + (uint64(h4) * R3)
|
||||||
}
|
d3 := (d2 >> 26) + (uint64(h0) * r3) + (uint64(h1) * r2) + (uint64(h2) * r1) + (uint64(h3) * r0) + (uint64(h4) * R4)
|
||||||
|
d4 := (d3 >> 26) + (uint64(h0) * r4) + (uint64(h1) * r3) + (uint64(h2) * r2) + (uint64(h3) * r1) + (uint64(h4) * r0)
|
||||||
|
|
||||||
func mul64(a, b uint64) uint128 {
|
// h %= p
|
||||||
hi, lo := bitsMul64(a, b)
|
h0 = uint32(d0) & 0x3ffffff
|
||||||
return uint128{lo, hi}
|
h1 = uint32(d1) & 0x3ffffff
|
||||||
}
|
h2 = uint32(d2) & 0x3ffffff
|
||||||
|
h3 = uint32(d3) & 0x3ffffff
|
||||||
|
h4 = uint32(d4) & 0x3ffffff
|
||||||
|
|
||||||
func add128(a, b uint128) uint128 {
|
h0 += uint32(d4>>26) * 5
|
||||||
lo, c := bitsAdd64(a.lo, b.lo, 0)
|
h1 += h0 >> 26
|
||||||
hi, c := bitsAdd64(a.hi, b.hi, c)
|
h0 = h0 & 0x3ffffff
|
||||||
if c != 0 {
|
|
||||||
panic("poly1305: unexpected overflow")
|
|
||||||
}
|
|
||||||
return uint128{lo, hi}
|
|
||||||
}
|
|
||||||
|
|
||||||
func shiftRightBy2(a uint128) uint128 {
|
msg = msg[TagSize:]
|
||||||
a.lo = a.lo>>2 | (a.hi&3)<<62
|
|
||||||
a.hi = a.hi >> 2
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
|
|
||||||
// updateGeneric absorbs msg into the state.h accumulator. For each chunk m of
|
|
||||||
// 128 bits of message, it computes
|
|
||||||
//
|
|
||||||
// h₊ = (h + m) * r mod 2¹³⁰ - 5
|
|
||||||
//
|
|
||||||
// If the msg length is not a multiple of TagSize, it assumes the last
|
|
||||||
// incomplete chunk is the final one.
|
|
||||||
func updateGeneric(state *macState, msg []byte) {
|
|
||||||
h0, h1, h2 := state.h[0], state.h[1], state.h[2]
|
|
||||||
r0, r1 := state.r[0], state.r[1]
|
|
||||||
|
|
||||||
for len(msg) > 0 {
|
|
||||||
var c uint64
|
|
||||||
|
|
||||||
// For the first step, h + m, we use a chain of bits.Add64 intrinsics.
|
|
||||||
// The resulting value of h might exceed 2¹³⁰ - 5, but will be partially
|
|
||||||
// reduced at the end of the multiplication below.
|
|
||||||
//
|
|
||||||
// The spec requires us to set a bit just above the message size, not to
|
|
||||||
// hide leading zeroes. For full chunks, that's 1 << 128, so we can just
|
|
||||||
// add 1 to the most significant (2¹²⁸) limb, h2.
|
|
||||||
if len(msg) >= TagSize {
|
|
||||||
h0, c = bitsAdd64(h0, binary.LittleEndian.Uint64(msg[0:8]), 0)
|
|
||||||
h1, c = bitsAdd64(h1, binary.LittleEndian.Uint64(msg[8:16]), c)
|
|
||||||
h2 += c + 1
|
|
||||||
|
|
||||||
msg = msg[TagSize:]
|
|
||||||
} else {
|
|
||||||
var buf [TagSize]byte
|
|
||||||
copy(buf[:], msg)
|
|
||||||
buf[len(msg)] = 1
|
|
||||||
|
|
||||||
h0, c = bitsAdd64(h0, binary.LittleEndian.Uint64(buf[0:8]), 0)
|
|
||||||
h1, c = bitsAdd64(h1, binary.LittleEndian.Uint64(buf[8:16]), c)
|
|
||||||
h2 += c
|
|
||||||
|
|
||||||
msg = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Multiplication of big number limbs is similar to elementary school
|
|
||||||
// columnar multiplication. Instead of digits, there are 64-bit limbs.
|
|
||||||
//
|
|
||||||
// We are multiplying a 3 limbs number, h, by a 2 limbs number, r.
|
|
||||||
//
|
|
||||||
// h2 h1 h0 x
|
|
||||||
// r1 r0 =
|
|
||||||
// ----------------
|
|
||||||
// h2r0 h1r0 h0r0 <-- individual 128-bit products
|
|
||||||
// + h2r1 h1r1 h0r1
|
|
||||||
// ------------------------
|
|
||||||
// m3 m2 m1 m0 <-- result in 128-bit overlapping limbs
|
|
||||||
// ------------------------
|
|
||||||
// m3.hi m2.hi m1.hi m0.hi <-- carry propagation
|
|
||||||
// + m3.lo m2.lo m1.lo m0.lo
|
|
||||||
// -------------------------------
|
|
||||||
// t4 t3 t2 t1 t0 <-- final result in 64-bit limbs
|
|
||||||
//
|
|
||||||
// The main difference from pen-and-paper multiplication is that we do
|
|
||||||
// carry propagation in a separate step, as if we wrote two digit sums
|
|
||||||
// at first (the 128-bit limbs), and then carried the tens all at once.
|
|
||||||
|
|
||||||
h0r0 := mul64(h0, r0)
|
|
||||||
h1r0 := mul64(h1, r0)
|
|
||||||
h2r0 := mul64(h2, r0)
|
|
||||||
h0r1 := mul64(h0, r1)
|
|
||||||
h1r1 := mul64(h1, r1)
|
|
||||||
h2r1 := mul64(h2, r1)
|
|
||||||
|
|
||||||
// Since h2 is known to be at most 7 (5 + 1 + 1), and r0 and r1 have their
|
|
||||||
// top 4 bits cleared by rMask{0,1}, we know that their product is not going
|
|
||||||
// to overflow 64 bits, so we can ignore the high part of the products.
|
|
||||||
//
|
|
||||||
// This also means that the product doesn't have a fifth limb (t4).
|
|
||||||
if h2r0.hi != 0 {
|
|
||||||
panic("poly1305: unexpected overflow")
|
|
||||||
}
|
|
||||||
if h2r1.hi != 0 {
|
|
||||||
panic("poly1305: unexpected overflow")
|
|
||||||
}
|
|
||||||
|
|
||||||
m0 := h0r0
|
|
||||||
m1 := add128(h1r0, h0r1) // These two additions don't overflow thanks again
|
|
||||||
m2 := add128(h2r0, h1r1) // to the 4 masked bits at the top of r0 and r1.
|
|
||||||
m3 := h2r1
|
|
||||||
|
|
||||||
t0 := m0.lo
|
|
||||||
t1, c := bitsAdd64(m1.lo, m0.hi, 0)
|
|
||||||
t2, c := bitsAdd64(m2.lo, m1.hi, c)
|
|
||||||
t3, _ := bitsAdd64(m3.lo, m2.hi, c)
|
|
||||||
|
|
||||||
// Now we have the result as 4 64-bit limbs, and we need to reduce it
|
|
||||||
// modulo 2¹³⁰ - 5. The special shape of this Crandall prime lets us do
|
|
||||||
// a cheap partial reduction according to the reduction identity
|
|
||||||
//
|
|
||||||
// c * 2¹³⁰ + n = c * 5 + n mod 2¹³⁰ - 5
|
|
||||||
//
|
|
||||||
// because 2¹³⁰ = 5 mod 2¹³⁰ - 5. Partial reduction since the result is
|
|
||||||
// likely to be larger than 2¹³⁰ - 5, but still small enough to fit the
|
|
||||||
// assumptions we make about h in the rest of the code.
|
|
||||||
//
|
|
||||||
// See also https://speakerdeck.com/gtank/engineering-prime-numbers?slide=23
|
|
||||||
|
|
||||||
// We split the final result at the 2¹³⁰ mark into h and cc, the carry.
|
|
||||||
// Note that the carry bits are effectively shifted left by 2, in other
|
|
||||||
// words, cc = c * 4 for the c in the reduction identity.
|
|
||||||
h0, h1, h2 = t0, t1, t2&maskLow2Bits
|
|
||||||
cc := uint128{t2 & maskNotLow2Bits, t3}
|
|
||||||
|
|
||||||
// To add c * 5 to h, we first add cc = c * 4, and then add (cc >> 2) = c.
|
|
||||||
|
|
||||||
h0, c = bitsAdd64(h0, cc.lo, 0)
|
|
||||||
h1, c = bitsAdd64(h1, cc.hi, c)
|
|
||||||
h2 += c
|
|
||||||
|
|
||||||
cc = shiftRightBy2(cc)
|
|
||||||
|
|
||||||
h0, c = bitsAdd64(h0, cc.lo, 0)
|
|
||||||
h1, c = bitsAdd64(h1, cc.hi, c)
|
|
||||||
h2 += c
|
|
||||||
|
|
||||||
// h2 is at most 3 + 1 + 1 = 5, making the whole of h at most
|
|
||||||
//
|
|
||||||
// 5 * 2¹²⁸ + (2¹²⁸ - 1) = 6 * 2¹²⁸ - 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state.h[0], state.h[1], state.h[2] = h0, h1, h2
|
h[0], h[1], h[2], h[3], h[4] = h0, h1, h2, h3, h4
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
func finalizeGeneric(out *[TagSize]byte, h *[5]uint32, s *[4]uint32) {
|
||||||
maskLow2Bits uint64 = 0x0000000000000003
|
h0, h1, h2, h3, h4 := h[0], h[1], h[2], h[3], h[4]
|
||||||
maskNotLow2Bits uint64 = ^maskLow2Bits
|
|
||||||
)
|
|
||||||
|
|
||||||
// select64 returns x if v == 1 and y if v == 0, in constant time.
|
// h %= p reduction
|
||||||
func select64(v, x, y uint64) uint64 { return ^(v-1)&x | (v-1)&y }
|
h2 += h1 >> 26
|
||||||
|
h1 &= 0x3ffffff
|
||||||
|
h3 += h2 >> 26
|
||||||
|
h2 &= 0x3ffffff
|
||||||
|
h4 += h3 >> 26
|
||||||
|
h3 &= 0x3ffffff
|
||||||
|
h0 += 5 * (h4 >> 26)
|
||||||
|
h4 &= 0x3ffffff
|
||||||
|
h1 += h0 >> 26
|
||||||
|
h0 &= 0x3ffffff
|
||||||
|
|
||||||
// [p0, p1, p2] is 2¹³⁰ - 5 in little endian order.
|
// h - p
|
||||||
const (
|
t0 := h0 + 5
|
||||||
p0 = 0xFFFFFFFFFFFFFFFB
|
t1 := h1 + (t0 >> 26)
|
||||||
p1 = 0xFFFFFFFFFFFFFFFF
|
t2 := h2 + (t1 >> 26)
|
||||||
p2 = 0x0000000000000003
|
t3 := h3 + (t2 >> 26)
|
||||||
)
|
t4 := h4 + (t3 >> 26) - (1 << 26)
|
||||||
|
t0 &= 0x3ffffff
|
||||||
|
t1 &= 0x3ffffff
|
||||||
|
t2 &= 0x3ffffff
|
||||||
|
t3 &= 0x3ffffff
|
||||||
|
|
||||||
// finalize completes the modular reduction of h and computes
|
// select h if h < p else h - p
|
||||||
//
|
t_mask := (t4 >> 31) - 1
|
||||||
// out = h + s mod 2¹²⁸
|
h_mask := ^t_mask
|
||||||
//
|
h0 = (h0 & h_mask) | (t0 & t_mask)
|
||||||
func finalize(out *[TagSize]byte, h *[3]uint64, s *[2]uint64) {
|
h1 = (h1 & h_mask) | (t1 & t_mask)
|
||||||
h0, h1, h2 := h[0], h[1], h[2]
|
h2 = (h2 & h_mask) | (t2 & t_mask)
|
||||||
|
h3 = (h3 & h_mask) | (t3 & t_mask)
|
||||||
|
h4 = (h4 & h_mask) | (t4 & t_mask)
|
||||||
|
|
||||||
// After the partial reduction in updateGeneric, h might be more than
|
// h %= 2^128
|
||||||
// 2¹³⁰ - 5, but will be less than 2 * (2¹³⁰ - 5). To complete the reduction
|
h0 |= h1 << 26
|
||||||
// in constant time, we compute t = h - (2¹³⁰ - 5), and select h as the
|
h1 = ((h1 >> 6) | (h2 << 20))
|
||||||
// result if the subtraction underflows, and t otherwise.
|
h2 = ((h2 >> 12) | (h3 << 14))
|
||||||
|
h3 = ((h3 >> 18) | (h4 << 8))
|
||||||
|
|
||||||
hMinusP0, b := bitsSub64(h0, p0, 0)
|
// s: the s part of the key
|
||||||
hMinusP1, b := bitsSub64(h1, p1, b)
|
// tag = (h + s) % (2^128)
|
||||||
_, b = bitsSub64(h2, p2, b)
|
t := uint64(h0) + uint64(s[0])
|
||||||
|
h0 = uint32(t)
|
||||||
|
t = uint64(h1) + uint64(s[1]) + (t >> 32)
|
||||||
|
h1 = uint32(t)
|
||||||
|
t = uint64(h2) + uint64(s[2]) + (t >> 32)
|
||||||
|
h2 = uint32(t)
|
||||||
|
t = uint64(h3) + uint64(s[3]) + (t >> 32)
|
||||||
|
h3 = uint32(t)
|
||||||
|
|
||||||
// h = h if h < p else h - p
|
binary.LittleEndian.PutUint32(out[0:], h0)
|
||||||
h0 = select64(b, h0, hMinusP0)
|
binary.LittleEndian.PutUint32(out[4:], h1)
|
||||||
h1 = select64(b, h1, hMinusP1)
|
binary.LittleEndian.PutUint32(out[8:], h2)
|
||||||
|
binary.LittleEndian.PutUint32(out[12:], h3)
|
||||||
// Finally, we compute the last Poly1305 step
|
|
||||||
//
|
|
||||||
// tag = h + s mod 2¹²⁸
|
|
||||||
//
|
|
||||||
// by just doing a wide addition with the 128 low bits of h and discarding
|
|
||||||
// the overflow.
|
|
||||||
h0, c := bitsAdd64(h0, s[0], 0)
|
|
||||||
h1, _ = bitsAdd64(h1, s[1], c)
|
|
||||||
|
|
||||||
binary.LittleEndian.PutUint64(out[0:8], h0)
|
|
||||||
binary.LittleEndian.PutUint64(out[8:16], h1)
|
|
||||||
}
|
}
|
||||||
|
16
vendor/golang.org/x/crypto/poly1305/sum_noasm.go
generated
vendored
Normal file
16
vendor/golang.org/x/crypto/poly1305/sum_noasm.go
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build s390x,!go1.11 !arm,!amd64,!s390x gccgo appengine nacl
|
||||||
|
|
||||||
|
package poly1305
|
||||||
|
|
||||||
|
// Sum generates an authenticator for msg using a one-time key and puts the
|
||||||
|
// 16-byte result into out. Authenticating two different messages with the same
|
||||||
|
// key allows an attacker to forge messages at will.
|
||||||
|
func Sum(out *[TagSize]byte, msg []byte, key *[32]byte) {
|
||||||
|
h := newMAC(key)
|
||||||
|
h.Write(msg)
|
||||||
|
h.Sum(out)
|
||||||
|
}
|
47
vendor/golang.org/x/crypto/poly1305/sum_ppc64le.go
generated
vendored
47
vendor/golang.org/x/crypto/poly1305/sum_ppc64le.go
generated
vendored
@ -1,47 +0,0 @@
|
|||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build !gccgo,!purego
|
|
||||||
|
|
||||||
package poly1305
|
|
||||||
|
|
||||||
//go:noescape
|
|
||||||
func update(state *macState, msg []byte)
|
|
||||||
|
|
||||||
// mac is a wrapper for macGeneric that redirects calls that would have gone to
|
|
||||||
// updateGeneric to update.
|
|
||||||
//
|
|
||||||
// Its Write and Sum methods are otherwise identical to the macGeneric ones, but
|
|
||||||
// using function pointers would carry a major performance cost.
|
|
||||||
type mac struct{ macGeneric }
|
|
||||||
|
|
||||||
func (h *mac) Write(p []byte) (int, error) {
|
|
||||||
nn := len(p)
|
|
||||||
if h.offset > 0 {
|
|
||||||
n := copy(h.buffer[h.offset:], p)
|
|
||||||
if h.offset+n < TagSize {
|
|
||||||
h.offset += n
|
|
||||||
return nn, nil
|
|
||||||
}
|
|
||||||
p = p[n:]
|
|
||||||
h.offset = 0
|
|
||||||
update(&h.macState, h.buffer[:])
|
|
||||||
}
|
|
||||||
if n := len(p) - (len(p) % TagSize); n > 0 {
|
|
||||||
update(&h.macState, p[:n])
|
|
||||||
p = p[n:]
|
|
||||||
}
|
|
||||||
if len(p) > 0 {
|
|
||||||
h.offset += copy(h.buffer[h.offset:], p)
|
|
||||||
}
|
|
||||||
return nn, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *mac) Sum(out *[16]byte) {
|
|
||||||
state := h.macState
|
|
||||||
if h.offset > 0 {
|
|
||||||
update(&state, h.buffer[:h.offset])
|
|
||||||
}
|
|
||||||
finalize(out, &state.h, &state.s)
|
|
||||||
}
|
|
181
vendor/golang.org/x/crypto/poly1305/sum_ppc64le.s
generated
vendored
181
vendor/golang.org/x/crypto/poly1305/sum_ppc64le.s
generated
vendored
@ -1,181 +0,0 @@
|
|||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build !gccgo,!purego
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
// This was ported from the amd64 implementation.
|
|
||||||
|
|
||||||
#define POLY1305_ADD(msg, h0, h1, h2, t0, t1, t2) \
|
|
||||||
MOVD (msg), t0; \
|
|
||||||
MOVD 8(msg), t1; \
|
|
||||||
MOVD $1, t2; \
|
|
||||||
ADDC t0, h0, h0; \
|
|
||||||
ADDE t1, h1, h1; \
|
|
||||||
ADDE t2, h2; \
|
|
||||||
ADD $16, msg
|
|
||||||
|
|
||||||
#define POLY1305_MUL(h0, h1, h2, r0, r1, t0, t1, t2, t3, t4, t5) \
|
|
||||||
MULLD r0, h0, t0; \
|
|
||||||
MULLD r0, h1, t4; \
|
|
||||||
MULHDU r0, h0, t1; \
|
|
||||||
MULHDU r0, h1, t5; \
|
|
||||||
ADDC t4, t1, t1; \
|
|
||||||
MULLD r0, h2, t2; \
|
|
||||||
ADDZE t5; \
|
|
||||||
MULHDU r1, h0, t4; \
|
|
||||||
MULLD r1, h0, h0; \
|
|
||||||
ADD t5, t2, t2; \
|
|
||||||
ADDC h0, t1, t1; \
|
|
||||||
MULLD h2, r1, t3; \
|
|
||||||
ADDZE t4, h0; \
|
|
||||||
MULHDU r1, h1, t5; \
|
|
||||||
MULLD r1, h1, t4; \
|
|
||||||
ADDC t4, t2, t2; \
|
|
||||||
ADDE t5, t3, t3; \
|
|
||||||
ADDC h0, t2, t2; \
|
|
||||||
MOVD $-4, t4; \
|
|
||||||
MOVD t0, h0; \
|
|
||||||
MOVD t1, h1; \
|
|
||||||
ADDZE t3; \
|
|
||||||
ANDCC $3, t2, h2; \
|
|
||||||
AND t2, t4, t0; \
|
|
||||||
ADDC t0, h0, h0; \
|
|
||||||
ADDE t3, h1, h1; \
|
|
||||||
SLD $62, t3, t4; \
|
|
||||||
SRD $2, t2; \
|
|
||||||
ADDZE h2; \
|
|
||||||
OR t4, t2, t2; \
|
|
||||||
SRD $2, t3; \
|
|
||||||
ADDC t2, h0, h0; \
|
|
||||||
ADDE t3, h1, h1; \
|
|
||||||
ADDZE h2
|
|
||||||
|
|
||||||
DATA ·poly1305Mask<>+0x00(SB)/8, $0x0FFFFFFC0FFFFFFF
|
|
||||||
DATA ·poly1305Mask<>+0x08(SB)/8, $0x0FFFFFFC0FFFFFFC
|
|
||||||
GLOBL ·poly1305Mask<>(SB), RODATA, $16
|
|
||||||
|
|
||||||
// func update(state *[7]uint64, msg []byte)
|
|
||||||
TEXT ·update(SB), $0-32
|
|
||||||
MOVD state+0(FP), R3
|
|
||||||
MOVD msg_base+8(FP), R4
|
|
||||||
MOVD msg_len+16(FP), R5
|
|
||||||
|
|
||||||
MOVD 0(R3), R8 // h0
|
|
||||||
MOVD 8(R3), R9 // h1
|
|
||||||
MOVD 16(R3), R10 // h2
|
|
||||||
MOVD 24(R3), R11 // r0
|
|
||||||
MOVD 32(R3), R12 // r1
|
|
||||||
|
|
||||||
CMP R5, $16
|
|
||||||
BLT bytes_between_0_and_15
|
|
||||||
|
|
||||||
loop:
|
|
||||||
POLY1305_ADD(R4, R8, R9, R10, R20, R21, R22)
|
|
||||||
|
|
||||||
multiply:
|
|
||||||
POLY1305_MUL(R8, R9, R10, R11, R12, R16, R17, R18, R14, R20, R21)
|
|
||||||
ADD $-16, R5
|
|
||||||
CMP R5, $16
|
|
||||||
BGE loop
|
|
||||||
|
|
||||||
bytes_between_0_and_15:
|
|
||||||
CMP $0, R5
|
|
||||||
BEQ done
|
|
||||||
MOVD $0, R16 // h0
|
|
||||||
MOVD $0, R17 // h1
|
|
||||||
|
|
||||||
flush_buffer:
|
|
||||||
CMP R5, $8
|
|
||||||
BLE just1
|
|
||||||
|
|
||||||
MOVD $8, R21
|
|
||||||
SUB R21, R5, R21
|
|
||||||
|
|
||||||
// Greater than 8 -- load the rightmost remaining bytes in msg
|
|
||||||
// and put into R17 (h1)
|
|
||||||
MOVD (R4)(R21), R17
|
|
||||||
MOVD $16, R22
|
|
||||||
|
|
||||||
// Find the offset to those bytes
|
|
||||||
SUB R5, R22, R22
|
|
||||||
SLD $3, R22
|
|
||||||
|
|
||||||
// Shift to get only the bytes in msg
|
|
||||||
SRD R22, R17, R17
|
|
||||||
|
|
||||||
// Put 1 at high end
|
|
||||||
MOVD $1, R23
|
|
||||||
SLD $3, R21
|
|
||||||
SLD R21, R23, R23
|
|
||||||
OR R23, R17, R17
|
|
||||||
|
|
||||||
// Remainder is 8
|
|
||||||
MOVD $8, R5
|
|
||||||
|
|
||||||
just1:
|
|
||||||
CMP R5, $8
|
|
||||||
BLT less8
|
|
||||||
|
|
||||||
// Exactly 8
|
|
||||||
MOVD (R4), R16
|
|
||||||
|
|
||||||
CMP $0, R17
|
|
||||||
|
|
||||||
// Check if we've already set R17; if not
|
|
||||||
// set 1 to indicate end of msg.
|
|
||||||
BNE carry
|
|
||||||
MOVD $1, R17
|
|
||||||
BR carry
|
|
||||||
|
|
||||||
less8:
|
|
||||||
MOVD $0, R16 // h0
|
|
||||||
MOVD $0, R22 // shift count
|
|
||||||
CMP R5, $4
|
|
||||||
BLT less4
|
|
||||||
MOVWZ (R4), R16
|
|
||||||
ADD $4, R4
|
|
||||||
ADD $-4, R5
|
|
||||||
MOVD $32, R22
|
|
||||||
|
|
||||||
less4:
|
|
||||||
CMP R5, $2
|
|
||||||
BLT less2
|
|
||||||
MOVHZ (R4), R21
|
|
||||||
SLD R22, R21, R21
|
|
||||||
OR R16, R21, R16
|
|
||||||
ADD $16, R22
|
|
||||||
ADD $-2, R5
|
|
||||||
ADD $2, R4
|
|
||||||
|
|
||||||
less2:
|
|
||||||
CMP $0, R5
|
|
||||||
BEQ insert1
|
|
||||||
MOVBZ (R4), R21
|
|
||||||
SLD R22, R21, R21
|
|
||||||
OR R16, R21, R16
|
|
||||||
ADD $8, R22
|
|
||||||
|
|
||||||
insert1:
|
|
||||||
// Insert 1 at end of msg
|
|
||||||
MOVD $1, R21
|
|
||||||
SLD R22, R21, R21
|
|
||||||
OR R16, R21, R16
|
|
||||||
|
|
||||||
carry:
|
|
||||||
// Add new values to h0, h1, h2
|
|
||||||
ADDC R16, R8
|
|
||||||
ADDE R17, R9
|
|
||||||
ADDE $0, R10
|
|
||||||
MOVD $16, R5
|
|
||||||
ADD R5, R4
|
|
||||||
BR multiply
|
|
||||||
|
|
||||||
done:
|
|
||||||
// Save h0, h1, h2 in state
|
|
||||||
MOVD R8, 0(R3)
|
|
||||||
MOVD R9, 8(R3)
|
|
||||||
MOVD R10, 16(R3)
|
|
||||||
RET
|
|
75
vendor/golang.org/x/crypto/poly1305/sum_s390x.go
generated
vendored
75
vendor/golang.org/x/crypto/poly1305/sum_s390x.go
generated
vendored
@ -2,7 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build !gccgo,!purego
|
// +build s390x,go1.11,!gccgo,!appengine
|
||||||
|
|
||||||
package poly1305
|
package poly1305
|
||||||
|
|
||||||
@ -10,66 +10,33 @@ import (
|
|||||||
"golang.org/x/sys/cpu"
|
"golang.org/x/sys/cpu"
|
||||||
)
|
)
|
||||||
|
|
||||||
// updateVX is an assembly implementation of Poly1305 that uses vector
|
// poly1305vx is an assembly implementation of Poly1305 that uses vector
|
||||||
// instructions. It must only be called if the vector facility (vx) is
|
// instructions. It must only be called if the vector facility (vx) is
|
||||||
// available.
|
// available.
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func updateVX(state *macState, msg []byte)
|
func poly1305vx(out *[16]byte, m *byte, mlen uint64, key *[32]byte)
|
||||||
|
|
||||||
// mac is a replacement for macGeneric that uses a larger buffer and redirects
|
// poly1305vmsl is an assembly implementation of Poly1305 that uses vector
|
||||||
// calls that would have gone to updateGeneric to updateVX if the vector
|
// instructions, including VMSL. It must only be called if the vector facility (vx) is
|
||||||
// facility is installed.
|
// available and if VMSL is supported.
|
||||||
//
|
//go:noescape
|
||||||
// A larger buffer is required for good performance because the vector
|
func poly1305vmsl(out *[16]byte, m *byte, mlen uint64, key *[32]byte)
|
||||||
// implementation has a higher fixed cost per call than the generic
|
|
||||||
// implementation.
|
|
||||||
type mac struct {
|
|
||||||
macState
|
|
||||||
|
|
||||||
buffer [16 * TagSize]byte // size must be a multiple of block size (16)
|
// Sum generates an authenticator for m using a one-time key and puts the
|
||||||
offset int
|
// 16-byte result into out. Authenticating two different messages with the same
|
||||||
}
|
// key allows an attacker to forge messages at will.
|
||||||
|
func Sum(out *[16]byte, m []byte, key *[32]byte) {
|
||||||
func (h *mac) Write(p []byte) (int, error) {
|
if cpu.S390X.HasVX {
|
||||||
nn := len(p)
|
var mPtr *byte
|
||||||
if h.offset > 0 {
|
if len(m) > 0 {
|
||||||
n := copy(h.buffer[h.offset:], p)
|
mPtr = &m[0]
|
||||||
if h.offset+n < len(h.buffer) {
|
|
||||||
h.offset += n
|
|
||||||
return nn, nil
|
|
||||||
}
|
}
|
||||||
p = p[n:]
|
if cpu.S390X.HasVXE && len(m) > 256 {
|
||||||
h.offset = 0
|
poly1305vmsl(out, mPtr, uint64(len(m)), key)
|
||||||
if cpu.S390X.HasVX {
|
|
||||||
updateVX(&h.macState, h.buffer[:])
|
|
||||||
} else {
|
} else {
|
||||||
updateGeneric(&h.macState, h.buffer[:])
|
poly1305vx(out, mPtr, uint64(len(m)), key)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
sumGeneric(out, m, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
tail := len(p) % len(h.buffer) // number of bytes to copy into buffer
|
|
||||||
body := len(p) - tail // number of bytes to process now
|
|
||||||
if body > 0 {
|
|
||||||
if cpu.S390X.HasVX {
|
|
||||||
updateVX(&h.macState, p[:body])
|
|
||||||
} else {
|
|
||||||
updateGeneric(&h.macState, p[:body])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
h.offset = copy(h.buffer[:], p[body:]) // copy tail bytes - can be 0
|
|
||||||
return nn, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *mac) Sum(out *[TagSize]byte) {
|
|
||||||
state := h.macState
|
|
||||||
remainder := h.buffer[:h.offset]
|
|
||||||
|
|
||||||
// Use the generic implementation if we have 2 or fewer blocks left
|
|
||||||
// to sum. The vector implementation has a higher startup time.
|
|
||||||
if cpu.S390X.HasVX && len(remainder) > 2*TagSize {
|
|
||||||
updateVX(&state, remainder)
|
|
||||||
} else if len(remainder) > 0 {
|
|
||||||
updateGeneric(&state, remainder)
|
|
||||||
}
|
|
||||||
finalize(out, &state.h, &state.s)
|
|
||||||
}
|
}
|
||||||
|
627
vendor/golang.org/x/crypto/poly1305/sum_s390x.s
generated
vendored
627
vendor/golang.org/x/crypto/poly1305/sum_s390x.s
generated
vendored
@ -2,187 +2,115 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build !gccgo,!purego
|
// +build s390x,go1.11,!gccgo,!appengine
|
||||||
|
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
|
|
||||||
// This implementation of Poly1305 uses the vector facility (vx)
|
// Implementation of Poly1305 using the vector facility (vx).
|
||||||
// to process up to 2 blocks (32 bytes) per iteration using an
|
|
||||||
// algorithm based on the one described in:
|
|
||||||
//
|
|
||||||
// NEON crypto, Daniel J. Bernstein & Peter Schwabe
|
|
||||||
// https://cryptojedi.org/papers/neoncrypto-20120320.pdf
|
|
||||||
//
|
|
||||||
// This algorithm uses 5 26-bit limbs to represent a 130-bit
|
|
||||||
// value. These limbs are, for the most part, zero extended and
|
|
||||||
// placed into 64-bit vector register elements. Each vector
|
|
||||||
// register is 128-bits wide and so holds 2 of these elements.
|
|
||||||
// Using 26-bit limbs allows us plenty of headroom to accomodate
|
|
||||||
// accumulations before and after multiplication without
|
|
||||||
// overflowing either 32-bits (before multiplication) or 64-bits
|
|
||||||
// (after multiplication).
|
|
||||||
//
|
|
||||||
// In order to parallelise the operations required to calculate
|
|
||||||
// the sum we use two separate accumulators and then sum those
|
|
||||||
// in an extra final step. For compatibility with the generic
|
|
||||||
// implementation we perform this summation at the end of every
|
|
||||||
// updateVX call.
|
|
||||||
//
|
|
||||||
// To use two accumulators we must multiply the message blocks
|
|
||||||
// by r² rather than r. Only the final message block should be
|
|
||||||
// multiplied by r.
|
|
||||||
//
|
|
||||||
// Example:
|
|
||||||
//
|
|
||||||
// We want to calculate the sum (h) for a 64 byte message (m):
|
|
||||||
//
|
|
||||||
// h = m[0:16]r⁴ + m[16:32]r³ + m[32:48]r² + m[48:64]r
|
|
||||||
//
|
|
||||||
// To do this we split the calculation into the even indices
|
|
||||||
// and odd indices of the message. These form our SIMD 'lanes':
|
|
||||||
//
|
|
||||||
// h = m[ 0:16]r⁴ + m[32:48]r² + <- lane 0
|
|
||||||
// m[16:32]r³ + m[48:64]r <- lane 1
|
|
||||||
//
|
|
||||||
// To calculate this iteratively we refactor so that both lanes
|
|
||||||
// are written in terms of r² and r:
|
|
||||||
//
|
|
||||||
// h = (m[ 0:16]r² + m[32:48])r² + <- lane 0
|
|
||||||
// (m[16:32]r² + m[48:64])r <- lane 1
|
|
||||||
// ^ ^
|
|
||||||
// | coefficients for second iteration
|
|
||||||
// coefficients for first iteration
|
|
||||||
//
|
|
||||||
// So in this case we would have two iterations. In the first
|
|
||||||
// both lanes are multiplied by r². In the second only the
|
|
||||||
// first lane is multiplied by r² and the second lane is
|
|
||||||
// instead multiplied by r. This gives use the odd and even
|
|
||||||
// powers of r that we need from the original equation.
|
|
||||||
//
|
|
||||||
// Notation:
|
|
||||||
//
|
|
||||||
// h - accumulator
|
|
||||||
// r - key
|
|
||||||
// m - message
|
|
||||||
//
|
|
||||||
// [a, b] - SIMD register holding two 64-bit values
|
|
||||||
// [a, b, c, d] - SIMD register holding four 32-bit values
|
|
||||||
// xᵢ[n] - limb n of variable x with bit width i
|
|
||||||
//
|
|
||||||
// Limbs are expressed in little endian order, so for 26-bit
|
|
||||||
// limbs x₂₆[4] will be the most significant limb and x₂₆[0]
|
|
||||||
// will be the least significant limb.
|
|
||||||
|
|
||||||
// masking constants
|
// constants
|
||||||
#define MOD24 V0 // [0x0000000000ffffff, 0x0000000000ffffff] - mask low 24-bits
|
#define MOD26 V0
|
||||||
#define MOD26 V1 // [0x0000000003ffffff, 0x0000000003ffffff] - mask low 26-bits
|
#define EX0 V1
|
||||||
|
#define EX1 V2
|
||||||
|
#define EX2 V3
|
||||||
|
|
||||||
// expansion constants (see EXPAND macro)
|
// temporaries
|
||||||
#define EX0 V2
|
#define T_0 V4
|
||||||
#define EX1 V3
|
#define T_1 V5
|
||||||
#define EX2 V4
|
#define T_2 V6
|
||||||
|
#define T_3 V7
|
||||||
|
#define T_4 V8
|
||||||
|
|
||||||
// key (r², r or 1 depending on context)
|
// key (r)
|
||||||
#define R_0 V5
|
#define R_0 V9
|
||||||
#define R_1 V6
|
#define R_1 V10
|
||||||
#define R_2 V7
|
#define R_2 V11
|
||||||
#define R_3 V8
|
#define R_3 V12
|
||||||
#define R_4 V9
|
#define R_4 V13
|
||||||
|
#define R5_1 V14
|
||||||
|
#define R5_2 V15
|
||||||
|
#define R5_3 V16
|
||||||
|
#define R5_4 V17
|
||||||
|
#define RSAVE_0 R5
|
||||||
|
#define RSAVE_1 R6
|
||||||
|
#define RSAVE_2 R7
|
||||||
|
#define RSAVE_3 R8
|
||||||
|
#define RSAVE_4 R9
|
||||||
|
#define R5SAVE_1 V28
|
||||||
|
#define R5SAVE_2 V29
|
||||||
|
#define R5SAVE_3 V30
|
||||||
|
#define R5SAVE_4 V31
|
||||||
|
|
||||||
// precalculated coefficients (5r², 5r or 0 depending on context)
|
// message block
|
||||||
#define R5_1 V10
|
#define F_0 V18
|
||||||
#define R5_2 V11
|
#define F_1 V19
|
||||||
#define R5_3 V12
|
#define F_2 V20
|
||||||
#define R5_4 V13
|
#define F_3 V21
|
||||||
|
#define F_4 V22
|
||||||
|
|
||||||
// message block (m)
|
// accumulator
|
||||||
#define M_0 V14
|
#define H_0 V23
|
||||||
#define M_1 V15
|
#define H_1 V24
|
||||||
#define M_2 V16
|
#define H_2 V25
|
||||||
#define M_3 V17
|
#define H_3 V26
|
||||||
#define M_4 V18
|
#define H_4 V27
|
||||||
|
|
||||||
// accumulator (h)
|
GLOBL ·keyMask<>(SB), RODATA, $16
|
||||||
#define H_0 V19
|
DATA ·keyMask<>+0(SB)/8, $0xffffff0ffcffff0f
|
||||||
#define H_1 V20
|
DATA ·keyMask<>+8(SB)/8, $0xfcffff0ffcffff0f
|
||||||
#define H_2 V21
|
|
||||||
#define H_3 V22
|
|
||||||
#define H_4 V23
|
|
||||||
|
|
||||||
// temporary registers (for short-lived values)
|
GLOBL ·bswapMask<>(SB), RODATA, $16
|
||||||
#define T_0 V24
|
DATA ·bswapMask<>+0(SB)/8, $0x0f0e0d0c0b0a0908
|
||||||
#define T_1 V25
|
DATA ·bswapMask<>+8(SB)/8, $0x0706050403020100
|
||||||
#define T_2 V26
|
|
||||||
#define T_3 V27
|
|
||||||
#define T_4 V28
|
|
||||||
|
|
||||||
GLOBL ·constants<>(SB), RODATA, $0x30
|
GLOBL ·constants<>(SB), RODATA, $64
|
||||||
|
// MOD26
|
||||||
|
DATA ·constants<>+0(SB)/8, $0x3ffffff
|
||||||
|
DATA ·constants<>+8(SB)/8, $0x3ffffff
|
||||||
// EX0
|
// EX0
|
||||||
DATA ·constants<>+0x00(SB)/8, $0x0006050403020100
|
DATA ·constants<>+16(SB)/8, $0x0006050403020100
|
||||||
DATA ·constants<>+0x08(SB)/8, $0x1016151413121110
|
DATA ·constants<>+24(SB)/8, $0x1016151413121110
|
||||||
// EX1
|
// EX1
|
||||||
DATA ·constants<>+0x10(SB)/8, $0x060c0b0a09080706
|
DATA ·constants<>+32(SB)/8, $0x060c0b0a09080706
|
||||||
DATA ·constants<>+0x18(SB)/8, $0x161c1b1a19181716
|
DATA ·constants<>+40(SB)/8, $0x161c1b1a19181716
|
||||||
// EX2
|
// EX2
|
||||||
DATA ·constants<>+0x20(SB)/8, $0x0d0d0d0d0d0f0e0d
|
DATA ·constants<>+48(SB)/8, $0x0d0d0d0d0d0f0e0d
|
||||||
DATA ·constants<>+0x28(SB)/8, $0x1d1d1d1d1d1f1e1d
|
DATA ·constants<>+56(SB)/8, $0x1d1d1d1d1d1f1e1d
|
||||||
|
|
||||||
// MULTIPLY multiplies each lane of f and g, partially reduced
|
// h = (f*g) % (2**130-5) [partial reduction]
|
||||||
// modulo 2¹³⁰ - 5. The result, h, consists of partial products
|
|
||||||
// in each lane that need to be reduced further to produce the
|
|
||||||
// final result.
|
|
||||||
//
|
|
||||||
// h₁₃₀ = (f₁₃₀g₁₃₀) % 2¹³⁰ + (5f₁₃₀g₁₃₀) / 2¹³⁰
|
|
||||||
//
|
|
||||||
// Note that the multiplication by 5 of the high bits is
|
|
||||||
// achieved by precalculating the multiplication of four of the
|
|
||||||
// g coefficients by 5. These are g51-g54.
|
|
||||||
#define MULTIPLY(f0, f1, f2, f3, f4, g0, g1, g2, g3, g4, g51, g52, g53, g54, h0, h1, h2, h3, h4) \
|
#define MULTIPLY(f0, f1, f2, f3, f4, g0, g1, g2, g3, g4, g51, g52, g53, g54, h0, h1, h2, h3, h4) \
|
||||||
VMLOF f0, g0, h0 \
|
VMLOF f0, g0, h0 \
|
||||||
VMLOF f0, g3, h3 \
|
|
||||||
VMLOF f0, g1, h1 \
|
VMLOF f0, g1, h1 \
|
||||||
VMLOF f0, g4, h4 \
|
|
||||||
VMLOF f0, g2, h2 \
|
VMLOF f0, g2, h2 \
|
||||||
|
VMLOF f0, g3, h3 \
|
||||||
|
VMLOF f0, g4, h4 \
|
||||||
VMLOF f1, g54, T_0 \
|
VMLOF f1, g54, T_0 \
|
||||||
VMLOF f1, g2, T_3 \
|
|
||||||
VMLOF f1, g0, T_1 \
|
VMLOF f1, g0, T_1 \
|
||||||
VMLOF f1, g3, T_4 \
|
|
||||||
VMLOF f1, g1, T_2 \
|
VMLOF f1, g1, T_2 \
|
||||||
|
VMLOF f1, g2, T_3 \
|
||||||
|
VMLOF f1, g3, T_4 \
|
||||||
VMALOF f2, g53, h0, h0 \
|
VMALOF f2, g53, h0, h0 \
|
||||||
VMALOF f2, g1, h3, h3 \
|
|
||||||
VMALOF f2, g54, h1, h1 \
|
VMALOF f2, g54, h1, h1 \
|
||||||
VMALOF f2, g2, h4, h4 \
|
|
||||||
VMALOF f2, g0, h2, h2 \
|
VMALOF f2, g0, h2, h2 \
|
||||||
|
VMALOF f2, g1, h3, h3 \
|
||||||
|
VMALOF f2, g2, h4, h4 \
|
||||||
VMALOF f3, g52, T_0, T_0 \
|
VMALOF f3, g52, T_0, T_0 \
|
||||||
VMALOF f3, g0, T_3, T_3 \
|
|
||||||
VMALOF f3, g53, T_1, T_1 \
|
VMALOF f3, g53, T_1, T_1 \
|
||||||
VMALOF f3, g1, T_4, T_4 \
|
|
||||||
VMALOF f3, g54, T_2, T_2 \
|
VMALOF f3, g54, T_2, T_2 \
|
||||||
|
VMALOF f3, g0, T_3, T_3 \
|
||||||
|
VMALOF f3, g1, T_4, T_4 \
|
||||||
VMALOF f4, g51, h0, h0 \
|
VMALOF f4, g51, h0, h0 \
|
||||||
VMALOF f4, g54, h3, h3 \
|
|
||||||
VMALOF f4, g52, h1, h1 \
|
VMALOF f4, g52, h1, h1 \
|
||||||
VMALOF f4, g0, h4, h4 \
|
|
||||||
VMALOF f4, g53, h2, h2 \
|
VMALOF f4, g53, h2, h2 \
|
||||||
|
VMALOF f4, g54, h3, h3 \
|
||||||
|
VMALOF f4, g0, h4, h4 \
|
||||||
VAG T_0, h0, h0 \
|
VAG T_0, h0, h0 \
|
||||||
VAG T_3, h3, h3 \
|
|
||||||
VAG T_1, h1, h1 \
|
VAG T_1, h1, h1 \
|
||||||
VAG T_4, h4, h4 \
|
VAG T_2, h2, h2 \
|
||||||
VAG T_2, h2, h2
|
VAG T_3, h3, h3 \
|
||||||
|
VAG T_4, h4, h4
|
||||||
|
|
||||||
// REDUCE performs the following carry operations in four
|
// carry h0->h1 h3->h4, h1->h2 h4->h0, h0->h1 h2->h3, h3->h4
|
||||||
// stages, as specified in Bernstein & Schwabe:
|
|
||||||
//
|
|
||||||
// 1: h₂₆[0]->h₂₆[1] h₂₆[3]->h₂₆[4]
|
|
||||||
// 2: h₂₆[1]->h₂₆[2] h₂₆[4]->h₂₆[0]
|
|
||||||
// 3: h₂₆[0]->h₂₆[1] h₂₆[2]->h₂₆[3]
|
|
||||||
// 4: h₂₆[3]->h₂₆[4]
|
|
||||||
//
|
|
||||||
// The result is that all of the limbs are limited to 26-bits
|
|
||||||
// except for h₂₆[1] and h₂₆[4] which are limited to 27-bits.
|
|
||||||
//
|
|
||||||
// Note that although each limb is aligned at 26-bit intervals
|
|
||||||
// they may contain values that exceed 2²⁶ - 1, hence the need
|
|
||||||
// to carry the excess bits in each limb.
|
|
||||||
#define REDUCE(h0, h1, h2, h3, h4) \
|
#define REDUCE(h0, h1, h2, h3, h4) \
|
||||||
VESRLG $26, h0, T_0 \
|
VESRLG $26, h0, T_0 \
|
||||||
VESRLG $26, h3, T_1 \
|
VESRLG $26, h3, T_1 \
|
||||||
@ -208,155 +136,144 @@ DATA ·constants<>+0x28(SB)/8, $0x1d1d1d1d1d1f1e1d
|
|||||||
VN MOD26, h3, h3 \
|
VN MOD26, h3, h3 \
|
||||||
VAG T_2, h4, h4
|
VAG T_2, h4, h4
|
||||||
|
|
||||||
// EXPAND splits the 128-bit little-endian values in0 and in1
|
// expand in0 into d[0] and in1 into d[1]
|
||||||
// into 26-bit big-endian limbs and places the results into
|
|
||||||
// the first and second lane of d₂₆[0:4] respectively.
|
|
||||||
//
|
|
||||||
// The EX0, EX1 and EX2 constants are arrays of byte indices
|
|
||||||
// for permutation. The permutation both reverses the bytes
|
|
||||||
// in the input and ensures the bytes are copied into the
|
|
||||||
// destination limb ready to be shifted into their final
|
|
||||||
// position.
|
|
||||||
#define EXPAND(in0, in1, d0, d1, d2, d3, d4) \
|
#define EXPAND(in0, in1, d0, d1, d2, d3, d4) \
|
||||||
|
VGBM $0x0707, d1 \ // d1=tmp
|
||||||
|
VPERM in0, in1, EX2, d4 \
|
||||||
VPERM in0, in1, EX0, d0 \
|
VPERM in0, in1, EX0, d0 \
|
||||||
VPERM in0, in1, EX1, d2 \
|
VPERM in0, in1, EX1, d2 \
|
||||||
VPERM in0, in1, EX2, d4 \
|
VN d1, d4, d4 \
|
||||||
VESRLG $26, d0, d1 \
|
VESRLG $26, d0, d1 \
|
||||||
VESRLG $30, d2, d3 \
|
VESRLG $30, d2, d3 \
|
||||||
VESRLG $4, d2, d2 \
|
VESRLG $4, d2, d2 \
|
||||||
VN MOD26, d0, d0 \ // [in0₂₆[0], in1₂₆[0]]
|
VN MOD26, d0, d0 \
|
||||||
VN MOD26, d3, d3 \ // [in0₂₆[3], in1₂₆[3]]
|
VN MOD26, d1, d1 \
|
||||||
VN MOD26, d1, d1 \ // [in0₂₆[1], in1₂₆[1]]
|
VN MOD26, d2, d2 \
|
||||||
VN MOD24, d4, d4 \ // [in0₂₆[4], in1₂₆[4]]
|
VN MOD26, d3, d3
|
||||||
VN MOD26, d2, d2 // [in0₂₆[2], in1₂₆[2]]
|
|
||||||
|
|
||||||
// func updateVX(state *macState, msg []byte)
|
// pack h4:h0 into h1:h0 (no carry)
|
||||||
TEXT ·updateVX(SB), NOSPLIT, $0
|
#define PACK(h0, h1, h2, h3, h4) \
|
||||||
MOVD state+0(FP), R1
|
VESLG $26, h1, h1 \
|
||||||
LMG msg+8(FP), R2, R3 // R2=msg_base, R3=msg_len
|
VESLG $26, h3, h3 \
|
||||||
|
VO h0, h1, h0 \
|
||||||
|
VO h2, h3, h2 \
|
||||||
|
VESLG $4, h2, h2 \
|
||||||
|
VLEIB $7, $48, h1 \
|
||||||
|
VSLB h1, h2, h2 \
|
||||||
|
VO h0, h2, h0 \
|
||||||
|
VLEIB $7, $104, h1 \
|
||||||
|
VSLB h1, h4, h3 \
|
||||||
|
VO h3, h0, h0 \
|
||||||
|
VLEIB $7, $24, h1 \
|
||||||
|
VSRLB h1, h4, h1
|
||||||
|
|
||||||
// load EX0, EX1 and EX2
|
// if h > 2**130-5 then h -= 2**130-5
|
||||||
|
#define MOD(h0, h1, t0, t1, t2) \
|
||||||
|
VZERO t0 \
|
||||||
|
VLEIG $1, $5, t0 \
|
||||||
|
VACCQ h0, t0, t1 \
|
||||||
|
VAQ h0, t0, t0 \
|
||||||
|
VONE t2 \
|
||||||
|
VLEIG $1, $-4, t2 \
|
||||||
|
VAQ t2, t1, t1 \
|
||||||
|
VACCQ h1, t1, t1 \
|
||||||
|
VONE t2 \
|
||||||
|
VAQ t2, t1, t1 \
|
||||||
|
VN h0, t1, t2 \
|
||||||
|
VNC t0, t1, t1 \
|
||||||
|
VO t1, t2, h0
|
||||||
|
|
||||||
|
// func poly1305vx(out *[16]byte, m *byte, mlen uint64, key *[32]key)
|
||||||
|
TEXT ·poly1305vx(SB), $0-32
|
||||||
|
// This code processes up to 2 blocks (32 bytes) per iteration
|
||||||
|
// using the algorithm described in:
|
||||||
|
// NEON crypto, Daniel J. Bernstein & Peter Schwabe
|
||||||
|
// https://cryptojedi.org/papers/neoncrypto-20120320.pdf
|
||||||
|
LMG out+0(FP), R1, R4 // R1=out, R2=m, R3=mlen, R4=key
|
||||||
|
|
||||||
|
// load MOD26, EX0, EX1 and EX2
|
||||||
MOVD $·constants<>(SB), R5
|
MOVD $·constants<>(SB), R5
|
||||||
VLM (R5), EX0, EX2
|
VLM (R5), MOD26, EX2
|
||||||
|
|
||||||
// generate masks
|
// setup r
|
||||||
VGMG $(64-24), $63, MOD24 // [0x00ffffff, 0x00ffffff]
|
VL (R4), T_0
|
||||||
VGMG $(64-26), $63, MOD26 // [0x03ffffff, 0x03ffffff]
|
MOVD $·keyMask<>(SB), R6
|
||||||
|
VL (R6), T_1
|
||||||
|
VN T_0, T_1, T_0
|
||||||
|
EXPAND(T_0, T_0, R_0, R_1, R_2, R_3, R_4)
|
||||||
|
|
||||||
// load h (accumulator) and r (key) from state
|
// setup r*5
|
||||||
VZERO T_1 // [0, 0]
|
VLEIG $0, $5, T_0
|
||||||
VL 0(R1), T_0 // [h₆₄[0], h₆₄[1]]
|
VLEIG $1, $5, T_0
|
||||||
VLEG $0, 16(R1), T_1 // [h₆₄[2], 0]
|
|
||||||
VL 24(R1), T_2 // [r₆₄[0], r₆₄[1]]
|
|
||||||
VPDI $0, T_0, T_2, T_3 // [h₆₄[0], r₆₄[0]]
|
|
||||||
VPDI $5, T_0, T_2, T_4 // [h₆₄[1], r₆₄[1]]
|
|
||||||
|
|
||||||
// unpack h and r into 26-bit limbs
|
// store r (for final block)
|
||||||
// note: h₆₄[2] may have the low 3 bits set, so h₂₆[4] is a 27-bit value
|
VMLOF T_0, R_1, R5SAVE_1
|
||||||
VN MOD26, T_3, H_0 // [h₂₆[0], r₂₆[0]]
|
VMLOF T_0, R_2, R5SAVE_2
|
||||||
VZERO H_1 // [0, 0]
|
VMLOF T_0, R_3, R5SAVE_3
|
||||||
VZERO H_3 // [0, 0]
|
VMLOF T_0, R_4, R5SAVE_4
|
||||||
VGMG $(64-12-14), $(63-12), T_0 // [0x03fff000, 0x03fff000] - 26-bit mask with low 12 bits masked out
|
VLGVG $0, R_0, RSAVE_0
|
||||||
VESLG $24, T_1, T_1 // [h₆₄[2]<<24, 0]
|
VLGVG $0, R_1, RSAVE_1
|
||||||
VERIMG $-26&63, T_3, MOD26, H_1 // [h₂₆[1], r₂₆[1]]
|
VLGVG $0, R_2, RSAVE_2
|
||||||
VESRLG $+52&63, T_3, H_2 // [h₂₆[2], r₂₆[2]] - low 12 bits only
|
VLGVG $0, R_3, RSAVE_3
|
||||||
VERIMG $-14&63, T_4, MOD26, H_3 // [h₂₆[1], r₂₆[1]]
|
VLGVG $0, R_4, RSAVE_4
|
||||||
VESRLG $40, T_4, H_4 // [h₂₆[4], r₂₆[4]] - low 24 bits only
|
|
||||||
VERIMG $+12&63, T_4, T_0, H_2 // [h₂₆[2], r₂₆[2]] - complete
|
|
||||||
VO T_1, H_4, H_4 // [h₂₆[4], r₂₆[4]] - complete
|
|
||||||
|
|
||||||
// replicate r across all 4 vector elements
|
// skip r**2 calculation
|
||||||
VREPF $3, H_0, R_0 // [r₂₆[0], r₂₆[0], r₂₆[0], r₂₆[0]]
|
|
||||||
VREPF $3, H_1, R_1 // [r₂₆[1], r₂₆[1], r₂₆[1], r₂₆[1]]
|
|
||||||
VREPF $3, H_2, R_2 // [r₂₆[2], r₂₆[2], r₂₆[2], r₂₆[2]]
|
|
||||||
VREPF $3, H_3, R_3 // [r₂₆[3], r₂₆[3], r₂₆[3], r₂₆[3]]
|
|
||||||
VREPF $3, H_4, R_4 // [r₂₆[4], r₂₆[4], r₂₆[4], r₂₆[4]]
|
|
||||||
|
|
||||||
// zero out lane 1 of h
|
|
||||||
VLEIG $1, $0, H_0 // [h₂₆[0], 0]
|
|
||||||
VLEIG $1, $0, H_1 // [h₂₆[1], 0]
|
|
||||||
VLEIG $1, $0, H_2 // [h₂₆[2], 0]
|
|
||||||
VLEIG $1, $0, H_3 // [h₂₆[3], 0]
|
|
||||||
VLEIG $1, $0, H_4 // [h₂₆[4], 0]
|
|
||||||
|
|
||||||
// calculate 5r (ignore least significant limb)
|
|
||||||
VREPIF $5, T_0
|
|
||||||
VMLF T_0, R_1, R5_1 // [5r₂₆[1], 5r₂₆[1], 5r₂₆[1], 5r₂₆[1]]
|
|
||||||
VMLF T_0, R_2, R5_2 // [5r₂₆[2], 5r₂₆[2], 5r₂₆[2], 5r₂₆[2]]
|
|
||||||
VMLF T_0, R_3, R5_3 // [5r₂₆[3], 5r₂₆[3], 5r₂₆[3], 5r₂₆[3]]
|
|
||||||
VMLF T_0, R_4, R5_4 // [5r₂₆[4], 5r₂₆[4], 5r₂₆[4], 5r₂₆[4]]
|
|
||||||
|
|
||||||
// skip r² calculation if we are only calculating one block
|
|
||||||
CMPBLE R3, $16, skip
|
CMPBLE R3, $16, skip
|
||||||
|
|
||||||
// calculate r²
|
// calculate r**2
|
||||||
MULTIPLY(R_0, R_1, R_2, R_3, R_4, R_0, R_1, R_2, R_3, R_4, R5_1, R5_2, R5_3, R5_4, M_0, M_1, M_2, M_3, M_4)
|
MULTIPLY(R_0, R_1, R_2, R_3, R_4, R_0, R_1, R_2, R_3, R_4, R5SAVE_1, R5SAVE_2, R5SAVE_3, R5SAVE_4, H_0, H_1, H_2, H_3, H_4)
|
||||||
REDUCE(M_0, M_1, M_2, M_3, M_4)
|
REDUCE(H_0, H_1, H_2, H_3, H_4)
|
||||||
VGBM $0x0f0f, T_0
|
VLEIG $0, $5, T_0
|
||||||
VERIMG $0, M_0, T_0, R_0 // [r₂₆[0], r²₂₆[0], r₂₆[0], r²₂₆[0]]
|
VLEIG $1, $5, T_0
|
||||||
VERIMG $0, M_1, T_0, R_1 // [r₂₆[1], r²₂₆[1], r₂₆[1], r²₂₆[1]]
|
VMLOF T_0, H_1, R5_1
|
||||||
VERIMG $0, M_2, T_0, R_2 // [r₂₆[2], r²₂₆[2], r₂₆[2], r²₂₆[2]]
|
VMLOF T_0, H_2, R5_2
|
||||||
VERIMG $0, M_3, T_0, R_3 // [r₂₆[3], r²₂₆[3], r₂₆[3], r²₂₆[3]]
|
VMLOF T_0, H_3, R5_3
|
||||||
VERIMG $0, M_4, T_0, R_4 // [r₂₆[4], r²₂₆[4], r₂₆[4], r²₂₆[4]]
|
VMLOF T_0, H_4, R5_4
|
||||||
|
VLR H_0, R_0
|
||||||
|
VLR H_1, R_1
|
||||||
|
VLR H_2, R_2
|
||||||
|
VLR H_3, R_3
|
||||||
|
VLR H_4, R_4
|
||||||
|
|
||||||
// calculate 5r² (ignore least significant limb)
|
// initialize h
|
||||||
VREPIF $5, T_0
|
VZERO H_0
|
||||||
VMLF T_0, R_1, R5_1 // [5r₂₆[1], 5r²₂₆[1], 5r₂₆[1], 5r²₂₆[1]]
|
VZERO H_1
|
||||||
VMLF T_0, R_2, R5_2 // [5r₂₆[2], 5r²₂₆[2], 5r₂₆[2], 5r²₂₆[2]]
|
VZERO H_2
|
||||||
VMLF T_0, R_3, R5_3 // [5r₂₆[3], 5r²₂₆[3], 5r₂₆[3], 5r²₂₆[3]]
|
VZERO H_3
|
||||||
VMLF T_0, R_4, R5_4 // [5r₂₆[4], 5r²₂₆[4], 5r₂₆[4], 5r²₂₆[4]]
|
VZERO H_4
|
||||||
|
|
||||||
loop:
|
loop:
|
||||||
CMPBLE R3, $32, b2 // 2 or fewer blocks remaining, need to change key coefficients
|
CMPBLE R3, $32, b2
|
||||||
|
VLM (R2), T_0, T_1
|
||||||
// load next 2 blocks from message
|
SUB $32, R3
|
||||||
VLM (R2), T_0, T_1
|
MOVD $32(R2), R2
|
||||||
|
EXPAND(T_0, T_1, F_0, F_1, F_2, F_3, F_4)
|
||||||
// update message slice
|
VLEIB $4, $1, F_4
|
||||||
SUB $32, R3
|
VLEIB $12, $1, F_4
|
||||||
MOVD $32(R2), R2
|
|
||||||
|
|
||||||
// unpack message blocks into 26-bit big-endian limbs
|
|
||||||
EXPAND(T_0, T_1, M_0, M_1, M_2, M_3, M_4)
|
|
||||||
|
|
||||||
// add 2¹²⁸ to each message block value
|
|
||||||
VLEIB $4, $1, M_4
|
|
||||||
VLEIB $12, $1, M_4
|
|
||||||
|
|
||||||
multiply:
|
multiply:
|
||||||
// accumulate the incoming message
|
VAG H_0, F_0, F_0
|
||||||
VAG H_0, M_0, M_0
|
VAG H_1, F_1, F_1
|
||||||
VAG H_3, M_3, M_3
|
VAG H_2, F_2, F_2
|
||||||
VAG H_1, M_1, M_1
|
VAG H_3, F_3, F_3
|
||||||
VAG H_4, M_4, M_4
|
VAG H_4, F_4, F_4
|
||||||
VAG H_2, M_2, M_2
|
MULTIPLY(F_0, F_1, F_2, F_3, F_4, R_0, R_1, R_2, R_3, R_4, R5_1, R5_2, R5_3, R5_4, H_0, H_1, H_2, H_3, H_4)
|
||||||
|
|
||||||
// multiply the accumulator by the key coefficient
|
|
||||||
MULTIPLY(M_0, M_1, M_2, M_3, M_4, R_0, R_1, R_2, R_3, R_4, R5_1, R5_2, R5_3, R5_4, H_0, H_1, H_2, H_3, H_4)
|
|
||||||
|
|
||||||
// carry and partially reduce the partial products
|
|
||||||
REDUCE(H_0, H_1, H_2, H_3, H_4)
|
REDUCE(H_0, H_1, H_2, H_3, H_4)
|
||||||
|
|
||||||
CMPBNE R3, $0, loop
|
CMPBNE R3, $0, loop
|
||||||
|
|
||||||
finish:
|
finish:
|
||||||
// sum lane 0 and lane 1 and put the result in lane 1
|
// sum vectors
|
||||||
VZERO T_0
|
VZERO T_0
|
||||||
VSUMQG H_0, T_0, H_0
|
VSUMQG H_0, T_0, H_0
|
||||||
VSUMQG H_3, T_0, H_3
|
|
||||||
VSUMQG H_1, T_0, H_1
|
VSUMQG H_1, T_0, H_1
|
||||||
VSUMQG H_4, T_0, H_4
|
|
||||||
VSUMQG H_2, T_0, H_2
|
VSUMQG H_2, T_0, H_2
|
||||||
|
VSUMQG H_3, T_0, H_3
|
||||||
|
VSUMQG H_4, T_0, H_4
|
||||||
|
|
||||||
// reduce again after summation
|
// h may be >= 2*(2**130-5) so we need to reduce it again
|
||||||
// TODO(mundaym): there might be a more efficient way to do this
|
|
||||||
// now that we only have 1 active lane. For example, we could
|
|
||||||
// simultaneously pack the values as we reduce them.
|
|
||||||
REDUCE(H_0, H_1, H_2, H_3, H_4)
|
REDUCE(H_0, H_1, H_2, H_3, H_4)
|
||||||
|
|
||||||
// carry h[1] through to h[4] so that only h[4] can exceed 2²⁶ - 1
|
// carry h1->h4
|
||||||
// TODO(mundaym): in testing this final carry was unnecessary.
|
|
||||||
// Needs a proof before it can be removed though.
|
|
||||||
VESRLG $26, H_1, T_1
|
VESRLG $26, H_1, T_1
|
||||||
VN MOD26, H_1, H_1
|
VN MOD26, H_1, H_1
|
||||||
VAQ T_1, H_2, H_2
|
VAQ T_1, H_2, H_2
|
||||||
@ -367,137 +284,95 @@ finish:
|
|||||||
VN MOD26, H_3, H_3
|
VN MOD26, H_3, H_3
|
||||||
VAQ T_3, H_4, H_4
|
VAQ T_3, H_4, H_4
|
||||||
|
|
||||||
// h is now < 2(2¹³⁰ - 5)
|
// h is now < 2*(2**130-5)
|
||||||
// Pack each lane in h₂₆[0:4] into h₁₂₈[0:1].
|
// pack h into h1 (hi) and h0 (lo)
|
||||||
VESLG $26, H_1, H_1
|
PACK(H_0, H_1, H_2, H_3, H_4)
|
||||||
VESLG $26, H_3, H_3
|
|
||||||
VO H_0, H_1, H_0
|
// if h > 2**130-5 then h -= 2**130-5
|
||||||
VO H_2, H_3, H_2
|
MOD(H_0, H_1, T_0, T_1, T_2)
|
||||||
VESLG $4, H_2, H_2
|
|
||||||
VLEIB $7, $48, H_1
|
// h += s
|
||||||
VSLB H_1, H_2, H_2
|
MOVD $·bswapMask<>(SB), R5
|
||||||
VO H_0, H_2, H_0
|
VL (R5), T_1
|
||||||
VLEIB $7, $104, H_1
|
VL 16(R4), T_0
|
||||||
VSLB H_1, H_4, H_3
|
VPERM T_0, T_0, T_1, T_0 // reverse bytes (to big)
|
||||||
VO H_3, H_0, H_0
|
VAQ T_0, H_0, H_0
|
||||||
VLEIB $7, $24, H_1
|
VPERM H_0, H_0, T_1, H_0 // reverse bytes (to little)
|
||||||
VSRLB H_1, H_4, H_1
|
VST H_0, (R1)
|
||||||
|
|
||||||
// update state
|
|
||||||
VSTEG $1, H_0, 0(R1)
|
|
||||||
VSTEG $0, H_0, 8(R1)
|
|
||||||
VSTEG $1, H_1, 16(R1)
|
|
||||||
RET
|
RET
|
||||||
|
|
||||||
b2: // 2 or fewer blocks remaining
|
b2:
|
||||||
CMPBLE R3, $16, b1
|
CMPBLE R3, $16, b1
|
||||||
|
|
||||||
// Load the 2 remaining blocks (17-32 bytes remaining).
|
// 2 blocks remaining
|
||||||
MOVD $-17(R3), R0 // index of final byte to load modulo 16
|
SUB $17, R3
|
||||||
VL (R2), T_0 // load full 16 byte block
|
VL (R2), T_0
|
||||||
VLL R0, 16(R2), T_1 // load final (possibly partial) block and pad with zeros to 16 bytes
|
VLL R3, 16(R2), T_1
|
||||||
|
ADD $1, R3
|
||||||
// The Poly1305 algorithm requires that a 1 bit be appended to
|
|
||||||
// each message block. If the final block is less than 16 bytes
|
|
||||||
// long then it is easiest to insert the 1 before the message
|
|
||||||
// block is split into 26-bit limbs. If, on the other hand, the
|
|
||||||
// final message block is 16 bytes long then we append the 1 bit
|
|
||||||
// after expansion as normal.
|
|
||||||
MOVBZ $1, R0
|
MOVBZ $1, R0
|
||||||
MOVD $-16(R3), R3 // index of byte in last block to insert 1 at (could be 16)
|
CMPBEQ R3, $16, 2(PC)
|
||||||
CMPBEQ R3, $16, 2(PC) // skip the insertion if the final block is 16 bytes long
|
VLVGB R3, R0, T_1
|
||||||
VLVGB R3, R0, T_1 // insert 1 into the byte at index R3
|
EXPAND(T_0, T_1, F_0, F_1, F_2, F_3, F_4)
|
||||||
|
|
||||||
// Split both blocks into 26-bit limbs in the appropriate lanes.
|
|
||||||
EXPAND(T_0, T_1, M_0, M_1, M_2, M_3, M_4)
|
|
||||||
|
|
||||||
// Append a 1 byte to the end of the second to last block.
|
|
||||||
VLEIB $4, $1, M_4
|
|
||||||
|
|
||||||
// Append a 1 byte to the end of the last block only if it is a
|
|
||||||
// full 16 byte block.
|
|
||||||
CMPBNE R3, $16, 2(PC)
|
CMPBNE R3, $16, 2(PC)
|
||||||
VLEIB $12, $1, M_4
|
VLEIB $12, $1, F_4
|
||||||
|
VLEIB $4, $1, F_4
|
||||||
|
|
||||||
// Finally, set up the coefficients for the final multiplication.
|
// setup [r²,r]
|
||||||
// We have previously saved r and 5r in the 32-bit even indexes
|
VLVGG $1, RSAVE_0, R_0
|
||||||
// of the R_[0-4] and R5_[1-4] coefficient registers.
|
VLVGG $1, RSAVE_1, R_1
|
||||||
//
|
VLVGG $1, RSAVE_2, R_2
|
||||||
// We want lane 0 to be multiplied by r² so that can be kept the
|
VLVGG $1, RSAVE_3, R_3
|
||||||
// same. We want lane 1 to be multiplied by r so we need to move
|
VLVGG $1, RSAVE_4, R_4
|
||||||
// the saved r value into the 32-bit odd index in lane 1 by
|
VPDI $0, R5_1, R5SAVE_1, R5_1
|
||||||
// rotating the 64-bit lane by 32.
|
VPDI $0, R5_2, R5SAVE_2, R5_2
|
||||||
VGBM $0x00ff, T_0 // [0, 0xffffffffffffffff] - mask lane 1 only
|
VPDI $0, R5_3, R5SAVE_3, R5_3
|
||||||
VERIMG $32, R_0, T_0, R_0 // [_, r²₂₆[0], _, r₂₆[0]]
|
VPDI $0, R5_4, R5SAVE_4, R5_4
|
||||||
VERIMG $32, R_1, T_0, R_1 // [_, r²₂₆[1], _, r₂₆[1]]
|
|
||||||
VERIMG $32, R_2, T_0, R_2 // [_, r²₂₆[2], _, r₂₆[2]]
|
|
||||||
VERIMG $32, R_3, T_0, R_3 // [_, r²₂₆[3], _, r₂₆[3]]
|
|
||||||
VERIMG $32, R_4, T_0, R_4 // [_, r²₂₆[4], _, r₂₆[4]]
|
|
||||||
VERIMG $32, R5_1, T_0, R5_1 // [_, 5r²₂₆[1], _, 5r₂₆[1]]
|
|
||||||
VERIMG $32, R5_2, T_0, R5_2 // [_, 5r²₂₆[2], _, 5r₂₆[2]]
|
|
||||||
VERIMG $32, R5_3, T_0, R5_3 // [_, 5r²₂₆[3], _, 5r₂₆[3]]
|
|
||||||
VERIMG $32, R5_4, T_0, R5_4 // [_, 5r²₂₆[4], _, 5r₂₆[4]]
|
|
||||||
|
|
||||||
MOVD $0, R3
|
MOVD $0, R3
|
||||||
BR multiply
|
BR multiply
|
||||||
|
|
||||||
skip:
|
skip:
|
||||||
|
VZERO H_0
|
||||||
|
VZERO H_1
|
||||||
|
VZERO H_2
|
||||||
|
VZERO H_3
|
||||||
|
VZERO H_4
|
||||||
|
|
||||||
CMPBEQ R3, $0, finish
|
CMPBEQ R3, $0, finish
|
||||||
|
|
||||||
b1: // 1 block remaining
|
b1:
|
||||||
|
// 1 block remaining
|
||||||
// Load the final block (1-16 bytes). This will be placed into
|
SUB $1, R3
|
||||||
// lane 0.
|
VLL R3, (R2), T_0
|
||||||
MOVD $-1(R3), R0
|
ADD $1, R3
|
||||||
VLL R0, (R2), T_0 // pad to 16 bytes with zeros
|
|
||||||
|
|
||||||
// The Poly1305 algorithm requires that a 1 bit be appended to
|
|
||||||
// each message block. If the final block is less than 16 bytes
|
|
||||||
// long then it is easiest to insert the 1 before the message
|
|
||||||
// block is split into 26-bit limbs. If, on the other hand, the
|
|
||||||
// final message block is 16 bytes long then we append the 1 bit
|
|
||||||
// after expansion as normal.
|
|
||||||
MOVBZ $1, R0
|
MOVBZ $1, R0
|
||||||
CMPBEQ R3, $16, 2(PC)
|
CMPBEQ R3, $16, 2(PC)
|
||||||
VLVGB R3, R0, T_0
|
VLVGB R3, R0, T_0
|
||||||
|
VZERO T_1
|
||||||
// Set the message block in lane 1 to the value 0 so that it
|
EXPAND(T_0, T_1, F_0, F_1, F_2, F_3, F_4)
|
||||||
// can be accumulated without affecting the final result.
|
|
||||||
VZERO T_1
|
|
||||||
|
|
||||||
// Split the final message block into 26-bit limbs in lane 0.
|
|
||||||
// Lane 1 will be contain 0.
|
|
||||||
EXPAND(T_0, T_1, M_0, M_1, M_2, M_3, M_4)
|
|
||||||
|
|
||||||
// Append a 1 byte to the end of the last block only if it is a
|
|
||||||
// full 16 byte block.
|
|
||||||
CMPBNE R3, $16, 2(PC)
|
CMPBNE R3, $16, 2(PC)
|
||||||
VLEIB $4, $1, M_4
|
VLEIB $4, $1, F_4
|
||||||
|
VLEIG $1, $1, R_0
|
||||||
|
VZERO R_1
|
||||||
|
VZERO R_2
|
||||||
|
VZERO R_3
|
||||||
|
VZERO R_4
|
||||||
|
VZERO R5_1
|
||||||
|
VZERO R5_2
|
||||||
|
VZERO R5_3
|
||||||
|
VZERO R5_4
|
||||||
|
|
||||||
// We have previously saved r and 5r in the 32-bit even indexes
|
// setup [r, 1]
|
||||||
// of the R_[0-4] and R5_[1-4] coefficient registers.
|
VLVGG $0, RSAVE_0, R_0
|
||||||
//
|
VLVGG $0, RSAVE_1, R_1
|
||||||
// We want lane 0 to be multiplied by r so we need to move the
|
VLVGG $0, RSAVE_2, R_2
|
||||||
// saved r value into the 32-bit odd index in lane 0. We want
|
VLVGG $0, RSAVE_3, R_3
|
||||||
// lane 1 to be set to the value 1. This makes multiplication
|
VLVGG $0, RSAVE_4, R_4
|
||||||
// a no-op. We do this by setting lane 1 in every register to 0
|
VPDI $0, R5SAVE_1, R5_1, R5_1
|
||||||
// and then just setting the 32-bit index 3 in R_0 to 1.
|
VPDI $0, R5SAVE_2, R5_2, R5_2
|
||||||
VZERO T_0
|
VPDI $0, R5SAVE_3, R5_3, R5_3
|
||||||
MOVD $0, R0
|
VPDI $0, R5SAVE_4, R5_4, R5_4
|
||||||
MOVD $0x10111213, R12
|
|
||||||
VLVGP R12, R0, T_1 // [_, 0x10111213, _, 0x00000000]
|
|
||||||
VPERM T_0, R_0, T_1, R_0 // [_, r₂₆[0], _, 0]
|
|
||||||
VPERM T_0, R_1, T_1, R_1 // [_, r₂₆[1], _, 0]
|
|
||||||
VPERM T_0, R_2, T_1, R_2 // [_, r₂₆[2], _, 0]
|
|
||||||
VPERM T_0, R_3, T_1, R_3 // [_, r₂₆[3], _, 0]
|
|
||||||
VPERM T_0, R_4, T_1, R_4 // [_, r₂₆[4], _, 0]
|
|
||||||
VPERM T_0, R5_1, T_1, R5_1 // [_, 5r₂₆[1], _, 0]
|
|
||||||
VPERM T_0, R5_2, T_1, R5_2 // [_, 5r₂₆[2], _, 0]
|
|
||||||
VPERM T_0, R5_3, T_1, R5_3 // [_, 5r₂₆[3], _, 0]
|
|
||||||
VPERM T_0, R5_4, T_1, R5_4 // [_, 5r₂₆[4], _, 0]
|
|
||||||
|
|
||||||
// Set the value of lane 1 to be 1.
|
|
||||||
VLEIF $3, $1, R_0 // [_, r₂₆[0], _, 1]
|
|
||||||
|
|
||||||
MOVD $0, R3
|
MOVD $0, R3
|
||||||
BR multiply
|
BR multiply
|
||||||
|
909
vendor/golang.org/x/crypto/poly1305/sum_vmsl_s390x.s
generated
vendored
Normal file
909
vendor/golang.org/x/crypto/poly1305/sum_vmsl_s390x.s
generated
vendored
Normal file
@ -0,0 +1,909 @@
|
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build s390x,go1.11,!gccgo,!appengine
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
// Implementation of Poly1305 using the vector facility (vx) and the VMSL instruction.
|
||||||
|
|
||||||
|
// constants
|
||||||
|
#define EX0 V1
|
||||||
|
#define EX1 V2
|
||||||
|
#define EX2 V3
|
||||||
|
|
||||||
|
// temporaries
|
||||||
|
#define T_0 V4
|
||||||
|
#define T_1 V5
|
||||||
|
#define T_2 V6
|
||||||
|
#define T_3 V7
|
||||||
|
#define T_4 V8
|
||||||
|
#define T_5 V9
|
||||||
|
#define T_6 V10
|
||||||
|
#define T_7 V11
|
||||||
|
#define T_8 V12
|
||||||
|
#define T_9 V13
|
||||||
|
#define T_10 V14
|
||||||
|
|
||||||
|
// r**2 & r**4
|
||||||
|
#define R_0 V15
|
||||||
|
#define R_1 V16
|
||||||
|
#define R_2 V17
|
||||||
|
#define R5_1 V18
|
||||||
|
#define R5_2 V19
|
||||||
|
// key (r)
|
||||||
|
#define RSAVE_0 R7
|
||||||
|
#define RSAVE_1 R8
|
||||||
|
#define RSAVE_2 R9
|
||||||
|
#define R5SAVE_1 R10
|
||||||
|
#define R5SAVE_2 R11
|
||||||
|
|
||||||
|
// message block
|
||||||
|
#define M0 V20
|
||||||
|
#define M1 V21
|
||||||
|
#define M2 V22
|
||||||
|
#define M3 V23
|
||||||
|
#define M4 V24
|
||||||
|
#define M5 V25
|
||||||
|
|
||||||
|
// accumulator
|
||||||
|
#define H0_0 V26
|
||||||
|
#define H1_0 V27
|
||||||
|
#define H2_0 V28
|
||||||
|
#define H0_1 V29
|
||||||
|
#define H1_1 V30
|
||||||
|
#define H2_1 V31
|
||||||
|
|
||||||
|
GLOBL ·keyMask<>(SB), RODATA, $16
|
||||||
|
DATA ·keyMask<>+0(SB)/8, $0xffffff0ffcffff0f
|
||||||
|
DATA ·keyMask<>+8(SB)/8, $0xfcffff0ffcffff0f
|
||||||
|
|
||||||
|
GLOBL ·bswapMask<>(SB), RODATA, $16
|
||||||
|
DATA ·bswapMask<>+0(SB)/8, $0x0f0e0d0c0b0a0908
|
||||||
|
DATA ·bswapMask<>+8(SB)/8, $0x0706050403020100
|
||||||
|
|
||||||
|
GLOBL ·constants<>(SB), RODATA, $48
|
||||||
|
// EX0
|
||||||
|
DATA ·constants<>+0(SB)/8, $0x18191a1b1c1d1e1f
|
||||||
|
DATA ·constants<>+8(SB)/8, $0x0000050403020100
|
||||||
|
// EX1
|
||||||
|
DATA ·constants<>+16(SB)/8, $0x18191a1b1c1d1e1f
|
||||||
|
DATA ·constants<>+24(SB)/8, $0x00000a0908070605
|
||||||
|
// EX2
|
||||||
|
DATA ·constants<>+32(SB)/8, $0x18191a1b1c1d1e1f
|
||||||
|
DATA ·constants<>+40(SB)/8, $0x0000000f0e0d0c0b
|
||||||
|
|
||||||
|
GLOBL ·c<>(SB), RODATA, $48
|
||||||
|
// EX0
|
||||||
|
DATA ·c<>+0(SB)/8, $0x0000050403020100
|
||||||
|
DATA ·c<>+8(SB)/8, $0x0000151413121110
|
||||||
|
// EX1
|
||||||
|
DATA ·c<>+16(SB)/8, $0x00000a0908070605
|
||||||
|
DATA ·c<>+24(SB)/8, $0x00001a1918171615
|
||||||
|
// EX2
|
||||||
|
DATA ·c<>+32(SB)/8, $0x0000000f0e0d0c0b
|
||||||
|
DATA ·c<>+40(SB)/8, $0x0000001f1e1d1c1b
|
||||||
|
|
||||||
|
GLOBL ·reduce<>(SB), RODATA, $32
|
||||||
|
// 44 bit
|
||||||
|
DATA ·reduce<>+0(SB)/8, $0x0
|
||||||
|
DATA ·reduce<>+8(SB)/8, $0xfffffffffff
|
||||||
|
// 42 bit
|
||||||
|
DATA ·reduce<>+16(SB)/8, $0x0
|
||||||
|
DATA ·reduce<>+24(SB)/8, $0x3ffffffffff
|
||||||
|
|
||||||
|
// h = (f*g) % (2**130-5) [partial reduction]
|
||||||
|
// uses T_0...T_9 temporary registers
|
||||||
|
// input: m02_0, m02_1, m02_2, m13_0, m13_1, m13_2, r_0, r_1, r_2, r5_1, r5_2, m4_0, m4_1, m4_2, m5_0, m5_1, m5_2
|
||||||
|
// temp: t0, t1, t2, t3, t4, t5, t6, t7, t8, t9
|
||||||
|
// output: m02_0, m02_1, m02_2, m13_0, m13_1, m13_2
|
||||||
|
#define MULTIPLY(m02_0, m02_1, m02_2, m13_0, m13_1, m13_2, r_0, r_1, r_2, r5_1, r5_2, m4_0, m4_1, m4_2, m5_0, m5_1, m5_2, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9) \
|
||||||
|
\ // Eliminate the dependency for the last 2 VMSLs
|
||||||
|
VMSLG m02_0, r_2, m4_2, m4_2 \
|
||||||
|
VMSLG m13_0, r_2, m5_2, m5_2 \ // 8 VMSLs pipelined
|
||||||
|
VMSLG m02_0, r_0, m4_0, m4_0 \
|
||||||
|
VMSLG m02_1, r5_2, V0, T_0 \
|
||||||
|
VMSLG m02_0, r_1, m4_1, m4_1 \
|
||||||
|
VMSLG m02_1, r_0, V0, T_1 \
|
||||||
|
VMSLG m02_1, r_1, V0, T_2 \
|
||||||
|
VMSLG m02_2, r5_1, V0, T_3 \
|
||||||
|
VMSLG m02_2, r5_2, V0, T_4 \
|
||||||
|
VMSLG m13_0, r_0, m5_0, m5_0 \
|
||||||
|
VMSLG m13_1, r5_2, V0, T_5 \
|
||||||
|
VMSLG m13_0, r_1, m5_1, m5_1 \
|
||||||
|
VMSLG m13_1, r_0, V0, T_6 \
|
||||||
|
VMSLG m13_1, r_1, V0, T_7 \
|
||||||
|
VMSLG m13_2, r5_1, V0, T_8 \
|
||||||
|
VMSLG m13_2, r5_2, V0, T_9 \
|
||||||
|
VMSLG m02_2, r_0, m4_2, m4_2 \
|
||||||
|
VMSLG m13_2, r_0, m5_2, m5_2 \
|
||||||
|
VAQ m4_0, T_0, m02_0 \
|
||||||
|
VAQ m4_1, T_1, m02_1 \
|
||||||
|
VAQ m5_0, T_5, m13_0 \
|
||||||
|
VAQ m5_1, T_6, m13_1 \
|
||||||
|
VAQ m02_0, T_3, m02_0 \
|
||||||
|
VAQ m02_1, T_4, m02_1 \
|
||||||
|
VAQ m13_0, T_8, m13_0 \
|
||||||
|
VAQ m13_1, T_9, m13_1 \
|
||||||
|
VAQ m4_2, T_2, m02_2 \
|
||||||
|
VAQ m5_2, T_7, m13_2 \
|
||||||
|
|
||||||
|
// SQUARE uses three limbs of r and r_2*5 to output square of r
|
||||||
|
// uses T_1, T_5 and T_7 temporary registers
|
||||||
|
// input: r_0, r_1, r_2, r5_2
|
||||||
|
// temp: TEMP0, TEMP1, TEMP2
|
||||||
|
// output: p0, p1, p2
|
||||||
|
#define SQUARE(r_0, r_1, r_2, r5_2, p0, p1, p2, TEMP0, TEMP1, TEMP2) \
|
||||||
|
VMSLG r_0, r_0, p0, p0 \
|
||||||
|
VMSLG r_1, r5_2, V0, TEMP0 \
|
||||||
|
VMSLG r_2, r5_2, p1, p1 \
|
||||||
|
VMSLG r_0, r_1, V0, TEMP1 \
|
||||||
|
VMSLG r_1, r_1, p2, p2 \
|
||||||
|
VMSLG r_0, r_2, V0, TEMP2 \
|
||||||
|
VAQ TEMP0, p0, p0 \
|
||||||
|
VAQ TEMP1, p1, p1 \
|
||||||
|
VAQ TEMP2, p2, p2 \
|
||||||
|
VAQ TEMP0, p0, p0 \
|
||||||
|
VAQ TEMP1, p1, p1 \
|
||||||
|
VAQ TEMP2, p2, p2 \
|
||||||
|
|
||||||
|
// carry h0->h1->h2->h0 || h3->h4->h5->h3
|
||||||
|
// uses T_2, T_4, T_5, T_7, T_8, T_9
|
||||||
|
// t6, t7, t8, t9, t10, t11
|
||||||
|
// input: h0, h1, h2, h3, h4, h5
|
||||||
|
// temp: t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11
|
||||||
|
// output: h0, h1, h2, h3, h4, h5
|
||||||
|
#define REDUCE(h0, h1, h2, h3, h4, h5, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11) \
|
||||||
|
VLM (R12), t6, t7 \ // 44 and 42 bit clear mask
|
||||||
|
VLEIB $7, $0x28, t10 \ // 5 byte shift mask
|
||||||
|
VREPIB $4, t8 \ // 4 bit shift mask
|
||||||
|
VREPIB $2, t11 \ // 2 bit shift mask
|
||||||
|
VSRLB t10, h0, t0 \ // h0 byte shift
|
||||||
|
VSRLB t10, h1, t1 \ // h1 byte shift
|
||||||
|
VSRLB t10, h2, t2 \ // h2 byte shift
|
||||||
|
VSRLB t10, h3, t3 \ // h3 byte shift
|
||||||
|
VSRLB t10, h4, t4 \ // h4 byte shift
|
||||||
|
VSRLB t10, h5, t5 \ // h5 byte shift
|
||||||
|
VSRL t8, t0, t0 \ // h0 bit shift
|
||||||
|
VSRL t8, t1, t1 \ // h2 bit shift
|
||||||
|
VSRL t11, t2, t2 \ // h2 bit shift
|
||||||
|
VSRL t8, t3, t3 \ // h3 bit shift
|
||||||
|
VSRL t8, t4, t4 \ // h4 bit shift
|
||||||
|
VESLG $2, t2, t9 \ // h2 carry x5
|
||||||
|
VSRL t11, t5, t5 \ // h5 bit shift
|
||||||
|
VN t6, h0, h0 \ // h0 clear carry
|
||||||
|
VAQ t2, t9, t2 \ // h2 carry x5
|
||||||
|
VESLG $2, t5, t9 \ // h5 carry x5
|
||||||
|
VN t6, h1, h1 \ // h1 clear carry
|
||||||
|
VN t7, h2, h2 \ // h2 clear carry
|
||||||
|
VAQ t5, t9, t5 \ // h5 carry x5
|
||||||
|
VN t6, h3, h3 \ // h3 clear carry
|
||||||
|
VN t6, h4, h4 \ // h4 clear carry
|
||||||
|
VN t7, h5, h5 \ // h5 clear carry
|
||||||
|
VAQ t0, h1, h1 \ // h0->h1
|
||||||
|
VAQ t3, h4, h4 \ // h3->h4
|
||||||
|
VAQ t1, h2, h2 \ // h1->h2
|
||||||
|
VAQ t4, h5, h5 \ // h4->h5
|
||||||
|
VAQ t2, h0, h0 \ // h2->h0
|
||||||
|
VAQ t5, h3, h3 \ // h5->h3
|
||||||
|
VREPG $1, t6, t6 \ // 44 and 42 bit masks across both halves
|
||||||
|
VREPG $1, t7, t7 \
|
||||||
|
VSLDB $8, h0, h0, h0 \ // set up [h0/1/2, h3/4/5]
|
||||||
|
VSLDB $8, h1, h1, h1 \
|
||||||
|
VSLDB $8, h2, h2, h2 \
|
||||||
|
VO h0, h3, h3 \
|
||||||
|
VO h1, h4, h4 \
|
||||||
|
VO h2, h5, h5 \
|
||||||
|
VESRLG $44, h3, t0 \ // 44 bit shift right
|
||||||
|
VESRLG $44, h4, t1 \
|
||||||
|
VESRLG $42, h5, t2 \
|
||||||
|
VN t6, h3, h3 \ // clear carry bits
|
||||||
|
VN t6, h4, h4 \
|
||||||
|
VN t7, h5, h5 \
|
||||||
|
VESLG $2, t2, t9 \ // multiply carry by 5
|
||||||
|
VAQ t9, t2, t2 \
|
||||||
|
VAQ t0, h4, h4 \
|
||||||
|
VAQ t1, h5, h5 \
|
||||||
|
VAQ t2, h3, h3 \
|
||||||
|
|
||||||
|
// carry h0->h1->h2->h0
|
||||||
|
// input: h0, h1, h2
|
||||||
|
// temp: t0, t1, t2, t3, t4, t5, t6, t7, t8
|
||||||
|
// output: h0, h1, h2
|
||||||
|
#define REDUCE2(h0, h1, h2, t0, t1, t2, t3, t4, t5, t6, t7, t8) \
|
||||||
|
VLEIB $7, $0x28, t3 \ // 5 byte shift mask
|
||||||
|
VREPIB $4, t4 \ // 4 bit shift mask
|
||||||
|
VREPIB $2, t7 \ // 2 bit shift mask
|
||||||
|
VGBM $0x003F, t5 \ // mask to clear carry bits
|
||||||
|
VSRLB t3, h0, t0 \
|
||||||
|
VSRLB t3, h1, t1 \
|
||||||
|
VSRLB t3, h2, t2 \
|
||||||
|
VESRLG $4, t5, t5 \ // 44 bit clear mask
|
||||||
|
VSRL t4, t0, t0 \
|
||||||
|
VSRL t4, t1, t1 \
|
||||||
|
VSRL t7, t2, t2 \
|
||||||
|
VESRLG $2, t5, t6 \ // 42 bit clear mask
|
||||||
|
VESLG $2, t2, t8 \
|
||||||
|
VAQ t8, t2, t2 \
|
||||||
|
VN t5, h0, h0 \
|
||||||
|
VN t5, h1, h1 \
|
||||||
|
VN t6, h2, h2 \
|
||||||
|
VAQ t0, h1, h1 \
|
||||||
|
VAQ t1, h2, h2 \
|
||||||
|
VAQ t2, h0, h0 \
|
||||||
|
VSRLB t3, h0, t0 \
|
||||||
|
VSRLB t3, h1, t1 \
|
||||||
|
VSRLB t3, h2, t2 \
|
||||||
|
VSRL t4, t0, t0 \
|
||||||
|
VSRL t4, t1, t1 \
|
||||||
|
VSRL t7, t2, t2 \
|
||||||
|
VN t5, h0, h0 \
|
||||||
|
VN t5, h1, h1 \
|
||||||
|
VESLG $2, t2, t8 \
|
||||||
|
VN t6, h2, h2 \
|
||||||
|
VAQ t0, h1, h1 \
|
||||||
|
VAQ t8, t2, t2 \
|
||||||
|
VAQ t1, h2, h2 \
|
||||||
|
VAQ t2, h0, h0 \
|
||||||
|
|
||||||
|
// expands two message blocks into the lower halfs of the d registers
|
||||||
|
// moves the contents of the d registers into upper halfs
|
||||||
|
// input: in1, in2, d0, d1, d2, d3, d4, d5
|
||||||
|
// temp: TEMP0, TEMP1, TEMP2, TEMP3
|
||||||
|
// output: d0, d1, d2, d3, d4, d5
|
||||||
|
#define EXPACC(in1, in2, d0, d1, d2, d3, d4, d5, TEMP0, TEMP1, TEMP2, TEMP3) \
|
||||||
|
VGBM $0xff3f, TEMP0 \
|
||||||
|
VGBM $0xff1f, TEMP1 \
|
||||||
|
VESLG $4, d1, TEMP2 \
|
||||||
|
VESLG $4, d4, TEMP3 \
|
||||||
|
VESRLG $4, TEMP0, TEMP0 \
|
||||||
|
VPERM in1, d0, EX0, d0 \
|
||||||
|
VPERM in2, d3, EX0, d3 \
|
||||||
|
VPERM in1, d2, EX2, d2 \
|
||||||
|
VPERM in2, d5, EX2, d5 \
|
||||||
|
VPERM in1, TEMP2, EX1, d1 \
|
||||||
|
VPERM in2, TEMP3, EX1, d4 \
|
||||||
|
VN TEMP0, d0, d0 \
|
||||||
|
VN TEMP0, d3, d3 \
|
||||||
|
VESRLG $4, d1, d1 \
|
||||||
|
VESRLG $4, d4, d4 \
|
||||||
|
VN TEMP1, d2, d2 \
|
||||||
|
VN TEMP1, d5, d5 \
|
||||||
|
VN TEMP0, d1, d1 \
|
||||||
|
VN TEMP0, d4, d4 \
|
||||||
|
|
||||||
|
// expands one message block into the lower halfs of the d registers
|
||||||
|
// moves the contents of the d registers into upper halfs
|
||||||
|
// input: in, d0, d1, d2
|
||||||
|
// temp: TEMP0, TEMP1, TEMP2
|
||||||
|
// output: d0, d1, d2
|
||||||
|
#define EXPACC2(in, d0, d1, d2, TEMP0, TEMP1, TEMP2) \
|
||||||
|
VGBM $0xff3f, TEMP0 \
|
||||||
|
VESLG $4, d1, TEMP2 \
|
||||||
|
VGBM $0xff1f, TEMP1 \
|
||||||
|
VPERM in, d0, EX0, d0 \
|
||||||
|
VESRLG $4, TEMP0, TEMP0 \
|
||||||
|
VPERM in, d2, EX2, d2 \
|
||||||
|
VPERM in, TEMP2, EX1, d1 \
|
||||||
|
VN TEMP0, d0, d0 \
|
||||||
|
VN TEMP1, d2, d2 \
|
||||||
|
VESRLG $4, d1, d1 \
|
||||||
|
VN TEMP0, d1, d1 \
|
||||||
|
|
||||||
|
// pack h2:h0 into h1:h0 (no carry)
|
||||||
|
// input: h0, h1, h2
|
||||||
|
// output: h0, h1, h2
|
||||||
|
#define PACK(h0, h1, h2) \
|
||||||
|
VMRLG h1, h2, h2 \ // copy h1 to upper half h2
|
||||||
|
VESLG $44, h1, h1 \ // shift limb 1 44 bits, leaving 20
|
||||||
|
VO h0, h1, h0 \ // combine h0 with 20 bits from limb 1
|
||||||
|
VESRLG $20, h2, h1 \ // put top 24 bits of limb 1 into h1
|
||||||
|
VLEIG $1, $0, h1 \ // clear h2 stuff from lower half of h1
|
||||||
|
VO h0, h1, h0 \ // h0 now has 88 bits (limb 0 and 1)
|
||||||
|
VLEIG $0, $0, h2 \ // clear upper half of h2
|
||||||
|
VESRLG $40, h2, h1 \ // h1 now has upper two bits of result
|
||||||
|
VLEIB $7, $88, h1 \ // for byte shift (11 bytes)
|
||||||
|
VSLB h1, h2, h2 \ // shift h2 11 bytes to the left
|
||||||
|
VO h0, h2, h0 \ // combine h0 with 20 bits from limb 1
|
||||||
|
VLEIG $0, $0, h1 \ // clear upper half of h1
|
||||||
|
|
||||||
|
// if h > 2**130-5 then h -= 2**130-5
|
||||||
|
// input: h0, h1
|
||||||
|
// temp: t0, t1, t2
|
||||||
|
// output: h0
|
||||||
|
#define MOD(h0, h1, t0, t1, t2) \
|
||||||
|
VZERO t0 \
|
||||||
|
VLEIG $1, $5, t0 \
|
||||||
|
VACCQ h0, t0, t1 \
|
||||||
|
VAQ h0, t0, t0 \
|
||||||
|
VONE t2 \
|
||||||
|
VLEIG $1, $-4, t2 \
|
||||||
|
VAQ t2, t1, t1 \
|
||||||
|
VACCQ h1, t1, t1 \
|
||||||
|
VONE t2 \
|
||||||
|
VAQ t2, t1, t1 \
|
||||||
|
VN h0, t1, t2 \
|
||||||
|
VNC t0, t1, t1 \
|
||||||
|
VO t1, t2, h0 \
|
||||||
|
|
||||||
|
// func poly1305vmsl(out *[16]byte, m *byte, mlen uint64, key *[32]key)
|
||||||
|
TEXT ·poly1305vmsl(SB), $0-32
|
||||||
|
// This code processes 6 + up to 4 blocks (32 bytes) per iteration
|
||||||
|
// using the algorithm described in:
|
||||||
|
// NEON crypto, Daniel J. Bernstein & Peter Schwabe
|
||||||
|
// https://cryptojedi.org/papers/neoncrypto-20120320.pdf
|
||||||
|
// And as moddified for VMSL as described in
|
||||||
|
// Accelerating Poly1305 Cryptographic Message Authentication on the z14
|
||||||
|
// O'Farrell et al, CASCON 2017, p48-55
|
||||||
|
// https://ibm.ent.box.com/s/jf9gedj0e9d2vjctfyh186shaztavnht
|
||||||
|
|
||||||
|
LMG out+0(FP), R1, R4 // R1=out, R2=m, R3=mlen, R4=key
|
||||||
|
VZERO V0 // c
|
||||||
|
|
||||||
|
// load EX0, EX1 and EX2
|
||||||
|
MOVD $·constants<>(SB), R5
|
||||||
|
VLM (R5), EX0, EX2 // c
|
||||||
|
|
||||||
|
// setup r
|
||||||
|
VL (R4), T_0
|
||||||
|
MOVD $·keyMask<>(SB), R6
|
||||||
|
VL (R6), T_1
|
||||||
|
VN T_0, T_1, T_0
|
||||||
|
VZERO T_2 // limbs for r
|
||||||
|
VZERO T_3
|
||||||
|
VZERO T_4
|
||||||
|
EXPACC2(T_0, T_2, T_3, T_4, T_1, T_5, T_7)
|
||||||
|
|
||||||
|
// T_2, T_3, T_4: [0, r]
|
||||||
|
|
||||||
|
// setup r*20
|
||||||
|
VLEIG $0, $0, T_0
|
||||||
|
VLEIG $1, $20, T_0 // T_0: [0, 20]
|
||||||
|
VZERO T_5
|
||||||
|
VZERO T_6
|
||||||
|
VMSLG T_0, T_3, T_5, T_5
|
||||||
|
VMSLG T_0, T_4, T_6, T_6
|
||||||
|
|
||||||
|
// store r for final block in GR
|
||||||
|
VLGVG $1, T_2, RSAVE_0 // c
|
||||||
|
VLGVG $1, T_3, RSAVE_1 // c
|
||||||
|
VLGVG $1, T_4, RSAVE_2 // c
|
||||||
|
VLGVG $1, T_5, R5SAVE_1 // c
|
||||||
|
VLGVG $1, T_6, R5SAVE_2 // c
|
||||||
|
|
||||||
|
// initialize h
|
||||||
|
VZERO H0_0
|
||||||
|
VZERO H1_0
|
||||||
|
VZERO H2_0
|
||||||
|
VZERO H0_1
|
||||||
|
VZERO H1_1
|
||||||
|
VZERO H2_1
|
||||||
|
|
||||||
|
// initialize pointer for reduce constants
|
||||||
|
MOVD $·reduce<>(SB), R12
|
||||||
|
|
||||||
|
// calculate r**2 and 20*(r**2)
|
||||||
|
VZERO R_0
|
||||||
|
VZERO R_1
|
||||||
|
VZERO R_2
|
||||||
|
SQUARE(T_2, T_3, T_4, T_6, R_0, R_1, R_2, T_1, T_5, T_7)
|
||||||
|
REDUCE2(R_0, R_1, R_2, M0, M1, M2, M3, M4, R5_1, R5_2, M5, T_1)
|
||||||
|
VZERO R5_1
|
||||||
|
VZERO R5_2
|
||||||
|
VMSLG T_0, R_1, R5_1, R5_1
|
||||||
|
VMSLG T_0, R_2, R5_2, R5_2
|
||||||
|
|
||||||
|
// skip r**4 calculation if 3 blocks or less
|
||||||
|
CMPBLE R3, $48, b4
|
||||||
|
|
||||||
|
// calculate r**4 and 20*(r**4)
|
||||||
|
VZERO T_8
|
||||||
|
VZERO T_9
|
||||||
|
VZERO T_10
|
||||||
|
SQUARE(R_0, R_1, R_2, R5_2, T_8, T_9, T_10, T_1, T_5, T_7)
|
||||||
|
REDUCE2(T_8, T_9, T_10, M0, M1, M2, M3, M4, T_2, T_3, M5, T_1)
|
||||||
|
VZERO T_2
|
||||||
|
VZERO T_3
|
||||||
|
VMSLG T_0, T_9, T_2, T_2
|
||||||
|
VMSLG T_0, T_10, T_3, T_3
|
||||||
|
|
||||||
|
// put r**2 to the right and r**4 to the left of R_0, R_1, R_2
|
||||||
|
VSLDB $8, T_8, T_8, T_8
|
||||||
|
VSLDB $8, T_9, T_9, T_9
|
||||||
|
VSLDB $8, T_10, T_10, T_10
|
||||||
|
VSLDB $8, T_2, T_2, T_2
|
||||||
|
VSLDB $8, T_3, T_3, T_3
|
||||||
|
|
||||||
|
VO T_8, R_0, R_0
|
||||||
|
VO T_9, R_1, R_1
|
||||||
|
VO T_10, R_2, R_2
|
||||||
|
VO T_2, R5_1, R5_1
|
||||||
|
VO T_3, R5_2, R5_2
|
||||||
|
|
||||||
|
CMPBLE R3, $80, load // less than or equal to 5 blocks in message
|
||||||
|
|
||||||
|
// 6(or 5+1) blocks
|
||||||
|
SUB $81, R3
|
||||||
|
VLM (R2), M0, M4
|
||||||
|
VLL R3, 80(R2), M5
|
||||||
|
ADD $1, R3
|
||||||
|
MOVBZ $1, R0
|
||||||
|
CMPBGE R3, $16, 2(PC)
|
||||||
|
VLVGB R3, R0, M5
|
||||||
|
MOVD $96(R2), R2
|
||||||
|
EXPACC(M0, M1, H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, T_0, T_1, T_2, T_3)
|
||||||
|
EXPACC(M2, M3, H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, T_0, T_1, T_2, T_3)
|
||||||
|
VLEIB $2, $1, H2_0
|
||||||
|
VLEIB $2, $1, H2_1
|
||||||
|
VLEIB $10, $1, H2_0
|
||||||
|
VLEIB $10, $1, H2_1
|
||||||
|
|
||||||
|
VZERO M0
|
||||||
|
VZERO M1
|
||||||
|
VZERO M2
|
||||||
|
VZERO M3
|
||||||
|
VZERO T_4
|
||||||
|
VZERO T_10
|
||||||
|
EXPACC(M4, M5, M0, M1, M2, M3, T_4, T_10, T_0, T_1, T_2, T_3)
|
||||||
|
VLR T_4, M4
|
||||||
|
VLEIB $10, $1, M2
|
||||||
|
CMPBLT R3, $16, 2(PC)
|
||||||
|
VLEIB $10, $1, T_10
|
||||||
|
MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, T_10, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
||||||
|
REDUCE(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, T_10, M0, M1, M2, M3, M4, T_4, T_5, T_2, T_7, T_8, T_9)
|
||||||
|
VMRHG V0, H0_1, H0_0
|
||||||
|
VMRHG V0, H1_1, H1_0
|
||||||
|
VMRHG V0, H2_1, H2_0
|
||||||
|
VMRLG V0, H0_1, H0_1
|
||||||
|
VMRLG V0, H1_1, H1_1
|
||||||
|
VMRLG V0, H2_1, H2_1
|
||||||
|
|
||||||
|
SUB $16, R3
|
||||||
|
CMPBLE R3, $0, square
|
||||||
|
|
||||||
|
load:
|
||||||
|
// load EX0, EX1 and EX2
|
||||||
|
MOVD $·c<>(SB), R5
|
||||||
|
VLM (R5), EX0, EX2
|
||||||
|
|
||||||
|
loop:
|
||||||
|
CMPBLE R3, $64, add // b4 // last 4 or less blocks left
|
||||||
|
|
||||||
|
// next 4 full blocks
|
||||||
|
VLM (R2), M2, M5
|
||||||
|
SUB $64, R3
|
||||||
|
MOVD $64(R2), R2
|
||||||
|
REDUCE(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, T_10, M0, M1, T_0, T_1, T_3, T_4, T_5, T_2, T_7, T_8, T_9)
|
||||||
|
|
||||||
|
// expacc in-lined to create [m2, m3] limbs
|
||||||
|
VGBM $0x3f3f, T_0 // 44 bit clear mask
|
||||||
|
VGBM $0x1f1f, T_1 // 40 bit clear mask
|
||||||
|
VPERM M2, M3, EX0, T_3
|
||||||
|
VESRLG $4, T_0, T_0 // 44 bit clear mask ready
|
||||||
|
VPERM M2, M3, EX1, T_4
|
||||||
|
VPERM M2, M3, EX2, T_5
|
||||||
|
VN T_0, T_3, T_3
|
||||||
|
VESRLG $4, T_4, T_4
|
||||||
|
VN T_1, T_5, T_5
|
||||||
|
VN T_0, T_4, T_4
|
||||||
|
VMRHG H0_1, T_3, H0_0
|
||||||
|
VMRHG H1_1, T_4, H1_0
|
||||||
|
VMRHG H2_1, T_5, H2_0
|
||||||
|
VMRLG H0_1, T_3, H0_1
|
||||||
|
VMRLG H1_1, T_4, H1_1
|
||||||
|
VMRLG H2_1, T_5, H2_1
|
||||||
|
VLEIB $10, $1, H2_0
|
||||||
|
VLEIB $10, $1, H2_1
|
||||||
|
VPERM M4, M5, EX0, T_3
|
||||||
|
VPERM M4, M5, EX1, T_4
|
||||||
|
VPERM M4, M5, EX2, T_5
|
||||||
|
VN T_0, T_3, T_3
|
||||||
|
VESRLG $4, T_4, T_4
|
||||||
|
VN T_1, T_5, T_5
|
||||||
|
VN T_0, T_4, T_4
|
||||||
|
VMRHG V0, T_3, M0
|
||||||
|
VMRHG V0, T_4, M1
|
||||||
|
VMRHG V0, T_5, M2
|
||||||
|
VMRLG V0, T_3, M3
|
||||||
|
VMRLG V0, T_4, M4
|
||||||
|
VMRLG V0, T_5, M5
|
||||||
|
VLEIB $10, $1, M2
|
||||||
|
VLEIB $10, $1, M5
|
||||||
|
|
||||||
|
MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, M5, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
||||||
|
CMPBNE R3, $0, loop
|
||||||
|
REDUCE(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, T_10, M0, M1, M3, M4, M5, T_4, T_5, T_2, T_7, T_8, T_9)
|
||||||
|
VMRHG V0, H0_1, H0_0
|
||||||
|
VMRHG V0, H1_1, H1_0
|
||||||
|
VMRHG V0, H2_1, H2_0
|
||||||
|
VMRLG V0, H0_1, H0_1
|
||||||
|
VMRLG V0, H1_1, H1_1
|
||||||
|
VMRLG V0, H2_1, H2_1
|
||||||
|
|
||||||
|
// load EX0, EX1, EX2
|
||||||
|
MOVD $·constants<>(SB), R5
|
||||||
|
VLM (R5), EX0, EX2
|
||||||
|
|
||||||
|
// sum vectors
|
||||||
|
VAQ H0_0, H0_1, H0_0
|
||||||
|
VAQ H1_0, H1_1, H1_0
|
||||||
|
VAQ H2_0, H2_1, H2_0
|
||||||
|
|
||||||
|
// h may be >= 2*(2**130-5) so we need to reduce it again
|
||||||
|
// M0...M4 are used as temps here
|
||||||
|
REDUCE2(H0_0, H1_0, H2_0, M0, M1, M2, M3, M4, T_9, T_10, H0_1, M5)
|
||||||
|
|
||||||
|
next: // carry h1->h2
|
||||||
|
VLEIB $7, $0x28, T_1
|
||||||
|
VREPIB $4, T_2
|
||||||
|
VGBM $0x003F, T_3
|
||||||
|
VESRLG $4, T_3
|
||||||
|
|
||||||
|
// byte shift
|
||||||
|
VSRLB T_1, H1_0, T_4
|
||||||
|
|
||||||
|
// bit shift
|
||||||
|
VSRL T_2, T_4, T_4
|
||||||
|
|
||||||
|
// clear h1 carry bits
|
||||||
|
VN T_3, H1_0, H1_0
|
||||||
|
|
||||||
|
// add carry
|
||||||
|
VAQ T_4, H2_0, H2_0
|
||||||
|
|
||||||
|
// h is now < 2*(2**130-5)
|
||||||
|
// pack h into h1 (hi) and h0 (lo)
|
||||||
|
PACK(H0_0, H1_0, H2_0)
|
||||||
|
|
||||||
|
// if h > 2**130-5 then h -= 2**130-5
|
||||||
|
MOD(H0_0, H1_0, T_0, T_1, T_2)
|
||||||
|
|
||||||
|
// h += s
|
||||||
|
MOVD $·bswapMask<>(SB), R5
|
||||||
|
VL (R5), T_1
|
||||||
|
VL 16(R4), T_0
|
||||||
|
VPERM T_0, T_0, T_1, T_0 // reverse bytes (to big)
|
||||||
|
VAQ T_0, H0_0, H0_0
|
||||||
|
VPERM H0_0, H0_0, T_1, H0_0 // reverse bytes (to little)
|
||||||
|
VST H0_0, (R1)
|
||||||
|
RET
|
||||||
|
|
||||||
|
add:
|
||||||
|
// load EX0, EX1, EX2
|
||||||
|
MOVD $·constants<>(SB), R5
|
||||||
|
VLM (R5), EX0, EX2
|
||||||
|
|
||||||
|
REDUCE(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, T_10, M0, M1, M3, M4, M5, T_4, T_5, T_2, T_7, T_8, T_9)
|
||||||
|
VMRHG V0, H0_1, H0_0
|
||||||
|
VMRHG V0, H1_1, H1_0
|
||||||
|
VMRHG V0, H2_1, H2_0
|
||||||
|
VMRLG V0, H0_1, H0_1
|
||||||
|
VMRLG V0, H1_1, H1_1
|
||||||
|
VMRLG V0, H2_1, H2_1
|
||||||
|
CMPBLE R3, $64, b4
|
||||||
|
|
||||||
|
b4:
|
||||||
|
CMPBLE R3, $48, b3 // 3 blocks or less
|
||||||
|
|
||||||
|
// 4(3+1) blocks remaining
|
||||||
|
SUB $49, R3
|
||||||
|
VLM (R2), M0, M2
|
||||||
|
VLL R3, 48(R2), M3
|
||||||
|
ADD $1, R3
|
||||||
|
MOVBZ $1, R0
|
||||||
|
CMPBEQ R3, $16, 2(PC)
|
||||||
|
VLVGB R3, R0, M3
|
||||||
|
MOVD $64(R2), R2
|
||||||
|
EXPACC(M0, M1, H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, T_0, T_1, T_2, T_3)
|
||||||
|
VLEIB $10, $1, H2_0
|
||||||
|
VLEIB $10, $1, H2_1
|
||||||
|
VZERO M0
|
||||||
|
VZERO M1
|
||||||
|
VZERO M4
|
||||||
|
VZERO M5
|
||||||
|
VZERO T_4
|
||||||
|
VZERO T_10
|
||||||
|
EXPACC(M2, M3, M0, M1, M4, M5, T_4, T_10, T_0, T_1, T_2, T_3)
|
||||||
|
VLR T_4, M2
|
||||||
|
VLEIB $10, $1, M4
|
||||||
|
CMPBNE R3, $16, 2(PC)
|
||||||
|
VLEIB $10, $1, T_10
|
||||||
|
MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M4, M5, M2, T_10, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
||||||
|
REDUCE(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, T_10, M0, M1, M3, M4, M5, T_4, T_5, T_2, T_7, T_8, T_9)
|
||||||
|
VMRHG V0, H0_1, H0_0
|
||||||
|
VMRHG V0, H1_1, H1_0
|
||||||
|
VMRHG V0, H2_1, H2_0
|
||||||
|
VMRLG V0, H0_1, H0_1
|
||||||
|
VMRLG V0, H1_1, H1_1
|
||||||
|
VMRLG V0, H2_1, H2_1
|
||||||
|
SUB $16, R3
|
||||||
|
CMPBLE R3, $0, square // this condition must always hold true!
|
||||||
|
|
||||||
|
b3:
|
||||||
|
CMPBLE R3, $32, b2
|
||||||
|
|
||||||
|
// 3 blocks remaining
|
||||||
|
|
||||||
|
// setup [r²,r]
|
||||||
|
VSLDB $8, R_0, R_0, R_0
|
||||||
|
VSLDB $8, R_1, R_1, R_1
|
||||||
|
VSLDB $8, R_2, R_2, R_2
|
||||||
|
VSLDB $8, R5_1, R5_1, R5_1
|
||||||
|
VSLDB $8, R5_2, R5_2, R5_2
|
||||||
|
|
||||||
|
VLVGG $1, RSAVE_0, R_0
|
||||||
|
VLVGG $1, RSAVE_1, R_1
|
||||||
|
VLVGG $1, RSAVE_2, R_2
|
||||||
|
VLVGG $1, R5SAVE_1, R5_1
|
||||||
|
VLVGG $1, R5SAVE_2, R5_2
|
||||||
|
|
||||||
|
// setup [h0, h1]
|
||||||
|
VSLDB $8, H0_0, H0_0, H0_0
|
||||||
|
VSLDB $8, H1_0, H1_0, H1_0
|
||||||
|
VSLDB $8, H2_0, H2_0, H2_0
|
||||||
|
VO H0_1, H0_0, H0_0
|
||||||
|
VO H1_1, H1_0, H1_0
|
||||||
|
VO H2_1, H2_0, H2_0
|
||||||
|
VZERO H0_1
|
||||||
|
VZERO H1_1
|
||||||
|
VZERO H2_1
|
||||||
|
|
||||||
|
VZERO M0
|
||||||
|
VZERO M1
|
||||||
|
VZERO M2
|
||||||
|
VZERO M3
|
||||||
|
VZERO M4
|
||||||
|
VZERO M5
|
||||||
|
|
||||||
|
// H*[r**2, r]
|
||||||
|
MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, M5, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
||||||
|
REDUCE2(H0_0, H1_0, H2_0, M0, M1, M2, M3, M4, H0_1, H1_1, T_10, M5)
|
||||||
|
|
||||||
|
SUB $33, R3
|
||||||
|
VLM (R2), M0, M1
|
||||||
|
VLL R3, 32(R2), M2
|
||||||
|
ADD $1, R3
|
||||||
|
MOVBZ $1, R0
|
||||||
|
CMPBEQ R3, $16, 2(PC)
|
||||||
|
VLVGB R3, R0, M2
|
||||||
|
|
||||||
|
// H += m0
|
||||||
|
VZERO T_1
|
||||||
|
VZERO T_2
|
||||||
|
VZERO T_3
|
||||||
|
EXPACC2(M0, T_1, T_2, T_3, T_4, T_5, T_6)
|
||||||
|
VLEIB $10, $1, T_3
|
||||||
|
VAG H0_0, T_1, H0_0
|
||||||
|
VAG H1_0, T_2, H1_0
|
||||||
|
VAG H2_0, T_3, H2_0
|
||||||
|
|
||||||
|
VZERO M0
|
||||||
|
VZERO M3
|
||||||
|
VZERO M4
|
||||||
|
VZERO M5
|
||||||
|
VZERO T_10
|
||||||
|
|
||||||
|
// (H+m0)*r
|
||||||
|
MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M3, M4, M5, V0, T_10, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
||||||
|
REDUCE2(H0_0, H1_0, H2_0, M0, M3, M4, M5, T_10, H0_1, H1_1, H2_1, T_9)
|
||||||
|
|
||||||
|
// H += m1
|
||||||
|
VZERO V0
|
||||||
|
VZERO T_1
|
||||||
|
VZERO T_2
|
||||||
|
VZERO T_3
|
||||||
|
EXPACC2(M1, T_1, T_2, T_3, T_4, T_5, T_6)
|
||||||
|
VLEIB $10, $1, T_3
|
||||||
|
VAQ H0_0, T_1, H0_0
|
||||||
|
VAQ H1_0, T_2, H1_0
|
||||||
|
VAQ H2_0, T_3, H2_0
|
||||||
|
REDUCE2(H0_0, H1_0, H2_0, M0, M3, M4, M5, T_9, H0_1, H1_1, H2_1, T_10)
|
||||||
|
|
||||||
|
// [H, m2] * [r**2, r]
|
||||||
|
EXPACC2(M2, H0_0, H1_0, H2_0, T_1, T_2, T_3)
|
||||||
|
CMPBNE R3, $16, 2(PC)
|
||||||
|
VLEIB $10, $1, H2_0
|
||||||
|
VZERO M0
|
||||||
|
VZERO M1
|
||||||
|
VZERO M2
|
||||||
|
VZERO M3
|
||||||
|
VZERO M4
|
||||||
|
VZERO M5
|
||||||
|
MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, M5, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
||||||
|
REDUCE2(H0_0, H1_0, H2_0, M0, M1, M2, M3, M4, H0_1, H1_1, M5, T_10)
|
||||||
|
SUB $16, R3
|
||||||
|
CMPBLE R3, $0, next // this condition must always hold true!
|
||||||
|
|
||||||
|
b2:
|
||||||
|
CMPBLE R3, $16, b1
|
||||||
|
|
||||||
|
// 2 blocks remaining
|
||||||
|
|
||||||
|
// setup [r²,r]
|
||||||
|
VSLDB $8, R_0, R_0, R_0
|
||||||
|
VSLDB $8, R_1, R_1, R_1
|
||||||
|
VSLDB $8, R_2, R_2, R_2
|
||||||
|
VSLDB $8, R5_1, R5_1, R5_1
|
||||||
|
VSLDB $8, R5_2, R5_2, R5_2
|
||||||
|
|
||||||
|
VLVGG $1, RSAVE_0, R_0
|
||||||
|
VLVGG $1, RSAVE_1, R_1
|
||||||
|
VLVGG $1, RSAVE_2, R_2
|
||||||
|
VLVGG $1, R5SAVE_1, R5_1
|
||||||
|
VLVGG $1, R5SAVE_2, R5_2
|
||||||
|
|
||||||
|
// setup [h0, h1]
|
||||||
|
VSLDB $8, H0_0, H0_0, H0_0
|
||||||
|
VSLDB $8, H1_0, H1_0, H1_0
|
||||||
|
VSLDB $8, H2_0, H2_0, H2_0
|
||||||
|
VO H0_1, H0_0, H0_0
|
||||||
|
VO H1_1, H1_0, H1_0
|
||||||
|
VO H2_1, H2_0, H2_0
|
||||||
|
VZERO H0_1
|
||||||
|
VZERO H1_1
|
||||||
|
VZERO H2_1
|
||||||
|
|
||||||
|
VZERO M0
|
||||||
|
VZERO M1
|
||||||
|
VZERO M2
|
||||||
|
VZERO M3
|
||||||
|
VZERO M4
|
||||||
|
VZERO M5
|
||||||
|
|
||||||
|
// H*[r**2, r]
|
||||||
|
MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, M5, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
||||||
|
REDUCE(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, T_10, M0, M1, M2, M3, M4, T_4, T_5, T_2, T_7, T_8, T_9)
|
||||||
|
VMRHG V0, H0_1, H0_0
|
||||||
|
VMRHG V0, H1_1, H1_0
|
||||||
|
VMRHG V0, H2_1, H2_0
|
||||||
|
VMRLG V0, H0_1, H0_1
|
||||||
|
VMRLG V0, H1_1, H1_1
|
||||||
|
VMRLG V0, H2_1, H2_1
|
||||||
|
|
||||||
|
// move h to the left and 0s at the right
|
||||||
|
VSLDB $8, H0_0, H0_0, H0_0
|
||||||
|
VSLDB $8, H1_0, H1_0, H1_0
|
||||||
|
VSLDB $8, H2_0, H2_0, H2_0
|
||||||
|
|
||||||
|
// get message blocks and append 1 to start
|
||||||
|
SUB $17, R3
|
||||||
|
VL (R2), M0
|
||||||
|
VLL R3, 16(R2), M1
|
||||||
|
ADD $1, R3
|
||||||
|
MOVBZ $1, R0
|
||||||
|
CMPBEQ R3, $16, 2(PC)
|
||||||
|
VLVGB R3, R0, M1
|
||||||
|
VZERO T_6
|
||||||
|
VZERO T_7
|
||||||
|
VZERO T_8
|
||||||
|
EXPACC2(M0, T_6, T_7, T_8, T_1, T_2, T_3)
|
||||||
|
EXPACC2(M1, T_6, T_7, T_8, T_1, T_2, T_3)
|
||||||
|
VLEIB $2, $1, T_8
|
||||||
|
CMPBNE R3, $16, 2(PC)
|
||||||
|
VLEIB $10, $1, T_8
|
||||||
|
|
||||||
|
// add [m0, m1] to h
|
||||||
|
VAG H0_0, T_6, H0_0
|
||||||
|
VAG H1_0, T_7, H1_0
|
||||||
|
VAG H2_0, T_8, H2_0
|
||||||
|
|
||||||
|
VZERO M2
|
||||||
|
VZERO M3
|
||||||
|
VZERO M4
|
||||||
|
VZERO M5
|
||||||
|
VZERO T_10
|
||||||
|
VZERO M0
|
||||||
|
|
||||||
|
// at this point R_0 .. R5_2 look like [r**2, r]
|
||||||
|
MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M2, M3, M4, M5, T_10, M0, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
||||||
|
REDUCE2(H0_0, H1_0, H2_0, M2, M3, M4, M5, T_9, H0_1, H1_1, H2_1, T_10)
|
||||||
|
SUB $16, R3, R3
|
||||||
|
CMPBLE R3, $0, next
|
||||||
|
|
||||||
|
b1:
|
||||||
|
CMPBLE R3, $0, next
|
||||||
|
|
||||||
|
// 1 block remaining
|
||||||
|
|
||||||
|
// setup [r²,r]
|
||||||
|
VSLDB $8, R_0, R_0, R_0
|
||||||
|
VSLDB $8, R_1, R_1, R_1
|
||||||
|
VSLDB $8, R_2, R_2, R_2
|
||||||
|
VSLDB $8, R5_1, R5_1, R5_1
|
||||||
|
VSLDB $8, R5_2, R5_2, R5_2
|
||||||
|
|
||||||
|
VLVGG $1, RSAVE_0, R_0
|
||||||
|
VLVGG $1, RSAVE_1, R_1
|
||||||
|
VLVGG $1, RSAVE_2, R_2
|
||||||
|
VLVGG $1, R5SAVE_1, R5_1
|
||||||
|
VLVGG $1, R5SAVE_2, R5_2
|
||||||
|
|
||||||
|
// setup [h0, h1]
|
||||||
|
VSLDB $8, H0_0, H0_0, H0_0
|
||||||
|
VSLDB $8, H1_0, H1_0, H1_0
|
||||||
|
VSLDB $8, H2_0, H2_0, H2_0
|
||||||
|
VO H0_1, H0_0, H0_0
|
||||||
|
VO H1_1, H1_0, H1_0
|
||||||
|
VO H2_1, H2_0, H2_0
|
||||||
|
VZERO H0_1
|
||||||
|
VZERO H1_1
|
||||||
|
VZERO H2_1
|
||||||
|
|
||||||
|
VZERO M0
|
||||||
|
VZERO M1
|
||||||
|
VZERO M2
|
||||||
|
VZERO M3
|
||||||
|
VZERO M4
|
||||||
|
VZERO M5
|
||||||
|
|
||||||
|
// H*[r**2, r]
|
||||||
|
MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, M5, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
||||||
|
REDUCE2(H0_0, H1_0, H2_0, M0, M1, M2, M3, M4, T_9, T_10, H0_1, M5)
|
||||||
|
|
||||||
|
// set up [0, m0] limbs
|
||||||
|
SUB $1, R3
|
||||||
|
VLL R3, (R2), M0
|
||||||
|
ADD $1, R3
|
||||||
|
MOVBZ $1, R0
|
||||||
|
CMPBEQ R3, $16, 2(PC)
|
||||||
|
VLVGB R3, R0, M0
|
||||||
|
VZERO T_1
|
||||||
|
VZERO T_2
|
||||||
|
VZERO T_3
|
||||||
|
EXPACC2(M0, T_1, T_2, T_3, T_4, T_5, T_6)// limbs: [0, m]
|
||||||
|
CMPBNE R3, $16, 2(PC)
|
||||||
|
VLEIB $10, $1, T_3
|
||||||
|
|
||||||
|
// h+m0
|
||||||
|
VAQ H0_0, T_1, H0_0
|
||||||
|
VAQ H1_0, T_2, H1_0
|
||||||
|
VAQ H2_0, T_3, H2_0
|
||||||
|
|
||||||
|
VZERO M0
|
||||||
|
VZERO M1
|
||||||
|
VZERO M2
|
||||||
|
VZERO M3
|
||||||
|
VZERO M4
|
||||||
|
VZERO M5
|
||||||
|
MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, M5, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
||||||
|
REDUCE2(H0_0, H1_0, H2_0, M0, M1, M2, M3, M4, T_9, T_10, H0_1, M5)
|
||||||
|
|
||||||
|
BR next
|
||||||
|
|
||||||
|
square:
|
||||||
|
// setup [r²,r]
|
||||||
|
VSLDB $8, R_0, R_0, R_0
|
||||||
|
VSLDB $8, R_1, R_1, R_1
|
||||||
|
VSLDB $8, R_2, R_2, R_2
|
||||||
|
VSLDB $8, R5_1, R5_1, R5_1
|
||||||
|
VSLDB $8, R5_2, R5_2, R5_2
|
||||||
|
|
||||||
|
VLVGG $1, RSAVE_0, R_0
|
||||||
|
VLVGG $1, RSAVE_1, R_1
|
||||||
|
VLVGG $1, RSAVE_2, R_2
|
||||||
|
VLVGG $1, R5SAVE_1, R5_1
|
||||||
|
VLVGG $1, R5SAVE_2, R5_2
|
||||||
|
|
||||||
|
// setup [h0, h1]
|
||||||
|
VSLDB $8, H0_0, H0_0, H0_0
|
||||||
|
VSLDB $8, H1_0, H1_0, H1_0
|
||||||
|
VSLDB $8, H2_0, H2_0, H2_0
|
||||||
|
VO H0_1, H0_0, H0_0
|
||||||
|
VO H1_1, H1_0, H1_0
|
||||||
|
VO H2_1, H2_0, H2_0
|
||||||
|
VZERO H0_1
|
||||||
|
VZERO H1_1
|
||||||
|
VZERO H2_1
|
||||||
|
|
||||||
|
VZERO M0
|
||||||
|
VZERO M1
|
||||||
|
VZERO M2
|
||||||
|
VZERO M3
|
||||||
|
VZERO M4
|
||||||
|
VZERO M5
|
||||||
|
|
||||||
|
// (h0*r**2) + (h1*r)
|
||||||
|
MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, M5, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
||||||
|
REDUCE2(H0_0, H1_0, H2_0, M0, M1, M2, M3, M4, T_9, T_10, H0_1, M5)
|
||||||
|
BR next
|
@ -99,24 +99,30 @@ TEXT ·salsa2020XORKeyStream(SB),0,$456-40 // frame = 424 + 32 byte alignment
|
|||||||
MOVL 36 (SP),CX
|
MOVL 36 (SP),CX
|
||||||
MOVL DX,288(SP)
|
MOVL DX,288(SP)
|
||||||
MOVL CX,304(SP)
|
MOVL CX,304(SP)
|
||||||
|
ADDQ $1,DX
|
||||||
SHLQ $32,CX
|
SHLQ $32,CX
|
||||||
ADDQ CX,DX
|
ADDQ CX,DX
|
||||||
ADDQ $1,DX
|
|
||||||
MOVQ DX,CX
|
MOVQ DX,CX
|
||||||
SHRQ $32,CX
|
SHRQ $32,CX
|
||||||
MOVL DX, 292 (SP)
|
MOVL DX, 292 (SP)
|
||||||
MOVL CX, 308 (SP)
|
MOVL CX, 308 (SP)
|
||||||
ADDQ $1,DX
|
ADDQ $1,DX
|
||||||
|
SHLQ $32,CX
|
||||||
|
ADDQ CX,DX
|
||||||
MOVQ DX,CX
|
MOVQ DX,CX
|
||||||
SHRQ $32,CX
|
SHRQ $32,CX
|
||||||
MOVL DX, 296 (SP)
|
MOVL DX, 296 (SP)
|
||||||
MOVL CX, 312 (SP)
|
MOVL CX, 312 (SP)
|
||||||
ADDQ $1,DX
|
ADDQ $1,DX
|
||||||
|
SHLQ $32,CX
|
||||||
|
ADDQ CX,DX
|
||||||
MOVQ DX,CX
|
MOVQ DX,CX
|
||||||
SHRQ $32,CX
|
SHRQ $32,CX
|
||||||
MOVL DX, 300 (SP)
|
MOVL DX, 300 (SP)
|
||||||
MOVL CX, 316 (SP)
|
MOVL CX, 316 (SP)
|
||||||
ADDQ $1,DX
|
ADDQ $1,DX
|
||||||
|
SHLQ $32,CX
|
||||||
|
ADDQ CX,DX
|
||||||
MOVQ DX,CX
|
MOVQ DX,CX
|
||||||
SHRQ $32,CX
|
SHRQ $32,CX
|
||||||
MOVL DX,16(SP)
|
MOVL DX,16(SP)
|
3
vendor/golang.org/x/crypto/salsa20/salsa/salsa20_amd64.go
generated
vendored
3
vendor/golang.org/x/crypto/salsa20/salsa/salsa20_amd64.go
generated
vendored
@ -6,9 +6,10 @@
|
|||||||
|
|
||||||
package salsa
|
package salsa
|
||||||
|
|
||||||
|
// This function is implemented in salsa2020_amd64.s.
|
||||||
|
|
||||||
//go:noescape
|
//go:noescape
|
||||||
|
|
||||||
// salsa2020XORKeyStream is implemented in salsa20_amd64.s.
|
|
||||||
func salsa2020XORKeyStream(out, in *byte, n uint64, nonce, key *byte)
|
func salsa2020XORKeyStream(out, in *byte, n uint64, nonce, key *byte)
|
||||||
|
|
||||||
// XORKeyStream crypts bytes from in to out using the given key and counters.
|
// XORKeyStream crypts bytes from in to out using the given key and counters.
|
||||||
|
14
vendor/golang.org/x/crypto/salsa20/salsa/salsa20_noasm.go
generated
vendored
14
vendor/golang.org/x/crypto/salsa20/salsa/salsa20_noasm.go
generated
vendored
@ -1,14 +0,0 @@
|
|||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build !amd64 appengine gccgo
|
|
||||||
|
|
||||||
package salsa
|
|
||||||
|
|
||||||
// XORKeyStream crypts bytes from in to out using the given key and counters.
|
|
||||||
// In and out must overlap entirely or not at all. Counter
|
|
||||||
// contains the raw salsa20 counter bytes (both nonce and block counter).
|
|
||||||
func XORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) {
|
|
||||||
genericXORKeyStream(out, in, counter, key)
|
|
||||||
}
|
|
9
vendor/golang.org/x/crypto/salsa20/salsa/salsa20_ref.go
generated
vendored
9
vendor/golang.org/x/crypto/salsa20/salsa/salsa20_ref.go
generated
vendored
@ -2,6 +2,8 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !amd64 appengine gccgo
|
||||||
|
|
||||||
package salsa
|
package salsa
|
||||||
|
|
||||||
const rounds = 20
|
const rounds = 20
|
||||||
@ -200,9 +202,10 @@ func core(out *[64]byte, in *[16]byte, k *[32]byte, c *[16]byte) {
|
|||||||
out[63] = byte(x15 >> 24)
|
out[63] = byte(x15 >> 24)
|
||||||
}
|
}
|
||||||
|
|
||||||
// genericXORKeyStream is the generic implementation of XORKeyStream to be used
|
// XORKeyStream crypts bytes from in to out using the given key and counters.
|
||||||
// when no assembly implementation is available.
|
// In and out must overlap entirely or not at all. Counter
|
||||||
func genericXORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) {
|
// contains the raw salsa20 counter bytes (both nonce and block counter).
|
||||||
|
func XORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) {
|
||||||
var block [64]byte
|
var block [64]byte
|
||||||
var counterCopy [16]byte
|
var counterCopy [16]byte
|
||||||
copy(counterCopy[:], counter[:])
|
copy(counterCopy[:], counter[:])
|
||||||
|
39
vendor/golang.org/x/crypto/ssh/certs.go
generated
vendored
39
vendor/golang.org/x/crypto/ssh/certs.go
generated
vendored
@ -17,14 +17,12 @@ import (
|
|||||||
// These constants from [PROTOCOL.certkeys] represent the algorithm names
|
// These constants from [PROTOCOL.certkeys] represent the algorithm names
|
||||||
// for certificate types supported by this package.
|
// for certificate types supported by this package.
|
||||||
const (
|
const (
|
||||||
CertAlgoRSAv01 = "ssh-rsa-cert-v01@openssh.com"
|
CertAlgoRSAv01 = "ssh-rsa-cert-v01@openssh.com"
|
||||||
CertAlgoDSAv01 = "ssh-dss-cert-v01@openssh.com"
|
CertAlgoDSAv01 = "ssh-dss-cert-v01@openssh.com"
|
||||||
CertAlgoECDSA256v01 = "ecdsa-sha2-nistp256-cert-v01@openssh.com"
|
CertAlgoECDSA256v01 = "ecdsa-sha2-nistp256-cert-v01@openssh.com"
|
||||||
CertAlgoECDSA384v01 = "ecdsa-sha2-nistp384-cert-v01@openssh.com"
|
CertAlgoECDSA384v01 = "ecdsa-sha2-nistp384-cert-v01@openssh.com"
|
||||||
CertAlgoECDSA521v01 = "ecdsa-sha2-nistp521-cert-v01@openssh.com"
|
CertAlgoECDSA521v01 = "ecdsa-sha2-nistp521-cert-v01@openssh.com"
|
||||||
CertAlgoSKECDSA256v01 = "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com"
|
CertAlgoED25519v01 = "ssh-ed25519-cert-v01@openssh.com"
|
||||||
CertAlgoED25519v01 = "ssh-ed25519-cert-v01@openssh.com"
|
|
||||||
CertAlgoSKED25519v01 = "sk-ssh-ed25519-cert-v01@openssh.com"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Certificate types distinguish between host and user
|
// Certificate types distinguish between host and user
|
||||||
@ -39,7 +37,6 @@ const (
|
|||||||
type Signature struct {
|
type Signature struct {
|
||||||
Format string
|
Format string
|
||||||
Blob []byte
|
Blob []byte
|
||||||
Rest []byte `ssh:"rest"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CertTimeInfinity can be used for OpenSSHCertV01.ValidBefore to indicate that
|
// CertTimeInfinity can be used for OpenSSHCertV01.ValidBefore to indicate that
|
||||||
@ -414,8 +411,8 @@ func (c *CertChecker) CheckCert(principal string, cert *Certificate) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SignCert signs the certificate with an authority, setting the Nonce,
|
// SignCert sets c.SignatureKey to the authority's public key and stores a
|
||||||
// SignatureKey, and Signature fields.
|
// Signature, by authority, in the certificate.
|
||||||
func (c *Certificate) SignCert(rand io.Reader, authority Signer) error {
|
func (c *Certificate) SignCert(rand io.Reader, authority Signer) error {
|
||||||
c.Nonce = make([]byte, 32)
|
c.Nonce = make([]byte, 32)
|
||||||
if _, err := io.ReadFull(rand, c.Nonce); err != nil {
|
if _, err := io.ReadFull(rand, c.Nonce); err != nil {
|
||||||
@ -432,14 +429,12 @@ func (c *Certificate) SignCert(rand io.Reader, authority Signer) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var certAlgoNames = map[string]string{
|
var certAlgoNames = map[string]string{
|
||||||
KeyAlgoRSA: CertAlgoRSAv01,
|
KeyAlgoRSA: CertAlgoRSAv01,
|
||||||
KeyAlgoDSA: CertAlgoDSAv01,
|
KeyAlgoDSA: CertAlgoDSAv01,
|
||||||
KeyAlgoECDSA256: CertAlgoECDSA256v01,
|
KeyAlgoECDSA256: CertAlgoECDSA256v01,
|
||||||
KeyAlgoECDSA384: CertAlgoECDSA384v01,
|
KeyAlgoECDSA384: CertAlgoECDSA384v01,
|
||||||
KeyAlgoECDSA521: CertAlgoECDSA521v01,
|
KeyAlgoECDSA521: CertAlgoECDSA521v01,
|
||||||
KeyAlgoSKECDSA256: CertAlgoSKECDSA256v01,
|
KeyAlgoED25519: CertAlgoED25519v01,
|
||||||
KeyAlgoED25519: CertAlgoED25519v01,
|
|
||||||
KeyAlgoSKED25519: CertAlgoSKED25519v01,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// certToPrivAlgo returns the underlying algorithm for a certificate algorithm.
|
// certToPrivAlgo returns the underlying algorithm for a certificate algorithm.
|
||||||
@ -523,12 +518,6 @@ func parseSignatureBody(in []byte) (out *Signature, rest []byte, ok bool) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
switch out.Format {
|
|
||||||
case KeyAlgoSKECDSA256, CertAlgoSKECDSA256v01, KeyAlgoSKED25519, CertAlgoSKED25519v01:
|
|
||||||
out.Rest = in
|
|
||||||
return out, nil, ok
|
|
||||||
}
|
|
||||||
|
|
||||||
return out, in, ok
|
return out, in, ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
77
vendor/golang.org/x/crypto/ssh/cipher.go
generated
vendored
77
vendor/golang.org/x/crypto/ssh/cipher.go
generated
vendored
@ -16,8 +16,9 @@ import (
|
|||||||
"hash"
|
"hash"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"math/bits"
|
||||||
|
|
||||||
"golang.org/x/crypto/chacha20"
|
"golang.org/x/crypto/internal/chacha20"
|
||||||
"golang.org/x/crypto/poly1305"
|
"golang.org/x/crypto/poly1305"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -119,7 +120,7 @@ var cipherModes = map[string]*cipherMode{
|
|||||||
chacha20Poly1305ID: {64, 0, newChaCha20Cipher},
|
chacha20Poly1305ID: {64, 0, newChaCha20Cipher},
|
||||||
|
|
||||||
// CBC mode is insecure and so is not included in the default config.
|
// CBC mode is insecure and so is not included in the default config.
|
||||||
// (See https://www.ieee-security.org/TC/SP2013/papers/4977a526.pdf). If absolutely
|
// (See http://www.isg.rhul.ac.uk/~kp/SandPfinal.pdf). If absolutely
|
||||||
// needed, it's possible to specify a custom Config to enable it.
|
// needed, it's possible to specify a custom Config to enable it.
|
||||||
// You should expect that an active attacker can recover plaintext if
|
// You should expect that an active attacker can recover plaintext if
|
||||||
// you do.
|
// you do.
|
||||||
@ -148,8 +149,8 @@ type streamPacketCipher struct {
|
|||||||
macResult []byte
|
macResult []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// readCipherPacket reads and decrypt a single packet from the reader argument.
|
// readPacket reads and decrypt a single packet from the reader argument.
|
||||||
func (s *streamPacketCipher) readCipherPacket(seqNum uint32, r io.Reader) ([]byte, error) {
|
func (s *streamPacketCipher) readPacket(seqNum uint32, r io.Reader) ([]byte, error) {
|
||||||
if _, err := io.ReadFull(r, s.prefix[:]); err != nil {
|
if _, err := io.ReadFull(r, s.prefix[:]); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -220,8 +221,8 @@ func (s *streamPacketCipher) readCipherPacket(seqNum uint32, r io.Reader) ([]byt
|
|||||||
return s.packetData[:length-paddingLength-1], nil
|
return s.packetData[:length-paddingLength-1], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// writeCipherPacket encrypts and sends a packet of data to the writer argument
|
// writePacket encrypts and sends a packet of data to the writer argument
|
||||||
func (s *streamPacketCipher) writeCipherPacket(seqNum uint32, w io.Writer, rand io.Reader, packet []byte) error {
|
func (s *streamPacketCipher) writePacket(seqNum uint32, w io.Writer, rand io.Reader, packet []byte) error {
|
||||||
if len(packet) > maxPacket {
|
if len(packet) > maxPacket {
|
||||||
return errors.New("ssh: packet too large")
|
return errors.New("ssh: packet too large")
|
||||||
}
|
}
|
||||||
@ -326,7 +327,7 @@ func newGCMCipher(key, iv, unusedMacKey []byte, unusedAlgs directionAlgorithms)
|
|||||||
|
|
||||||
const gcmTagSize = 16
|
const gcmTagSize = 16
|
||||||
|
|
||||||
func (c *gcmCipher) writeCipherPacket(seqNum uint32, w io.Writer, rand io.Reader, packet []byte) error {
|
func (c *gcmCipher) writePacket(seqNum uint32, w io.Writer, rand io.Reader, packet []byte) error {
|
||||||
// Pad out to multiple of 16 bytes. This is different from the
|
// Pad out to multiple of 16 bytes. This is different from the
|
||||||
// stream cipher because that encrypts the length too.
|
// stream cipher because that encrypts the length too.
|
||||||
padding := byte(packetSizeMultiple - (1+len(packet))%packetSizeMultiple)
|
padding := byte(packetSizeMultiple - (1+len(packet))%packetSizeMultiple)
|
||||||
@ -369,7 +370,7 @@ func (c *gcmCipher) incIV() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *gcmCipher) readCipherPacket(seqNum uint32, r io.Reader) ([]byte, error) {
|
func (c *gcmCipher) readPacket(seqNum uint32, r io.Reader) ([]byte, error) {
|
||||||
if _, err := io.ReadFull(r, c.prefix[:]); err != nil {
|
if _, err := io.ReadFull(r, c.prefix[:]); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -485,8 +486,8 @@ type cbcError string
|
|||||||
|
|
||||||
func (e cbcError) Error() string { return string(e) }
|
func (e cbcError) Error() string { return string(e) }
|
||||||
|
|
||||||
func (c *cbcCipher) readCipherPacket(seqNum uint32, r io.Reader) ([]byte, error) {
|
func (c *cbcCipher) readPacket(seqNum uint32, r io.Reader) ([]byte, error) {
|
||||||
p, err := c.readCipherPacketLeaky(seqNum, r)
|
p, err := c.readPacketLeaky(seqNum, r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if _, ok := err.(cbcError); ok {
|
if _, ok := err.(cbcError); ok {
|
||||||
// Verification error: read a fixed amount of
|
// Verification error: read a fixed amount of
|
||||||
@ -499,7 +500,7 @@ func (c *cbcCipher) readCipherPacket(seqNum uint32, r io.Reader) ([]byte, error)
|
|||||||
return p, err
|
return p, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cbcCipher) readCipherPacketLeaky(seqNum uint32, r io.Reader) ([]byte, error) {
|
func (c *cbcCipher) readPacketLeaky(seqNum uint32, r io.Reader) ([]byte, error) {
|
||||||
blockSize := c.decrypter.BlockSize()
|
blockSize := c.decrypter.BlockSize()
|
||||||
|
|
||||||
// Read the header, which will include some of the subsequent data in the
|
// Read the header, which will include some of the subsequent data in the
|
||||||
@ -575,7 +576,7 @@ func (c *cbcCipher) readCipherPacketLeaky(seqNum uint32, r io.Reader) ([]byte, e
|
|||||||
return c.packetData[prefixLen:paddingStart], nil
|
return c.packetData[prefixLen:paddingStart], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cbcCipher) writeCipherPacket(seqNum uint32, w io.Writer, rand io.Reader, packet []byte) error {
|
func (c *cbcCipher) writePacket(seqNum uint32, w io.Writer, rand io.Reader, packet []byte) error {
|
||||||
effectiveBlockSize := maxUInt32(cbcMinPacketSizeMultiple, c.encrypter.BlockSize())
|
effectiveBlockSize := maxUInt32(cbcMinPacketSizeMultiple, c.encrypter.BlockSize())
|
||||||
|
|
||||||
// Length of encrypted portion of the packet (header, payload, padding).
|
// Length of encrypted portion of the packet (header, payload, padding).
|
||||||
@ -641,8 +642,8 @@ const chacha20Poly1305ID = "chacha20-poly1305@openssh.com"
|
|||||||
// the methods here also implement padding, which RFC4253 Section 6
|
// the methods here also implement padding, which RFC4253 Section 6
|
||||||
// also requires of stream ciphers.
|
// also requires of stream ciphers.
|
||||||
type chacha20Poly1305Cipher struct {
|
type chacha20Poly1305Cipher struct {
|
||||||
lengthKey [32]byte
|
lengthKey [8]uint32
|
||||||
contentKey [32]byte
|
contentKey [8]uint32
|
||||||
buf []byte
|
buf []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -655,21 +656,21 @@ func newChaCha20Cipher(key, unusedIV, unusedMACKey []byte, unusedAlgs directionA
|
|||||||
buf: make([]byte, 256),
|
buf: make([]byte, 256),
|
||||||
}
|
}
|
||||||
|
|
||||||
copy(c.contentKey[:], key[:32])
|
for i := range c.contentKey {
|
||||||
copy(c.lengthKey[:], key[32:])
|
c.contentKey[i] = binary.LittleEndian.Uint32(key[i*4 : (i+1)*4])
|
||||||
|
}
|
||||||
|
for i := range c.lengthKey {
|
||||||
|
c.lengthKey[i] = binary.LittleEndian.Uint32(key[(i+8)*4 : (i+9)*4])
|
||||||
|
}
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *chacha20Poly1305Cipher) readCipherPacket(seqNum uint32, r io.Reader) ([]byte, error) {
|
func (c *chacha20Poly1305Cipher) readPacket(seqNum uint32, r io.Reader) ([]byte, error) {
|
||||||
nonce := make([]byte, 12)
|
nonce := [3]uint32{0, 0, bits.ReverseBytes32(seqNum)}
|
||||||
binary.BigEndian.PutUint32(nonce[8:], seqNum)
|
s := chacha20.New(c.contentKey, nonce)
|
||||||
s, err := chacha20.NewUnauthenticatedCipher(c.contentKey[:], nonce)
|
var polyKey [32]byte
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var polyKey, discardBuf [32]byte
|
|
||||||
s.XORKeyStream(polyKey[:], polyKey[:])
|
s.XORKeyStream(polyKey[:], polyKey[:])
|
||||||
s.XORKeyStream(discardBuf[:], discardBuf[:]) // skip the next 32 bytes
|
s.Advance() // skip next 32 bytes
|
||||||
|
|
||||||
encryptedLength := c.buf[:4]
|
encryptedLength := c.buf[:4]
|
||||||
if _, err := io.ReadFull(r, encryptedLength); err != nil {
|
if _, err := io.ReadFull(r, encryptedLength); err != nil {
|
||||||
@ -677,11 +678,7 @@ func (c *chacha20Poly1305Cipher) readCipherPacket(seqNum uint32, r io.Reader) ([
|
|||||||
}
|
}
|
||||||
|
|
||||||
var lenBytes [4]byte
|
var lenBytes [4]byte
|
||||||
ls, err := chacha20.NewUnauthenticatedCipher(c.lengthKey[:], nonce)
|
chacha20.New(c.lengthKey, nonce).XORKeyStream(lenBytes[:], encryptedLength)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
ls.XORKeyStream(lenBytes[:], encryptedLength)
|
|
||||||
|
|
||||||
length := binary.BigEndian.Uint32(lenBytes[:])
|
length := binary.BigEndian.Uint32(lenBytes[:])
|
||||||
if length > maxPacket {
|
if length > maxPacket {
|
||||||
@ -726,16 +723,12 @@ func (c *chacha20Poly1305Cipher) readCipherPacket(seqNum uint32, r io.Reader) ([
|
|||||||
return plain, nil
|
return plain, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *chacha20Poly1305Cipher) writeCipherPacket(seqNum uint32, w io.Writer, rand io.Reader, payload []byte) error {
|
func (c *chacha20Poly1305Cipher) writePacket(seqNum uint32, w io.Writer, rand io.Reader, payload []byte) error {
|
||||||
nonce := make([]byte, 12)
|
nonce := [3]uint32{0, 0, bits.ReverseBytes32(seqNum)}
|
||||||
binary.BigEndian.PutUint32(nonce[8:], seqNum)
|
s := chacha20.New(c.contentKey, nonce)
|
||||||
s, err := chacha20.NewUnauthenticatedCipher(c.contentKey[:], nonce)
|
var polyKey [32]byte
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
var polyKey, discardBuf [32]byte
|
|
||||||
s.XORKeyStream(polyKey[:], polyKey[:])
|
s.XORKeyStream(polyKey[:], polyKey[:])
|
||||||
s.XORKeyStream(discardBuf[:], discardBuf[:]) // skip the next 32 bytes
|
s.Advance() // skip next 32 bytes
|
||||||
|
|
||||||
// There is no blocksize, so fall back to multiple of 8 byte
|
// There is no blocksize, so fall back to multiple of 8 byte
|
||||||
// padding, as described in RFC 4253, Sec 6.
|
// padding, as described in RFC 4253, Sec 6.
|
||||||
@ -755,11 +748,7 @@ func (c *chacha20Poly1305Cipher) writeCipherPacket(seqNum uint32, w io.Writer, r
|
|||||||
}
|
}
|
||||||
|
|
||||||
binary.BigEndian.PutUint32(c.buf, uint32(1+len(payload)+padding))
|
binary.BigEndian.PutUint32(c.buf, uint32(1+len(payload)+padding))
|
||||||
ls, err := chacha20.NewUnauthenticatedCipher(c.lengthKey[:], nonce)
|
chacha20.New(c.lengthKey, nonce).XORKeyStream(c.buf, c.buf[:4])
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
ls.XORKeyStream(c.buf, c.buf[:4])
|
|
||||||
c.buf[4] = byte(padding)
|
c.buf[4] = byte(padding)
|
||||||
copy(c.buf[5:], payload)
|
copy(c.buf[5:], payload)
|
||||||
packetEnd := 5 + len(payload) + padding
|
packetEnd := 5 + len(payload) + padding
|
||||||
|
136
vendor/golang.org/x/crypto/ssh/client_auth.go
generated
vendored
136
vendor/golang.org/x/crypto/ssh/client_auth.go
generated
vendored
@ -36,7 +36,7 @@ func (c *connection) clientAuthenticate(config *ClientConfig) error {
|
|||||||
|
|
||||||
// during the authentication phase the client first attempts the "none" method
|
// during the authentication phase the client first attempts the "none" method
|
||||||
// then any untried methods suggested by the server.
|
// then any untried methods suggested by the server.
|
||||||
var tried []string
|
tried := make(map[string]bool)
|
||||||
var lastMethods []string
|
var lastMethods []string
|
||||||
|
|
||||||
sessionID := c.transport.getSessionID()
|
sessionID := c.transport.getSessionID()
|
||||||
@ -49,9 +49,7 @@ func (c *connection) clientAuthenticate(config *ClientConfig) error {
|
|||||||
// success
|
// success
|
||||||
return nil
|
return nil
|
||||||
} else if ok == authFailure {
|
} else if ok == authFailure {
|
||||||
if m := auth.method(); !contains(tried, m) {
|
tried[auth.method()] = true
|
||||||
tried = append(tried, m)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if methods == nil {
|
if methods == nil {
|
||||||
methods = lastMethods
|
methods = lastMethods
|
||||||
@ -63,7 +61,7 @@ func (c *connection) clientAuthenticate(config *ClientConfig) error {
|
|||||||
findNext:
|
findNext:
|
||||||
for _, a := range config.Auth {
|
for _, a := range config.Auth {
|
||||||
candidateMethod := a.method()
|
candidateMethod := a.method()
|
||||||
if contains(tried, candidateMethod) {
|
if tried[candidateMethod] {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for _, meth := range methods {
|
for _, meth := range methods {
|
||||||
@ -74,16 +72,16 @@ func (c *connection) clientAuthenticate(config *ClientConfig) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return fmt.Errorf("ssh: unable to authenticate, attempted methods %v, no supported methods remain", tried)
|
return fmt.Errorf("ssh: unable to authenticate, attempted methods %v, no supported methods remain", keys(tried))
|
||||||
}
|
}
|
||||||
|
|
||||||
func contains(list []string, e string) bool {
|
func keys(m map[string]bool) []string {
|
||||||
for _, s := range list {
|
s := make([]string, 0, len(m))
|
||||||
if s == e {
|
|
||||||
return true
|
for key := range m {
|
||||||
}
|
s = append(s, key)
|
||||||
}
|
}
|
||||||
return false
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// An AuthMethod represents an instance of an RFC 4252 authentication method.
|
// An AuthMethod represents an instance of an RFC 4252 authentication method.
|
||||||
@ -525,117 +523,3 @@ func (r *retryableAuthMethod) method() string {
|
|||||||
func RetryableAuthMethod(auth AuthMethod, maxTries int) AuthMethod {
|
func RetryableAuthMethod(auth AuthMethod, maxTries int) AuthMethod {
|
||||||
return &retryableAuthMethod{authMethod: auth, maxTries: maxTries}
|
return &retryableAuthMethod{authMethod: auth, maxTries: maxTries}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GSSAPIWithMICAuthMethod is an AuthMethod with "gssapi-with-mic" authentication.
|
|
||||||
// See RFC 4462 section 3
|
|
||||||
// gssAPIClient is implementation of the GSSAPIClient interface, see the definition of the interface for details.
|
|
||||||
// target is the server host you want to log in to.
|
|
||||||
func GSSAPIWithMICAuthMethod(gssAPIClient GSSAPIClient, target string) AuthMethod {
|
|
||||||
if gssAPIClient == nil {
|
|
||||||
panic("gss-api client must be not nil with enable gssapi-with-mic")
|
|
||||||
}
|
|
||||||
return &gssAPIWithMICCallback{gssAPIClient: gssAPIClient, target: target}
|
|
||||||
}
|
|
||||||
|
|
||||||
type gssAPIWithMICCallback struct {
|
|
||||||
gssAPIClient GSSAPIClient
|
|
||||||
target string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *gssAPIWithMICCallback) auth(session []byte, user string, c packetConn, rand io.Reader) (authResult, []string, error) {
|
|
||||||
m := &userAuthRequestMsg{
|
|
||||||
User: user,
|
|
||||||
Service: serviceSSH,
|
|
||||||
Method: g.method(),
|
|
||||||
}
|
|
||||||
// The GSS-API authentication method is initiated when the client sends an SSH_MSG_USERAUTH_REQUEST.
|
|
||||||
// See RFC 4462 section 3.2.
|
|
||||||
m.Payload = appendU32(m.Payload, 1)
|
|
||||||
m.Payload = appendString(m.Payload, string(krb5OID))
|
|
||||||
if err := c.writePacket(Marshal(m)); err != nil {
|
|
||||||
return authFailure, nil, err
|
|
||||||
}
|
|
||||||
// The server responds to the SSH_MSG_USERAUTH_REQUEST with either an
|
|
||||||
// SSH_MSG_USERAUTH_FAILURE if none of the mechanisms are supported or
|
|
||||||
// with an SSH_MSG_USERAUTH_GSSAPI_RESPONSE.
|
|
||||||
// See RFC 4462 section 3.3.
|
|
||||||
// OpenSSH supports Kerberos V5 mechanism only for GSS-API authentication,so I don't want to check
|
|
||||||
// selected mech if it is valid.
|
|
||||||
packet, err := c.readPacket()
|
|
||||||
if err != nil {
|
|
||||||
return authFailure, nil, err
|
|
||||||
}
|
|
||||||
userAuthGSSAPIResp := &userAuthGSSAPIResponse{}
|
|
||||||
if err := Unmarshal(packet, userAuthGSSAPIResp); err != nil {
|
|
||||||
return authFailure, nil, err
|
|
||||||
}
|
|
||||||
// Start the loop into the exchange token.
|
|
||||||
// See RFC 4462 section 3.4.
|
|
||||||
var token []byte
|
|
||||||
defer g.gssAPIClient.DeleteSecContext()
|
|
||||||
for {
|
|
||||||
// Initiates the establishment of a security context between the application and a remote peer.
|
|
||||||
nextToken, needContinue, err := g.gssAPIClient.InitSecContext("host@"+g.target, token, false)
|
|
||||||
if err != nil {
|
|
||||||
return authFailure, nil, err
|
|
||||||
}
|
|
||||||
if len(nextToken) > 0 {
|
|
||||||
if err := c.writePacket(Marshal(&userAuthGSSAPIToken{
|
|
||||||
Token: nextToken,
|
|
||||||
})); err != nil {
|
|
||||||
return authFailure, nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !needContinue {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
packet, err = c.readPacket()
|
|
||||||
if err != nil {
|
|
||||||
return authFailure, nil, err
|
|
||||||
}
|
|
||||||
switch packet[0] {
|
|
||||||
case msgUserAuthFailure:
|
|
||||||
var msg userAuthFailureMsg
|
|
||||||
if err := Unmarshal(packet, &msg); err != nil {
|
|
||||||
return authFailure, nil, err
|
|
||||||
}
|
|
||||||
if msg.PartialSuccess {
|
|
||||||
return authPartialSuccess, msg.Methods, nil
|
|
||||||
}
|
|
||||||
return authFailure, msg.Methods, nil
|
|
||||||
case msgUserAuthGSSAPIError:
|
|
||||||
userAuthGSSAPIErrorResp := &userAuthGSSAPIError{}
|
|
||||||
if err := Unmarshal(packet, userAuthGSSAPIErrorResp); err != nil {
|
|
||||||
return authFailure, nil, err
|
|
||||||
}
|
|
||||||
return authFailure, nil, fmt.Errorf("GSS-API Error:\n"+
|
|
||||||
"Major Status: %d\n"+
|
|
||||||
"Minor Status: %d\n"+
|
|
||||||
"Error Message: %s\n", userAuthGSSAPIErrorResp.MajorStatus, userAuthGSSAPIErrorResp.MinorStatus,
|
|
||||||
userAuthGSSAPIErrorResp.Message)
|
|
||||||
case msgUserAuthGSSAPIToken:
|
|
||||||
userAuthGSSAPITokenReq := &userAuthGSSAPIToken{}
|
|
||||||
if err := Unmarshal(packet, userAuthGSSAPITokenReq); err != nil {
|
|
||||||
return authFailure, nil, err
|
|
||||||
}
|
|
||||||
token = userAuthGSSAPITokenReq.Token
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Binding Encryption Keys.
|
|
||||||
// See RFC 4462 section 3.5.
|
|
||||||
micField := buildMIC(string(session), user, "ssh-connection", "gssapi-with-mic")
|
|
||||||
micToken, err := g.gssAPIClient.GetMIC(micField)
|
|
||||||
if err != nil {
|
|
||||||
return authFailure, nil, err
|
|
||||||
}
|
|
||||||
if err := c.writePacket(Marshal(&userAuthGSSAPIMIC{
|
|
||||||
MIC: micToken,
|
|
||||||
})); err != nil {
|
|
||||||
return authFailure, nil, err
|
|
||||||
}
|
|
||||||
return handleAuthResponse(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *gssAPIWithMICCallback) method() string {
|
|
||||||
return "gssapi-with-mic"
|
|
||||||
}
|
|
||||||
|
37
vendor/golang.org/x/crypto/ssh/common.go
generated
vendored
37
vendor/golang.org/x/crypto/ssh/common.go
generated
vendored
@ -51,21 +51,6 @@ var supportedKexAlgos = []string{
|
|||||||
kexAlgoDH14SHA1, kexAlgoDH1SHA1,
|
kexAlgoDH14SHA1, kexAlgoDH1SHA1,
|
||||||
}
|
}
|
||||||
|
|
||||||
// serverForbiddenKexAlgos contains key exchange algorithms, that are forbidden
|
|
||||||
// for the server half.
|
|
||||||
var serverForbiddenKexAlgos = map[string]struct{}{
|
|
||||||
kexAlgoDHGEXSHA1: {}, // server half implementation is only minimal to satisfy the automated tests
|
|
||||||
kexAlgoDHGEXSHA256: {}, // server half implementation is only minimal to satisfy the automated tests
|
|
||||||
}
|
|
||||||
|
|
||||||
// preferredKexAlgos specifies the default preference for key-exchange algorithms
|
|
||||||
// in preference order.
|
|
||||||
var preferredKexAlgos = []string{
|
|
||||||
kexAlgoCurve25519SHA256,
|
|
||||||
kexAlgoECDH256, kexAlgoECDH384, kexAlgoECDH521,
|
|
||||||
kexAlgoDH14SHA1,
|
|
||||||
}
|
|
||||||
|
|
||||||
// supportedHostKeyAlgos specifies the supported host-key algorithms (i.e. methods
|
// supportedHostKeyAlgos specifies the supported host-key algorithms (i.e. methods
|
||||||
// of authenticating servers) in preference order.
|
// of authenticating servers) in preference order.
|
||||||
var supportedHostKeyAlgos = []string{
|
var supportedHostKeyAlgos = []string{
|
||||||
@ -124,7 +109,6 @@ func findCommon(what string, client []string, server []string) (common string, e
|
|||||||
return "", fmt.Errorf("ssh: no common algorithm for %s; client offered: %v, server offered: %v", what, client, server)
|
return "", fmt.Errorf("ssh: no common algorithm for %s; client offered: %v, server offered: %v", what, client, server)
|
||||||
}
|
}
|
||||||
|
|
||||||
// directionAlgorithms records algorithm choices in one direction (either read or write)
|
|
||||||
type directionAlgorithms struct {
|
type directionAlgorithms struct {
|
||||||
Cipher string
|
Cipher string
|
||||||
MAC string
|
MAC string
|
||||||
@ -153,7 +137,7 @@ type algorithms struct {
|
|||||||
r directionAlgorithms
|
r directionAlgorithms
|
||||||
}
|
}
|
||||||
|
|
||||||
func findAgreedAlgorithms(isClient bool, clientKexInit, serverKexInit *kexInitMsg) (algs *algorithms, err error) {
|
func findAgreedAlgorithms(clientKexInit, serverKexInit *kexInitMsg) (algs *algorithms, err error) {
|
||||||
result := &algorithms{}
|
result := &algorithms{}
|
||||||
|
|
||||||
result.kex, err = findCommon("key exchange", clientKexInit.KexAlgos, serverKexInit.KexAlgos)
|
result.kex, err = findCommon("key exchange", clientKexInit.KexAlgos, serverKexInit.KexAlgos)
|
||||||
@ -166,37 +150,32 @@ func findAgreedAlgorithms(isClient bool, clientKexInit, serverKexInit *kexInitMs
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
stoc, ctos := &result.w, &result.r
|
result.w.Cipher, err = findCommon("client to server cipher", clientKexInit.CiphersClientServer, serverKexInit.CiphersClientServer)
|
||||||
if isClient {
|
|
||||||
ctos, stoc = stoc, ctos
|
|
||||||
}
|
|
||||||
|
|
||||||
ctos.Cipher, err = findCommon("client to server cipher", clientKexInit.CiphersClientServer, serverKexInit.CiphersClientServer)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
stoc.Cipher, err = findCommon("server to client cipher", clientKexInit.CiphersServerClient, serverKexInit.CiphersServerClient)
|
result.r.Cipher, err = findCommon("server to client cipher", clientKexInit.CiphersServerClient, serverKexInit.CiphersServerClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctos.MAC, err = findCommon("client to server MAC", clientKexInit.MACsClientServer, serverKexInit.MACsClientServer)
|
result.w.MAC, err = findCommon("client to server MAC", clientKexInit.MACsClientServer, serverKexInit.MACsClientServer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
stoc.MAC, err = findCommon("server to client MAC", clientKexInit.MACsServerClient, serverKexInit.MACsServerClient)
|
result.r.MAC, err = findCommon("server to client MAC", clientKexInit.MACsServerClient, serverKexInit.MACsServerClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctos.Compression, err = findCommon("client to server compression", clientKexInit.CompressionClientServer, serverKexInit.CompressionClientServer)
|
result.w.Compression, err = findCommon("client to server compression", clientKexInit.CompressionClientServer, serverKexInit.CompressionClientServer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
stoc.Compression, err = findCommon("server to client compression", clientKexInit.CompressionServerClient, serverKexInit.CompressionServerClient)
|
result.r.Compression, err = findCommon("server to client compression", clientKexInit.CompressionServerClient, serverKexInit.CompressionServerClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -254,7 +233,7 @@ func (c *Config) SetDefaults() {
|
|||||||
c.Ciphers = ciphers
|
c.Ciphers = ciphers
|
||||||
|
|
||||||
if c.KeyExchanges == nil {
|
if c.KeyExchanges == nil {
|
||||||
c.KeyExchanges = preferredKexAlgos
|
c.KeyExchanges = supportedKexAlgos
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.MACs == nil {
|
if c.MACs == nil {
|
||||||
|
5
vendor/golang.org/x/crypto/ssh/handshake.go
generated
vendored
5
vendor/golang.org/x/crypto/ssh/handshake.go
generated
vendored
@ -543,8 +543,7 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error {
|
|||||||
|
|
||||||
clientInit := otherInit
|
clientInit := otherInit
|
||||||
serverInit := t.sentInitMsg
|
serverInit := t.sentInitMsg
|
||||||
isClient := len(t.hostKeys) == 0
|
if len(t.hostKeys) == 0 {
|
||||||
if isClient {
|
|
||||||
clientInit, serverInit = serverInit, clientInit
|
clientInit, serverInit = serverInit, clientInit
|
||||||
|
|
||||||
magics.clientKexInit = t.sentInitPacket
|
magics.clientKexInit = t.sentInitPacket
|
||||||
@ -552,7 +551,7 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
t.algorithms, err = findAgreedAlgorithms(isClient, clientInit, serverInit)
|
t.algorithms, err = findAgreedAlgorithms(clientInit, serverInit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
93
vendor/golang.org/x/crypto/ssh/internal/bcrypt_pbkdf/bcrypt_pbkdf.go
generated
vendored
93
vendor/golang.org/x/crypto/ssh/internal/bcrypt_pbkdf/bcrypt_pbkdf.go
generated
vendored
@ -1,93 +0,0 @@
|
|||||||
// Copyright 2014 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// Package bcrypt_pbkdf implements bcrypt_pbkdf(3) from OpenBSD.
|
|
||||||
//
|
|
||||||
// See https://flak.tedunangst.com/post/bcrypt-pbkdf and
|
|
||||||
// https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libutil/bcrypt_pbkdf.c.
|
|
||||||
package bcrypt_pbkdf
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/sha512"
|
|
||||||
"errors"
|
|
||||||
"golang.org/x/crypto/blowfish"
|
|
||||||
)
|
|
||||||
|
|
||||||
const blockSize = 32
|
|
||||||
|
|
||||||
// Key derives a key from the password, salt and rounds count, returning a
|
|
||||||
// []byte of length keyLen that can be used as cryptographic key.
|
|
||||||
func Key(password, salt []byte, rounds, keyLen int) ([]byte, error) {
|
|
||||||
if rounds < 1 {
|
|
||||||
return nil, errors.New("bcrypt_pbkdf: number of rounds is too small")
|
|
||||||
}
|
|
||||||
if len(password) == 0 {
|
|
||||||
return nil, errors.New("bcrypt_pbkdf: empty password")
|
|
||||||
}
|
|
||||||
if len(salt) == 0 || len(salt) > 1<<20 {
|
|
||||||
return nil, errors.New("bcrypt_pbkdf: bad salt length")
|
|
||||||
}
|
|
||||||
if keyLen > 1024 {
|
|
||||||
return nil, errors.New("bcrypt_pbkdf: keyLen is too large")
|
|
||||||
}
|
|
||||||
|
|
||||||
numBlocks := (keyLen + blockSize - 1) / blockSize
|
|
||||||
key := make([]byte, numBlocks*blockSize)
|
|
||||||
|
|
||||||
h := sha512.New()
|
|
||||||
h.Write(password)
|
|
||||||
shapass := h.Sum(nil)
|
|
||||||
|
|
||||||
shasalt := make([]byte, 0, sha512.Size)
|
|
||||||
cnt, tmp := make([]byte, 4), make([]byte, blockSize)
|
|
||||||
for block := 1; block <= numBlocks; block++ {
|
|
||||||
h.Reset()
|
|
||||||
h.Write(salt)
|
|
||||||
cnt[0] = byte(block >> 24)
|
|
||||||
cnt[1] = byte(block >> 16)
|
|
||||||
cnt[2] = byte(block >> 8)
|
|
||||||
cnt[3] = byte(block)
|
|
||||||
h.Write(cnt)
|
|
||||||
bcryptHash(tmp, shapass, h.Sum(shasalt))
|
|
||||||
|
|
||||||
out := make([]byte, blockSize)
|
|
||||||
copy(out, tmp)
|
|
||||||
for i := 2; i <= rounds; i++ {
|
|
||||||
h.Reset()
|
|
||||||
h.Write(tmp)
|
|
||||||
bcryptHash(tmp, shapass, h.Sum(shasalt))
|
|
||||||
for j := 0; j < len(out); j++ {
|
|
||||||
out[j] ^= tmp[j]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, v := range out {
|
|
||||||
key[i*numBlocks+(block-1)] = v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return key[:keyLen], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var magic = []byte("OxychromaticBlowfishSwatDynamite")
|
|
||||||
|
|
||||||
func bcryptHash(out, shapass, shasalt []byte) {
|
|
||||||
c, err := blowfish.NewSaltedCipher(shapass, shasalt)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
for i := 0; i < 64; i++ {
|
|
||||||
blowfish.ExpandKey(shasalt, c)
|
|
||||||
blowfish.ExpandKey(shapass, c)
|
|
||||||
}
|
|
||||||
copy(out, magic)
|
|
||||||
for i := 0; i < 32; i += 8 {
|
|
||||||
for j := 0; j < 64; j++ {
|
|
||||||
c.Encrypt(out[i:i+8], out[i:i+8])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Swap bytes due to different endianness.
|
|
||||||
for i := 0; i < 32; i += 4 {
|
|
||||||
out[i+3], out[i+2], out[i+1], out[i] = out[i], out[i+1], out[i+2], out[i+3]
|
|
||||||
}
|
|
||||||
}
|
|
251
vendor/golang.org/x/crypto/ssh/kex.go
generated
vendored
251
vendor/golang.org/x/crypto/ssh/kex.go
generated
vendored
@ -10,9 +10,7 @@ import (
|
|||||||
"crypto/elliptic"
|
"crypto/elliptic"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/subtle"
|
"crypto/subtle"
|
||||||
"encoding/binary"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
@ -26,12 +24,6 @@ const (
|
|||||||
kexAlgoECDH384 = "ecdh-sha2-nistp384"
|
kexAlgoECDH384 = "ecdh-sha2-nistp384"
|
||||||
kexAlgoECDH521 = "ecdh-sha2-nistp521"
|
kexAlgoECDH521 = "ecdh-sha2-nistp521"
|
||||||
kexAlgoCurve25519SHA256 = "curve25519-sha256@libssh.org"
|
kexAlgoCurve25519SHA256 = "curve25519-sha256@libssh.org"
|
||||||
|
|
||||||
// For the following kex only the client half contains a production
|
|
||||||
// ready implementation. The server half only consists of a minimal
|
|
||||||
// implementation to satisfy the automated tests.
|
|
||||||
kexAlgoDHGEXSHA1 = "diffie-hellman-group-exchange-sha1"
|
|
||||||
kexAlgoDHGEXSHA256 = "diffie-hellman-group-exchange-sha256"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// kexResult captures the outcome of a key exchange.
|
// kexResult captures the outcome of a key exchange.
|
||||||
@ -212,7 +204,7 @@ func (group *dhGroup) Server(c packetConn, randSource io.Reader, magics *handsha
|
|||||||
HostKey: hostKeyBytes,
|
HostKey: hostKeyBytes,
|
||||||
Signature: sig,
|
Signature: sig,
|
||||||
Hash: crypto.SHA1,
|
Hash: crypto.SHA1,
|
||||||
}, err
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ecdh performs Elliptic Curve Diffie-Hellman key exchange as
|
// ecdh performs Elliptic Curve Diffie-Hellman key exchange as
|
||||||
@ -410,8 +402,6 @@ func init() {
|
|||||||
kexAlgoMap[kexAlgoECDH384] = &ecdh{elliptic.P384()}
|
kexAlgoMap[kexAlgoECDH384] = &ecdh{elliptic.P384()}
|
||||||
kexAlgoMap[kexAlgoECDH256] = &ecdh{elliptic.P256()}
|
kexAlgoMap[kexAlgoECDH256] = &ecdh{elliptic.P256()}
|
||||||
kexAlgoMap[kexAlgoCurve25519SHA256] = &curve25519sha256{}
|
kexAlgoMap[kexAlgoCurve25519SHA256] = &curve25519sha256{}
|
||||||
kexAlgoMap[kexAlgoDHGEXSHA1] = &dhGEXSHA{hashFunc: crypto.SHA1}
|
|
||||||
kexAlgoMap[kexAlgoDHGEXSHA256] = &dhGEXSHA{hashFunc: crypto.SHA256}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// curve25519sha256 implements the curve25519-sha256@libssh.org key
|
// curve25519sha256 implements the curve25519-sha256@libssh.org key
|
||||||
@ -548,242 +538,3 @@ func (kex *curve25519sha256) Server(c packetConn, rand io.Reader, magics *handsh
|
|||||||
Hash: crypto.SHA256,
|
Hash: crypto.SHA256,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// dhGEXSHA implements the diffie-hellman-group-exchange-sha1 and
|
|
||||||
// diffie-hellman-group-exchange-sha256 key agreement protocols,
|
|
||||||
// as described in RFC 4419
|
|
||||||
type dhGEXSHA struct {
|
|
||||||
g, p *big.Int
|
|
||||||
hashFunc crypto.Hash
|
|
||||||
}
|
|
||||||
|
|
||||||
const numMRTests = 64
|
|
||||||
|
|
||||||
const (
|
|
||||||
dhGroupExchangeMinimumBits = 2048
|
|
||||||
dhGroupExchangePreferredBits = 2048
|
|
||||||
dhGroupExchangeMaximumBits = 8192
|
|
||||||
)
|
|
||||||
|
|
||||||
func (gex *dhGEXSHA) diffieHellman(theirPublic, myPrivate *big.Int) (*big.Int, error) {
|
|
||||||
if theirPublic.Sign() <= 0 || theirPublic.Cmp(gex.p) >= 0 {
|
|
||||||
return nil, fmt.Errorf("ssh: DH parameter out of bounds")
|
|
||||||
}
|
|
||||||
return new(big.Int).Exp(theirPublic, myPrivate, gex.p), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (gex dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshakeMagics) (*kexResult, error) {
|
|
||||||
// Send GexRequest
|
|
||||||
kexDHGexRequest := kexDHGexRequestMsg{
|
|
||||||
MinBits: dhGroupExchangeMinimumBits,
|
|
||||||
PreferedBits: dhGroupExchangePreferredBits,
|
|
||||||
MaxBits: dhGroupExchangeMaximumBits,
|
|
||||||
}
|
|
||||||
if err := c.writePacket(Marshal(&kexDHGexRequest)); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Receive GexGroup
|
|
||||||
packet, err := c.readPacket()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var kexDHGexGroup kexDHGexGroupMsg
|
|
||||||
if err = Unmarshal(packet, &kexDHGexGroup); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// reject if p's bit length < dhGroupExchangeMinimumBits or > dhGroupExchangeMaximumBits
|
|
||||||
if kexDHGexGroup.P.BitLen() < dhGroupExchangeMinimumBits || kexDHGexGroup.P.BitLen() > dhGroupExchangeMaximumBits {
|
|
||||||
return nil, fmt.Errorf("ssh: server-generated gex p is out of range (%d bits)", kexDHGexGroup.P.BitLen())
|
|
||||||
}
|
|
||||||
|
|
||||||
gex.p = kexDHGexGroup.P
|
|
||||||
gex.g = kexDHGexGroup.G
|
|
||||||
|
|
||||||
// Check if p is safe by verifing that p and (p-1)/2 are primes
|
|
||||||
one := big.NewInt(1)
|
|
||||||
var pHalf = &big.Int{}
|
|
||||||
pHalf.Rsh(gex.p, 1)
|
|
||||||
if !gex.p.ProbablyPrime(numMRTests) || !pHalf.ProbablyPrime(numMRTests) {
|
|
||||||
return nil, fmt.Errorf("ssh: server provided gex p is not safe")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if g is safe by verifing that g > 1 and g < p - 1
|
|
||||||
var pMinusOne = &big.Int{}
|
|
||||||
pMinusOne.Sub(gex.p, one)
|
|
||||||
if gex.g.Cmp(one) != 1 && gex.g.Cmp(pMinusOne) != -1 {
|
|
||||||
return nil, fmt.Errorf("ssh: server provided gex g is not safe")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send GexInit
|
|
||||||
x, err := rand.Int(randSource, pHalf)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
X := new(big.Int).Exp(gex.g, x, gex.p)
|
|
||||||
kexDHGexInit := kexDHGexInitMsg{
|
|
||||||
X: X,
|
|
||||||
}
|
|
||||||
if err := c.writePacket(Marshal(&kexDHGexInit)); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Receive GexReply
|
|
||||||
packet, err = c.readPacket()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var kexDHGexReply kexDHGexReplyMsg
|
|
||||||
if err = Unmarshal(packet, &kexDHGexReply); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
kInt, err := gex.diffieHellman(kexDHGexReply.Y, x)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if k is safe by verifing that k > 1 and k < p - 1
|
|
||||||
if kInt.Cmp(one) != 1 && kInt.Cmp(pMinusOne) != -1 {
|
|
||||||
return nil, fmt.Errorf("ssh: derived k is not safe")
|
|
||||||
}
|
|
||||||
|
|
||||||
h := gex.hashFunc.New()
|
|
||||||
magics.write(h)
|
|
||||||
writeString(h, kexDHGexReply.HostKey)
|
|
||||||
binary.Write(h, binary.BigEndian, uint32(dhGroupExchangeMinimumBits))
|
|
||||||
binary.Write(h, binary.BigEndian, uint32(dhGroupExchangePreferredBits))
|
|
||||||
binary.Write(h, binary.BigEndian, uint32(dhGroupExchangeMaximumBits))
|
|
||||||
writeInt(h, gex.p)
|
|
||||||
writeInt(h, gex.g)
|
|
||||||
writeInt(h, X)
|
|
||||||
writeInt(h, kexDHGexReply.Y)
|
|
||||||
K := make([]byte, intLength(kInt))
|
|
||||||
marshalInt(K, kInt)
|
|
||||||
h.Write(K)
|
|
||||||
|
|
||||||
return &kexResult{
|
|
||||||
H: h.Sum(nil),
|
|
||||||
K: K,
|
|
||||||
HostKey: kexDHGexReply.HostKey,
|
|
||||||
Signature: kexDHGexReply.Signature,
|
|
||||||
Hash: gex.hashFunc,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Server half implementation of the Diffie Hellman Key Exchange with SHA1 and SHA256.
|
|
||||||
//
|
|
||||||
// This is a minimal implementation to satisfy the automated tests.
|
|
||||||
func (gex dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshakeMagics, priv Signer) (result *kexResult, err error) {
|
|
||||||
// Receive GexRequest
|
|
||||||
packet, err := c.readPacket()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var kexDHGexRequest kexDHGexRequestMsg
|
|
||||||
if err = Unmarshal(packet, &kexDHGexRequest); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// smoosh the user's preferred size into our own limits
|
|
||||||
if kexDHGexRequest.PreferedBits > dhGroupExchangeMaximumBits {
|
|
||||||
kexDHGexRequest.PreferedBits = dhGroupExchangeMaximumBits
|
|
||||||
}
|
|
||||||
if kexDHGexRequest.PreferedBits < dhGroupExchangeMinimumBits {
|
|
||||||
kexDHGexRequest.PreferedBits = dhGroupExchangeMinimumBits
|
|
||||||
}
|
|
||||||
// fix min/max if they're inconsistent. technically, we could just pout
|
|
||||||
// and hang up, but there's no harm in giving them the benefit of the
|
|
||||||
// doubt and just picking a bitsize for them.
|
|
||||||
if kexDHGexRequest.MinBits > kexDHGexRequest.PreferedBits {
|
|
||||||
kexDHGexRequest.MinBits = kexDHGexRequest.PreferedBits
|
|
||||||
}
|
|
||||||
if kexDHGexRequest.MaxBits < kexDHGexRequest.PreferedBits {
|
|
||||||
kexDHGexRequest.MaxBits = kexDHGexRequest.PreferedBits
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send GexGroup
|
|
||||||
// This is the group called diffie-hellman-group14-sha1 in RFC
|
|
||||||
// 4253 and Oakley Group 14 in RFC 3526.
|
|
||||||
p, _ := new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF", 16)
|
|
||||||
gex.p = p
|
|
||||||
gex.g = big.NewInt(2)
|
|
||||||
|
|
||||||
kexDHGexGroup := kexDHGexGroupMsg{
|
|
||||||
P: gex.p,
|
|
||||||
G: gex.g,
|
|
||||||
}
|
|
||||||
if err := c.writePacket(Marshal(&kexDHGexGroup)); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Receive GexInit
|
|
||||||
packet, err = c.readPacket()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var kexDHGexInit kexDHGexInitMsg
|
|
||||||
if err = Unmarshal(packet, &kexDHGexInit); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var pHalf = &big.Int{}
|
|
||||||
pHalf.Rsh(gex.p, 1)
|
|
||||||
|
|
||||||
y, err := rand.Int(randSource, pHalf)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
Y := new(big.Int).Exp(gex.g, y, gex.p)
|
|
||||||
kInt, err := gex.diffieHellman(kexDHGexInit.X, y)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
hostKeyBytes := priv.PublicKey().Marshal()
|
|
||||||
|
|
||||||
h := gex.hashFunc.New()
|
|
||||||
magics.write(h)
|
|
||||||
writeString(h, hostKeyBytes)
|
|
||||||
binary.Write(h, binary.BigEndian, uint32(dhGroupExchangeMinimumBits))
|
|
||||||
binary.Write(h, binary.BigEndian, uint32(dhGroupExchangePreferredBits))
|
|
||||||
binary.Write(h, binary.BigEndian, uint32(dhGroupExchangeMaximumBits))
|
|
||||||
writeInt(h, gex.p)
|
|
||||||
writeInt(h, gex.g)
|
|
||||||
writeInt(h, kexDHGexInit.X)
|
|
||||||
writeInt(h, Y)
|
|
||||||
|
|
||||||
K := make([]byte, intLength(kInt))
|
|
||||||
marshalInt(K, kInt)
|
|
||||||
h.Write(K)
|
|
||||||
|
|
||||||
H := h.Sum(nil)
|
|
||||||
|
|
||||||
// H is already a hash, but the hostkey signing will apply its
|
|
||||||
// own key-specific hash algorithm.
|
|
||||||
sig, err := signAndMarshal(priv, randSource, H)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
kexDHGexReply := kexDHGexReplyMsg{
|
|
||||||
HostKey: hostKeyBytes,
|
|
||||||
Y: Y,
|
|
||||||
Signature: sig,
|
|
||||||
}
|
|
||||||
packet = Marshal(&kexDHGexReply)
|
|
||||||
|
|
||||||
err = c.writePacket(packet)
|
|
||||||
|
|
||||||
return &kexResult{
|
|
||||||
H: H,
|
|
||||||
K: K,
|
|
||||||
HostKey: hostKeyBytes,
|
|
||||||
Signature: sig,
|
|
||||||
Hash: gex.hashFunc,
|
|
||||||
}, err
|
|
||||||
}
|
|
||||||
|
482
vendor/golang.org/x/crypto/ssh/keys.go
generated
vendored
482
vendor/golang.org/x/crypto/ssh/keys.go
generated
vendored
@ -7,8 +7,6 @@ package ssh
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto"
|
"crypto"
|
||||||
"crypto/aes"
|
|
||||||
"crypto/cipher"
|
|
||||||
"crypto/dsa"
|
"crypto/dsa"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"crypto/elliptic"
|
"crypto/elliptic"
|
||||||
@ -27,20 +25,17 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"golang.org/x/crypto/ed25519"
|
"golang.org/x/crypto/ed25519"
|
||||||
"golang.org/x/crypto/ssh/internal/bcrypt_pbkdf"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// These constants represent the algorithm names for key types supported by this
|
// These constants represent the algorithm names for key types supported by this
|
||||||
// package.
|
// package.
|
||||||
const (
|
const (
|
||||||
KeyAlgoRSA = "ssh-rsa"
|
KeyAlgoRSA = "ssh-rsa"
|
||||||
KeyAlgoDSA = "ssh-dss"
|
KeyAlgoDSA = "ssh-dss"
|
||||||
KeyAlgoECDSA256 = "ecdsa-sha2-nistp256"
|
KeyAlgoECDSA256 = "ecdsa-sha2-nistp256"
|
||||||
KeyAlgoSKECDSA256 = "sk-ecdsa-sha2-nistp256@openssh.com"
|
KeyAlgoECDSA384 = "ecdsa-sha2-nistp384"
|
||||||
KeyAlgoECDSA384 = "ecdsa-sha2-nistp384"
|
KeyAlgoECDSA521 = "ecdsa-sha2-nistp521"
|
||||||
KeyAlgoECDSA521 = "ecdsa-sha2-nistp521"
|
KeyAlgoED25519 = "ssh-ed25519"
|
||||||
KeyAlgoED25519 = "ssh-ed25519"
|
|
||||||
KeyAlgoSKED25519 = "sk-ssh-ed25519@openssh.com"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// These constants represent non-default signature algorithms that are supported
|
// These constants represent non-default signature algorithms that are supported
|
||||||
@ -63,13 +58,9 @@ func parsePubKey(in []byte, algo string) (pubKey PublicKey, rest []byte, err err
|
|||||||
return parseDSA(in)
|
return parseDSA(in)
|
||||||
case KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521:
|
case KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521:
|
||||||
return parseECDSA(in)
|
return parseECDSA(in)
|
||||||
case KeyAlgoSKECDSA256:
|
|
||||||
return parseSKECDSA(in)
|
|
||||||
case KeyAlgoED25519:
|
case KeyAlgoED25519:
|
||||||
return parseED25519(in)
|
return parseED25519(in)
|
||||||
case KeyAlgoSKED25519:
|
case CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoED25519v01:
|
||||||
return parseSKEd25519(in)
|
|
||||||
case CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoSKECDSA256v01, CertAlgoED25519v01, CertAlgoSKED25519v01:
|
|
||||||
cert, err := parseCert(in, certToPrivAlgo(algo))
|
cert, err := parseCert(in, certToPrivAlgo(algo))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
@ -562,11 +553,9 @@ func parseED25519(in []byte) (out PublicKey, rest []byte, err error) {
|
|||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if l := len(w.KeyBytes); l != ed25519.PublicKeySize {
|
key := ed25519.PublicKey(w.KeyBytes)
|
||||||
return nil, nil, fmt.Errorf("invalid size %d for Ed25519 public key", l)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ed25519PublicKey(w.KeyBytes), w.Rest, nil
|
return (ed25519PublicKey)(key), w.Rest, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k ed25519PublicKey) Marshal() []byte {
|
func (k ed25519PublicKey) Marshal() []byte {
|
||||||
@ -584,11 +573,9 @@ func (k ed25519PublicKey) Verify(b []byte, sig *Signature) error {
|
|||||||
if sig.Format != k.Type() {
|
if sig.Format != k.Type() {
|
||||||
return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
|
return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
|
||||||
}
|
}
|
||||||
if l := len(k); l != ed25519.PublicKeySize {
|
|
||||||
return fmt.Errorf("ssh: invalid size %d for Ed25519 public key", l)
|
|
||||||
}
|
|
||||||
|
|
||||||
if ok := ed25519.Verify(ed25519.PublicKey(k), b, sig.Blob); !ok {
|
edKey := (ed25519.PublicKey)(k)
|
||||||
|
if ok := ed25519.Verify(edKey, b, sig.Blob); !ok {
|
||||||
return errors.New("ssh: signature did not verify")
|
return errors.New("ssh: signature did not verify")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -698,224 +685,6 @@ func (k *ecdsaPublicKey) CryptoPublicKey() crypto.PublicKey {
|
|||||||
return (*ecdsa.PublicKey)(k)
|
return (*ecdsa.PublicKey)(k)
|
||||||
}
|
}
|
||||||
|
|
||||||
// skFields holds the additional fields present in U2F/FIDO2 signatures.
|
|
||||||
// See openssh/PROTOCOL.u2f 'SSH U2F Signatures' for details.
|
|
||||||
type skFields struct {
|
|
||||||
// Flags contains U2F/FIDO2 flags such as 'user present'
|
|
||||||
Flags byte
|
|
||||||
// Counter is a monotonic signature counter which can be
|
|
||||||
// used to detect concurrent use of a private key, should
|
|
||||||
// it be extracted from hardware.
|
|
||||||
Counter uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type skECDSAPublicKey struct {
|
|
||||||
// application is a URL-like string, typically "ssh:" for SSH.
|
|
||||||
// see openssh/PROTOCOL.u2f for details.
|
|
||||||
application string
|
|
||||||
ecdsa.PublicKey
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *skECDSAPublicKey) Type() string {
|
|
||||||
return KeyAlgoSKECDSA256
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *skECDSAPublicKey) nistID() string {
|
|
||||||
return "nistp256"
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseSKECDSA(in []byte) (out PublicKey, rest []byte, err error) {
|
|
||||||
var w struct {
|
|
||||||
Curve string
|
|
||||||
KeyBytes []byte
|
|
||||||
Application string
|
|
||||||
Rest []byte `ssh:"rest"`
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := Unmarshal(in, &w); err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
key := new(skECDSAPublicKey)
|
|
||||||
key.application = w.Application
|
|
||||||
|
|
||||||
if w.Curve != "nistp256" {
|
|
||||||
return nil, nil, errors.New("ssh: unsupported curve")
|
|
||||||
}
|
|
||||||
key.Curve = elliptic.P256()
|
|
||||||
|
|
||||||
key.X, key.Y = elliptic.Unmarshal(key.Curve, w.KeyBytes)
|
|
||||||
if key.X == nil || key.Y == nil {
|
|
||||||
return nil, nil, errors.New("ssh: invalid curve point")
|
|
||||||
}
|
|
||||||
|
|
||||||
return key, w.Rest, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *skECDSAPublicKey) Marshal() []byte {
|
|
||||||
// See RFC 5656, section 3.1.
|
|
||||||
keyBytes := elliptic.Marshal(k.Curve, k.X, k.Y)
|
|
||||||
w := struct {
|
|
||||||
Name string
|
|
||||||
ID string
|
|
||||||
Key []byte
|
|
||||||
Application string
|
|
||||||
}{
|
|
||||||
k.Type(),
|
|
||||||
k.nistID(),
|
|
||||||
keyBytes,
|
|
||||||
k.application,
|
|
||||||
}
|
|
||||||
|
|
||||||
return Marshal(&w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *skECDSAPublicKey) Verify(data []byte, sig *Signature) error {
|
|
||||||
if sig.Format != k.Type() {
|
|
||||||
return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
|
|
||||||
}
|
|
||||||
|
|
||||||
h := ecHash(k.Curve).New()
|
|
||||||
h.Write([]byte(k.application))
|
|
||||||
appDigest := h.Sum(nil)
|
|
||||||
|
|
||||||
h.Reset()
|
|
||||||
h.Write(data)
|
|
||||||
dataDigest := h.Sum(nil)
|
|
||||||
|
|
||||||
var ecSig struct {
|
|
||||||
R *big.Int
|
|
||||||
S *big.Int
|
|
||||||
}
|
|
||||||
if err := Unmarshal(sig.Blob, &ecSig); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var skf skFields
|
|
||||||
if err := Unmarshal(sig.Rest, &skf); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
blob := struct {
|
|
||||||
ApplicationDigest []byte `ssh:"rest"`
|
|
||||||
Flags byte
|
|
||||||
Counter uint32
|
|
||||||
MessageDigest []byte `ssh:"rest"`
|
|
||||||
}{
|
|
||||||
appDigest,
|
|
||||||
skf.Flags,
|
|
||||||
skf.Counter,
|
|
||||||
dataDigest,
|
|
||||||
}
|
|
||||||
|
|
||||||
original := Marshal(blob)
|
|
||||||
|
|
||||||
h.Reset()
|
|
||||||
h.Write(original)
|
|
||||||
digest := h.Sum(nil)
|
|
||||||
|
|
||||||
if ecdsa.Verify((*ecdsa.PublicKey)(&k.PublicKey), digest, ecSig.R, ecSig.S) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return errors.New("ssh: signature did not verify")
|
|
||||||
}
|
|
||||||
|
|
||||||
type skEd25519PublicKey struct {
|
|
||||||
// application is a URL-like string, typically "ssh:" for SSH.
|
|
||||||
// see openssh/PROTOCOL.u2f for details.
|
|
||||||
application string
|
|
||||||
ed25519.PublicKey
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *skEd25519PublicKey) Type() string {
|
|
||||||
return KeyAlgoSKED25519
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseSKEd25519(in []byte) (out PublicKey, rest []byte, err error) {
|
|
||||||
var w struct {
|
|
||||||
KeyBytes []byte
|
|
||||||
Application string
|
|
||||||
Rest []byte `ssh:"rest"`
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := Unmarshal(in, &w); err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if l := len(w.KeyBytes); l != ed25519.PublicKeySize {
|
|
||||||
return nil, nil, fmt.Errorf("invalid size %d for Ed25519 public key", l)
|
|
||||||
}
|
|
||||||
|
|
||||||
key := new(skEd25519PublicKey)
|
|
||||||
key.application = w.Application
|
|
||||||
key.PublicKey = ed25519.PublicKey(w.KeyBytes)
|
|
||||||
|
|
||||||
return key, w.Rest, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *skEd25519PublicKey) Marshal() []byte {
|
|
||||||
w := struct {
|
|
||||||
Name string
|
|
||||||
KeyBytes []byte
|
|
||||||
Application string
|
|
||||||
}{
|
|
||||||
KeyAlgoSKED25519,
|
|
||||||
[]byte(k.PublicKey),
|
|
||||||
k.application,
|
|
||||||
}
|
|
||||||
return Marshal(&w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *skEd25519PublicKey) Verify(data []byte, sig *Signature) error {
|
|
||||||
if sig.Format != k.Type() {
|
|
||||||
return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
|
|
||||||
}
|
|
||||||
if l := len(k.PublicKey); l != ed25519.PublicKeySize {
|
|
||||||
return fmt.Errorf("invalid size %d for Ed25519 public key", l)
|
|
||||||
}
|
|
||||||
|
|
||||||
h := sha256.New()
|
|
||||||
h.Write([]byte(k.application))
|
|
||||||
appDigest := h.Sum(nil)
|
|
||||||
|
|
||||||
h.Reset()
|
|
||||||
h.Write(data)
|
|
||||||
dataDigest := h.Sum(nil)
|
|
||||||
|
|
||||||
var edSig struct {
|
|
||||||
Signature []byte `ssh:"rest"`
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := Unmarshal(sig.Blob, &edSig); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var skf skFields
|
|
||||||
if err := Unmarshal(sig.Rest, &skf); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
blob := struct {
|
|
||||||
ApplicationDigest []byte `ssh:"rest"`
|
|
||||||
Flags byte
|
|
||||||
Counter uint32
|
|
||||||
MessageDigest []byte `ssh:"rest"`
|
|
||||||
}{
|
|
||||||
appDigest,
|
|
||||||
skf.Flags,
|
|
||||||
skf.Counter,
|
|
||||||
dataDigest,
|
|
||||||
}
|
|
||||||
|
|
||||||
original := Marshal(blob)
|
|
||||||
|
|
||||||
if ok := ed25519.Verify(k.PublicKey, original, edSig.Signature); !ok {
|
|
||||||
return errors.New("ssh: signature did not verify")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewSignerFromKey takes an *rsa.PrivateKey, *dsa.PrivateKey,
|
// NewSignerFromKey takes an *rsa.PrivateKey, *dsa.PrivateKey,
|
||||||
// *ecdsa.PrivateKey or any other crypto.Signer and returns a
|
// *ecdsa.PrivateKey or any other crypto.Signer and returns a
|
||||||
// corresponding Signer instance. ECDSA keys must use P-256, P-384 or
|
// corresponding Signer instance. ECDSA keys must use P-256, P-384 or
|
||||||
@ -1061,18 +830,14 @@ func NewPublicKey(key interface{}) (PublicKey, error) {
|
|||||||
case *dsa.PublicKey:
|
case *dsa.PublicKey:
|
||||||
return (*dsaPublicKey)(key), nil
|
return (*dsaPublicKey)(key), nil
|
||||||
case ed25519.PublicKey:
|
case ed25519.PublicKey:
|
||||||
if l := len(key); l != ed25519.PublicKeySize {
|
return (ed25519PublicKey)(key), nil
|
||||||
return nil, fmt.Errorf("ssh: invalid size %d for Ed25519 public key", l)
|
|
||||||
}
|
|
||||||
return ed25519PublicKey(key), nil
|
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("ssh: unsupported key type %T", key)
|
return nil, fmt.Errorf("ssh: unsupported key type %T", key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParsePrivateKey returns a Signer from a PEM encoded private key. It supports
|
// ParsePrivateKey returns a Signer from a PEM encoded private key. It supports
|
||||||
// the same keys as ParseRawPrivateKey. If the private key is encrypted, it
|
// the same keys as ParseRawPrivateKey.
|
||||||
// will return a PassphraseMissingError.
|
|
||||||
func ParsePrivateKey(pemBytes []byte) (Signer, error) {
|
func ParsePrivateKey(pemBytes []byte) (Signer, error) {
|
||||||
key, err := ParseRawPrivateKey(pemBytes)
|
key, err := ParseRawPrivateKey(pemBytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1085,8 +850,8 @@ func ParsePrivateKey(pemBytes []byte) (Signer, error) {
|
|||||||
// ParsePrivateKeyWithPassphrase returns a Signer from a PEM encoded private
|
// ParsePrivateKeyWithPassphrase returns a Signer from a PEM encoded private
|
||||||
// key and passphrase. It supports the same keys as
|
// key and passphrase. It supports the same keys as
|
||||||
// ParseRawPrivateKeyWithPassphrase.
|
// ParseRawPrivateKeyWithPassphrase.
|
||||||
func ParsePrivateKeyWithPassphrase(pemBytes, passphrase []byte) (Signer, error) {
|
func ParsePrivateKeyWithPassphrase(pemBytes, passPhrase []byte) (Signer, error) {
|
||||||
key, err := ParseRawPrivateKeyWithPassphrase(pemBytes, passphrase)
|
key, err := ParseRawPrivateKeyWithPassphrase(pemBytes, passPhrase)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -1102,21 +867,8 @@ func encryptedBlock(block *pem.Block) bool {
|
|||||||
return strings.Contains(block.Headers["Proc-Type"], "ENCRYPTED")
|
return strings.Contains(block.Headers["Proc-Type"], "ENCRYPTED")
|
||||||
}
|
}
|
||||||
|
|
||||||
// A PassphraseMissingError indicates that parsing this private key requires a
|
|
||||||
// passphrase. Use ParsePrivateKeyWithPassphrase.
|
|
||||||
type PassphraseMissingError struct {
|
|
||||||
// PublicKey will be set if the private key format includes an unencrypted
|
|
||||||
// public key along with the encrypted private key.
|
|
||||||
PublicKey PublicKey
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*PassphraseMissingError) Error() string {
|
|
||||||
return "ssh: this private key is passphrase protected"
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseRawPrivateKey returns a private key from a PEM encoded private key. It
|
// ParseRawPrivateKey returns a private key from a PEM encoded private key. It
|
||||||
// supports RSA (PKCS#1), PKCS#8, DSA (OpenSSL), and ECDSA private keys. If the
|
// supports RSA (PKCS#1), PKCS#8, DSA (OpenSSL), and ECDSA private keys.
|
||||||
// private key is encrypted, it will return a PassphraseMissingError.
|
|
||||||
func ParseRawPrivateKey(pemBytes []byte) (interface{}, error) {
|
func ParseRawPrivateKey(pemBytes []byte) (interface{}, error) {
|
||||||
block, _ := pem.Decode(pemBytes)
|
block, _ := pem.Decode(pemBytes)
|
||||||
if block == nil {
|
if block == nil {
|
||||||
@ -1124,7 +876,7 @@ func ParseRawPrivateKey(pemBytes []byte) (interface{}, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if encryptedBlock(block) {
|
if encryptedBlock(block) {
|
||||||
return nil, &PassphraseMissingError{}
|
return nil, errors.New("ssh: cannot decode encrypted private keys")
|
||||||
}
|
}
|
||||||
|
|
||||||
switch block.Type {
|
switch block.Type {
|
||||||
@ -1138,35 +890,33 @@ func ParseRawPrivateKey(pemBytes []byte) (interface{}, error) {
|
|||||||
case "DSA PRIVATE KEY":
|
case "DSA PRIVATE KEY":
|
||||||
return ParseDSAPrivateKey(block.Bytes)
|
return ParseDSAPrivateKey(block.Bytes)
|
||||||
case "OPENSSH PRIVATE KEY":
|
case "OPENSSH PRIVATE KEY":
|
||||||
return parseOpenSSHPrivateKey(block.Bytes, unencryptedOpenSSHKey)
|
return parseOpenSSHPrivateKey(block.Bytes)
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("ssh: unsupported key type %q", block.Type)
|
return nil, fmt.Errorf("ssh: unsupported key type %q", block.Type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseRawPrivateKeyWithPassphrase returns a private key decrypted with
|
// ParseRawPrivateKeyWithPassphrase returns a private key decrypted with
|
||||||
// passphrase from a PEM encoded private key. If the passphrase is wrong, it
|
// passphrase from a PEM encoded private key. If wrong passphrase, return
|
||||||
// will return x509.IncorrectPasswordError.
|
// x509.IncorrectPasswordError.
|
||||||
func ParseRawPrivateKeyWithPassphrase(pemBytes, passphrase []byte) (interface{}, error) {
|
func ParseRawPrivateKeyWithPassphrase(pemBytes, passPhrase []byte) (interface{}, error) {
|
||||||
block, _ := pem.Decode(pemBytes)
|
block, _ := pem.Decode(pemBytes)
|
||||||
if block == nil {
|
if block == nil {
|
||||||
return nil, errors.New("ssh: no key found")
|
return nil, errors.New("ssh: no key found")
|
||||||
}
|
}
|
||||||
|
buf := block.Bytes
|
||||||
|
|
||||||
if block.Type == "OPENSSH PRIVATE KEY" {
|
if encryptedBlock(block) {
|
||||||
return parseOpenSSHPrivateKey(block.Bytes, passphraseProtectedOpenSSHKey(passphrase))
|
if x509.IsEncryptedPEMBlock(block) {
|
||||||
}
|
var err error
|
||||||
|
buf, err = x509.DecryptPEMBlock(block, passPhrase)
|
||||||
if !encryptedBlock(block) || !x509.IsEncryptedPEMBlock(block) {
|
if err != nil {
|
||||||
return nil, errors.New("ssh: not an encrypted key")
|
if err == x509.IncorrectPasswordError {
|
||||||
}
|
return nil, err
|
||||||
|
}
|
||||||
buf, err := x509.DecryptPEMBlock(block, passphrase)
|
return nil, fmt.Errorf("ssh: cannot decode encrypted private keys: %v", err)
|
||||||
if err != nil {
|
}
|
||||||
if err == x509.IncorrectPasswordError {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("ssh: cannot decode encrypted private keys: %v", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch block.Type {
|
switch block.Type {
|
||||||
@ -1176,6 +926,8 @@ func ParseRawPrivateKeyWithPassphrase(pemBytes, passphrase []byte) (interface{},
|
|||||||
return x509.ParseECPrivateKey(buf)
|
return x509.ParseECPrivateKey(buf)
|
||||||
case "DSA PRIVATE KEY":
|
case "DSA PRIVATE KEY":
|
||||||
return ParseDSAPrivateKey(buf)
|
return ParseDSAPrivateKey(buf)
|
||||||
|
case "OPENSSH PRIVATE KEY":
|
||||||
|
return parseOpenSSHPrivateKey(buf)
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("ssh: unsupported key type %q", block.Type)
|
return nil, fmt.Errorf("ssh: unsupported key type %q", block.Type)
|
||||||
}
|
}
|
||||||
@ -1213,68 +965,9 @@ func ParseDSAPrivateKey(der []byte) (*dsa.PrivateKey, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func unencryptedOpenSSHKey(cipherName, kdfName, kdfOpts string, privKeyBlock []byte) ([]byte, error) {
|
// Implemented based on the documentation at
|
||||||
if kdfName != "none" || cipherName != "none" {
|
// https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.key
|
||||||
return nil, &PassphraseMissingError{}
|
func parseOpenSSHPrivateKey(key []byte) (crypto.PrivateKey, error) {
|
||||||
}
|
|
||||||
if kdfOpts != "" {
|
|
||||||
return nil, errors.New("ssh: invalid openssh private key")
|
|
||||||
}
|
|
||||||
return privKeyBlock, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func passphraseProtectedOpenSSHKey(passphrase []byte) openSSHDecryptFunc {
|
|
||||||
return func(cipherName, kdfName, kdfOpts string, privKeyBlock []byte) ([]byte, error) {
|
|
||||||
if kdfName == "none" || cipherName == "none" {
|
|
||||||
return nil, errors.New("ssh: key is not password protected")
|
|
||||||
}
|
|
||||||
if kdfName != "bcrypt" {
|
|
||||||
return nil, fmt.Errorf("ssh: unknown KDF %q, only supports %q", kdfName, "bcrypt")
|
|
||||||
}
|
|
||||||
|
|
||||||
var opts struct {
|
|
||||||
Salt string
|
|
||||||
Rounds uint32
|
|
||||||
}
|
|
||||||
if err := Unmarshal([]byte(kdfOpts), &opts); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
k, err := bcrypt_pbkdf.Key(passphrase, []byte(opts.Salt), int(opts.Rounds), 32+16)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
key, iv := k[:32], k[32:]
|
|
||||||
|
|
||||||
c, err := aes.NewCipher(key)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
switch cipherName {
|
|
||||||
case "aes256-ctr":
|
|
||||||
ctr := cipher.NewCTR(c, iv)
|
|
||||||
ctr.XORKeyStream(privKeyBlock, privKeyBlock)
|
|
||||||
case "aes256-cbc":
|
|
||||||
if len(privKeyBlock)%c.BlockSize() != 0 {
|
|
||||||
return nil, fmt.Errorf("ssh: invalid encrypted private key length, not a multiple of the block size")
|
|
||||||
}
|
|
||||||
cbc := cipher.NewCBCDecrypter(c, iv)
|
|
||||||
cbc.CryptBlocks(privKeyBlock, privKeyBlock)
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("ssh: unknown cipher %q, only supports %q or %q", cipherName, "aes256-ctr", "aes256-cbc")
|
|
||||||
}
|
|
||||||
|
|
||||||
return privKeyBlock, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type openSSHDecryptFunc func(CipherName, KdfName, KdfOpts string, PrivKeyBlock []byte) ([]byte, error)
|
|
||||||
|
|
||||||
// parseOpenSSHPrivateKey parses an OpenSSH private key, using the decrypt
|
|
||||||
// function to unwrap the encrypted portion. unencryptedOpenSSHKey can be used
|
|
||||||
// as the decrypt function to parse an unencrypted private key. See
|
|
||||||
// https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.key.
|
|
||||||
func parseOpenSSHPrivateKey(key []byte, decrypt openSSHDecryptFunc) (crypto.PrivateKey, error) {
|
|
||||||
const magic = "openssh-key-v1\x00"
|
const magic = "openssh-key-v1\x00"
|
||||||
if len(key) < len(magic) || string(key[:len(magic)]) != magic {
|
if len(key) < len(magic) || string(key[:len(magic)]) != magic {
|
||||||
return nil, errors.New("ssh: invalid openssh private key format")
|
return nil, errors.New("ssh: invalid openssh private key format")
|
||||||
@ -1293,22 +986,9 @@ func parseOpenSSHPrivateKey(key []byte, decrypt openSSHDecryptFunc) (crypto.Priv
|
|||||||
if err := Unmarshal(remaining, &w); err != nil {
|
if err := Unmarshal(remaining, &w); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if w.NumKeys != 1 {
|
|
||||||
// We only support single key files, and so does OpenSSH.
|
|
||||||
// https://github.com/openssh/openssh-portable/blob/4103a3ec7/sshkey.c#L4171
|
|
||||||
return nil, errors.New("ssh: multi-key files are not supported")
|
|
||||||
}
|
|
||||||
|
|
||||||
privKeyBlock, err := decrypt(w.CipherName, w.KdfName, w.KdfOpts, w.PrivKeyBlock)
|
if w.KdfName != "none" || w.CipherName != "none" {
|
||||||
if err != nil {
|
return nil, errors.New("ssh: cannot decode encrypted private keys")
|
||||||
if err, ok := err.(*PassphraseMissingError); ok {
|
|
||||||
pub, errPub := ParsePublicKey(w.PubKey)
|
|
||||||
if errPub != nil {
|
|
||||||
return nil, fmt.Errorf("ssh: failed to parse embedded public key: %v", errPub)
|
|
||||||
}
|
|
||||||
err.PublicKey = pub
|
|
||||||
}
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pk1 := struct {
|
pk1 := struct {
|
||||||
@ -1318,13 +998,15 @@ func parseOpenSSHPrivateKey(key []byte, decrypt openSSHDecryptFunc) (crypto.Priv
|
|||||||
Rest []byte `ssh:"rest"`
|
Rest []byte `ssh:"rest"`
|
||||||
}{}
|
}{}
|
||||||
|
|
||||||
if err := Unmarshal(privKeyBlock, &pk1); err != nil || pk1.Check1 != pk1.Check2 {
|
if err := Unmarshal(w.PrivKeyBlock, &pk1); err != nil {
|
||||||
if w.CipherName != "none" {
|
return nil, err
|
||||||
return nil, x509.IncorrectPasswordError
|
|
||||||
}
|
|
||||||
return nil, errors.New("ssh: malformed OpenSSH key")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if pk1.Check1 != pk1.Check2 {
|
||||||
|
return nil, errors.New("ssh: checkint mismatch")
|
||||||
|
}
|
||||||
|
|
||||||
|
// we only handle ed25519 and rsa keys currently
|
||||||
switch pk1.Keytype {
|
switch pk1.Keytype {
|
||||||
case KeyAlgoRSA:
|
case KeyAlgoRSA:
|
||||||
// https://github.com/openssh/openssh-portable/blob/master/sshkey.c#L2760-L2773
|
// https://github.com/openssh/openssh-portable/blob/master/sshkey.c#L2760-L2773
|
||||||
@ -1343,8 +1025,10 @@ func parseOpenSSHPrivateKey(key []byte, decrypt openSSHDecryptFunc) (crypto.Priv
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := checkOpenSSHKeyPadding(key.Pad); err != nil {
|
for i, b := range key.Pad {
|
||||||
return nil, err
|
if int(b) != i+1 {
|
||||||
|
return nil, errors.New("ssh: padding not as expected")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pk := &rsa.PrivateKey{
|
pk := &rsa.PrivateKey{
|
||||||
@ -1379,78 +1063,20 @@ func parseOpenSSHPrivateKey(key []byte, decrypt openSSHDecryptFunc) (crypto.Priv
|
|||||||
return nil, errors.New("ssh: private key unexpected length")
|
return nil, errors.New("ssh: private key unexpected length")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := checkOpenSSHKeyPadding(key.Pad); err != nil {
|
for i, b := range key.Pad {
|
||||||
return nil, err
|
if int(b) != i+1 {
|
||||||
|
return nil, errors.New("ssh: padding not as expected")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pk := ed25519.PrivateKey(make([]byte, ed25519.PrivateKeySize))
|
pk := ed25519.PrivateKey(make([]byte, ed25519.PrivateKeySize))
|
||||||
copy(pk, key.Priv)
|
copy(pk, key.Priv)
|
||||||
return &pk, nil
|
return &pk, nil
|
||||||
case KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521:
|
|
||||||
key := struct {
|
|
||||||
Curve string
|
|
||||||
Pub []byte
|
|
||||||
D *big.Int
|
|
||||||
Comment string
|
|
||||||
Pad []byte `ssh:"rest"`
|
|
||||||
}{}
|
|
||||||
|
|
||||||
if err := Unmarshal(pk1.Rest, &key); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := checkOpenSSHKeyPadding(key.Pad); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var curve elliptic.Curve
|
|
||||||
switch key.Curve {
|
|
||||||
case "nistp256":
|
|
||||||
curve = elliptic.P256()
|
|
||||||
case "nistp384":
|
|
||||||
curve = elliptic.P384()
|
|
||||||
case "nistp521":
|
|
||||||
curve = elliptic.P521()
|
|
||||||
default:
|
|
||||||
return nil, errors.New("ssh: unhandled elliptic curve: " + key.Curve)
|
|
||||||
}
|
|
||||||
|
|
||||||
X, Y := elliptic.Unmarshal(curve, key.Pub)
|
|
||||||
if X == nil || Y == nil {
|
|
||||||
return nil, errors.New("ssh: failed to unmarshal public key")
|
|
||||||
}
|
|
||||||
|
|
||||||
if key.D.Cmp(curve.Params().N) >= 0 {
|
|
||||||
return nil, errors.New("ssh: scalar is out of range")
|
|
||||||
}
|
|
||||||
|
|
||||||
x, y := curve.ScalarBaseMult(key.D.Bytes())
|
|
||||||
if x.Cmp(X) != 0 || y.Cmp(Y) != 0 {
|
|
||||||
return nil, errors.New("ssh: public key does not match private key")
|
|
||||||
}
|
|
||||||
|
|
||||||
return &ecdsa.PrivateKey{
|
|
||||||
PublicKey: ecdsa.PublicKey{
|
|
||||||
Curve: curve,
|
|
||||||
X: X,
|
|
||||||
Y: Y,
|
|
||||||
},
|
|
||||||
D: key.D,
|
|
||||||
}, nil
|
|
||||||
default:
|
default:
|
||||||
return nil, errors.New("ssh: unhandled key type")
|
return nil, errors.New("ssh: unhandled key type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkOpenSSHKeyPadding(pad []byte) error {
|
|
||||||
for i, b := range pad {
|
|
||||||
if int(b) != i+1 {
|
|
||||||
return errors.New("ssh: padding not as expected")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// FingerprintLegacyMD5 returns the user presentation of the key's
|
// FingerprintLegacyMD5 returns the user presentation of the key's
|
||||||
// fingerprint as described by RFC 4716 section 4.
|
// fingerprint as described by RFC 4716 section 4.
|
||||||
func FingerprintLegacyMD5(pubKey PublicKey) string {
|
func FingerprintLegacyMD5(pubKey PublicKey) string {
|
||||||
|
100
vendor/golang.org/x/crypto/ssh/messages.go
generated
vendored
100
vendor/golang.org/x/crypto/ssh/messages.go
generated
vendored
@ -97,36 +97,6 @@ type kexDHReplyMsg struct {
|
|||||||
Signature []byte
|
Signature []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// See RFC 4419, section 5.
|
|
||||||
const msgKexDHGexGroup = 31
|
|
||||||
|
|
||||||
type kexDHGexGroupMsg struct {
|
|
||||||
P *big.Int `sshtype:"31"`
|
|
||||||
G *big.Int
|
|
||||||
}
|
|
||||||
|
|
||||||
const msgKexDHGexInit = 32
|
|
||||||
|
|
||||||
type kexDHGexInitMsg struct {
|
|
||||||
X *big.Int `sshtype:"32"`
|
|
||||||
}
|
|
||||||
|
|
||||||
const msgKexDHGexReply = 33
|
|
||||||
|
|
||||||
type kexDHGexReplyMsg struct {
|
|
||||||
HostKey []byte `sshtype:"33"`
|
|
||||||
Y *big.Int
|
|
||||||
Signature []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
const msgKexDHGexRequest = 34
|
|
||||||
|
|
||||||
type kexDHGexRequestMsg struct {
|
|
||||||
MinBits uint32 `sshtype:"34"`
|
|
||||||
PreferedBits uint32
|
|
||||||
MaxBits uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
// See RFC 4253, section 10.
|
// See RFC 4253, section 10.
|
||||||
const msgServiceRequest = 5
|
const msgServiceRequest = 5
|
||||||
|
|
||||||
@ -305,42 +275,6 @@ type userAuthPubKeyOkMsg struct {
|
|||||||
PubKey []byte
|
PubKey []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// See RFC 4462, section 3
|
|
||||||
const msgUserAuthGSSAPIResponse = 60
|
|
||||||
|
|
||||||
type userAuthGSSAPIResponse struct {
|
|
||||||
SupportMech []byte `sshtype:"60"`
|
|
||||||
}
|
|
||||||
|
|
||||||
const msgUserAuthGSSAPIToken = 61
|
|
||||||
|
|
||||||
type userAuthGSSAPIToken struct {
|
|
||||||
Token []byte `sshtype:"61"`
|
|
||||||
}
|
|
||||||
|
|
||||||
const msgUserAuthGSSAPIMIC = 66
|
|
||||||
|
|
||||||
type userAuthGSSAPIMIC struct {
|
|
||||||
MIC []byte `sshtype:"66"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// See RFC 4462, section 3.9
|
|
||||||
const msgUserAuthGSSAPIErrTok = 64
|
|
||||||
|
|
||||||
type userAuthGSSAPIErrTok struct {
|
|
||||||
ErrorToken []byte `sshtype:"64"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// See RFC 4462, section 3.8
|
|
||||||
const msgUserAuthGSSAPIError = 65
|
|
||||||
|
|
||||||
type userAuthGSSAPIError struct {
|
|
||||||
MajorStatus uint32 `sshtype:"65"`
|
|
||||||
MinorStatus uint32
|
|
||||||
Message string
|
|
||||||
LanguageTag string
|
|
||||||
}
|
|
||||||
|
|
||||||
// typeTags returns the possible type bytes for the given reflect.Type, which
|
// typeTags returns the possible type bytes for the given reflect.Type, which
|
||||||
// should be a struct. The possible values are separated by a '|' character.
|
// should be a struct. The possible values are separated by a '|' character.
|
||||||
func typeTags(structType reflect.Type) (tags []byte) {
|
func typeTags(structType reflect.Type) (tags []byte) {
|
||||||
@ -822,14 +756,6 @@ func decode(packet []byte) (interface{}, error) {
|
|||||||
msg = new(channelRequestSuccessMsg)
|
msg = new(channelRequestSuccessMsg)
|
||||||
case msgChannelFailure:
|
case msgChannelFailure:
|
||||||
msg = new(channelRequestFailureMsg)
|
msg = new(channelRequestFailureMsg)
|
||||||
case msgUserAuthGSSAPIToken:
|
|
||||||
msg = new(userAuthGSSAPIToken)
|
|
||||||
case msgUserAuthGSSAPIMIC:
|
|
||||||
msg = new(userAuthGSSAPIMIC)
|
|
||||||
case msgUserAuthGSSAPIErrTok:
|
|
||||||
msg = new(userAuthGSSAPIErrTok)
|
|
||||||
case msgUserAuthGSSAPIError:
|
|
||||||
msg = new(userAuthGSSAPIError)
|
|
||||||
default:
|
default:
|
||||||
return nil, unexpectedMessageError(0, packet[0])
|
return nil, unexpectedMessageError(0, packet[0])
|
||||||
}
|
}
|
||||||
@ -838,29 +764,3 @@ func decode(packet []byte) (interface{}, error) {
|
|||||||
}
|
}
|
||||||
return msg, nil
|
return msg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var packetTypeNames = map[byte]string{
|
|
||||||
msgDisconnect: "disconnectMsg",
|
|
||||||
msgServiceRequest: "serviceRequestMsg",
|
|
||||||
msgServiceAccept: "serviceAcceptMsg",
|
|
||||||
msgKexInit: "kexInitMsg",
|
|
||||||
msgKexDHInit: "kexDHInitMsg",
|
|
||||||
msgKexDHReply: "kexDHReplyMsg",
|
|
||||||
msgUserAuthRequest: "userAuthRequestMsg",
|
|
||||||
msgUserAuthSuccess: "userAuthSuccessMsg",
|
|
||||||
msgUserAuthFailure: "userAuthFailureMsg",
|
|
||||||
msgUserAuthPubKeyOk: "userAuthPubKeyOkMsg",
|
|
||||||
msgGlobalRequest: "globalRequestMsg",
|
|
||||||
msgRequestSuccess: "globalRequestSuccessMsg",
|
|
||||||
msgRequestFailure: "globalRequestFailureMsg",
|
|
||||||
msgChannelOpen: "channelOpenMsg",
|
|
||||||
msgChannelData: "channelDataMsg",
|
|
||||||
msgChannelOpenConfirm: "channelOpenConfirmMsg",
|
|
||||||
msgChannelOpenFailure: "channelOpenFailureMsg",
|
|
||||||
msgChannelWindowAdjust: "windowAdjustMsg",
|
|
||||||
msgChannelEOF: "channelEOFMsg",
|
|
||||||
msgChannelClose: "channelCloseMsg",
|
|
||||||
msgChannelRequest: "channelRequestMsg",
|
|
||||||
msgChannelSuccess: "channelRequestSuccessMsg",
|
|
||||||
msgChannelFailure: "channelRequestFailureMsg",
|
|
||||||
}
|
|
||||||
|
23
vendor/golang.org/x/crypto/ssh/mux.go
generated
vendored
23
vendor/golang.org/x/crypto/ssh/mux.go
generated
vendored
@ -240,7 +240,7 @@ func (m *mux) onePacket() error {
|
|||||||
id := binary.BigEndian.Uint32(packet[1:])
|
id := binary.BigEndian.Uint32(packet[1:])
|
||||||
ch := m.chanList.getChan(id)
|
ch := m.chanList.getChan(id)
|
||||||
if ch == nil {
|
if ch == nil {
|
||||||
return m.handleUnknownChannelPacket(id, packet)
|
return fmt.Errorf("ssh: invalid channel %d", id)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ch.handlePacket(packet)
|
return ch.handlePacket(packet)
|
||||||
@ -328,24 +328,3 @@ func (m *mux) openChannel(chanType string, extra []byte) (*channel, error) {
|
|||||||
return nil, fmt.Errorf("ssh: unexpected packet in response to channel open: %T", msg)
|
return nil, fmt.Errorf("ssh: unexpected packet in response to channel open: %T", msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mux) handleUnknownChannelPacket(id uint32, packet []byte) error {
|
|
||||||
msg, err := decode(packet)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
switch msg := msg.(type) {
|
|
||||||
// RFC 4254 section 5.4 says unrecognized channel requests should
|
|
||||||
// receive a failure response.
|
|
||||||
case *channelRequestMsg:
|
|
||||||
if msg.WantReply {
|
|
||||||
return m.sendMessage(channelRequestFailureMsg{
|
|
||||||
PeersID: msg.PeersID,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("ssh: invalid channel %d", id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
128
vendor/golang.org/x/crypto/ssh/server.go
generated
vendored
128
vendor/golang.org/x/crypto/ssh/server.go
generated
vendored
@ -45,20 +45,6 @@ type Permissions struct {
|
|||||||
Extensions map[string]string
|
Extensions map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
type GSSAPIWithMICConfig struct {
|
|
||||||
// AllowLogin, must be set, is called when gssapi-with-mic
|
|
||||||
// authentication is selected (RFC 4462 section 3). The srcName is from the
|
|
||||||
// results of the GSS-API authentication. The format is username@DOMAIN.
|
|
||||||
// GSSAPI just guarantees to the server who the user is, but not if they can log in, and with what permissions.
|
|
||||||
// This callback is called after the user identity is established with GSSAPI to decide if the user can login with
|
|
||||||
// which permissions. If the user is allowed to login, it should return a nil error.
|
|
||||||
AllowLogin func(conn ConnMetadata, srcName string) (*Permissions, error)
|
|
||||||
|
|
||||||
// Server must be set. It's the implementation
|
|
||||||
// of the GSSAPIServer interface. See GSSAPIServer interface for details.
|
|
||||||
Server GSSAPIServer
|
|
||||||
}
|
|
||||||
|
|
||||||
// ServerConfig holds server specific configuration data.
|
// ServerConfig holds server specific configuration data.
|
||||||
type ServerConfig struct {
|
type ServerConfig struct {
|
||||||
// Config contains configuration shared between client and server.
|
// Config contains configuration shared between client and server.
|
||||||
@ -113,10 +99,6 @@ type ServerConfig struct {
|
|||||||
// BannerCallback, if present, is called and the return string is sent to
|
// BannerCallback, if present, is called and the return string is sent to
|
||||||
// the client after key exchange completed but before authentication.
|
// the client after key exchange completed but before authentication.
|
||||||
BannerCallback func(conn ConnMetadata) string
|
BannerCallback func(conn ConnMetadata) string
|
||||||
|
|
||||||
// GSSAPIWithMICConfig includes gssapi server and callback, which if both non-nil, is used
|
|
||||||
// when gssapi-with-mic authentication is selected (RFC 4462 section 3).
|
|
||||||
GSSAPIWithMICConfig *GSSAPIWithMICConfig
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddHostKey adds a private key as a host key. If an existing host
|
// AddHostKey adds a private key as a host key. If an existing host
|
||||||
@ -193,12 +175,6 @@ func NewServerConn(c net.Conn, config *ServerConfig) (*ServerConn, <-chan NewCha
|
|||||||
if fullConf.MaxAuthTries == 0 {
|
if fullConf.MaxAuthTries == 0 {
|
||||||
fullConf.MaxAuthTries = 6
|
fullConf.MaxAuthTries = 6
|
||||||
}
|
}
|
||||||
// Check if the config contains any unsupported key exchanges
|
|
||||||
for _, kex := range fullConf.KeyExchanges {
|
|
||||||
if _, ok := serverForbiddenKexAlgos[kex]; ok {
|
|
||||||
return nil, nil, nil, fmt.Errorf("ssh: unsupported key exchange %s for server", kex)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
s := &connection{
|
s := &connection{
|
||||||
sshConn: sshConn{conn: c},
|
sshConn: sshConn{conn: c},
|
||||||
@ -228,9 +204,7 @@ func (s *connection) serverHandshake(config *ServerConfig) (*Permissions, error)
|
|||||||
return nil, errors.New("ssh: server has no host keys")
|
return nil, errors.New("ssh: server has no host keys")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !config.NoClientAuth && config.PasswordCallback == nil && config.PublicKeyCallback == nil &&
|
if !config.NoClientAuth && config.PasswordCallback == nil && config.PublicKeyCallback == nil && config.KeyboardInteractiveCallback == nil {
|
||||||
config.KeyboardInteractiveCallback == nil && (config.GSSAPIWithMICConfig == nil ||
|
|
||||||
config.GSSAPIWithMICConfig.AllowLogin == nil || config.GSSAPIWithMICConfig.Server == nil) {
|
|
||||||
return nil, errors.New("ssh: no authentication methods configured but NoClientAuth is also false")
|
return nil, errors.New("ssh: no authentication methods configured but NoClientAuth is also false")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,8 +258,8 @@ func (s *connection) serverHandshake(config *ServerConfig) (*Permissions, error)
|
|||||||
|
|
||||||
func isAcceptableAlgo(algo string) bool {
|
func isAcceptableAlgo(algo string) bool {
|
||||||
switch algo {
|
switch algo {
|
||||||
case KeyAlgoRSA, KeyAlgoDSA, KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521, KeyAlgoSKECDSA256, KeyAlgoED25519, KeyAlgoSKED25519,
|
case KeyAlgoRSA, KeyAlgoDSA, KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521, KeyAlgoED25519,
|
||||||
CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoSKECDSA256v01, CertAlgoED25519v01, CertAlgoSKED25519v01:
|
CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoED25519v01:
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
@ -321,55 +295,6 @@ func checkSourceAddress(addr net.Addr, sourceAddrs string) error {
|
|||||||
return fmt.Errorf("ssh: remote address %v is not allowed because of source-address restriction", addr)
|
return fmt.Errorf("ssh: remote address %v is not allowed because of source-address restriction", addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func gssExchangeToken(gssapiConfig *GSSAPIWithMICConfig, firstToken []byte, s *connection,
|
|
||||||
sessionID []byte, userAuthReq userAuthRequestMsg) (authErr error, perms *Permissions, err error) {
|
|
||||||
gssAPIServer := gssapiConfig.Server
|
|
||||||
defer gssAPIServer.DeleteSecContext()
|
|
||||||
var srcName string
|
|
||||||
for {
|
|
||||||
var (
|
|
||||||
outToken []byte
|
|
||||||
needContinue bool
|
|
||||||
)
|
|
||||||
outToken, srcName, needContinue, err = gssAPIServer.AcceptSecContext(firstToken)
|
|
||||||
if err != nil {
|
|
||||||
return err, nil, nil
|
|
||||||
}
|
|
||||||
if len(outToken) != 0 {
|
|
||||||
if err := s.transport.writePacket(Marshal(&userAuthGSSAPIToken{
|
|
||||||
Token: outToken,
|
|
||||||
})); err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !needContinue {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
packet, err := s.transport.readPacket()
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
userAuthGSSAPITokenReq := &userAuthGSSAPIToken{}
|
|
||||||
if err := Unmarshal(packet, userAuthGSSAPITokenReq); err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
packet, err := s.transport.readPacket()
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
userAuthGSSAPIMICReq := &userAuthGSSAPIMIC{}
|
|
||||||
if err := Unmarshal(packet, userAuthGSSAPIMICReq); err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
mic := buildMIC(string(sessionID), userAuthReq.User, userAuthReq.Service, userAuthReq.Method)
|
|
||||||
if err := gssAPIServer.VerifyMIC(mic, userAuthGSSAPIMICReq.MIC); err != nil {
|
|
||||||
return err, nil, nil
|
|
||||||
}
|
|
||||||
perms, authErr = gssapiConfig.AllowLogin(s, srcName)
|
|
||||||
return authErr, perms, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ServerAuthError represents server authentication errors and is
|
// ServerAuthError represents server authentication errors and is
|
||||||
// sometimes returned by NewServerConn. It appends any authentication
|
// sometimes returned by NewServerConn. It appends any authentication
|
||||||
// errors that may occur, and is returned if all of the authentication
|
// errors that may occur, and is returned if all of the authentication
|
||||||
@ -571,49 +496,6 @@ userAuthLoop:
|
|||||||
authErr = candidate.result
|
authErr = candidate.result
|
||||||
perms = candidate.perms
|
perms = candidate.perms
|
||||||
}
|
}
|
||||||
case "gssapi-with-mic":
|
|
||||||
gssapiConfig := config.GSSAPIWithMICConfig
|
|
||||||
userAuthRequestGSSAPI, err := parseGSSAPIPayload(userAuthReq.Payload)
|
|
||||||
if err != nil {
|
|
||||||
return nil, parseError(msgUserAuthRequest)
|
|
||||||
}
|
|
||||||
// OpenSSH supports Kerberos V5 mechanism only for GSS-API authentication.
|
|
||||||
if userAuthRequestGSSAPI.N == 0 {
|
|
||||||
authErr = fmt.Errorf("ssh: Mechanism negotiation is not supported")
|
|
||||||
break
|
|
||||||
}
|
|
||||||
var i uint32
|
|
||||||
present := false
|
|
||||||
for i = 0; i < userAuthRequestGSSAPI.N; i++ {
|
|
||||||
if userAuthRequestGSSAPI.OIDS[i].Equal(krb5Mesh) {
|
|
||||||
present = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !present {
|
|
||||||
authErr = fmt.Errorf("ssh: GSSAPI authentication must use the Kerberos V5 mechanism")
|
|
||||||
break
|
|
||||||
}
|
|
||||||
// Initial server response, see RFC 4462 section 3.3.
|
|
||||||
if err := s.transport.writePacket(Marshal(&userAuthGSSAPIResponse{
|
|
||||||
SupportMech: krb5OID,
|
|
||||||
})); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
// Exchange token, see RFC 4462 section 3.4.
|
|
||||||
packet, err := s.transport.readPacket()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
userAuthGSSAPITokenReq := &userAuthGSSAPIToken{}
|
|
||||||
if err := Unmarshal(packet, userAuthGSSAPITokenReq); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
authErr, perms, err = gssExchangeToken(gssapiConfig, userAuthGSSAPITokenReq.Token, s, sessionID,
|
|
||||||
userAuthReq)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
authErr = fmt.Errorf("ssh: unknown method %q", userAuthReq.Method)
|
authErr = fmt.Errorf("ssh: unknown method %q", userAuthReq.Method)
|
||||||
}
|
}
|
||||||
@ -640,10 +522,6 @@ userAuthLoop:
|
|||||||
if config.KeyboardInteractiveCallback != nil {
|
if config.KeyboardInteractiveCallback != nil {
|
||||||
failureMsg.Methods = append(failureMsg.Methods, "keyboard-interactive")
|
failureMsg.Methods = append(failureMsg.Methods, "keyboard-interactive")
|
||||||
}
|
}
|
||||||
if config.GSSAPIWithMICConfig != nil && config.GSSAPIWithMICConfig.Server != nil &&
|
|
||||||
config.GSSAPIWithMICConfig.AllowLogin != nil {
|
|
||||||
failureMsg.Methods = append(failureMsg.Methods, "gssapi-with-mic")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(failureMsg.Methods) == 0 {
|
if len(failureMsg.Methods) == 0 {
|
||||||
return nil, errors.New("ssh: no authentication methods configured but NoClientAuth is also false")
|
return nil, errors.New("ssh: no authentication methods configured but NoClientAuth is also false")
|
||||||
|
139
vendor/golang.org/x/crypto/ssh/ssh_gss.go
generated
vendored
139
vendor/golang.org/x/crypto/ssh/ssh_gss.go
generated
vendored
@ -1,139 +0,0 @@
|
|||||||
// Copyright 2011 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ssh
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/asn1"
|
|
||||||
"errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
var krb5OID []byte
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
krb5OID, _ = asn1.Marshal(krb5Mesh)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GSSAPIClient provides the API to plug-in GSSAPI authentication for client logins.
|
|
||||||
type GSSAPIClient interface {
|
|
||||||
// InitSecContext initiates the establishment of a security context for GSS-API between the
|
|
||||||
// ssh client and ssh server. Initially the token parameter should be specified as nil.
|
|
||||||
// The routine may return a outputToken which should be transferred to
|
|
||||||
// the ssh server, where the ssh server will present it to
|
|
||||||
// AcceptSecContext. If no token need be sent, InitSecContext will indicate this by setting
|
|
||||||
// needContinue to false. To complete the context
|
|
||||||
// establishment, one or more reply tokens may be required from the ssh
|
|
||||||
// server;if so, InitSecContext will return a needContinue which is true.
|
|
||||||
// In this case, InitSecContext should be called again when the
|
|
||||||
// reply token is received from the ssh server, passing the reply
|
|
||||||
// token to InitSecContext via the token parameters.
|
|
||||||
// See RFC 2743 section 2.2.1 and RFC 4462 section 3.4.
|
|
||||||
InitSecContext(target string, token []byte, isGSSDelegCreds bool) (outputToken []byte, needContinue bool, err error)
|
|
||||||
// GetMIC generates a cryptographic MIC for the SSH2 message, and places
|
|
||||||
// the MIC in a token for transfer to the ssh server.
|
|
||||||
// The contents of the MIC field are obtained by calling GSS_GetMIC()
|
|
||||||
// over the following, using the GSS-API context that was just
|
|
||||||
// established:
|
|
||||||
// string session identifier
|
|
||||||
// byte SSH_MSG_USERAUTH_REQUEST
|
|
||||||
// string user name
|
|
||||||
// string service
|
|
||||||
// string "gssapi-with-mic"
|
|
||||||
// See RFC 2743 section 2.3.1 and RFC 4462 3.5.
|
|
||||||
GetMIC(micFiled []byte) ([]byte, error)
|
|
||||||
// Whenever possible, it should be possible for
|
|
||||||
// DeleteSecContext() calls to be successfully processed even
|
|
||||||
// if other calls cannot succeed, thereby enabling context-related
|
|
||||||
// resources to be released.
|
|
||||||
// In addition to deleting established security contexts,
|
|
||||||
// gss_delete_sec_context must also be able to delete "half-built"
|
|
||||||
// security contexts resulting from an incomplete sequence of
|
|
||||||
// InitSecContext()/AcceptSecContext() calls.
|
|
||||||
// See RFC 2743 section 2.2.3.
|
|
||||||
DeleteSecContext() error
|
|
||||||
}
|
|
||||||
|
|
||||||
// GSSAPIServer provides the API to plug in GSSAPI authentication for server logins.
|
|
||||||
type GSSAPIServer interface {
|
|
||||||
// AcceptSecContext allows a remotely initiated security context between the application
|
|
||||||
// and a remote peer to be established by the ssh client. The routine may return a
|
|
||||||
// outputToken which should be transferred to the ssh client,
|
|
||||||
// where the ssh client will present it to InitSecContext.
|
|
||||||
// If no token need be sent, AcceptSecContext will indicate this
|
|
||||||
// by setting the needContinue to false. To
|
|
||||||
// complete the context establishment, one or more reply tokens may be
|
|
||||||
// required from the ssh client. if so, AcceptSecContext
|
|
||||||
// will return a needContinue which is true, in which case it
|
|
||||||
// should be called again when the reply token is received from the ssh
|
|
||||||
// client, passing the token to AcceptSecContext via the
|
|
||||||
// token parameters.
|
|
||||||
// The srcName return value is the authenticated username.
|
|
||||||
// See RFC 2743 section 2.2.2 and RFC 4462 section 3.4.
|
|
||||||
AcceptSecContext(token []byte) (outputToken []byte, srcName string, needContinue bool, err error)
|
|
||||||
// VerifyMIC verifies that a cryptographic MIC, contained in the token parameter,
|
|
||||||
// fits the supplied message is received from the ssh client.
|
|
||||||
// See RFC 2743 section 2.3.2.
|
|
||||||
VerifyMIC(micField []byte, micToken []byte) error
|
|
||||||
// Whenever possible, it should be possible for
|
|
||||||
// DeleteSecContext() calls to be successfully processed even
|
|
||||||
// if other calls cannot succeed, thereby enabling context-related
|
|
||||||
// resources to be released.
|
|
||||||
// In addition to deleting established security contexts,
|
|
||||||
// gss_delete_sec_context must also be able to delete "half-built"
|
|
||||||
// security contexts resulting from an incomplete sequence of
|
|
||||||
// InitSecContext()/AcceptSecContext() calls.
|
|
||||||
// See RFC 2743 section 2.2.3.
|
|
||||||
DeleteSecContext() error
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
// OpenSSH supports Kerberos V5 mechanism only for GSS-API authentication,
|
|
||||||
// so we also support the krb5 mechanism only.
|
|
||||||
// See RFC 1964 section 1.
|
|
||||||
krb5Mesh = asn1.ObjectIdentifier{1, 2, 840, 113554, 1, 2, 2}
|
|
||||||
)
|
|
||||||
|
|
||||||
// The GSS-API authentication method is initiated when the client sends an SSH_MSG_USERAUTH_REQUEST
|
|
||||||
// See RFC 4462 section 3.2.
|
|
||||||
type userAuthRequestGSSAPI struct {
|
|
||||||
N uint32
|
|
||||||
OIDS []asn1.ObjectIdentifier
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseGSSAPIPayload(payload []byte) (*userAuthRequestGSSAPI, error) {
|
|
||||||
n, rest, ok := parseUint32(payload)
|
|
||||||
if !ok {
|
|
||||||
return nil, errors.New("parse uint32 failed")
|
|
||||||
}
|
|
||||||
s := &userAuthRequestGSSAPI{
|
|
||||||
N: n,
|
|
||||||
OIDS: make([]asn1.ObjectIdentifier, n),
|
|
||||||
}
|
|
||||||
for i := 0; i < int(n); i++ {
|
|
||||||
var (
|
|
||||||
desiredMech []byte
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
desiredMech, rest, ok = parseString(rest)
|
|
||||||
if !ok {
|
|
||||||
return nil, errors.New("parse string failed")
|
|
||||||
}
|
|
||||||
if rest, err = asn1.Unmarshal(desiredMech, &s.OIDS[i]); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return s, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// See RFC 4462 section 3.6.
|
|
||||||
func buildMIC(sessionID string, username string, service string, authMethod string) []byte {
|
|
||||||
out := make([]byte, 0, 0)
|
|
||||||
out = appendString(out, sessionID)
|
|
||||||
out = append(out, msgUserAuthRequest)
|
|
||||||
out = appendString(out, username)
|
|
||||||
out = appendString(out, service)
|
|
||||||
out = appendString(out, authMethod)
|
|
||||||
return out
|
|
||||||
}
|
|
88
vendor/golang.org/x/crypto/ssh/terminal/terminal.go
generated
vendored
88
vendor/golang.org/x/crypto/ssh/terminal/terminal.go
generated
vendored
@ -7,8 +7,6 @@ package terminal
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"io"
|
"io"
|
||||||
"runtime"
|
|
||||||
"strconv"
|
|
||||||
"sync"
|
"sync"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
)
|
)
|
||||||
@ -113,7 +111,6 @@ func NewTerminal(c io.ReadWriter, prompt string) *Terminal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
keyCtrlC = 3
|
|
||||||
keyCtrlD = 4
|
keyCtrlD = 4
|
||||||
keyCtrlU = 21
|
keyCtrlU = 21
|
||||||
keyEnter = '\r'
|
keyEnter = '\r'
|
||||||
@ -152,12 +149,8 @@ func bytesToKey(b []byte, pasteActive bool) (rune, []byte) {
|
|||||||
switch b[0] {
|
switch b[0] {
|
||||||
case 1: // ^A
|
case 1: // ^A
|
||||||
return keyHome, b[1:]
|
return keyHome, b[1:]
|
||||||
case 2: // ^B
|
|
||||||
return keyLeft, b[1:]
|
|
||||||
case 5: // ^E
|
case 5: // ^E
|
||||||
return keyEnd, b[1:]
|
return keyEnd, b[1:]
|
||||||
case 6: // ^F
|
|
||||||
return keyRight, b[1:]
|
|
||||||
case 8: // ^H
|
case 8: // ^H
|
||||||
return keyBackspace, b[1:]
|
return keyBackspace, b[1:]
|
||||||
case 11: // ^K
|
case 11: // ^K
|
||||||
@ -278,44 +271,34 @@ func (t *Terminal) moveCursorToPos(pos int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *Terminal) move(up, down, left, right int) {
|
func (t *Terminal) move(up, down, left, right int) {
|
||||||
m := []rune{}
|
movement := make([]rune, 3*(up+down+left+right))
|
||||||
|
m := movement
|
||||||
// 1 unit up can be expressed as ^[[A or ^[A
|
for i := 0; i < up; i++ {
|
||||||
// 5 units up can be expressed as ^[[5A
|
m[0] = keyEscape
|
||||||
|
m[1] = '['
|
||||||
if up == 1 {
|
m[2] = 'A'
|
||||||
m = append(m, keyEscape, '[', 'A')
|
m = m[3:]
|
||||||
} else if up > 1 {
|
}
|
||||||
m = append(m, keyEscape, '[')
|
for i := 0; i < down; i++ {
|
||||||
m = append(m, []rune(strconv.Itoa(up))...)
|
m[0] = keyEscape
|
||||||
m = append(m, 'A')
|
m[1] = '['
|
||||||
|
m[2] = 'B'
|
||||||
|
m = m[3:]
|
||||||
|
}
|
||||||
|
for i := 0; i < left; i++ {
|
||||||
|
m[0] = keyEscape
|
||||||
|
m[1] = '['
|
||||||
|
m[2] = 'D'
|
||||||
|
m = m[3:]
|
||||||
|
}
|
||||||
|
for i := 0; i < right; i++ {
|
||||||
|
m[0] = keyEscape
|
||||||
|
m[1] = '['
|
||||||
|
m[2] = 'C'
|
||||||
|
m = m[3:]
|
||||||
}
|
}
|
||||||
|
|
||||||
if down == 1 {
|
t.queue(movement)
|
||||||
m = append(m, keyEscape, '[', 'B')
|
|
||||||
} else if down > 1 {
|
|
||||||
m = append(m, keyEscape, '[')
|
|
||||||
m = append(m, []rune(strconv.Itoa(down))...)
|
|
||||||
m = append(m, 'B')
|
|
||||||
}
|
|
||||||
|
|
||||||
if right == 1 {
|
|
||||||
m = append(m, keyEscape, '[', 'C')
|
|
||||||
} else if right > 1 {
|
|
||||||
m = append(m, keyEscape, '[')
|
|
||||||
m = append(m, []rune(strconv.Itoa(right))...)
|
|
||||||
m = append(m, 'C')
|
|
||||||
}
|
|
||||||
|
|
||||||
if left == 1 {
|
|
||||||
m = append(m, keyEscape, '[', 'D')
|
|
||||||
} else if left > 1 {
|
|
||||||
m = append(m, keyEscape, '[')
|
|
||||||
m = append(m, []rune(strconv.Itoa(left))...)
|
|
||||||
m = append(m, 'D')
|
|
||||||
}
|
|
||||||
|
|
||||||
t.queue(m)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Terminal) clearLineToRight() {
|
func (t *Terminal) clearLineToRight() {
|
||||||
@ -743,9 +726,6 @@ func (t *Terminal) readLine() (line string, err error) {
|
|||||||
return "", io.EOF
|
return "", io.EOF
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if key == keyCtrlC {
|
|
||||||
return "", io.EOF
|
|
||||||
}
|
|
||||||
if key == keyPasteStart {
|
if key == keyPasteStart {
|
||||||
t.pasteActive = true
|
t.pasteActive = true
|
||||||
if len(t.line) == 0 {
|
if len(t.line) == 0 {
|
||||||
@ -948,8 +928,6 @@ func (s *stRingBuffer) NthPreviousEntry(n int) (value string, ok bool) {
|
|||||||
// readPasswordLine reads from reader until it finds \n or io.EOF.
|
// readPasswordLine reads from reader until it finds \n or io.EOF.
|
||||||
// The slice returned does not include the \n.
|
// The slice returned does not include the \n.
|
||||||
// readPasswordLine also ignores any \r it finds.
|
// readPasswordLine also ignores any \r it finds.
|
||||||
// Windows uses \r as end of line. So, on Windows, readPasswordLine
|
|
||||||
// reads until it finds \r and ignores any \n it finds during processing.
|
|
||||||
func readPasswordLine(reader io.Reader) ([]byte, error) {
|
func readPasswordLine(reader io.Reader) ([]byte, error) {
|
||||||
var buf [1]byte
|
var buf [1]byte
|
||||||
var ret []byte
|
var ret []byte
|
||||||
@ -958,20 +936,10 @@ func readPasswordLine(reader io.Reader) ([]byte, error) {
|
|||||||
n, err := reader.Read(buf[:])
|
n, err := reader.Read(buf[:])
|
||||||
if n > 0 {
|
if n > 0 {
|
||||||
switch buf[0] {
|
switch buf[0] {
|
||||||
case '\b':
|
|
||||||
if len(ret) > 0 {
|
|
||||||
ret = ret[:len(ret)-1]
|
|
||||||
}
|
|
||||||
case '\n':
|
case '\n':
|
||||||
if runtime.GOOS != "windows" {
|
return ret, nil
|
||||||
return ret, nil
|
|
||||||
}
|
|
||||||
// otherwise ignore \n
|
|
||||||
case '\r':
|
case '\r':
|
||||||
if runtime.GOOS == "windows" {
|
// remove \r from passwords on Windows
|
||||||
return ret, nil
|
|
||||||
}
|
|
||||||
// otherwise ignore \r
|
|
||||||
default:
|
default:
|
||||||
ret = append(ret, buf[0])
|
ret = append(ret, buf[0])
|
||||||
}
|
}
|
||||||
|
4
vendor/golang.org/x/crypto/ssh/terminal/util_windows.go
generated
vendored
4
vendor/golang.org/x/crypto/ssh/terminal/util_windows.go
generated
vendored
@ -85,8 +85,8 @@ func ReadPassword(fd int) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
old := st
|
old := st
|
||||||
|
|
||||||
st &^= (windows.ENABLE_ECHO_INPUT | windows.ENABLE_LINE_INPUT)
|
st &^= (windows.ENABLE_ECHO_INPUT)
|
||||||
st |= (windows.ENABLE_PROCESSED_OUTPUT | windows.ENABLE_PROCESSED_INPUT)
|
st |= (windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_LINE_INPUT | windows.ENABLE_PROCESSED_OUTPUT)
|
||||||
if err := windows.SetConsoleMode(windows.Handle(fd), st); err != nil {
|
if err := windows.SetConsoleMode(windows.Handle(fd), st); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
12
vendor/golang.org/x/crypto/ssh/transport.go
generated
vendored
12
vendor/golang.org/x/crypto/ssh/transport.go
generated
vendored
@ -53,14 +53,14 @@ type transport struct {
|
|||||||
// packetCipher represents a combination of SSH encryption/MAC
|
// packetCipher represents a combination of SSH encryption/MAC
|
||||||
// protocol. A single instance should be used for one direction only.
|
// protocol. A single instance should be used for one direction only.
|
||||||
type packetCipher interface {
|
type packetCipher interface {
|
||||||
// writeCipherPacket encrypts the packet and writes it to w. The
|
// writePacket encrypts the packet and writes it to w. The
|
||||||
// contents of the packet are generally scrambled.
|
// contents of the packet are generally scrambled.
|
||||||
writeCipherPacket(seqnum uint32, w io.Writer, rand io.Reader, packet []byte) error
|
writePacket(seqnum uint32, w io.Writer, rand io.Reader, packet []byte) error
|
||||||
|
|
||||||
// readCipherPacket reads and decrypts a packet of data. The
|
// readPacket reads and decrypts a packet of data. The
|
||||||
// returned packet may be overwritten by future calls of
|
// returned packet may be overwritten by future calls of
|
||||||
// readPacket.
|
// readPacket.
|
||||||
readCipherPacket(seqnum uint32, r io.Reader) ([]byte, error)
|
readPacket(seqnum uint32, r io.Reader) ([]byte, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// connectionState represents one side (read or write) of the
|
// connectionState represents one side (read or write) of the
|
||||||
@ -127,7 +127,7 @@ func (t *transport) readPacket() (p []byte, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *connectionState) readPacket(r *bufio.Reader) ([]byte, error) {
|
func (s *connectionState) readPacket(r *bufio.Reader) ([]byte, error) {
|
||||||
packet, err := s.packetCipher.readCipherPacket(s.seqNum, r)
|
packet, err := s.packetCipher.readPacket(s.seqNum, r)
|
||||||
s.seqNum++
|
s.seqNum++
|
||||||
if err == nil && len(packet) == 0 {
|
if err == nil && len(packet) == 0 {
|
||||||
err = errors.New("ssh: zero length packet")
|
err = errors.New("ssh: zero length packet")
|
||||||
@ -175,7 +175,7 @@ func (t *transport) writePacket(packet []byte) error {
|
|||||||
func (s *connectionState) writePacket(w *bufio.Writer, rand io.Reader, packet []byte) error {
|
func (s *connectionState) writePacket(w *bufio.Writer, rand io.Reader, packet []byte) error {
|
||||||
changeKeys := len(packet) > 0 && packet[0] == msgNewKeys
|
changeKeys := len(packet) > 0 && packet[0] == msgNewKeys
|
||||||
|
|
||||||
err := s.packetCipher.writeCipherPacket(s.seqNum, w, rand, packet)
|
err := s.packetCipher.writePacket(s.seqNum, w, rand, packet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
1
vendor/golang.org/x/net/html/const.go
generated
vendored
1
vendor/golang.org/x/net/html/const.go
generated
vendored
@ -52,6 +52,7 @@ var isSpecialElementMap = map[string]bool{
|
|||||||
"iframe": true,
|
"iframe": true,
|
||||||
"img": true,
|
"img": true,
|
||||||
"input": true,
|
"input": true,
|
||||||
|
"isindex": true, // The 'isindex' element has been removed, but keep it for backwards compatibility.
|
||||||
"keygen": true,
|
"keygen": true,
|
||||||
"li": true,
|
"li": true,
|
||||||
"link": true,
|
"link": true,
|
||||||
|
1
vendor/golang.org/x/net/html/foreign.go
generated
vendored
1
vendor/golang.org/x/net/html/foreign.go
generated
vendored
@ -172,6 +172,7 @@ var svgAttributeAdjustments = map[string]string{
|
|||||||
"diffuseconstant": "diffuseConstant",
|
"diffuseconstant": "diffuseConstant",
|
||||||
"edgemode": "edgeMode",
|
"edgemode": "edgeMode",
|
||||||
"externalresourcesrequired": "externalResourcesRequired",
|
"externalresourcesrequired": "externalResourcesRequired",
|
||||||
|
"filterres": "filterRes",
|
||||||
"filterunits": "filterUnits",
|
"filterunits": "filterUnits",
|
||||||
"glyphref": "glyphRef",
|
"glyphref": "glyphRef",
|
||||||
"gradienttransform": "gradientTransform",
|
"gradienttransform": "gradientTransform",
|
||||||
|
5
vendor/golang.org/x/net/html/node.go
generated
vendored
5
vendor/golang.org/x/net/html/node.go
generated
vendored
@ -18,11 +18,6 @@ const (
|
|||||||
ElementNode
|
ElementNode
|
||||||
CommentNode
|
CommentNode
|
||||||
DoctypeNode
|
DoctypeNode
|
||||||
// RawNode nodes are not returned by the parser, but can be part of the
|
|
||||||
// Node tree passed to func Render to insert raw HTML (without escaping).
|
|
||||||
// If so, this package makes no guarantee that the rendered HTML is secure
|
|
||||||
// (from e.g. Cross Site Scripting attacks) or well-formed.
|
|
||||||
RawNode
|
|
||||||
scopeMarkerNode
|
scopeMarkerNode
|
||||||
)
|
)
|
||||||
|
|
||||||
|
304
vendor/golang.org/x/net/html/parse.go
generated
vendored
304
vendor/golang.org/x/net/html/parse.go
generated
vendored
@ -184,17 +184,6 @@ func (p *parser) clearStackToContext(s scope) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseGenericRawTextElements implements the generic raw text element parsing
|
|
||||||
// algorithm defined in 12.2.6.2.
|
|
||||||
// https://html.spec.whatwg.org/multipage/parsing.html#parsing-elements-that-contain-only-text
|
|
||||||
// TODO: Since both RAWTEXT and RCDATA states are treated as tokenizer's part
|
|
||||||
// officially, need to make tokenizer consider both states.
|
|
||||||
func (p *parser) parseGenericRawTextElement() {
|
|
||||||
p.addElement()
|
|
||||||
p.originalIM = p.im
|
|
||||||
p.im = textIM
|
|
||||||
}
|
|
||||||
|
|
||||||
// generateImpliedEndTags pops nodes off the stack of open elements as long as
|
// generateImpliedEndTags pops nodes off the stack of open elements as long as
|
||||||
// the top node has a tag name of dd, dt, li, optgroup, option, p, rb, rp, rt or rtc.
|
// the top node has a tag name of dd, dt, li, optgroup, option, p, rb, rp, rt or rtc.
|
||||||
// If exceptions are specified, nodes with that name will not be popped off.
|
// If exceptions are specified, nodes with that name will not be popped off.
|
||||||
@ -203,17 +192,16 @@ func (p *parser) generateImpliedEndTags(exceptions ...string) {
|
|||||||
loop:
|
loop:
|
||||||
for i = len(p.oe) - 1; i >= 0; i-- {
|
for i = len(p.oe) - 1; i >= 0; i-- {
|
||||||
n := p.oe[i]
|
n := p.oe[i]
|
||||||
if n.Type != ElementNode {
|
if n.Type == ElementNode {
|
||||||
break
|
switch n.DataAtom {
|
||||||
}
|
case a.Dd, a.Dt, a.Li, a.Optgroup, a.Option, a.P, a.Rb, a.Rp, a.Rt, a.Rtc:
|
||||||
switch n.DataAtom {
|
for _, except := range exceptions {
|
||||||
case a.Dd, a.Dt, a.Li, a.Optgroup, a.Option, a.P, a.Rb, a.Rp, a.Rt, a.Rtc:
|
if n.Data == except {
|
||||||
for _, except := range exceptions {
|
break loop
|
||||||
if n.Data == except {
|
}
|
||||||
break loop
|
|
||||||
}
|
}
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -381,7 +369,8 @@ findIdenticalElements:
|
|||||||
// Section 12.2.4.3.
|
// Section 12.2.4.3.
|
||||||
func (p *parser) clearActiveFormattingElements() {
|
func (p *parser) clearActiveFormattingElements() {
|
||||||
for {
|
for {
|
||||||
if n := p.afe.pop(); len(p.afe) == 0 || n.Type == scopeMarkerNode {
|
n := p.afe.pop()
|
||||||
|
if len(p.afe) == 0 || n.Type == scopeMarkerNode {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -636,29 +625,25 @@ func inHeadIM(p *parser) bool {
|
|||||||
switch p.tok.DataAtom {
|
switch p.tok.DataAtom {
|
||||||
case a.Html:
|
case a.Html:
|
||||||
return inBodyIM(p)
|
return inBodyIM(p)
|
||||||
case a.Base, a.Basefont, a.Bgsound, a.Link, a.Meta:
|
case a.Base, a.Basefont, a.Bgsound, a.Command, a.Link, a.Meta:
|
||||||
p.addElement()
|
p.addElement()
|
||||||
p.oe.pop()
|
p.oe.pop()
|
||||||
p.acknowledgeSelfClosingTag()
|
p.acknowledgeSelfClosingTag()
|
||||||
return true
|
return true
|
||||||
case a.Noscript:
|
case a.Noscript:
|
||||||
if p.scripting {
|
|
||||||
p.parseGenericRawTextElement()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
p.addElement()
|
p.addElement()
|
||||||
p.im = inHeadNoscriptIM
|
if p.scripting {
|
||||||
// Don't let the tokenizer go into raw text mode when scripting is disabled.
|
p.setOriginalIM()
|
||||||
p.tokenizer.NextIsNotRawText()
|
p.im = textIM
|
||||||
|
} else {
|
||||||
|
p.im = inHeadNoscriptIM
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
case a.Script, a.Title:
|
case a.Script, a.Title, a.Noframes, a.Style:
|
||||||
p.addElement()
|
p.addElement()
|
||||||
p.setOriginalIM()
|
p.setOriginalIM()
|
||||||
p.im = textIM
|
p.im = textIM
|
||||||
return true
|
return true
|
||||||
case a.Noframes, a.Style:
|
|
||||||
p.parseGenericRawTextElement()
|
|
||||||
return true
|
|
||||||
case a.Head:
|
case a.Head:
|
||||||
// Ignore the token.
|
// Ignore the token.
|
||||||
return true
|
return true
|
||||||
@ -870,7 +855,7 @@ func inBodyIM(p *parser) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
copyAttributes(p.oe[0], p.tok)
|
copyAttributes(p.oe[0], p.tok)
|
||||||
case a.Base, a.Basefont, a.Bgsound, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Template, a.Title:
|
case a.Base, a.Basefont, a.Bgsound, a.Command, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Template, a.Title:
|
||||||
return inHeadIM(p)
|
return inHeadIM(p)
|
||||||
case a.Body:
|
case a.Body:
|
||||||
if p.oe.contains(a.Template) {
|
if p.oe.contains(a.Template) {
|
||||||
@ -896,7 +881,7 @@ func inBodyIM(p *parser) bool {
|
|||||||
p.addElement()
|
p.addElement()
|
||||||
p.im = inFramesetIM
|
p.im = inFramesetIM
|
||||||
return true
|
return true
|
||||||
case a.Address, a.Article, a.Aside, a.Blockquote, a.Center, a.Details, a.Dialog, a.Dir, a.Div, a.Dl, a.Fieldset, a.Figcaption, a.Figure, a.Footer, a.Header, a.Hgroup, a.Main, a.Menu, a.Nav, a.Ol, a.P, a.Section, a.Summary, a.Ul:
|
case a.Address, a.Article, a.Aside, a.Blockquote, a.Center, a.Details, a.Dir, a.Div, a.Dl, a.Fieldset, a.Figcaption, a.Figure, a.Footer, a.Header, a.Hgroup, a.Menu, a.Nav, a.Ol, a.P, a.Section, a.Summary, a.Ul:
|
||||||
p.popUntil(buttonScope, a.P)
|
p.popUntil(buttonScope, a.P)
|
||||||
p.addElement()
|
p.addElement()
|
||||||
case a.H1, a.H2, a.H3, a.H4, a.H5, a.H6:
|
case a.H1, a.H2, a.H3, a.H4, a.H5, a.H6:
|
||||||
@ -1029,6 +1014,53 @@ func inBodyIM(p *parser) bool {
|
|||||||
p.tok.DataAtom = a.Img
|
p.tok.DataAtom = a.Img
|
||||||
p.tok.Data = a.Img.String()
|
p.tok.Data = a.Img.String()
|
||||||
return false
|
return false
|
||||||
|
case a.Isindex:
|
||||||
|
if p.form != nil {
|
||||||
|
// Ignore the token.
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
action := ""
|
||||||
|
prompt := "This is a searchable index. Enter search keywords: "
|
||||||
|
attr := []Attribute{{Key: "name", Val: "isindex"}}
|
||||||
|
for _, t := range p.tok.Attr {
|
||||||
|
switch t.Key {
|
||||||
|
case "action":
|
||||||
|
action = t.Val
|
||||||
|
case "name":
|
||||||
|
// Ignore the attribute.
|
||||||
|
case "prompt":
|
||||||
|
prompt = t.Val
|
||||||
|
default:
|
||||||
|
attr = append(attr, t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p.acknowledgeSelfClosingTag()
|
||||||
|
p.popUntil(buttonScope, a.P)
|
||||||
|
p.parseImpliedToken(StartTagToken, a.Form, a.Form.String())
|
||||||
|
if p.form == nil {
|
||||||
|
// NOTE: The 'isindex' element has been removed,
|
||||||
|
// and the 'template' element has not been designed to be
|
||||||
|
// collaborative with the index element.
|
||||||
|
//
|
||||||
|
// Ignore the token.
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if action != "" {
|
||||||
|
p.form.Attr = []Attribute{{Key: "action", Val: action}}
|
||||||
|
}
|
||||||
|
p.parseImpliedToken(StartTagToken, a.Hr, a.Hr.String())
|
||||||
|
p.parseImpliedToken(StartTagToken, a.Label, a.Label.String())
|
||||||
|
p.addText(prompt)
|
||||||
|
p.addChild(&Node{
|
||||||
|
Type: ElementNode,
|
||||||
|
DataAtom: a.Input,
|
||||||
|
Data: a.Input.String(),
|
||||||
|
Attr: attr,
|
||||||
|
})
|
||||||
|
p.oe.pop()
|
||||||
|
p.parseImpliedToken(EndTagToken, a.Label, a.Label.String())
|
||||||
|
p.parseImpliedToken(StartTagToken, a.Hr, a.Hr.String())
|
||||||
|
p.parseImpliedToken(EndTagToken, a.Form, a.Form.String())
|
||||||
case a.Textarea:
|
case a.Textarea:
|
||||||
p.addElement()
|
p.addElement()
|
||||||
p.setOriginalIM()
|
p.setOriginalIM()
|
||||||
@ -1038,21 +1070,18 @@ func inBodyIM(p *parser) bool {
|
|||||||
p.popUntil(buttonScope, a.P)
|
p.popUntil(buttonScope, a.P)
|
||||||
p.reconstructActiveFormattingElements()
|
p.reconstructActiveFormattingElements()
|
||||||
p.framesetOK = false
|
p.framesetOK = false
|
||||||
p.parseGenericRawTextElement()
|
p.addElement()
|
||||||
|
p.setOriginalIM()
|
||||||
|
p.im = textIM
|
||||||
case a.Iframe:
|
case a.Iframe:
|
||||||
p.framesetOK = false
|
p.framesetOK = false
|
||||||
p.parseGenericRawTextElement()
|
|
||||||
case a.Noembed:
|
|
||||||
p.parseGenericRawTextElement()
|
|
||||||
case a.Noscript:
|
|
||||||
if p.scripting {
|
|
||||||
p.parseGenericRawTextElement()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
p.reconstructActiveFormattingElements()
|
|
||||||
p.addElement()
|
p.addElement()
|
||||||
// Don't let the tokenizer go into raw text mode when scripting is disabled.
|
p.setOriginalIM()
|
||||||
p.tokenizer.NextIsNotRawText()
|
p.im = textIM
|
||||||
|
case a.Noembed, a.Noscript:
|
||||||
|
p.addElement()
|
||||||
|
p.setOriginalIM()
|
||||||
|
p.im = textIM
|
||||||
case a.Select:
|
case a.Select:
|
||||||
p.reconstructActiveFormattingElements()
|
p.reconstructActiveFormattingElements()
|
||||||
p.addElement()
|
p.addElement()
|
||||||
@ -1108,7 +1137,7 @@ func inBodyIM(p *parser) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
case a.Address, a.Article, a.Aside, a.Blockquote, a.Button, a.Center, a.Details, a.Dialog, a.Dir, a.Div, a.Dl, a.Fieldset, a.Figcaption, a.Figure, a.Footer, a.Header, a.Hgroup, a.Listing, a.Main, a.Menu, a.Nav, a.Ol, a.Pre, a.Section, a.Summary, a.Ul:
|
case a.Address, a.Article, a.Aside, a.Blockquote, a.Button, a.Center, a.Details, a.Dir, a.Div, a.Dl, a.Fieldset, a.Figcaption, a.Figure, a.Footer, a.Header, a.Hgroup, a.Listing, a.Menu, a.Nav, a.Ol, a.Pre, a.Section, a.Summary, a.Ul:
|
||||||
p.popUntil(defaultScope, p.tok.DataAtom)
|
p.popUntil(defaultScope, p.tok.DataAtom)
|
||||||
case a.Form:
|
case a.Form:
|
||||||
if p.oe.contains(a.Template) {
|
if p.oe.contains(a.Template) {
|
||||||
@ -1169,13 +1198,14 @@ func inBodyIM(p *parser) bool {
|
|||||||
if len(p.templateStack) > 0 {
|
if len(p.templateStack) > 0 {
|
||||||
p.im = inTemplateIM
|
p.im = inTemplateIM
|
||||||
return false
|
return false
|
||||||
}
|
} else {
|
||||||
for _, e := range p.oe {
|
for _, e := range p.oe {
|
||||||
switch e.DataAtom {
|
switch e.DataAtom {
|
||||||
case a.Dd, a.Dt, a.Li, a.Optgroup, a.Option, a.P, a.Rb, a.Rp, a.Rt, a.Rtc, a.Tbody, a.Td, a.Tfoot, a.Th,
|
case a.Dd, a.Dt, a.Li, a.Optgroup, a.Option, a.P, a.Rb, a.Rp, a.Rt, a.Rtc, a.Tbody, a.Td, a.Tfoot, a.Th,
|
||||||
a.Thead, a.Tr, a.Body, a.Html:
|
a.Thead, a.Tr, a.Body, a.Html:
|
||||||
default:
|
default:
|
||||||
return true
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1191,15 +1221,9 @@ func (p *parser) inBodyEndTagFormatting(tagAtom a.Atom, tagName string) {
|
|||||||
// Once the code successfully parses the comprehensive test suite, we should
|
// Once the code successfully parses the comprehensive test suite, we should
|
||||||
// refactor this code to be more idiomatic.
|
// refactor this code to be more idiomatic.
|
||||||
|
|
||||||
// Steps 1-2
|
// Steps 1-4. The outer loop.
|
||||||
if current := p.oe.top(); current.Data == tagName && p.afe.index(current) == -1 {
|
|
||||||
p.oe.pop()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Steps 3-5. The outer loop.
|
|
||||||
for i := 0; i < 8; i++ {
|
for i := 0; i < 8; i++ {
|
||||||
// Step 6. Find the formatting element.
|
// Step 5. Find the formatting element.
|
||||||
var formattingElement *Node
|
var formattingElement *Node
|
||||||
for j := len(p.afe) - 1; j >= 0; j-- {
|
for j := len(p.afe) - 1; j >= 0; j-- {
|
||||||
if p.afe[j].Type == scopeMarkerNode {
|
if p.afe[j].Type == scopeMarkerNode {
|
||||||
@ -1214,22 +1238,17 @@ func (p *parser) inBodyEndTagFormatting(tagAtom a.Atom, tagName string) {
|
|||||||
p.inBodyEndTagOther(tagAtom, tagName)
|
p.inBodyEndTagOther(tagAtom, tagName)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 7. Ignore the tag if formatting element is not in the stack of open elements.
|
|
||||||
feIndex := p.oe.index(formattingElement)
|
feIndex := p.oe.index(formattingElement)
|
||||||
if feIndex == -1 {
|
if feIndex == -1 {
|
||||||
p.afe.remove(formattingElement)
|
p.afe.remove(formattingElement)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Step 8. Ignore the tag if formatting element is not in the scope.
|
|
||||||
if !p.elementInScope(defaultScope, tagAtom) {
|
if !p.elementInScope(defaultScope, tagAtom) {
|
||||||
// Ignore the tag.
|
// Ignore the tag.
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 9. This step is omitted because it's just a parse error but no need to return.
|
// Steps 9-10. Find the furthest block.
|
||||||
|
|
||||||
// Steps 10-11. Find the furthest block.
|
|
||||||
var furthestBlock *Node
|
var furthestBlock *Node
|
||||||
for _, e := range p.oe[feIndex:] {
|
for _, e := range p.oe[feIndex:] {
|
||||||
if isSpecialElement(e) {
|
if isSpecialElement(e) {
|
||||||
@ -1246,65 +1265,47 @@ func (p *parser) inBodyEndTagFormatting(tagAtom a.Atom, tagName string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Steps 12-13. Find the common ancestor and bookmark node.
|
// Steps 11-12. Find the common ancestor and bookmark node.
|
||||||
commonAncestor := p.oe[feIndex-1]
|
commonAncestor := p.oe[feIndex-1]
|
||||||
bookmark := p.afe.index(formattingElement)
|
bookmark := p.afe.index(formattingElement)
|
||||||
|
|
||||||
// Step 14. The inner loop. Find the lastNode to reparent.
|
// Step 13. The inner loop. Find the lastNode to reparent.
|
||||||
lastNode := furthestBlock
|
lastNode := furthestBlock
|
||||||
node := furthestBlock
|
node := furthestBlock
|
||||||
x := p.oe.index(node)
|
x := p.oe.index(node)
|
||||||
// Step 14.1.
|
// Steps 13.1-13.2
|
||||||
j := 0
|
for j := 0; j < 3; j++ {
|
||||||
for {
|
// Step 13.3.
|
||||||
// Step 14.2.
|
|
||||||
j++
|
|
||||||
// Step. 14.3.
|
|
||||||
x--
|
x--
|
||||||
node = p.oe[x]
|
node = p.oe[x]
|
||||||
// Step 14.4. Go to the next step if node is formatting element.
|
// Step 13.4 - 13.5.
|
||||||
if node == formattingElement {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
// Step 14.5. Remove node from the list of active formatting elements if
|
|
||||||
// inner loop counter is greater than three and node is in the list of
|
|
||||||
// active formatting elements.
|
|
||||||
if ni := p.afe.index(node); j > 3 && ni > -1 {
|
|
||||||
p.afe.remove(node)
|
|
||||||
// If any element of the list of active formatting elements is removed,
|
|
||||||
// we need to take care whether bookmark should be decremented or not.
|
|
||||||
// This is because the value of bookmark may exceed the size of the
|
|
||||||
// list by removing elements from the list.
|
|
||||||
if ni <= bookmark {
|
|
||||||
bookmark--
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// Step 14.6. Continue the next inner loop if node is not in the list of
|
|
||||||
// active formatting elements.
|
|
||||||
if p.afe.index(node) == -1 {
|
if p.afe.index(node) == -1 {
|
||||||
p.oe.remove(node)
|
p.oe.remove(node)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// Step 14.7.
|
// Step 13.6.
|
||||||
|
if node == formattingElement {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
// Step 13.7.
|
||||||
clone := node.clone()
|
clone := node.clone()
|
||||||
p.afe[p.afe.index(node)] = clone
|
p.afe[p.afe.index(node)] = clone
|
||||||
p.oe[p.oe.index(node)] = clone
|
p.oe[p.oe.index(node)] = clone
|
||||||
node = clone
|
node = clone
|
||||||
// Step 14.8.
|
// Step 13.8.
|
||||||
if lastNode == furthestBlock {
|
if lastNode == furthestBlock {
|
||||||
bookmark = p.afe.index(node) + 1
|
bookmark = p.afe.index(node) + 1
|
||||||
}
|
}
|
||||||
// Step 14.9.
|
// Step 13.9.
|
||||||
if lastNode.Parent != nil {
|
if lastNode.Parent != nil {
|
||||||
lastNode.Parent.RemoveChild(lastNode)
|
lastNode.Parent.RemoveChild(lastNode)
|
||||||
}
|
}
|
||||||
node.AppendChild(lastNode)
|
node.AppendChild(lastNode)
|
||||||
// Step 14.10.
|
// Step 13.10.
|
||||||
lastNode = node
|
lastNode = node
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 15. Reparent lastNode to the common ancestor,
|
// Step 14. Reparent lastNode to the common ancestor,
|
||||||
// or for misnested table nodes, to the foster parent.
|
// or for misnested table nodes, to the foster parent.
|
||||||
if lastNode.Parent != nil {
|
if lastNode.Parent != nil {
|
||||||
lastNode.Parent.RemoveChild(lastNode)
|
lastNode.Parent.RemoveChild(lastNode)
|
||||||
@ -1316,13 +1317,13 @@ func (p *parser) inBodyEndTagFormatting(tagAtom a.Atom, tagName string) {
|
|||||||
commonAncestor.AppendChild(lastNode)
|
commonAncestor.AppendChild(lastNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Steps 16-18. Reparent nodes from the furthest block's children
|
// Steps 15-17. Reparent nodes from the furthest block's children
|
||||||
// to a clone of the formatting element.
|
// to a clone of the formatting element.
|
||||||
clone := formattingElement.clone()
|
clone := formattingElement.clone()
|
||||||
reparentChildren(clone, furthestBlock)
|
reparentChildren(clone, furthestBlock)
|
||||||
furthestBlock.AppendChild(clone)
|
furthestBlock.AppendChild(clone)
|
||||||
|
|
||||||
// Step 19. Fix up the list of active formatting elements.
|
// Step 18. Fix up the list of active formatting elements.
|
||||||
if oldLoc := p.afe.index(formattingElement); oldLoc != -1 && oldLoc < bookmark {
|
if oldLoc := p.afe.index(formattingElement); oldLoc != -1 && oldLoc < bookmark {
|
||||||
// Move the bookmark with the rest of the list.
|
// Move the bookmark with the rest of the list.
|
||||||
bookmark--
|
bookmark--
|
||||||
@ -1330,7 +1331,7 @@ func (p *parser) inBodyEndTagFormatting(tagAtom a.Atom, tagName string) {
|
|||||||
p.afe.remove(formattingElement)
|
p.afe.remove(formattingElement)
|
||||||
p.afe.insert(bookmark, clone)
|
p.afe.insert(bookmark, clone)
|
||||||
|
|
||||||
// Step 20. Fix up the stack of open elements.
|
// Step 19. Fix up the stack of open elements.
|
||||||
p.oe.remove(formattingElement)
|
p.oe.remove(formattingElement)
|
||||||
p.oe.insert(p.oe.index(furthestBlock)+1, clone)
|
p.oe.insert(p.oe.index(furthestBlock)+1, clone)
|
||||||
}
|
}
|
||||||
@ -1501,13 +1502,14 @@ func inCaptionIM(p *parser) bool {
|
|||||||
case StartTagToken:
|
case StartTagToken:
|
||||||
switch p.tok.DataAtom {
|
switch p.tok.DataAtom {
|
||||||
case a.Caption, a.Col, a.Colgroup, a.Tbody, a.Td, a.Tfoot, a.Thead, a.Tr:
|
case a.Caption, a.Col, a.Colgroup, a.Tbody, a.Td, a.Tfoot, a.Thead, a.Tr:
|
||||||
if !p.popUntil(tableScope, a.Caption) {
|
if p.popUntil(tableScope, a.Caption) {
|
||||||
|
p.clearActiveFormattingElements()
|
||||||
|
p.im = inTableIM
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
// Ignore the token.
|
// Ignore the token.
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
p.clearActiveFormattingElements()
|
|
||||||
p.im = inTableIM
|
|
||||||
return false
|
|
||||||
case a.Select:
|
case a.Select:
|
||||||
p.reconstructActiveFormattingElements()
|
p.reconstructActiveFormattingElements()
|
||||||
p.addElement()
|
p.addElement()
|
||||||
@ -1524,13 +1526,14 @@ func inCaptionIM(p *parser) bool {
|
|||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
case a.Table:
|
case a.Table:
|
||||||
if !p.popUntil(tableScope, a.Caption) {
|
if p.popUntil(tableScope, a.Caption) {
|
||||||
|
p.clearActiveFormattingElements()
|
||||||
|
p.im = inTableIM
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
// Ignore the token.
|
// Ignore the token.
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
p.clearActiveFormattingElements()
|
|
||||||
p.im = inTableIM
|
|
||||||
return false
|
|
||||||
case a.Body, a.Col, a.Colgroup, a.Html, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr:
|
case a.Body, a.Col, a.Colgroup, a.Html, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr:
|
||||||
// Ignore the token.
|
// Ignore the token.
|
||||||
return true
|
return true
|
||||||
@ -1774,11 +1777,12 @@ func inSelectIM(p *parser) bool {
|
|||||||
}
|
}
|
||||||
p.addElement()
|
p.addElement()
|
||||||
case a.Select:
|
case a.Select:
|
||||||
if !p.popUntil(selectScope, a.Select) {
|
if p.popUntil(selectScope, a.Select) {
|
||||||
|
p.resetInsertionMode()
|
||||||
|
} else {
|
||||||
// Ignore the token.
|
// Ignore the token.
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
p.resetInsertionMode()
|
|
||||||
case a.Input, a.Keygen, a.Textarea:
|
case a.Input, a.Keygen, a.Textarea:
|
||||||
if p.elementInScope(selectScope, a.Select) {
|
if p.elementInScope(selectScope, a.Select) {
|
||||||
p.parseImpliedToken(EndTagToken, a.Select, a.Select.String())
|
p.parseImpliedToken(EndTagToken, a.Select, a.Select.String())
|
||||||
@ -1806,11 +1810,12 @@ func inSelectIM(p *parser) bool {
|
|||||||
p.oe = p.oe[:i]
|
p.oe = p.oe[:i]
|
||||||
}
|
}
|
||||||
case a.Select:
|
case a.Select:
|
||||||
if !p.popUntil(selectScope, a.Select) {
|
if p.popUntil(selectScope, a.Select) {
|
||||||
|
p.resetInsertionMode()
|
||||||
|
} else {
|
||||||
// Ignore the token.
|
// Ignore the token.
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
p.resetInsertionMode()
|
|
||||||
case a.Template:
|
case a.Template:
|
||||||
return inHeadIM(p)
|
return inHeadIM(p)
|
||||||
}
|
}
|
||||||
@ -2131,31 +2136,28 @@ func parseForeignContent(p *parser) bool {
|
|||||||
Data: p.tok.Data,
|
Data: p.tok.Data,
|
||||||
})
|
})
|
||||||
case StartTagToken:
|
case StartTagToken:
|
||||||
if !p.fragment {
|
b := breakout[p.tok.Data]
|
||||||
b := breakout[p.tok.Data]
|
if p.tok.DataAtom == a.Font {
|
||||||
if p.tok.DataAtom == a.Font {
|
loop:
|
||||||
loop:
|
for _, attr := range p.tok.Attr {
|
||||||
for _, attr := range p.tok.Attr {
|
switch attr.Key {
|
||||||
switch attr.Key {
|
case "color", "face", "size":
|
||||||
case "color", "face", "size":
|
b = true
|
||||||
b = true
|
break loop
|
||||||
break loop
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if b {
|
|
||||||
for i := len(p.oe) - 1; i >= 0; i-- {
|
|
||||||
n := p.oe[i]
|
|
||||||
if n.Namespace == "" || htmlIntegrationPoint(n) || mathMLTextIntegrationPoint(n) {
|
|
||||||
p.oe = p.oe[:i+1]
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
current := p.adjustedCurrentNode()
|
if b {
|
||||||
switch current.Namespace {
|
for i := len(p.oe) - 1; i >= 0; i-- {
|
||||||
|
n := p.oe[i]
|
||||||
|
if n.Namespace == "" || htmlIntegrationPoint(n) || mathMLTextIntegrationPoint(n) {
|
||||||
|
p.oe = p.oe[:i+1]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
switch p.top().Namespace {
|
||||||
case "math":
|
case "math":
|
||||||
adjustAttributeNames(p.tok.Attr, mathMLAttributeAdjustments)
|
adjustAttributeNames(p.tok.Attr, mathMLAttributeAdjustments)
|
||||||
case "svg":
|
case "svg":
|
||||||
@ -2170,7 +2172,7 @@ func parseForeignContent(p *parser) bool {
|
|||||||
panic("html: bad parser state: unexpected namespace")
|
panic("html: bad parser state: unexpected namespace")
|
||||||
}
|
}
|
||||||
adjustForeignAttributes(p.tok.Attr)
|
adjustForeignAttributes(p.tok.Attr)
|
||||||
namespace := current.Namespace
|
namespace := p.top().Namespace
|
||||||
p.addElement()
|
p.addElement()
|
||||||
p.top().Namespace = namespace
|
p.top().Namespace = namespace
|
||||||
if namespace != "" {
|
if namespace != "" {
|
||||||
@ -2199,20 +2201,12 @@ func parseForeignContent(p *parser) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Section 12.2.4.2.
|
|
||||||
func (p *parser) adjustedCurrentNode() *Node {
|
|
||||||
if len(p.oe) == 1 && p.fragment && p.context != nil {
|
|
||||||
return p.context
|
|
||||||
}
|
|
||||||
return p.oe.top()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Section 12.2.6.
|
// Section 12.2.6.
|
||||||
func (p *parser) inForeignContent() bool {
|
func (p *parser) inForeignContent() bool {
|
||||||
if len(p.oe) == 0 {
|
if len(p.oe) == 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
n := p.adjustedCurrentNode()
|
n := p.oe[len(p.oe)-1]
|
||||||
if n.Namespace == "" {
|
if n.Namespace == "" {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -2347,7 +2341,8 @@ func ParseWithOptions(r io.Reader, opts ...ParseOption) (*Node, error) {
|
|||||||
f(p)
|
f(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := p.parse(); err != nil {
|
err := p.parse()
|
||||||
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return p.doc, nil
|
return p.doc, nil
|
||||||
@ -2369,6 +2364,7 @@ func ParseFragmentWithOptions(r io.Reader, context *Node, opts ...ParseOption) (
|
|||||||
contextTag = context.DataAtom.String()
|
contextTag = context.DataAtom.String()
|
||||||
}
|
}
|
||||||
p := &parser{
|
p := &parser{
|
||||||
|
tokenizer: NewTokenizerFragment(r, contextTag),
|
||||||
doc: &Node{
|
doc: &Node{
|
||||||
Type: DocumentNode,
|
Type: DocumentNode,
|
||||||
},
|
},
|
||||||
@ -2376,11 +2372,6 @@ func ParseFragmentWithOptions(r io.Reader, context *Node, opts ...ParseOption) (
|
|||||||
fragment: true,
|
fragment: true,
|
||||||
context: context,
|
context: context,
|
||||||
}
|
}
|
||||||
if context != nil && context.Namespace != "" {
|
|
||||||
p.tokenizer = NewTokenizer(r)
|
|
||||||
} else {
|
|
||||||
p.tokenizer = NewTokenizerFragment(r, contextTag)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, f := range opts {
|
for _, f := range opts {
|
||||||
f(p)
|
f(p)
|
||||||
@ -2405,7 +2396,8 @@ func ParseFragmentWithOptions(r io.Reader, context *Node, opts ...ParseOption) (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := p.parse(); err != nil {
|
err := p.parse()
|
||||||
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
34
vendor/golang.org/x/net/html/render.go
generated
vendored
34
vendor/golang.org/x/net/html/render.go
generated
vendored
@ -134,9 +134,6 @@ func render1(w writer, n *Node) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return w.WriteByte('>')
|
return w.WriteByte('>')
|
||||||
case RawNode:
|
|
||||||
_, err := w.WriteString(n.Data)
|
|
||||||
return err
|
|
||||||
default:
|
default:
|
||||||
return errors.New("html: unknown node type")
|
return errors.New("html: unknown node type")
|
||||||
}
|
}
|
||||||
@ -255,19 +252,20 @@ func writeQuoted(w writer, s string) error {
|
|||||||
// Section 12.1.2, "Elements", gives this list of void elements. Void elements
|
// Section 12.1.2, "Elements", gives this list of void elements. Void elements
|
||||||
// are those that can't have any contents.
|
// are those that can't have any contents.
|
||||||
var voidElements = map[string]bool{
|
var voidElements = map[string]bool{
|
||||||
"area": true,
|
"area": true,
|
||||||
"base": true,
|
"base": true,
|
||||||
"br": true,
|
"br": true,
|
||||||
"col": true,
|
"col": true,
|
||||||
"embed": true,
|
"command": true,
|
||||||
"hr": true,
|
"embed": true,
|
||||||
"img": true,
|
"hr": true,
|
||||||
"input": true,
|
"img": true,
|
||||||
"keygen": true,
|
"input": true,
|
||||||
"link": true,
|
"keygen": true,
|
||||||
"meta": true,
|
"link": true,
|
||||||
"param": true,
|
"meta": true,
|
||||||
"source": true,
|
"param": true,
|
||||||
"track": true,
|
"source": true,
|
||||||
"wbr": true,
|
"track": true,
|
||||||
|
"wbr": true,
|
||||||
}
|
}
|
||||||
|
9
vendor/golang.org/x/net/html/token.go
generated
vendored
9
vendor/golang.org/x/net/html/token.go
generated
vendored
@ -296,7 +296,8 @@ func (z *Tokenizer) Buffered() []byte {
|
|||||||
// too many times in succession.
|
// too many times in succession.
|
||||||
func readAtLeastOneByte(r io.Reader, b []byte) (int, error) {
|
func readAtLeastOneByte(r io.Reader, b []byte) (int, error) {
|
||||||
for i := 0; i < 100; i++ {
|
for i := 0; i < 100; i++ {
|
||||||
if n, err := r.Read(b); n != 0 || err != nil {
|
n, err := r.Read(b)
|
||||||
|
if n != 0 || err != nil {
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -346,7 +347,6 @@ loop:
|
|||||||
break loop
|
break loop
|
||||||
}
|
}
|
||||||
if c != '/' {
|
if c != '/' {
|
||||||
z.raw.end--
|
|
||||||
continue loop
|
continue loop
|
||||||
}
|
}
|
||||||
if z.readRawEndTag() || z.err != nil {
|
if z.readRawEndTag() || z.err != nil {
|
||||||
@ -1067,11 +1067,6 @@ loop:
|
|||||||
|
|
||||||
// Raw returns the unmodified text of the current token. Calling Next, Token,
|
// Raw returns the unmodified text of the current token. Calling Next, Token,
|
||||||
// Text, TagName or TagAttr may change the contents of the returned slice.
|
// Text, TagName or TagAttr may change the contents of the returned slice.
|
||||||
//
|
|
||||||
// The token stream's raw bytes partition the byte stream (up until an
|
|
||||||
// ErrorToken). There are no overlaps or gaps between two consecutive token's
|
|
||||||
// raw bytes. One implication is that the byte offset of the current token is
|
|
||||||
// the sum of the lengths of all previous tokens' raw bytes.
|
|
||||||
func (z *Tokenizer) Raw() []byte {
|
func (z *Tokenizer) Raw() []byte {
|
||||||
return z.buf[z.raw.start:z.raw.end]
|
return z.buf[z.raw.start:z.raw.end]
|
||||||
}
|
}
|
||||||
|
8
vendor/golang.org/x/net/http2/client_conn_pool.go
generated
vendored
8
vendor/golang.org/x/net/http2/client_conn_pool.go
generated
vendored
@ -107,7 +107,6 @@ func (p *clientConnPool) getClientConn(req *http.Request, addr string, dialOnMis
|
|||||||
|
|
||||||
// dialCall is an in-flight Transport dial call to a host.
|
// dialCall is an in-flight Transport dial call to a host.
|
||||||
type dialCall struct {
|
type dialCall struct {
|
||||||
_ incomparable
|
|
||||||
p *clientConnPool
|
p *clientConnPool
|
||||||
done chan struct{} // closed when done
|
done chan struct{} // closed when done
|
||||||
res *ClientConn // valid after done is closed
|
res *ClientConn // valid after done is closed
|
||||||
@ -181,7 +180,6 @@ func (p *clientConnPool) addConnIfNeeded(key string, t *Transport, c *tls.Conn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
type addConnCall struct {
|
type addConnCall struct {
|
||||||
_ incomparable
|
|
||||||
p *clientConnPool
|
p *clientConnPool
|
||||||
done chan struct{} // closed when done
|
done chan struct{} // closed when done
|
||||||
err error
|
err error
|
||||||
@ -202,6 +200,12 @@ func (c *addConnCall) run(t *Transport, key string, tc *tls.Conn) {
|
|||||||
close(c.done)
|
close(c.done)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *clientConnPool) addConn(key string, cc *ClientConn) {
|
||||||
|
p.mu.Lock()
|
||||||
|
p.addConnLocked(key, cc)
|
||||||
|
p.mu.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
// p.mu must be held
|
// p.mu must be held
|
||||||
func (p *clientConnPool) addConnLocked(key string, cc *ClientConn) {
|
func (p *clientConnPool) addConnLocked(key string, cc *ClientConn) {
|
||||||
for _, v := range p.conns[key] {
|
for _, v := range p.conns[key] {
|
||||||
|
2
vendor/golang.org/x/net/http2/flow.go
generated
vendored
2
vendor/golang.org/x/net/http2/flow.go
generated
vendored
@ -8,8 +8,6 @@ package http2
|
|||||||
|
|
||||||
// flow is the flow control window's size.
|
// flow is the flow control window's size.
|
||||||
type flow struct {
|
type flow struct {
|
||||||
_ incomparable
|
|
||||||
|
|
||||||
// n is the number of DATA bytes we're allowed to send.
|
// n is the number of DATA bytes we're allowed to send.
|
||||||
// A flow is kept both on a conn and a per-stream.
|
// A flow is kept both on a conn and a per-stream.
|
||||||
n int32
|
n int32
|
||||||
|
2
vendor/golang.org/x/net/http2/hpack/encode.go
generated
vendored
2
vendor/golang.org/x/net/http2/hpack/encode.go
generated
vendored
@ -150,7 +150,7 @@ func appendIndexed(dst []byte, i uint64) []byte {
|
|||||||
// extended buffer.
|
// extended buffer.
|
||||||
//
|
//
|
||||||
// If f.Sensitive is true, "Never Indexed" representation is used. If
|
// If f.Sensitive is true, "Never Indexed" representation is used. If
|
||||||
// f.Sensitive is false and indexing is true, "Incremental Indexing"
|
// f.Sensitive is false and indexing is true, "Inremental Indexing"
|
||||||
// representation is used.
|
// representation is used.
|
||||||
func appendNewName(dst []byte, f HeaderField, indexing bool) []byte {
|
func appendNewName(dst []byte, f HeaderField, indexing bool) []byte {
|
||||||
dst = append(dst, encodeTypeByte(indexing, f.Sensitive))
|
dst = append(dst, encodeTypeByte(indexing, f.Sensitive))
|
||||||
|
7
vendor/golang.org/x/net/http2/hpack/huffman.go
generated
vendored
7
vendor/golang.org/x/net/http2/hpack/huffman.go
generated
vendored
@ -105,14 +105,7 @@ func huffmanDecode(buf *bytes.Buffer, maxLen int, v []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// incomparable is a zero-width, non-comparable type. Adding it to a struct
|
|
||||||
// makes that struct also non-comparable, and generally doesn't add
|
|
||||||
// any size (as long as it's first).
|
|
||||||
type incomparable [0]func()
|
|
||||||
|
|
||||||
type node struct {
|
type node struct {
|
||||||
_ incomparable
|
|
||||||
|
|
||||||
// children is non-nil for internal nodes
|
// children is non-nil for internal nodes
|
||||||
children *[256]*node
|
children *[256]*node
|
||||||
|
|
||||||
|
13
vendor/golang.org/x/net/http2/http2.go
generated
vendored
13
vendor/golang.org/x/net/http2/http2.go
generated
vendored
@ -19,6 +19,7 @@ package http2 // import "golang.org/x/net/http2"
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -172,6 +173,11 @@ func (s SettingID) String() string {
|
|||||||
return fmt.Sprintf("UNKNOWN_SETTING_%d", uint16(s))
|
return fmt.Sprintf("UNKNOWN_SETTING_%d", uint16(s))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
errInvalidHeaderFieldName = errors.New("http2: invalid header field name")
|
||||||
|
errInvalidHeaderFieldValue = errors.New("http2: invalid header field value")
|
||||||
|
)
|
||||||
|
|
||||||
// validWireHeaderFieldName reports whether v is a valid header field
|
// validWireHeaderFieldName reports whether v is a valid header field
|
||||||
// name (key). See httpguts.ValidHeaderName for the base rules.
|
// name (key). See httpguts.ValidHeaderName for the base rules.
|
||||||
//
|
//
|
||||||
@ -241,7 +247,6 @@ func (cw closeWaiter) Wait() {
|
|||||||
// Its buffered writer is lazily allocated as needed, to minimize
|
// Its buffered writer is lazily allocated as needed, to minimize
|
||||||
// idle memory usage with many connections.
|
// idle memory usage with many connections.
|
||||||
type bufferedWriter struct {
|
type bufferedWriter struct {
|
||||||
_ incomparable
|
|
||||||
w io.Writer // immutable
|
w io.Writer // immutable
|
||||||
bw *bufio.Writer // non-nil when data is buffered
|
bw *bufio.Writer // non-nil when data is buffered
|
||||||
}
|
}
|
||||||
@ -314,7 +319,6 @@ func bodyAllowedForStatus(status int) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type httpError struct {
|
type httpError struct {
|
||||||
_ incomparable
|
|
||||||
msg string
|
msg string
|
||||||
timeout bool
|
timeout bool
|
||||||
}
|
}
|
||||||
@ -378,8 +382,3 @@ func (s *sorter) SortStrings(ss []string) {
|
|||||||
func validPseudoPath(v string) bool {
|
func validPseudoPath(v string) bool {
|
||||||
return (len(v) > 0 && v[0] == '/') || v == "*"
|
return (len(v) > 0 && v[0] == '/') || v == "*"
|
||||||
}
|
}
|
||||||
|
|
||||||
// incomparable is a zero-width, non-comparable type. Adding it to a struct
|
|
||||||
// makes that struct also non-comparable, and generally doesn't add
|
|
||||||
// any size (as long as it's first).
|
|
||||||
type incomparable [0]func()
|
|
||||||
|
7
vendor/golang.org/x/net/http2/pipe.go
generated
vendored
7
vendor/golang.org/x/net/http2/pipe.go
generated
vendored
@ -17,7 +17,6 @@ type pipe struct {
|
|||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
c sync.Cond // c.L lazily initialized to &p.mu
|
c sync.Cond // c.L lazily initialized to &p.mu
|
||||||
b pipeBuffer // nil when done reading
|
b pipeBuffer // nil when done reading
|
||||||
unread int // bytes unread when done
|
|
||||||
err error // read error once empty. non-nil means closed.
|
err error // read error once empty. non-nil means closed.
|
||||||
breakErr error // immediate read error (caller doesn't see rest of b)
|
breakErr error // immediate read error (caller doesn't see rest of b)
|
||||||
donec chan struct{} // closed on error
|
donec chan struct{} // closed on error
|
||||||
@ -34,7 +33,7 @@ func (p *pipe) Len() int {
|
|||||||
p.mu.Lock()
|
p.mu.Lock()
|
||||||
defer p.mu.Unlock()
|
defer p.mu.Unlock()
|
||||||
if p.b == nil {
|
if p.b == nil {
|
||||||
return p.unread
|
return 0
|
||||||
}
|
}
|
||||||
return p.b.Len()
|
return p.b.Len()
|
||||||
}
|
}
|
||||||
@ -81,7 +80,6 @@ func (p *pipe) Write(d []byte) (n int, err error) {
|
|||||||
return 0, errClosedPipeWrite
|
return 0, errClosedPipeWrite
|
||||||
}
|
}
|
||||||
if p.breakErr != nil {
|
if p.breakErr != nil {
|
||||||
p.unread += len(d)
|
|
||||||
return len(d), nil // discard when there is no reader
|
return len(d), nil // discard when there is no reader
|
||||||
}
|
}
|
||||||
return p.b.Write(d)
|
return p.b.Write(d)
|
||||||
@ -119,9 +117,6 @@ func (p *pipe) closeWithError(dst *error, err error, fn func()) {
|
|||||||
}
|
}
|
||||||
p.readFn = fn
|
p.readFn = fn
|
||||||
if dst == &p.breakErr {
|
if dst == &p.breakErr {
|
||||||
if p.b != nil {
|
|
||||||
p.unread += p.b.Len()
|
|
||||||
}
|
|
||||||
p.b = nil
|
p.b = nil
|
||||||
}
|
}
|
||||||
*dst = err
|
*dst = err
|
||||||
|
33
vendor/golang.org/x/net/http2/server.go
generated
vendored
33
vendor/golang.org/x/net/http2/server.go
generated
vendored
@ -252,7 +252,7 @@ func ConfigureServer(s *http.Server, conf *Server) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !haveRequired {
|
if !haveRequired {
|
||||||
return fmt.Errorf("http2: TLSConfig.CipherSuites is missing an HTTP/2-required AES_128_GCM_SHA256 cipher (need at least one of TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 or TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256).")
|
return fmt.Errorf("http2: TLSConfig.CipherSuites is missing an HTTP/2-required AES_128_GCM_SHA256 cipher.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,7 +322,7 @@ type ServeConnOpts struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (o *ServeConnOpts) context() context.Context {
|
func (o *ServeConnOpts) context() context.Context {
|
||||||
if o != nil && o.Context != nil {
|
if o.Context != nil {
|
||||||
return o.Context
|
return o.Context
|
||||||
}
|
}
|
||||||
return context.Background()
|
return context.Background()
|
||||||
@ -581,10 +581,13 @@ type stream struct {
|
|||||||
cancelCtx func()
|
cancelCtx func()
|
||||||
|
|
||||||
// owned by serverConn's serve loop:
|
// owned by serverConn's serve loop:
|
||||||
bodyBytes int64 // body bytes seen so far
|
bodyBytes int64 // body bytes seen so far
|
||||||
declBodyBytes int64 // or -1 if undeclared
|
declBodyBytes int64 // or -1 if undeclared
|
||||||
flow flow // limits writing from Handler to client
|
flow flow // limits writing from Handler to client
|
||||||
inflow flow // what the client is allowed to POST/etc to us
|
inflow flow // what the client is allowed to POST/etc to us
|
||||||
|
parent *stream // or nil
|
||||||
|
numTrailerValues int64
|
||||||
|
weight uint8
|
||||||
state streamState
|
state streamState
|
||||||
resetQueued bool // RST_STREAM queued for write; set by sc.resetStream
|
resetQueued bool // RST_STREAM queued for write; set by sc.resetStream
|
||||||
gotTrailerHeader bool // HEADER frame for trailers was seen
|
gotTrailerHeader bool // HEADER frame for trailers was seen
|
||||||
@ -761,7 +764,6 @@ func (sc *serverConn) readFrames() {
|
|||||||
|
|
||||||
// frameWriteResult is the message passed from writeFrameAsync to the serve goroutine.
|
// frameWriteResult is the message passed from writeFrameAsync to the serve goroutine.
|
||||||
type frameWriteResult struct {
|
type frameWriteResult struct {
|
||||||
_ incomparable
|
|
||||||
wr FrameWriteRequest // what was written (or attempted)
|
wr FrameWriteRequest // what was written (or attempted)
|
||||||
err error // result of the writeFrame call
|
err error // result of the writeFrame call
|
||||||
}
|
}
|
||||||
@ -772,7 +774,7 @@ type frameWriteResult struct {
|
|||||||
// serverConn.
|
// serverConn.
|
||||||
func (sc *serverConn) writeFrameAsync(wr FrameWriteRequest) {
|
func (sc *serverConn) writeFrameAsync(wr FrameWriteRequest) {
|
||||||
err := wr.write.writeFrame(sc)
|
err := wr.write.writeFrame(sc)
|
||||||
sc.wroteFrameCh <- frameWriteResult{wr: wr, err: err}
|
sc.wroteFrameCh <- frameWriteResult{wr, err}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sc *serverConn) closeAllStreamsOnConnClose() {
|
func (sc *serverConn) closeAllStreamsOnConnClose() {
|
||||||
@ -1162,7 +1164,7 @@ func (sc *serverConn) startFrameWrite(wr FrameWriteRequest) {
|
|||||||
if wr.write.staysWithinBuffer(sc.bw.Available()) {
|
if wr.write.staysWithinBuffer(sc.bw.Available()) {
|
||||||
sc.writingFrameAsync = false
|
sc.writingFrameAsync = false
|
||||||
err := wr.write.writeFrame(sc)
|
err := wr.write.writeFrame(sc)
|
||||||
sc.wroteFrame(frameWriteResult{wr: wr, err: err})
|
sc.wroteFrame(frameWriteResult{wr, err})
|
||||||
} else {
|
} else {
|
||||||
sc.writingFrameAsync = true
|
sc.writingFrameAsync = true
|
||||||
go sc.writeFrameAsync(wr)
|
go sc.writeFrameAsync(wr)
|
||||||
@ -2058,7 +2060,7 @@ func (sc *serverConn) newWriterAndRequestNoBody(st *stream, rp requestParam) (*r
|
|||||||
var trailer http.Header
|
var trailer http.Header
|
||||||
for _, v := range rp.header["Trailer"] {
|
for _, v := range rp.header["Trailer"] {
|
||||||
for _, key := range strings.Split(v, ",") {
|
for _, key := range strings.Split(v, ",") {
|
||||||
key = http.CanonicalHeaderKey(textproto.TrimString(key))
|
key = http.CanonicalHeaderKey(strings.TrimSpace(key))
|
||||||
switch key {
|
switch key {
|
||||||
case "Transfer-Encoding", "Trailer", "Content-Length":
|
case "Transfer-Encoding", "Trailer", "Content-Length":
|
||||||
// Bogus. (copy of http1 rules)
|
// Bogus. (copy of http1 rules)
|
||||||
@ -2276,7 +2278,6 @@ func (sc *serverConn) sendWindowUpdate32(st *stream, n int32) {
|
|||||||
// requestBody is the Handler's Request.Body type.
|
// requestBody is the Handler's Request.Body type.
|
||||||
// Read and Close may be called concurrently.
|
// Read and Close may be called concurrently.
|
||||||
type requestBody struct {
|
type requestBody struct {
|
||||||
_ incomparable
|
|
||||||
stream *stream
|
stream *stream
|
||||||
conn *serverConn
|
conn *serverConn
|
||||||
closed bool // for use by Close only
|
closed bool // for use by Close only
|
||||||
@ -2414,11 +2415,7 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
|
|||||||
clen = strconv.Itoa(len(p))
|
clen = strconv.Itoa(len(p))
|
||||||
}
|
}
|
||||||
_, hasContentType := rws.snapHeader["Content-Type"]
|
_, hasContentType := rws.snapHeader["Content-Type"]
|
||||||
// If the Content-Encoding is non-blank, we shouldn't
|
if !hasContentType && bodyAllowedForStatus(rws.status) && len(p) > 0 {
|
||||||
// sniff the body. See Issue golang.org/issue/31753.
|
|
||||||
ce := rws.snapHeader.Get("Content-Encoding")
|
|
||||||
hasCE := len(ce) > 0
|
|
||||||
if !hasCE && !hasContentType && bodyAllowedForStatus(rws.status) && len(p) > 0 {
|
|
||||||
ctype = http.DetectContentType(p)
|
ctype = http.DetectContentType(p)
|
||||||
}
|
}
|
||||||
var date string
|
var date string
|
||||||
@ -2527,7 +2524,7 @@ const TrailerPrefix = "Trailer:"
|
|||||||
// trailers. That worked for a while, until we found the first major
|
// trailers. That worked for a while, until we found the first major
|
||||||
// user of Trailers in the wild: gRPC (using them only over http2),
|
// user of Trailers in the wild: gRPC (using them only over http2),
|
||||||
// and gRPC libraries permit setting trailers mid-stream without
|
// and gRPC libraries permit setting trailers mid-stream without
|
||||||
// predeclaring them. So: change of plans. We still permit the old
|
// predeclarnig them. So: change of plans. We still permit the old
|
||||||
// way, but we also permit this hack: if a Header() key begins with
|
// way, but we also permit this hack: if a Header() key begins with
|
||||||
// "Trailer:", the suffix of that key is a Trailer. Because ':' is an
|
// "Trailer:", the suffix of that key is a Trailer. Because ':' is an
|
||||||
// invalid token byte anyway, there is no ambiguity. (And it's already
|
// invalid token byte anyway, there is no ambiguity. (And it's already
|
||||||
@ -2827,7 +2824,7 @@ func (sc *serverConn) startPush(msg *startPushRequest) {
|
|||||||
// PUSH_PROMISE frames MUST only be sent on a peer-initiated stream that
|
// PUSH_PROMISE frames MUST only be sent on a peer-initiated stream that
|
||||||
// is in either the "open" or "half-closed (remote)" state.
|
// is in either the "open" or "half-closed (remote)" state.
|
||||||
if msg.parent.state != stateOpen && msg.parent.state != stateHalfClosedRemote {
|
if msg.parent.state != stateOpen && msg.parent.state != stateHalfClosedRemote {
|
||||||
// responseWriter.Push checks that the stream is peer-initiated.
|
// responseWriter.Push checks that the stream is peer-initiaed.
|
||||||
msg.done <- errStreamClosed
|
msg.done <- errStreamClosed
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
171
vendor/golang.org/x/net/http2/transport.go
generated
vendored
171
vendor/golang.org/x/net/http2/transport.go
generated
vendored
@ -93,7 +93,7 @@ type Transport struct {
|
|||||||
// send in the initial settings frame. It is how many bytes
|
// send in the initial settings frame. It is how many bytes
|
||||||
// of response headers are allowed. Unlike the http2 spec, zero here
|
// of response headers are allowed. Unlike the http2 spec, zero here
|
||||||
// means to use a default limit (currently 10MB). If you actually
|
// means to use a default limit (currently 10MB). If you actually
|
||||||
// want to advertise an unlimited value to the peer, Transport
|
// want to advertise an ulimited value to the peer, Transport
|
||||||
// interprets the highest possible value here (0xffffffff or 1<<32-1)
|
// interprets the highest possible value here (0xffffffff or 1<<32-1)
|
||||||
// to mean no limit.
|
// to mean no limit.
|
||||||
MaxHeaderListSize uint32
|
MaxHeaderListSize uint32
|
||||||
@ -108,19 +108,6 @@ type Transport struct {
|
|||||||
// waiting for their turn.
|
// waiting for their turn.
|
||||||
StrictMaxConcurrentStreams bool
|
StrictMaxConcurrentStreams bool
|
||||||
|
|
||||||
// ReadIdleTimeout is the timeout after which a health check using ping
|
|
||||||
// frame will be carried out if no frame is received on the connection.
|
|
||||||
// Note that a ping response will is considered a received frame, so if
|
|
||||||
// there is no other traffic on the connection, the health check will
|
|
||||||
// be performed every ReadIdleTimeout interval.
|
|
||||||
// If zero, no health check is performed.
|
|
||||||
ReadIdleTimeout time.Duration
|
|
||||||
|
|
||||||
// PingTimeout is the timeout after which the connection will be closed
|
|
||||||
// if a response to Ping is not received.
|
|
||||||
// Defaults to 15s.
|
|
||||||
PingTimeout time.Duration
|
|
||||||
|
|
||||||
// t1, if non-nil, is the standard library Transport using
|
// t1, if non-nil, is the standard library Transport using
|
||||||
// this transport. Its settings are used (but not its
|
// this transport. Its settings are used (but not its
|
||||||
// RoundTrip method, etc).
|
// RoundTrip method, etc).
|
||||||
@ -144,14 +131,6 @@ func (t *Transport) disableCompression() bool {
|
|||||||
return t.DisableCompression || (t.t1 != nil && t.t1.DisableCompression)
|
return t.DisableCompression || (t.t1 != nil && t.t1.DisableCompression)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Transport) pingTimeout() time.Duration {
|
|
||||||
if t.PingTimeout == 0 {
|
|
||||||
return 15 * time.Second
|
|
||||||
}
|
|
||||||
return t.PingTimeout
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// ConfigureTransport configures a net/http HTTP/1 Transport to use HTTP/2.
|
// ConfigureTransport configures a net/http HTTP/1 Transport to use HTTP/2.
|
||||||
// It returns an error if t1 has already been HTTP/2-enabled.
|
// It returns an error if t1 has already been HTTP/2-enabled.
|
||||||
func ConfigureTransport(t1 *http.Transport) error {
|
func ConfigureTransport(t1 *http.Transport) error {
|
||||||
@ -248,7 +227,6 @@ type ClientConn struct {
|
|||||||
br *bufio.Reader
|
br *bufio.Reader
|
||||||
fr *Framer
|
fr *Framer
|
||||||
lastActive time.Time
|
lastActive time.Time
|
||||||
lastIdle time.Time // time last idle
|
|
||||||
// Settings from peer: (also guarded by mu)
|
// Settings from peer: (also guarded by mu)
|
||||||
maxFrameSize uint32
|
maxFrameSize uint32
|
||||||
maxConcurrentStreams uint32
|
maxConcurrentStreams uint32
|
||||||
@ -625,7 +603,7 @@ func (t *Transport) expectContinueTimeout() time.Duration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *Transport) NewClientConn(c net.Conn) (*ClientConn, error) {
|
func (t *Transport) NewClientConn(c net.Conn) (*ClientConn, error) {
|
||||||
return t.newClientConn(c, t.disableKeepAlives())
|
return t.newClientConn(c, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, error) {
|
func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, error) {
|
||||||
@ -696,20 +674,6 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro
|
|||||||
return cc, nil
|
return cc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cc *ClientConn) healthCheck() {
|
|
||||||
pingTimeout := cc.t.pingTimeout()
|
|
||||||
// We don't need to periodically ping in the health check, because the readLoop of ClientConn will
|
|
||||||
// trigger the healthCheck again if there is no frame received.
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), pingTimeout)
|
|
||||||
defer cancel()
|
|
||||||
err := cc.Ping(ctx)
|
|
||||||
if err != nil {
|
|
||||||
cc.closeForLostPing()
|
|
||||||
cc.t.connPool().MarkDead(cc)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cc *ClientConn) setGoAway(f *GoAwayFrame) {
|
func (cc *ClientConn) setGoAway(f *GoAwayFrame) {
|
||||||
cc.mu.Lock()
|
cc.mu.Lock()
|
||||||
defer cc.mu.Unlock()
|
defer cc.mu.Unlock()
|
||||||
@ -772,8 +736,7 @@ func (cc *ClientConn) idleStateLocked() (st clientConnIdleState) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
st.canTakeNewRequest = cc.goAway == nil && !cc.closed && !cc.closing && maxConcurrentOkay &&
|
st.canTakeNewRequest = cc.goAway == nil && !cc.closed && !cc.closing && maxConcurrentOkay &&
|
||||||
int64(cc.nextStreamID)+2*int64(cc.pendingRequests) < math.MaxInt32 &&
|
int64(cc.nextStreamID)+2*int64(cc.pendingRequests) < math.MaxInt32
|
||||||
!cc.tooIdleLocked()
|
|
||||||
st.freshConn = cc.nextStreamID == 1 && st.canTakeNewRequest
|
st.freshConn = cc.nextStreamID == 1 && st.canTakeNewRequest
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -783,16 +746,6 @@ func (cc *ClientConn) canTakeNewRequestLocked() bool {
|
|||||||
return st.canTakeNewRequest
|
return st.canTakeNewRequest
|
||||||
}
|
}
|
||||||
|
|
||||||
// tooIdleLocked reports whether this connection has been been sitting idle
|
|
||||||
// for too much wall time.
|
|
||||||
func (cc *ClientConn) tooIdleLocked() bool {
|
|
||||||
// The Round(0) strips the monontonic clock reading so the
|
|
||||||
// times are compared based on their wall time. We don't want
|
|
||||||
// to reuse a connection that's been sitting idle during
|
|
||||||
// VM/laptop suspend if monotonic time was also frozen.
|
|
||||||
return cc.idleTimeout != 0 && !cc.lastIdle.IsZero() && time.Since(cc.lastIdle.Round(0)) > cc.idleTimeout
|
|
||||||
}
|
|
||||||
|
|
||||||
// onIdleTimeout is called from a time.AfterFunc goroutine. It will
|
// onIdleTimeout is called from a time.AfterFunc goroutine. It will
|
||||||
// only be called when we're idle, but because we're coming from a new
|
// only be called when we're idle, but because we're coming from a new
|
||||||
// goroutine, there could be a new request coming in at the same time,
|
// goroutine, there could be a new request coming in at the same time,
|
||||||
@ -881,12 +834,14 @@ func (cc *ClientConn) sendGoAway() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// closes the client connection immediately. In-flight requests are interrupted.
|
// Close closes the client connection immediately.
|
||||||
// err is sent to streams.
|
//
|
||||||
func (cc *ClientConn) closeForError(err error) error {
|
// In-flight requests are interrupted. For a graceful shutdown, use Shutdown instead.
|
||||||
|
func (cc *ClientConn) Close() error {
|
||||||
cc.mu.Lock()
|
cc.mu.Lock()
|
||||||
defer cc.cond.Broadcast()
|
defer cc.cond.Broadcast()
|
||||||
defer cc.mu.Unlock()
|
defer cc.mu.Unlock()
|
||||||
|
err := errors.New("http2: client connection force closed via ClientConn.Close")
|
||||||
for id, cs := range cc.streams {
|
for id, cs := range cc.streams {
|
||||||
select {
|
select {
|
||||||
case cs.resc <- resAndError{err: err}:
|
case cs.resc <- resAndError{err: err}:
|
||||||
@ -899,20 +854,6 @@ func (cc *ClientConn) closeForError(err error) error {
|
|||||||
return cc.tconn.Close()
|
return cc.tconn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close closes the client connection immediately.
|
|
||||||
//
|
|
||||||
// In-flight requests are interrupted. For a graceful shutdown, use Shutdown instead.
|
|
||||||
func (cc *ClientConn) Close() error {
|
|
||||||
err := errors.New("http2: client connection force closed via ClientConn.Close")
|
|
||||||
return cc.closeForError(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// closes the client connection immediately. In-flight requests are interrupted.
|
|
||||||
func (cc *ClientConn) closeForLostPing() error {
|
|
||||||
err := errors.New("http2: client connection lost")
|
|
||||||
return cc.closeForError(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
const maxAllocFrameSize = 512 << 10
|
const maxAllocFrameSize = 512 << 10
|
||||||
|
|
||||||
// frameBuffer returns a scratch buffer suitable for writing DATA frames.
|
// frameBuffer returns a scratch buffer suitable for writing DATA frames.
|
||||||
@ -963,7 +904,7 @@ func commaSeparatedTrailers(req *http.Request) (string, error) {
|
|||||||
k = http.CanonicalHeaderKey(k)
|
k = http.CanonicalHeaderKey(k)
|
||||||
switch k {
|
switch k {
|
||||||
case "Transfer-Encoding", "Trailer", "Content-Length":
|
case "Transfer-Encoding", "Trailer", "Content-Length":
|
||||||
return "", fmt.Errorf("invalid Trailer key %q", k)
|
return "", &badStringError{"invalid Trailer key", k}
|
||||||
}
|
}
|
||||||
keys = append(keys, k)
|
keys = append(keys, k)
|
||||||
}
|
}
|
||||||
@ -1209,7 +1150,6 @@ func (cc *ClientConn) awaitOpenSlotForRequest(req *http.Request) error {
|
|||||||
}
|
}
|
||||||
return errClientConnUnusable
|
return errClientConnUnusable
|
||||||
}
|
}
|
||||||
cc.lastIdle = time.Time{}
|
|
||||||
if int64(len(cc.streams))+1 <= int64(cc.maxConcurrentStreams) {
|
if int64(len(cc.streams))+1 <= int64(cc.maxConcurrentStreams) {
|
||||||
if waitingForConn != nil {
|
if waitingForConn != nil {
|
||||||
close(waitingForConn)
|
close(waitingForConn)
|
||||||
@ -1276,8 +1216,6 @@ var (
|
|||||||
|
|
||||||
// abort request body write, but send stream reset of cancel.
|
// abort request body write, but send stream reset of cancel.
|
||||||
errStopReqBodyWriteAndCancel = errors.New("http2: canceling request")
|
errStopReqBodyWriteAndCancel = errors.New("http2: canceling request")
|
||||||
|
|
||||||
errReqBodyTooLong = errors.New("http2: request body larger than specified content length")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (cs *clientStream) writeRequestBody(body io.Reader, bodyCloser io.Closer) (err error) {
|
func (cs *clientStream) writeRequestBody(body io.Reader, bodyCloser io.Closer) (err error) {
|
||||||
@ -1300,32 +1238,10 @@ func (cs *clientStream) writeRequestBody(body io.Reader, bodyCloser io.Closer) (
|
|||||||
|
|
||||||
req := cs.req
|
req := cs.req
|
||||||
hasTrailers := req.Trailer != nil
|
hasTrailers := req.Trailer != nil
|
||||||
remainLen := actualContentLength(req)
|
|
||||||
hasContentLen := remainLen != -1
|
|
||||||
|
|
||||||
var sawEOF bool
|
var sawEOF bool
|
||||||
for !sawEOF {
|
for !sawEOF {
|
||||||
n, err := body.Read(buf[:len(buf)-1])
|
n, err := body.Read(buf)
|
||||||
if hasContentLen {
|
|
||||||
remainLen -= int64(n)
|
|
||||||
if remainLen == 0 && err == nil {
|
|
||||||
// The request body's Content-Length was predeclared and
|
|
||||||
// we just finished reading it all, but the underlying io.Reader
|
|
||||||
// returned the final chunk with a nil error (which is one of
|
|
||||||
// the two valid things a Reader can do at EOF). Because we'd prefer
|
|
||||||
// to send the END_STREAM bit early, double-check that we're actually
|
|
||||||
// at EOF. Subsequent reads should return (0, EOF) at this point.
|
|
||||||
// If either value is different, we return an error in one of two ways below.
|
|
||||||
var n1 int
|
|
||||||
n1, err = body.Read(buf[n:])
|
|
||||||
remainLen -= int64(n1)
|
|
||||||
}
|
|
||||||
if remainLen < 0 {
|
|
||||||
err = errReqBodyTooLong
|
|
||||||
cc.writeStreamReset(cs.ID, ErrCodeCancel, err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
sawEOF = true
|
sawEOF = true
|
||||||
err = nil
|
err = nil
|
||||||
@ -1441,6 +1357,13 @@ func (cs *clientStream) awaitFlowControl(maxBytes int) (taken int32, err error)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type badStringError struct {
|
||||||
|
what string
|
||||||
|
str string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *badStringError) Error() string { return fmt.Sprintf("%s %q", e.what, e.str) }
|
||||||
|
|
||||||
// requires cc.mu be held.
|
// requires cc.mu be held.
|
||||||
func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trailers string, contentLength int64) ([]byte, error) {
|
func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trailers string, contentLength int64) ([]byte, error) {
|
||||||
cc.hbuf.Reset()
|
cc.hbuf.Reset()
|
||||||
@ -1531,29 +1454,7 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail
|
|||||||
if vv[0] == "" {
|
if vv[0] == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
} else if strings.EqualFold(k, "cookie") {
|
|
||||||
// Per 8.1.2.5 To allow for better compression efficiency, the
|
|
||||||
// Cookie header field MAY be split into separate header fields,
|
|
||||||
// each with one or more cookie-pairs.
|
|
||||||
for _, v := range vv {
|
|
||||||
for {
|
|
||||||
p := strings.IndexByte(v, ';')
|
|
||||||
if p < 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
f("cookie", v[:p])
|
|
||||||
p++
|
|
||||||
// strip space after semicolon if any.
|
|
||||||
for p+1 <= len(v) && v[p] == ' ' {
|
|
||||||
p++
|
|
||||||
}
|
|
||||||
v = v[p:]
|
|
||||||
}
|
|
||||||
if len(v) > 0 {
|
|
||||||
f("cookie", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range vv {
|
for _, v := range vv {
|
||||||
@ -1656,7 +1557,6 @@ func (cc *ClientConn) writeHeader(name, value string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type resAndError struct {
|
type resAndError struct {
|
||||||
_ incomparable
|
|
||||||
res *http.Response
|
res *http.Response
|
||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
@ -1692,7 +1592,6 @@ func (cc *ClientConn) streamByID(id uint32, andRemove bool) *clientStream {
|
|||||||
delete(cc.streams, id)
|
delete(cc.streams, id)
|
||||||
if len(cc.streams) == 0 && cc.idleTimer != nil {
|
if len(cc.streams) == 0 && cc.idleTimer != nil {
|
||||||
cc.idleTimer.Reset(cc.idleTimeout)
|
cc.idleTimer.Reset(cc.idleTimeout)
|
||||||
cc.lastIdle = time.Now()
|
|
||||||
}
|
}
|
||||||
close(cs.done)
|
close(cs.done)
|
||||||
// Wake up checkResetOrDone via clientStream.awaitFlowControl and
|
// Wake up checkResetOrDone via clientStream.awaitFlowControl and
|
||||||
@ -1704,7 +1603,6 @@ func (cc *ClientConn) streamByID(id uint32, andRemove bool) *clientStream {
|
|||||||
|
|
||||||
// clientConnReadLoop is the state owned by the clientConn's frame-reading readLoop.
|
// clientConnReadLoop is the state owned by the clientConn's frame-reading readLoop.
|
||||||
type clientConnReadLoop struct {
|
type clientConnReadLoop struct {
|
||||||
_ incomparable
|
|
||||||
cc *ClientConn
|
cc *ClientConn
|
||||||
closeWhenIdle bool
|
closeWhenIdle bool
|
||||||
}
|
}
|
||||||
@ -1784,17 +1682,8 @@ func (rl *clientConnReadLoop) run() error {
|
|||||||
rl.closeWhenIdle = cc.t.disableKeepAlives() || cc.singleUse
|
rl.closeWhenIdle = cc.t.disableKeepAlives() || cc.singleUse
|
||||||
gotReply := false // ever saw a HEADERS reply
|
gotReply := false // ever saw a HEADERS reply
|
||||||
gotSettings := false
|
gotSettings := false
|
||||||
readIdleTimeout := cc.t.ReadIdleTimeout
|
|
||||||
var t *time.Timer
|
|
||||||
if readIdleTimeout != 0 {
|
|
||||||
t = time.AfterFunc(readIdleTimeout, cc.healthCheck)
|
|
||||||
defer t.Stop()
|
|
||||||
}
|
|
||||||
for {
|
for {
|
||||||
f, err := cc.fr.ReadFrame()
|
f, err := cc.fr.ReadFrame()
|
||||||
if t != nil {
|
|
||||||
t.Reset(readIdleTimeout)
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cc.vlogf("http2: Transport readFrame error on conn %p: (%T) %v", cc, err, err)
|
cc.vlogf("http2: Transport readFrame error on conn %p: (%T) %v", cc, err, err)
|
||||||
}
|
}
|
||||||
@ -1943,9 +1832,7 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra
|
|||||||
return nil, errors.New("malformed response from server: malformed non-numeric status pseudo header")
|
return nil, errors.New("malformed response from server: malformed non-numeric status pseudo header")
|
||||||
}
|
}
|
||||||
|
|
||||||
regularFields := f.RegularFields()
|
header := make(http.Header)
|
||||||
strs := make([]string, len(regularFields))
|
|
||||||
header := make(http.Header, len(regularFields))
|
|
||||||
res := &http.Response{
|
res := &http.Response{
|
||||||
Proto: "HTTP/2.0",
|
Proto: "HTTP/2.0",
|
||||||
ProtoMajor: 2,
|
ProtoMajor: 2,
|
||||||
@ -1953,7 +1840,7 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra
|
|||||||
StatusCode: statusCode,
|
StatusCode: statusCode,
|
||||||
Status: status + " " + http.StatusText(statusCode),
|
Status: status + " " + http.StatusText(statusCode),
|
||||||
}
|
}
|
||||||
for _, hf := range regularFields {
|
for _, hf := range f.RegularFields() {
|
||||||
key := http.CanonicalHeaderKey(hf.Name)
|
key := http.CanonicalHeaderKey(hf.Name)
|
||||||
if key == "Trailer" {
|
if key == "Trailer" {
|
||||||
t := res.Trailer
|
t := res.Trailer
|
||||||
@ -1965,18 +1852,7 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra
|
|||||||
t[http.CanonicalHeaderKey(v)] = nil
|
t[http.CanonicalHeaderKey(v)] = nil
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
vv := header[key]
|
header[key] = append(header[key], hf.Value)
|
||||||
if vv == nil && len(strs) > 0 {
|
|
||||||
// More than likely this will be a single-element key.
|
|
||||||
// Most headers aren't multi-valued.
|
|
||||||
// Set the capacity on strs[0] to 1, so any future append
|
|
||||||
// won't extend the slice into the other strings.
|
|
||||||
vv, strs = strs[:1:1], strs[1:]
|
|
||||||
vv[0] = hf.Value
|
|
||||||
header[key] = vv
|
|
||||||
} else {
|
|
||||||
header[key] = append(vv, hf.Value)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2262,6 +2138,8 @@ func (rl *clientConnReadLoop) processData(f *DataFrame) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var errInvalidTrailers = errors.New("http2: invalid trailers")
|
||||||
|
|
||||||
func (rl *clientConnReadLoop) endStream(cs *clientStream) {
|
func (rl *clientConnReadLoop) endStream(cs *clientStream) {
|
||||||
// TODO: check that any declared content-length matches, like
|
// TODO: check that any declared content-length matches, like
|
||||||
// server.go's (*stream).endStream method.
|
// server.go's (*stream).endStream method.
|
||||||
@ -2492,6 +2370,7 @@ func (cc *ClientConn) writeStreamReset(streamID uint32, code ErrCode, err error)
|
|||||||
var (
|
var (
|
||||||
errResponseHeaderListSize = errors.New("http2: response header list larger than advertised limit")
|
errResponseHeaderListSize = errors.New("http2: response header list larger than advertised limit")
|
||||||
errRequestHeaderListSize = errors.New("http2: request header list larger than peer's advertised limit")
|
errRequestHeaderListSize = errors.New("http2: request header list larger than peer's advertised limit")
|
||||||
|
errPseudoTrailers = errors.New("http2: invalid pseudo header in trailers")
|
||||||
)
|
)
|
||||||
|
|
||||||
func (cc *ClientConn) logf(format string, args ...interface{}) {
|
func (cc *ClientConn) logf(format string, args ...interface{}) {
|
||||||
@ -2525,13 +2404,11 @@ func strSliceContains(ss []string, s string) bool {
|
|||||||
|
|
||||||
type erringRoundTripper struct{ err error }
|
type erringRoundTripper struct{ err error }
|
||||||
|
|
||||||
func (rt erringRoundTripper) RoundTripErr() error { return rt.err }
|
|
||||||
func (rt erringRoundTripper) RoundTrip(*http.Request) (*http.Response, error) { return nil, rt.err }
|
func (rt erringRoundTripper) RoundTrip(*http.Request) (*http.Response, error) { return nil, rt.err }
|
||||||
|
|
||||||
// gzipReader wraps a response body so it can lazily
|
// gzipReader wraps a response body so it can lazily
|
||||||
// call gzip.NewReader on the first call to Read
|
// call gzip.NewReader on the first call to Read
|
||||||
type gzipReader struct {
|
type gzipReader struct {
|
||||||
_ incomparable
|
|
||||||
body io.ReadCloser // underlying Response.Body
|
body io.ReadCloser // underlying Response.Body
|
||||||
zr *gzip.Reader // lazily-initialized gzip reader
|
zr *gzip.Reader // lazily-initialized gzip reader
|
||||||
zerr error // sticky error
|
zerr error // sticky error
|
||||||
|
2
vendor/golang.org/x/net/http2/writesched_priority.go
generated
vendored
2
vendor/golang.org/x/net/http2/writesched_priority.go
generated
vendored
@ -149,7 +149,7 @@ func (n *priorityNode) addBytes(b int64) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// walkReadyInOrder iterates over the tree in priority order, calling f for each node
|
// walkReadyInOrder iterates over the tree in priority order, calling f for each node
|
||||||
// with a non-empty write queue. When f returns true, this function returns true and the
|
// with a non-empty write queue. When f returns true, this funcion returns true and the
|
||||||
// walk halts. tmp is used as scratch space for sorting.
|
// walk halts. tmp is used as scratch space for sorting.
|
||||||
//
|
//
|
||||||
// f(n, openParent) takes two arguments: the node to visit, n, and a bool that is true
|
// f(n, openParent) takes two arguments: the node to visit, n, and a bool that is true
|
||||||
|
9
vendor/golang.org/x/net/http2/writesched_random.go
generated
vendored
9
vendor/golang.org/x/net/http2/writesched_random.go
generated
vendored
@ -19,8 +19,7 @@ type randomWriteScheduler struct {
|
|||||||
zero writeQueue
|
zero writeQueue
|
||||||
|
|
||||||
// sq contains the stream-specific queues, keyed by stream ID.
|
// sq contains the stream-specific queues, keyed by stream ID.
|
||||||
// When a stream is idle, closed, or emptied, it's deleted
|
// When a stream is idle or closed, it's deleted from the map.
|
||||||
// from the map.
|
|
||||||
sq map[uint32]*writeQueue
|
sq map[uint32]*writeQueue
|
||||||
|
|
||||||
// pool of empty queues for reuse.
|
// pool of empty queues for reuse.
|
||||||
@ -64,12 +63,8 @@ func (ws *randomWriteScheduler) Pop() (FrameWriteRequest, bool) {
|
|||||||
return ws.zero.shift(), true
|
return ws.zero.shift(), true
|
||||||
}
|
}
|
||||||
// Iterate over all non-idle streams until finding one that can be consumed.
|
// Iterate over all non-idle streams until finding one that can be consumed.
|
||||||
for streamID, q := range ws.sq {
|
for _, q := range ws.sq {
|
||||||
if wr, ok := q.consume(math.MaxInt32); ok {
|
if wr, ok := q.consume(math.MaxInt32); ok {
|
||||||
if q.empty() {
|
|
||||||
delete(ws.sq, streamID)
|
|
||||||
ws.queuePool.put(q)
|
|
||||||
}
|
|
||||||
return wr, true
|
return wr, true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
2
vendor/golang.org/x/net/idna/tables11.0.0.go
generated
vendored
2
vendor/golang.org/x/net/idna/tables11.0.0.go
generated
vendored
@ -1,6 +1,6 @@
|
|||||||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||||
|
|
||||||
// +build go1.13,!go1.14
|
// +build go1.13
|
||||||
|
|
||||||
package idna
|
package idna
|
||||||
|
|
||||||
|
4733
vendor/golang.org/x/net/idna/tables12.00.go
generated
vendored
4733
vendor/golang.org/x/net/idna/tables12.00.go
generated
vendored
File diff suppressed because it is too large
Load Diff
12
vendor/golang.org/x/net/internal/socket/norace.go
generated
vendored
12
vendor/golang.org/x/net/internal/socket/norace.go
generated
vendored
@ -1,12 +0,0 @@
|
|||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build !race
|
|
||||||
|
|
||||||
package socket
|
|
||||||
|
|
||||||
func (m *Message) raceRead() {
|
|
||||||
}
|
|
||||||
func (m *Message) raceWrite() {
|
|
||||||
}
|
|
37
vendor/golang.org/x/net/internal/socket/race.go
generated
vendored
37
vendor/golang.org/x/net/internal/socket/race.go
generated
vendored
@ -1,37 +0,0 @@
|
|||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build race
|
|
||||||
|
|
||||||
package socket
|
|
||||||
|
|
||||||
import (
|
|
||||||
"runtime"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
// This package reads and writes the Message buffers using a
|
|
||||||
// direct system call, which the race detector can't see.
|
|
||||||
// These functions tell the race detector what is going on during the syscall.
|
|
||||||
|
|
||||||
func (m *Message) raceRead() {
|
|
||||||
for _, b := range m.Buffers {
|
|
||||||
if len(b) > 0 {
|
|
||||||
runtime.RaceReadRange(unsafe.Pointer(&b[0]), len(b))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if b := m.OOB; len(b) > 0 {
|
|
||||||
runtime.RaceReadRange(unsafe.Pointer(&b[0]), len(b))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func (m *Message) raceWrite() {
|
|
||||||
for _, b := range m.Buffers {
|
|
||||||
if len(b) > 0 {
|
|
||||||
runtime.RaceWriteRange(unsafe.Pointer(&b[0]), len(b))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if b := m.OOB; len(b) > 0 {
|
|
||||||
runtime.RaceWriteRange(unsafe.Pointer(&b[0]), len(b))
|
|
||||||
}
|
|
||||||
}
|
|
6
vendor/golang.org/x/net/internal/socket/rawconn_mmsg.go
generated
vendored
6
vendor/golang.org/x/net/internal/socket/rawconn_mmsg.go
generated
vendored
@ -13,9 +13,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (c *Conn) recvMsgs(ms []Message, flags int) (int, error) {
|
func (c *Conn) recvMsgs(ms []Message, flags int) (int, error) {
|
||||||
for i := range ms {
|
|
||||||
ms[i].raceWrite()
|
|
||||||
}
|
|
||||||
hs := make(mmsghdrs, len(ms))
|
hs := make(mmsghdrs, len(ms))
|
||||||
var parseFn func([]byte, string) (net.Addr, error)
|
var parseFn func([]byte, string) (net.Addr, error)
|
||||||
if c.network != "tcp" {
|
if c.network != "tcp" {
|
||||||
@ -46,9 +43,6 @@ func (c *Conn) recvMsgs(ms []Message, flags int) (int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Conn) sendMsgs(ms []Message, flags int) (int, error) {
|
func (c *Conn) sendMsgs(ms []Message, flags int) (int, error) {
|
||||||
for i := range ms {
|
|
||||||
ms[i].raceRead()
|
|
||||||
}
|
|
||||||
hs := make(mmsghdrs, len(ms))
|
hs := make(mmsghdrs, len(ms))
|
||||||
var marshalFn func(net.Addr) []byte
|
var marshalFn func(net.Addr) []byte
|
||||||
if c.network != "tcp" {
|
if c.network != "tcp" {
|
||||||
|
2
vendor/golang.org/x/net/internal/socket/rawconn_msg.go
generated
vendored
2
vendor/golang.org/x/net/internal/socket/rawconn_msg.go
generated
vendored
@ -12,7 +12,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (c *Conn) recvMsg(m *Message, flags int) error {
|
func (c *Conn) recvMsg(m *Message, flags int) error {
|
||||||
m.raceWrite()
|
|
||||||
var h msghdr
|
var h msghdr
|
||||||
vs := make([]iovec, len(m.Buffers))
|
vs := make([]iovec, len(m.Buffers))
|
||||||
var sa []byte
|
var sa []byte
|
||||||
@ -49,7 +48,6 @@ func (c *Conn) recvMsg(m *Message, flags int) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Conn) sendMsg(m *Message, flags int) error {
|
func (c *Conn) sendMsg(m *Message, flags int) error {
|
||||||
m.raceRead()
|
|
||||||
var h msghdr
|
var h msghdr
|
||||||
vs := make([]iovec, len(m.Buffers))
|
vs := make([]iovec, len(m.Buffers))
|
||||||
var sa []byte
|
var sa []byte
|
||||||
|
27
vendor/golang.org/x/net/internal/socket/sys_dragonfly.go
generated
vendored
27
vendor/golang.org/x/net/internal/socket/sys_dragonfly.go
generated
vendored
@ -4,29 +4,4 @@
|
|||||||
|
|
||||||
package socket
|
package socket
|
||||||
|
|
||||||
import (
|
func probeProtocolStack() int { return 4 }
|
||||||
"sync"
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
// See version list in https://github.com/DragonFlyBSD/DragonFlyBSD/blob/master/sys/sys/param.h
|
|
||||||
var (
|
|
||||||
osreldateOnce sync.Once
|
|
||||||
osreldate uint32
|
|
||||||
)
|
|
||||||
|
|
||||||
// First __DragonFly_version after September 2019 ABI changes
|
|
||||||
// http://lists.dragonflybsd.org/pipermail/users/2019-September/358280.html
|
|
||||||
const _dragonflyABIChangeVersion = 500705
|
|
||||||
|
|
||||||
func probeProtocolStack() int {
|
|
||||||
osreldateOnce.Do(func() { osreldate, _ = syscall.SysctlUint32("kern.osreldate") })
|
|
||||||
var p uintptr
|
|
||||||
if int(unsafe.Sizeof(p)) == 8 && osreldate >= _dragonflyABIChangeVersion {
|
|
||||||
return int(unsafe.Sizeof(p))
|
|
||||||
}
|
|
||||||
// 64-bit Dragonfly before the September 2019 ABI changes still requires
|
|
||||||
// 32-bit aligned access to network subsystem.
|
|
||||||
return 4
|
|
||||||
}
|
|
||||||
|
1
vendor/golang.org/x/net/internal/socket/zsys_aix_ppc64.go
generated
vendored
1
vendor/golang.org/x/net/internal/socket/zsys_aix_ppc64.go
generated
vendored
@ -53,6 +53,7 @@ type sockaddrInet6 struct {
|
|||||||
const (
|
const (
|
||||||
sizeofIovec = 0x10
|
sizeofIovec = 0x10
|
||||||
sizeofMsghdr = 0x30
|
sizeofMsghdr = 0x30
|
||||||
|
sizeofMmsghdr = 0x38
|
||||||
sizeofCmsghdr = 0xc
|
sizeofCmsghdr = 0xc
|
||||||
|
|
||||||
sizeofSockaddrInet = 0x10
|
sizeofSockaddrInet = 0x10
|
||||||
|
1
vendor/golang.org/x/net/internal/socket/zsys_linux_386.go
generated
vendored
1
vendor/golang.org/x/net/internal/socket/zsys_linux_386.go
generated
vendored
@ -47,6 +47,7 @@ type sockaddrInet6 struct {
|
|||||||
const (
|
const (
|
||||||
sizeofIovec = 0x8
|
sizeofIovec = 0x8
|
||||||
sizeofMsghdr = 0x1c
|
sizeofMsghdr = 0x1c
|
||||||
|
sizeofMmsghdr = 0x20
|
||||||
sizeofCmsghdr = 0xc
|
sizeofCmsghdr = 0xc
|
||||||
|
|
||||||
sizeofSockaddrInet = 0x10
|
sizeofSockaddrInet = 0x10
|
||||||
|
1
vendor/golang.org/x/net/internal/socket/zsys_linux_amd64.go
generated
vendored
1
vendor/golang.org/x/net/internal/socket/zsys_linux_amd64.go
generated
vendored
@ -50,6 +50,7 @@ type sockaddrInet6 struct {
|
|||||||
const (
|
const (
|
||||||
sizeofIovec = 0x10
|
sizeofIovec = 0x10
|
||||||
sizeofMsghdr = 0x38
|
sizeofMsghdr = 0x38
|
||||||
|
sizeofMmsghdr = 0x40
|
||||||
sizeofCmsghdr = 0x10
|
sizeofCmsghdr = 0x10
|
||||||
|
|
||||||
sizeofSockaddrInet = 0x10
|
sizeofSockaddrInet = 0x10
|
||||||
|
6
vendor/golang.org/x/net/internal/socket/zsys_linux_arm.go
generated
vendored
6
vendor/golang.org/x/net/internal/socket/zsys_linux_arm.go
generated
vendored
@ -45,9 +45,9 @@ type sockaddrInet6 struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
sizeofIovec = 0x8
|
sizeofIovec = 0x8
|
||||||
sizeofMsghdr = 0x1c
|
sizeofMsghdr = 0x1c
|
||||||
|
sizeofMmsghdr = 0x20
|
||||||
sizeofCmsghdr = 0xc
|
sizeofCmsghdr = 0xc
|
||||||
|
|
||||||
sizeofSockaddrInet = 0x10
|
sizeofSockaddrInet = 0x10
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user