Ver Fonte

240528-0919-Kim

EricKIm há 5 meses atrás
pai
commit
ac134e7565
100 ficheiros alterados com 6195 adições e 642 exclusões
  1. 18 50
      controller.go
  2. 14 15
      go.mod
  3. 40 35
      go.sum
  4. 27 0
      vendor/filippo.io/edwards25519/LICENSE
  5. 14 0
      vendor/filippo.io/edwards25519/README.md
  6. 20 0
      vendor/filippo.io/edwards25519/doc.go
  7. 427 0
      vendor/filippo.io/edwards25519/edwards25519.go
  8. 349 0
      vendor/filippo.io/edwards25519/extra.go
  9. 420 0
      vendor/filippo.io/edwards25519/field/fe.go
  10. 16 0
      vendor/filippo.io/edwards25519/field/fe_amd64.go
  11. 379 0
      vendor/filippo.io/edwards25519/field/fe_amd64.s
  12. 12 0
      vendor/filippo.io/edwards25519/field/fe_amd64_noasm.go
  13. 16 0
      vendor/filippo.io/edwards25519/field/fe_arm64.go
  14. 42 0
      vendor/filippo.io/edwards25519/field/fe_arm64.s
  15. 12 0
      vendor/filippo.io/edwards25519/field/fe_arm64_noasm.go
  16. 50 0
      vendor/filippo.io/edwards25519/field/fe_extra.go
  17. 266 0
      vendor/filippo.io/edwards25519/field/fe_generic.go
  18. 343 0
      vendor/filippo.io/edwards25519/scalar.go
  19. 1147 0
      vendor/filippo.io/edwards25519/scalar_fiat.go
  20. 214 0
      vendor/filippo.io/edwards25519/scalarmult.go
  21. 129 0
      vendor/filippo.io/edwards25519/tables.go
  22. 16 15
      vendor/github.com/IBM/sarama/.golangci.yml
  23. 41 0
      vendor/github.com/IBM/sarama/.pre-commit-config.yaml
  24. 286 0
      vendor/github.com/IBM/sarama/CHANGELOG.md
  25. 128 0
      vendor/github.com/IBM/sarama/CODE_OF_CONDUCT.md
  26. 34 3
      vendor/github.com/IBM/sarama/CONTRIBUTING.md
  27. 32 12
      vendor/github.com/IBM/sarama/Dockerfile.kafka
  28. 1 0
      vendor/github.com/IBM/sarama/LICENSE.md
  29. 6 3
      vendor/github.com/IBM/sarama/README.md
  30. 11 0
      vendor/github.com/IBM/sarama/SECURITY.md
  31. 4 0
      vendor/github.com/IBM/sarama/acl_create_request.go
  32. 16 2
      vendor/github.com/IBM/sarama/acl_create_response.go
  33. 4 0
      vendor/github.com/IBM/sarama/acl_delete_request.go
  34. 14 1
      vendor/github.com/IBM/sarama/acl_delete_response.go
  35. 5 1
      vendor/github.com/IBM/sarama/acl_describe_request.go
  36. 8 0
      vendor/github.com/IBM/sarama/acl_describe_response.go
  37. 4 4
      vendor/github.com/IBM/sarama/acl_types.go
  38. 16 2
      vendor/github.com/IBM/sarama/add_offsets_to_txn_request.go
  39. 20 2
      vendor/github.com/IBM/sarama/add_offsets_to_txn_response.go
  40. 15 3
      vendor/github.com/IBM/sarama/add_partitions_to_txn_request.go
  41. 19 2
      vendor/github.com/IBM/sarama/add_partitions_to_txn_response.go
  42. 125 62
      vendor/github.com/IBM/sarama/admin.go
  43. 6 1
      vendor/github.com/IBM/sarama/alter_client_quotas_request.go
  44. 10 1
      vendor/github.com/IBM/sarama/alter_client_quotas_response.go
  45. 14 2
      vendor/github.com/IBM/sarama/alter_configs_request.go
  46. 36 4
      vendor/github.com/IBM/sarama/alter_configs_response.go
  47. 4 0
      vendor/github.com/IBM/sarama/alter_partition_reassignments_request.go
  48. 10 0
      vendor/github.com/IBM/sarama/alter_partition_reassignments_response.go
  49. 4 0
      vendor/github.com/IBM/sarama/alter_user_scram_credentials_request.go
  50. 8 0
      vendor/github.com/IBM/sarama/alter_user_scram_credentials_response.go
  51. 11 3
      vendor/github.com/IBM/sarama/api_versions_request.go
  52. 17 3
      vendor/github.com/IBM/sarama/api_versions_response.go
  53. 9 8
      vendor/github.com/IBM/sarama/async_producer.go
  54. 16 15
      vendor/github.com/IBM/sarama/balance_strategy.go
  55. 103 24
      vendor/github.com/IBM/sarama/broker.go
  56. 149 62
      vendor/github.com/IBM/sarama/client.go
  57. 1 1
      vendor/github.com/IBM/sarama/compress.go
  58. 33 13
      vendor/github.com/IBM/sarama/config.go
  59. 28 4
      vendor/github.com/IBM/sarama/consumer.go
  60. 137 56
      vendor/github.com/IBM/sarama/consumer_group.go
  61. 52 8
      vendor/github.com/IBM/sarama/consumer_group_members.go
  62. 15 2
      vendor/github.com/IBM/sarama/consumer_metadata_request.go
  63. 15 3
      vendor/github.com/IBM/sarama/consumer_metadata_response.go
  64. 14 2
      vendor/github.com/IBM/sarama/create_partitions_request.go
  65. 18 2
      vendor/github.com/IBM/sarama/create_partitions_response.go
  66. 28 7
      vendor/github.com/IBM/sarama/create_topics_request.go
  67. 21 5
      vendor/github.com/IBM/sarama/create_topics_response.go
  68. 44 7
      vendor/github.com/IBM/sarama/decompress.go
  69. 15 3
      vendor/github.com/IBM/sarama/delete_groups_request.go
  70. 18 2
      vendor/github.com/IBM/sarama/delete_groups_response.go
  71. 6 1
      vendor/github.com/IBM/sarama/delete_offsets_request.go
  72. 10 1
      vendor/github.com/IBM/sarama/delete_offsets_response.go
  73. 12 2
      vendor/github.com/IBM/sarama/delete_records_request.go
  74. 15 2
      vendor/github.com/IBM/sarama/delete_records_response.go
  75. 11 1
      vendor/github.com/IBM/sarama/delete_topics_request.go
  76. 15 1
      vendor/github.com/IBM/sarama/delete_topics_response.go
  77. 6 1
      vendor/github.com/IBM/sarama/describe_client_quotas_request.go
  78. 10 1
      vendor/github.com/IBM/sarama/describe_client_quotas_response.go
  79. 9 3
      vendor/github.com/IBM/sarama/describe_configs_request.go
  80. 26 3
      vendor/github.com/IBM/sarama/describe_configs_response.go
  81. 13 6
      vendor/github.com/IBM/sarama/describe_groups_request.go
  82. 19 6
      vendor/github.com/IBM/sarama/describe_groups_response.go
  83. 7 0
      vendor/github.com/IBM/sarama/describe_log_dirs_request.go
  84. 11 0
      vendor/github.com/IBM/sarama/describe_log_dirs_response.go
  85. 4 0
      vendor/github.com/IBM/sarama/describe_user_scram_credentials_request.go
  86. 8 0
      vendor/github.com/IBM/sarama/describe_user_scram_credentials_response.go
  87. 146 11
      vendor/github.com/IBM/sarama/docker-compose.yml
  88. 14 2
      vendor/github.com/IBM/sarama/end_txn_request.go
  89. 18 2
      vendor/github.com/IBM/sarama/end_txn_response.go
  90. 12 7
      vendor/github.com/IBM/sarama/entrypoint.sh
  91. 95 95
      vendor/github.com/IBM/sarama/errors.go
  92. 28 19
      vendor/github.com/IBM/sarama/fetch_request.go
  93. 27 19
      vendor/github.com/IBM/sarama/fetch_response.go
  94. 6 0
      vendor/github.com/IBM/sarama/find_coordinator_request.go
  95. 10 0
      vendor/github.com/IBM/sarama/find_coordinator_response.go
  96. 12 2
      vendor/github.com/IBM/sarama/gssapi_kerberos.go
  97. 14 3
      vendor/github.com/IBM/sarama/heartbeat_request.go
  98. 19 2
      vendor/github.com/IBM/sarama/heartbeat_response.go
  99. 6 1
      vendor/github.com/IBM/sarama/incremental_alter_configs_request.go
  100. 10 1
      vendor/github.com/IBM/sarama/incremental_alter_configs_response.go

+ 18 - 50
controller.go

@@ -25,31 +25,19 @@ func (c *Controller) GetYDB() (int, string) {
 	var gtbStr string
 	var err error
 	if XConfig["IsYDBFixed"] == "Yes" {
-		c.Gtb.ConnString = XConfig["YDBConnString"] + XConfig["DBOptionString"]
-		c.Gtb.SsoSubId = 0
-		c.Gtb.RemoteIp = "localhost"
-		c.Gtb.DeviceDesc = "API-Developer-Device"
-		c.Gtb.UserId = 5
-		c.Gtb.MemberId = 5
-		c.Gtb.UserPermId = 3
-		c.Gtb.MemberPermId = 3
-		c.Gtb.SgroupId = 1
-		c.Gtb.BranchId = 1
-		c.Gtb.StorageId = 1
-		c.Gtb.AgroupId = 1
-		c.Gtb.MemberBuyerId = 1
-		c.Gtb.MemberCompanyId = 1
-		c.Gtb.CompanySort = "AB" //디폴트는 구매/판매 모두 가능
-		c.Gtb.SalesQtyPoint = 0
-		c.Gtb.SalesPrcPoint = 0
-		c.Gtb.SalesAmtPoint = 0
-		c.Gtb.PurchQtyPoint = 0
-		c.Gtb.PurchPrcPoint = 0
-		c.Gtb.PurchAmtPoint = 0
-		c.Gtb.StockQtyPoint = 0
-		c.Gtb.StockPrcPoint = 0
-		c.Gtb.StockAmtPoint = 0
-		c.Gtb.AccAmtPoint = 0
+
+		data, err := ioutil.ReadFile("models/custom.yml")
+		if err != nil {
+			return 507, e.LogStr("ASDFQEWFA", "Can NOT Read custom.yml")
+		}
+
+		var config Config
+		if err := yaml.Unmarshal(data, &config); err == nil {
+			c.Gtb = config.Source
+			c.Gtb.ConnString = config.Source.ConnStr // custom.yml의 Variable name 이 서로 달라서 복사해줌.
+		} else {
+			return 507, e.LogStr("ASDWEWFA", "connString in custom.yml format mismatch ")
+		}
 
 	} else {
 		if gtbStr, err = MdbView(c.GateToken); err != nil {
@@ -91,9 +79,6 @@ func (c *Controller) GetYDB() (int, string) {
 		}
 	}
 
-	// fmt.Println("YDB-kkkk")
-	// fmt.Println(c.Gtb.ConnString)
-	// fmt.Println("YDB-qqqq")
 	if c.Db, err = xorm.NewEngine(XConfig["DbType"], c.Gtb.ConnString); err != nil {
 		return 600, e.LogStr("ADASEF", "DBEngine Open Error")
 	}
@@ -101,25 +86,7 @@ func (c *Controller) GetYDB() (int, string) {
 	if status, msg := c.AttachDB(); status != 200 { // DB 까지 붙여야 memory error 가 안난다.
 		return status, e.LogStr("PBUYJM-", msg)
 	}
-
 	return 200, ""
-	// var connHint string
-	// strArr := strings.Split(c.Gtb.ConnString, "@tcp")
-	// if len(strArr) == 2 {
-	// 	connHint = strArr[1]
-	// } else {
-	// 	return 507, e.LogStr("ASDFQEWFA", "connString format mismatch: "+strArr[1])
-	// }
-
-	// c.Db.ShowSQL(false)
-	// c.Db.SetMaxOpenConns(100)
-	// c.Db.SetMaxIdleConns(20)
-	// c.Db.SetConnMaxLifetime(60 * time.Second)
-	// if _, err := c.Db.IsTableExist("aaa"); err == nil {
-	// 	return 200, e.LogStr("ASDFASFQFE", "YDB connection in "+connHint)
-	// } else {
-	// 	return 600, e.LogStr("PMUHIUYBUYJM-", "YDB connection Fail in "+connHint)
-	// }
 
 }
 
@@ -148,10 +115,6 @@ func (c *Controller) CustomYmlToGateTokenBaseAndDbGet() (int, string) {
 		return 507, e.LogStr("ASDWEWFA", "connString in custom.yml format mismatch ")
 	}
 
-	if c.Db, err = xorm.NewEngine(XConfig["DbType"], c.Gtb.ConnString); err != nil {
-		return 600, e.LogStr("ADASEF", "DBEngine Open Error")
-	}
-
 	if status, msg := c.AttachDB(); status != 200 { // DB 까지 붙여야 memory error 가 안난다.
 		return status, e.LogStr("PBUYJM-", msg)
 	}
@@ -161,6 +124,11 @@ func (c *Controller) CustomYmlToGateTokenBaseAndDbGet() (int, string) {
 
 func (c *Controller) AttachDB() (int, string) {
 
+	var err error
+	if c.Db, err = xorm.NewEngine(XConfig["DbType"], c.Gtb.ConnString); err != nil {
+		return 600, e.LogStr("ADASEF", "DBEngine Open Error")
+	}
+
 	var connHint string
 	strArr := strings.Split(c.Gtb.ConnString, "@tcp")
 	if len(strArr) == 2 {

+ 14 - 15
go.mod

@@ -3,16 +3,20 @@ module github.com/dabory/abango-rest
 go 1.19
 
 require (
-	github.com/IBM/sarama v1.41.3
+	github.com/IBM/sarama v1.43.2
 	github.com/elastic/go-elasticsearch/v7 v7.17.10
-	github.com/go-sql-driver/mysql v1.7.1
+	github.com/go-redis/redis/v8 v8.11.5
+	github.com/go-sql-driver/mysql v1.8.1
 	github.com/go-xorm/xorm v0.7.9
-	github.com/tidwall/buntdb v1.3.0
+	gopkg.in/yaml.v2 v2.4.0
 )
 
 require (
+	filippo.io/edwards25519 v1.1.0 // indirect
+	github.com/cespare/xxhash/v2 v2.1.2 // indirect
 	github.com/davecgh/go-spew v1.1.1 // indirect
-	github.com/eapache/go-resiliency v1.4.0 // indirect
+	github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
+	github.com/eapache/go-resiliency v1.6.0 // indirect
 	github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 // indirect
 	github.com/eapache/queue v1.1.0 // indirect
 	github.com/golang/snappy v0.0.4 // indirect
@@ -24,18 +28,13 @@ require (
 	github.com/jcmturner/gofork v1.7.6 // indirect
 	github.com/jcmturner/gokrb5/v8 v8.4.4 // indirect
 	github.com/jcmturner/rpc/v2 v2.0.3 // indirect
-	github.com/klauspost/compress v1.16.7 // indirect
-	github.com/pierrec/lz4/v4 v4.1.18 // indirect
+	github.com/klauspost/compress v1.17.8 // indirect
+	github.com/kr/text v0.2.0 // indirect
+	github.com/pierrec/lz4/v4 v4.1.21 // indirect
 	github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
-	github.com/tidwall/btree v1.4.2 // indirect
-	github.com/tidwall/gjson v1.14.3 // indirect
-	github.com/tidwall/grect v0.1.4 // indirect
-	github.com/tidwall/match v1.1.1 // indirect
-	github.com/tidwall/pretty v1.2.0 // indirect
-	github.com/tidwall/rtred v0.1.2 // indirect
-	github.com/tidwall/tinyqueue v0.1.1 // indirect
-	golang.org/x/crypto v0.14.0 // indirect
-	golang.org/x/net v0.17.0 // indirect
+	github.com/rogpeppe/go-internal v1.12.0 // indirect
+	golang.org/x/crypto v0.22.0 // indirect
+	golang.org/x/net v0.24.0 // indirect
 	xorm.io/builder v0.3.6 // indirect
 	xorm.io/core v0.7.2-0.20190928055935-90aeac8d08eb // indirect
 )

+ 40 - 35
go.sum

@@ -2,25 +2,32 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
 cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
 cloud.google.com/go v0.37.4 h1:glPeL3BQJsbF6aIIYfZizMwc5LTYz250bDMjttbBGAU=
 cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw=
+filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
+filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/IBM/sarama v1.41.3 h1:MWBEJ12vHC8coMjdEXFq/6ftO6DUZnQlFYcxtOJFa7c=
-github.com/IBM/sarama v1.41.3/go.mod h1:Xxho9HkHd4K/MDUo/T/sOqwtX/17D33++E9Wib6hUdQ=
+github.com/IBM/sarama v1.43.2 h1:HABeEqRUh32z8yzY2hGB/j8mHSzC/HA9zlEjqFNCzSw=
+github.com/IBM/sarama v1.43.2/go.mod h1:Kyo4WkF24Z+1nz7xeVUFWIuKVV8RS3wM8mkvPKMdXFQ=
 github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
 github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
 github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
 github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
 github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
 github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
+github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
+github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
 github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
+github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4 h1:YcpmyvADGYw5LqMnHqSkyIELsHCGF6PkrmM31V8rF7o=
 github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=
+github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
+github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
 github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
-github.com/eapache/go-resiliency v1.4.0 h1:3OK9bWpPk5q6pbFAaYSEwD9CLUSHG8bnZuqX2yMt3B0=
-github.com/eapache/go-resiliency v1.4.0/go.mod h1:5yPzW0MIvSe0JDsv0v+DvcjEv2FyD6iZYSs1ZI+iQho=
+github.com/eapache/go-resiliency v1.6.0 h1:CqGDTLtpwuWKn6Nj3uNUdflaq+/kIPsg0gfNzHton30=
+github.com/eapache/go-resiliency v1.6.0/go.mod h1:5yPzW0MIvSe0JDsv0v+DvcjEv2FyD6iZYSs1ZI+iQho=
 github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
 github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 h1:Oy0F4ALJ04o5Qqpdz8XLIpNA3WM/iSIXqxtqo7UGVws=
 github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3/go.mod h1:YvSRo5mw33fLEx1+DlK6L2VV43tJt5Eyel9n9XBcR+0=
@@ -30,11 +37,14 @@ github.com/elastic/go-elasticsearch/v7 v7.17.10 h1:TCQ8i4PmIJuBunvBS6bwT2ybzVFxx
 github.com/elastic/go-elasticsearch/v7 v7.17.10/go.mod h1:OJ4wdbtDNk5g503kvlHLyErCgQwwzmDtaFC4XyOxXA4=
 github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
 github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
+github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
+github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
 github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
-github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
-github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
+github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
+github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
 github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:9wScpmSP5A3Bk8V3XHWUcJmYTh+ZnlHVyc+A4oZYS3Y=
 github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:56xuuqnHyryaerycW3BfssRdxQstACi0Epw/yC5E2xM=
@@ -85,23 +95,29 @@ github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJk
 github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
 github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
-github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
+github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU=
+github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
+github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
 github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A=
 github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
 github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o=
 github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
 github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
+github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
 github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
 github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
 github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
-github.com/pierrec/lz4/v4 v4.1.18 h1:xaKrnTkyoqfh1YItXl56+6KJNVYWlEEPuAQW9xsplYQ=
-github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
+github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
+github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -116,6 +132,8 @@ github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R
 github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
 github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM=
 github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
+github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
+github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
 github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
 github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -128,26 +146,7 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
 github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
 github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
-github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
-github.com/tidwall/assert v0.1.0 h1:aWcKyRBUAdLoVebxo95N7+YZVTFF/ASTr7BN4sLP6XI=
-github.com/tidwall/btree v1.4.2 h1:PpkaieETJMUxYNADsjgtNRcERX7mGc/GP2zp/r5FM3g=
-github.com/tidwall/btree v1.4.2/go.mod h1:LGm8L/DZjPLmeWGjv5kFrY8dL4uVhMmzmmLYmsObdKE=
-github.com/tidwall/buntdb v1.3.0 h1:gdhWO+/YwoB2qZMeAU9JcWWsHSYU3OvcieYgFRS0zwA=
-github.com/tidwall/buntdb v1.3.0/go.mod h1:lZZrZUWzlyDJKlLQ6DKAy53LnG7m5kHyrEHvvcDmBpU=
-github.com/tidwall/gjson v1.12.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
-github.com/tidwall/gjson v1.14.3 h1:9jvXn7olKEHU1S9vwoMGliaT8jq1vJ7IH/n9zD9Dnlw=
-github.com/tidwall/gjson v1.14.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
-github.com/tidwall/grect v0.1.4 h1:dA3oIgNgWdSspFzn1kS4S/RDpZFLrIxAZOdJKjYapOg=
-github.com/tidwall/grect v0.1.4/go.mod h1:9FBsaYRaR0Tcy4UwefBX/UDcDcDy9V5jUcxHzv2jd5Q=
-github.com/tidwall/lotsa v1.0.2 h1:dNVBH5MErdaQ/xd9s769R31/n2dXavsQ0Yf4TMEHHw8=
-github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
-github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
-github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
-github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
-github.com/tidwall/rtred v0.1.2 h1:exmoQtOLvDoO8ud++6LwVsAMTu0KPzLTUrMln8u1yu8=
-github.com/tidwall/rtred v0.1.2/go.mod h1:hd69WNXQ5RP9vHd7dqekAz+RIdtfBogmglkZSRxCHFQ=
-github.com/tidwall/tinyqueue v0.1.1 h1:SpNEvEggbpyN5DIReaJ2/1ndroY8iyEGxPYxoSaymYE=
-github.com/tidwall/tinyqueue v0.1.1/go.mod h1:O/QNHwrnjqr6IHItYrzoHAKYhBkLI67Q096fQP5zMYw=
+github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
 github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
@@ -157,8 +156,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
 golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
-golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
-golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
+golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
+golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
@@ -178,8 +177,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
-golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
-golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
+golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
+golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
 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/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -188,7 +187,7 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
+golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -200,6 +199,7 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@@ -208,6 +208,7 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -229,10 +230,14 @@ google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZi
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
 gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

+ 27 - 0
vendor/filippo.io/edwards25519/LICENSE

@@ -0,0 +1,27 @@
+Copyright (c) 2009 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+   * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+   * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ 14 - 0
vendor/filippo.io/edwards25519/README.md

@@ -0,0 +1,14 @@
+# filippo.io/edwards25519
+
+```
+import "filippo.io/edwards25519"
+```
+
+This library implements the edwards25519 elliptic curve, exposing the necessary APIs to build a wide array of higher-level primitives.
+Read the docs at [pkg.go.dev/filippo.io/edwards25519](https://pkg.go.dev/filippo.io/edwards25519).
+
+The code is originally derived from Adam Langley's internal implementation in the Go standard library, and includes George Tankersley's [performance improvements](https://golang.org/cl/71950). It was then further developed by Henry de Valence for use in ristretto255, and was finally [merged back into the Go standard library](https://golang.org/cl/276272) as of Go 1.17. It now tracks the upstream codebase and extends it with additional functionality.
+
+Most users don't need this package, and should instead use `crypto/ed25519` for signatures, `golang.org/x/crypto/curve25519` for Diffie-Hellman, or `github.com/gtank/ristretto255` for prime order group logic. However, for anyone currently using a fork of `crypto/internal/edwards25519`/`crypto/ed25519/internal/edwards25519` or `github.com/agl/edwards25519`, this package should be a safer, faster, and more powerful alternative.
+
+Since this package is meant to curb proliferation of edwards25519 implementations in the Go ecosystem, it welcomes requests for new APIs or reviewable performance improvements.

+ 20 - 0
vendor/filippo.io/edwards25519/doc.go

@@ -0,0 +1,20 @@
+// Copyright (c) 2021 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 edwards25519 implements group logic for the twisted Edwards curve
+//
+//	-x^2 + y^2 = 1 + -(121665/121666)*x^2*y^2
+//
+// This is better known as the Edwards curve equivalent to Curve25519, and is
+// the curve used by the Ed25519 signature scheme.
+//
+// Most users don't need this package, and should instead use crypto/ed25519 for
+// signatures, golang.org/x/crypto/curve25519 for Diffie-Hellman, or
+// github.com/gtank/ristretto255 for prime order group logic.
+//
+// However, developers who do need to interact with low-level edwards25519
+// operations can use this package, which is an extended version of
+// crypto/internal/edwards25519 from the standard library repackaged as
+// an importable module.
+package edwards25519

+ 427 - 0
vendor/filippo.io/edwards25519/edwards25519.go

@@ -0,0 +1,427 @@
+// Copyright (c) 2017 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 edwards25519
+
+import (
+	"errors"
+
+	"filippo.io/edwards25519/field"
+)
+
+// Point types.
+
+type projP1xP1 struct {
+	X, Y, Z, T field.Element
+}
+
+type projP2 struct {
+	X, Y, Z field.Element
+}
+
+// Point represents a point on the edwards25519 curve.
+//
+// This type works similarly to math/big.Int, and all arguments and receivers
+// are allowed to alias.
+//
+// The zero value is NOT valid, and it may be used only as a receiver.
+type Point struct {
+	// Make the type not comparable (i.e. used with == or as a map key), as
+	// equivalent points can be represented by different Go values.
+	_ incomparable
+
+	// The point is internally represented in extended coordinates (X, Y, Z, T)
+	// where x = X/Z, y = Y/Z, and xy = T/Z per https://eprint.iacr.org/2008/522.
+	x, y, z, t field.Element
+}
+
+type incomparable [0]func()
+
+func checkInitialized(points ...*Point) {
+	for _, p := range points {
+		if p.x == (field.Element{}) && p.y == (field.Element{}) {
+			panic("edwards25519: use of uninitialized Point")
+		}
+	}
+}
+
+type projCached struct {
+	YplusX, YminusX, Z, T2d field.Element
+}
+
+type affineCached struct {
+	YplusX, YminusX, T2d field.Element
+}
+
+// Constructors.
+
+func (v *projP2) Zero() *projP2 {
+	v.X.Zero()
+	v.Y.One()
+	v.Z.One()
+	return v
+}
+
+// identity is the point at infinity.
+var identity, _ = new(Point).SetBytes([]byte{
+	1, 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})
+
+// NewIdentityPoint returns a new Point set to the identity.
+func NewIdentityPoint() *Point {
+	return new(Point).Set(identity)
+}
+
+// generator is the canonical curve basepoint. See TestGenerator for the
+// correspondence of this encoding with the values in RFC 8032.
+var generator, _ = new(Point).SetBytes([]byte{
+	0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+	0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+	0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+	0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66})
+
+// NewGeneratorPoint returns a new Point set to the canonical generator.
+func NewGeneratorPoint() *Point {
+	return new(Point).Set(generator)
+}
+
+func (v *projCached) Zero() *projCached {
+	v.YplusX.One()
+	v.YminusX.One()
+	v.Z.One()
+	v.T2d.Zero()
+	return v
+}
+
+func (v *affineCached) Zero() *affineCached {
+	v.YplusX.One()
+	v.YminusX.One()
+	v.T2d.Zero()
+	return v
+}
+
+// Assignments.
+
+// Set sets v = u, and returns v.
+func (v *Point) Set(u *Point) *Point {
+	*v = *u
+	return v
+}
+
+// Encoding.
+
+// Bytes returns the canonical 32-byte encoding of v, according to RFC 8032,
+// Section 5.1.2.
+func (v *Point) Bytes() []byte {
+	// This function is outlined to make the allocations inline in the caller
+	// rather than happen on the heap.
+	var buf [32]byte
+	return v.bytes(&buf)
+}
+
+func (v *Point) bytes(buf *[32]byte) []byte {
+	checkInitialized(v)
+
+	var zInv, x, y field.Element
+	zInv.Invert(&v.z)       // zInv = 1 / Z
+	x.Multiply(&v.x, &zInv) // x = X / Z
+	y.Multiply(&v.y, &zInv) // y = Y / Z
+
+	out := copyFieldElement(buf, &y)
+	out[31] |= byte(x.IsNegative() << 7)
+	return out
+}
+
+var feOne = new(field.Element).One()
+
+// SetBytes sets v = x, where x is a 32-byte encoding of v. If x does not
+// represent a valid point on the curve, SetBytes returns nil and an error and
+// the receiver is unchanged. Otherwise, SetBytes returns v.
+//
+// Note that SetBytes accepts all non-canonical encodings of valid points.
+// That is, it follows decoding rules that match most implementations in
+// the ecosystem rather than RFC 8032.
+func (v *Point) SetBytes(x []byte) (*Point, error) {
+	// Specifically, the non-canonical encodings that are accepted are
+	//   1) the ones where the field element is not reduced (see the
+	//      (*field.Element).SetBytes docs) and
+	//   2) the ones where the x-coordinate is zero and the sign bit is set.
+	//
+	// Read more at https://hdevalence.ca/blog/2020-10-04-its-25519am,
+	// specifically the "Canonical A, R" section.
+
+	y, err := new(field.Element).SetBytes(x)
+	if err != nil {
+		return nil, errors.New("edwards25519: invalid point encoding length")
+	}
+
+	// -x² + y² = 1 + dx²y²
+	// x² + dx²y² = x²(dy² + 1) = y² - 1
+	// x² = (y² - 1) / (dy² + 1)
+
+	// u = y² - 1
+	y2 := new(field.Element).Square(y)
+	u := new(field.Element).Subtract(y2, feOne)
+
+	// v = dy² + 1
+	vv := new(field.Element).Multiply(y2, d)
+	vv = vv.Add(vv, feOne)
+
+	// x = +√(u/v)
+	xx, wasSquare := new(field.Element).SqrtRatio(u, vv)
+	if wasSquare == 0 {
+		return nil, errors.New("edwards25519: invalid point encoding")
+	}
+
+	// Select the negative square root if the sign bit is set.
+	xxNeg := new(field.Element).Negate(xx)
+	xx = xx.Select(xxNeg, xx, int(x[31]>>7))
+
+	v.x.Set(xx)
+	v.y.Set(y)
+	v.z.One()
+	v.t.Multiply(xx, y) // xy = T / Z
+
+	return v, nil
+}
+
+func copyFieldElement(buf *[32]byte, v *field.Element) []byte {
+	copy(buf[:], v.Bytes())
+	return buf[:]
+}
+
+// Conversions.
+
+func (v *projP2) FromP1xP1(p *projP1xP1) *projP2 {
+	v.X.Multiply(&p.X, &p.T)
+	v.Y.Multiply(&p.Y, &p.Z)
+	v.Z.Multiply(&p.Z, &p.T)
+	return v
+}
+
+func (v *projP2) FromP3(p *Point) *projP2 {
+	v.X.Set(&p.x)
+	v.Y.Set(&p.y)
+	v.Z.Set(&p.z)
+	return v
+}
+
+func (v *Point) fromP1xP1(p *projP1xP1) *Point {
+	v.x.Multiply(&p.X, &p.T)
+	v.y.Multiply(&p.Y, &p.Z)
+	v.z.Multiply(&p.Z, &p.T)
+	v.t.Multiply(&p.X, &p.Y)
+	return v
+}
+
+func (v *Point) fromP2(p *projP2) *Point {
+	v.x.Multiply(&p.X, &p.Z)
+	v.y.Multiply(&p.Y, &p.Z)
+	v.z.Square(&p.Z)
+	v.t.Multiply(&p.X, &p.Y)
+	return v
+}
+
+// d is a constant in the curve equation.
+var d, _ = new(field.Element).SetBytes([]byte{
+	0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb, 0x75,
+	0xab, 0xd8, 0x41, 0x41, 0x4d, 0x0a, 0x70, 0x00,
+	0x98, 0xe8, 0x79, 0x77, 0x79, 0x40, 0xc7, 0x8c,
+	0x73, 0xfe, 0x6f, 0x2b, 0xee, 0x6c, 0x03, 0x52})
+var d2 = new(field.Element).Add(d, d)
+
+func (v *projCached) FromP3(p *Point) *projCached {
+	v.YplusX.Add(&p.y, &p.x)
+	v.YminusX.Subtract(&p.y, &p.x)
+	v.Z.Set(&p.z)
+	v.T2d.Multiply(&p.t, d2)
+	return v
+}
+
+func (v *affineCached) FromP3(p *Point) *affineCached {
+	v.YplusX.Add(&p.y, &p.x)
+	v.YminusX.Subtract(&p.y, &p.x)
+	v.T2d.Multiply(&p.t, d2)
+
+	var invZ field.Element
+	invZ.Invert(&p.z)
+	v.YplusX.Multiply(&v.YplusX, &invZ)
+	v.YminusX.Multiply(&v.YminusX, &invZ)
+	v.T2d.Multiply(&v.T2d, &invZ)
+	return v
+}
+
+// (Re)addition and subtraction.
+
+// Add sets v = p + q, and returns v.
+func (v *Point) Add(p, q *Point) *Point {
+	checkInitialized(p, q)
+	qCached := new(projCached).FromP3(q)
+	result := new(projP1xP1).Add(p, qCached)
+	return v.fromP1xP1(result)
+}
+
+// Subtract sets v = p - q, and returns v.
+func (v *Point) Subtract(p, q *Point) *Point {
+	checkInitialized(p, q)
+	qCached := new(projCached).FromP3(q)
+	result := new(projP1xP1).Sub(p, qCached)
+	return v.fromP1xP1(result)
+}
+
+func (v *projP1xP1) Add(p *Point, q *projCached) *projP1xP1 {
+	var YplusX, YminusX, PP, MM, TT2d, ZZ2 field.Element
+
+	YplusX.Add(&p.y, &p.x)
+	YminusX.Subtract(&p.y, &p.x)
+
+	PP.Multiply(&YplusX, &q.YplusX)
+	MM.Multiply(&YminusX, &q.YminusX)
+	TT2d.Multiply(&p.t, &q.T2d)
+	ZZ2.Multiply(&p.z, &q.Z)
+
+	ZZ2.Add(&ZZ2, &ZZ2)
+
+	v.X.Subtract(&PP, &MM)
+	v.Y.Add(&PP, &MM)
+	v.Z.Add(&ZZ2, &TT2d)
+	v.T.Subtract(&ZZ2, &TT2d)
+	return v
+}
+
+func (v *projP1xP1) Sub(p *Point, q *projCached) *projP1xP1 {
+	var YplusX, YminusX, PP, MM, TT2d, ZZ2 field.Element
+
+	YplusX.Add(&p.y, &p.x)
+	YminusX.Subtract(&p.y, &p.x)
+
+	PP.Multiply(&YplusX, &q.YminusX) // flipped sign
+	MM.Multiply(&YminusX, &q.YplusX) // flipped sign
+	TT2d.Multiply(&p.t, &q.T2d)
+	ZZ2.Multiply(&p.z, &q.Z)
+
+	ZZ2.Add(&ZZ2, &ZZ2)
+
+	v.X.Subtract(&PP, &MM)
+	v.Y.Add(&PP, &MM)
+	v.Z.Subtract(&ZZ2, &TT2d) // flipped sign
+	v.T.Add(&ZZ2, &TT2d)      // flipped sign
+	return v
+}
+
+func (v *projP1xP1) AddAffine(p *Point, q *affineCached) *projP1xP1 {
+	var YplusX, YminusX, PP, MM, TT2d, Z2 field.Element
+
+	YplusX.Add(&p.y, &p.x)
+	YminusX.Subtract(&p.y, &p.x)
+
+	PP.Multiply(&YplusX, &q.YplusX)
+	MM.Multiply(&YminusX, &q.YminusX)
+	TT2d.Multiply(&p.t, &q.T2d)
+
+	Z2.Add(&p.z, &p.z)
+
+	v.X.Subtract(&PP, &MM)
+	v.Y.Add(&PP, &MM)
+	v.Z.Add(&Z2, &TT2d)
+	v.T.Subtract(&Z2, &TT2d)
+	return v
+}
+
+func (v *projP1xP1) SubAffine(p *Point, q *affineCached) *projP1xP1 {
+	var YplusX, YminusX, PP, MM, TT2d, Z2 field.Element
+
+	YplusX.Add(&p.y, &p.x)
+	YminusX.Subtract(&p.y, &p.x)
+
+	PP.Multiply(&YplusX, &q.YminusX) // flipped sign
+	MM.Multiply(&YminusX, &q.YplusX) // flipped sign
+	TT2d.Multiply(&p.t, &q.T2d)
+
+	Z2.Add(&p.z, &p.z)
+
+	v.X.Subtract(&PP, &MM)
+	v.Y.Add(&PP, &MM)
+	v.Z.Subtract(&Z2, &TT2d) // flipped sign
+	v.T.Add(&Z2, &TT2d)      // flipped sign
+	return v
+}
+
+// Doubling.
+
+func (v *projP1xP1) Double(p *projP2) *projP1xP1 {
+	var XX, YY, ZZ2, XplusYsq field.Element
+
+	XX.Square(&p.X)
+	YY.Square(&p.Y)
+	ZZ2.Square(&p.Z)
+	ZZ2.Add(&ZZ2, &ZZ2)
+	XplusYsq.Add(&p.X, &p.Y)
+	XplusYsq.Square(&XplusYsq)
+
+	v.Y.Add(&YY, &XX)
+	v.Z.Subtract(&YY, &XX)
+
+	v.X.Subtract(&XplusYsq, &v.Y)
+	v.T.Subtract(&ZZ2, &v.Z)
+	return v
+}
+
+// Negation.
+
+// Negate sets v = -p, and returns v.
+func (v *Point) Negate(p *Point) *Point {
+	checkInitialized(p)
+	v.x.Negate(&p.x)
+	v.y.Set(&p.y)
+	v.z.Set(&p.z)
+	v.t.Negate(&p.t)
+	return v
+}
+
+// Equal returns 1 if v is equivalent to u, and 0 otherwise.
+func (v *Point) Equal(u *Point) int {
+	checkInitialized(v, u)
+
+	var t1, t2, t3, t4 field.Element
+	t1.Multiply(&v.x, &u.z)
+	t2.Multiply(&u.x, &v.z)
+	t3.Multiply(&v.y, &u.z)
+	t4.Multiply(&u.y, &v.z)
+
+	return t1.Equal(&t2) & t3.Equal(&t4)
+}
+
+// Constant-time operations
+
+// Select sets v to a if cond == 1 and to b if cond == 0.
+func (v *projCached) Select(a, b *projCached, cond int) *projCached {
+	v.YplusX.Select(&a.YplusX, &b.YplusX, cond)
+	v.YminusX.Select(&a.YminusX, &b.YminusX, cond)
+	v.Z.Select(&a.Z, &b.Z, cond)
+	v.T2d.Select(&a.T2d, &b.T2d, cond)
+	return v
+}
+
+// Select sets v to a if cond == 1 and to b if cond == 0.
+func (v *affineCached) Select(a, b *affineCached, cond int) *affineCached {
+	v.YplusX.Select(&a.YplusX, &b.YplusX, cond)
+	v.YminusX.Select(&a.YminusX, &b.YminusX, cond)
+	v.T2d.Select(&a.T2d, &b.T2d, cond)
+	return v
+}
+
+// CondNeg negates v if cond == 1 and leaves it unchanged if cond == 0.
+func (v *projCached) CondNeg(cond int) *projCached {
+	v.YplusX.Swap(&v.YminusX, cond)
+	v.T2d.Select(new(field.Element).Negate(&v.T2d), &v.T2d, cond)
+	return v
+}
+
+// CondNeg negates v if cond == 1 and leaves it unchanged if cond == 0.
+func (v *affineCached) CondNeg(cond int) *affineCached {
+	v.YplusX.Swap(&v.YminusX, cond)
+	v.T2d.Select(new(field.Element).Negate(&v.T2d), &v.T2d, cond)
+	return v
+}

+ 349 - 0
vendor/filippo.io/edwards25519/extra.go

@@ -0,0 +1,349 @@
+// Copyright (c) 2021 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 edwards25519
+
+// This file contains additional functionality that is not included in the
+// upstream crypto/internal/edwards25519 package.
+
+import (
+	"errors"
+
+	"filippo.io/edwards25519/field"
+)
+
+// ExtendedCoordinates returns v in extended coordinates (X:Y:Z:T) where
+// x = X/Z, y = Y/Z, and xy = T/Z as in https://eprint.iacr.org/2008/522.
+func (v *Point) ExtendedCoordinates() (X, Y, Z, T *field.Element) {
+	// This function is outlined to make the allocations inline in the caller
+	// rather than happen on the heap. Don't change the style without making
+	// sure it doesn't increase the inliner cost.
+	var e [4]field.Element
+	X, Y, Z, T = v.extendedCoordinates(&e)
+	return
+}
+
+func (v *Point) extendedCoordinates(e *[4]field.Element) (X, Y, Z, T *field.Element) {
+	checkInitialized(v)
+	X = e[0].Set(&v.x)
+	Y = e[1].Set(&v.y)
+	Z = e[2].Set(&v.z)
+	T = e[3].Set(&v.t)
+	return
+}
+
+// SetExtendedCoordinates sets v = (X:Y:Z:T) in extended coordinates where
+// x = X/Z, y = Y/Z, and xy = T/Z as in https://eprint.iacr.org/2008/522.
+//
+// If the coordinates are invalid or don't represent a valid point on the curve,
+// SetExtendedCoordinates returns nil and an error and the receiver is
+// unchanged. Otherwise, SetExtendedCoordinates returns v.
+func (v *Point) SetExtendedCoordinates(X, Y, Z, T *field.Element) (*Point, error) {
+	if !isOnCurve(X, Y, Z, T) {
+		return nil, errors.New("edwards25519: invalid point coordinates")
+	}
+	v.x.Set(X)
+	v.y.Set(Y)
+	v.z.Set(Z)
+	v.t.Set(T)
+	return v, nil
+}
+
+func isOnCurve(X, Y, Z, T *field.Element) bool {
+	var lhs, rhs field.Element
+	XX := new(field.Element).Square(X)
+	YY := new(field.Element).Square(Y)
+	ZZ := new(field.Element).Square(Z)
+	TT := new(field.Element).Square(T)
+	// -x² + y² = 1 + dx²y²
+	// -(X/Z)² + (Y/Z)² = 1 + d(T/Z)²
+	// -X² + Y² = Z² + dT²
+	lhs.Subtract(YY, XX)
+	rhs.Multiply(d, TT).Add(&rhs, ZZ)
+	if lhs.Equal(&rhs) != 1 {
+		return false
+	}
+	// xy = T/Z
+	// XY/Z² = T/Z
+	// XY = TZ
+	lhs.Multiply(X, Y)
+	rhs.Multiply(T, Z)
+	return lhs.Equal(&rhs) == 1
+}
+
+// BytesMontgomery converts v to a point on the birationally-equivalent
+// Curve25519 Montgomery curve, and returns its canonical 32 bytes encoding
+// according to RFC 7748.
+//
+// Note that BytesMontgomery only encodes the u-coordinate, so v and -v encode
+// to the same value. If v is the identity point, BytesMontgomery returns 32
+// zero bytes, analogously to the X25519 function.
+//
+// The lack of an inverse operation (such as SetMontgomeryBytes) is deliberate:
+// while every valid edwards25519 point has a unique u-coordinate Montgomery
+// encoding, X25519 accepts inputs on the quadratic twist, which don't correspond
+// to any edwards25519 point, and every other X25519 input corresponds to two
+// edwards25519 points.
+func (v *Point) BytesMontgomery() []byte {
+	// This function is outlined to make the allocations inline in the caller
+	// rather than happen on the heap.
+	var buf [32]byte
+	return v.bytesMontgomery(&buf)
+}
+
+func (v *Point) bytesMontgomery(buf *[32]byte) []byte {
+	checkInitialized(v)
+
+	// RFC 7748, Section 4.1 provides the bilinear map to calculate the
+	// Montgomery u-coordinate
+	//
+	//              u = (1 + y) / (1 - y)
+	//
+	// where y = Y / Z.
+
+	var y, recip, u field.Element
+
+	y.Multiply(&v.y, y.Invert(&v.z))        // y = Y / Z
+	recip.Invert(recip.Subtract(feOne, &y)) // r = 1/(1 - y)
+	u.Multiply(u.Add(feOne, &y), &recip)    // u = (1 + y)*r
+
+	return copyFieldElement(buf, &u)
+}
+
+// MultByCofactor sets v = 8 * p, and returns v.
+func (v *Point) MultByCofactor(p *Point) *Point {
+	checkInitialized(p)
+	result := projP1xP1{}
+	pp := (&projP2{}).FromP3(p)
+	result.Double(pp)
+	pp.FromP1xP1(&result)
+	result.Double(pp)
+	pp.FromP1xP1(&result)
+	result.Double(pp)
+	return v.fromP1xP1(&result)
+}
+
+// Given k > 0, set s = s**(2*i).
+func (s *Scalar) pow2k(k int) {
+	for i := 0; i < k; i++ {
+		s.Multiply(s, s)
+	}
+}
+
+// Invert sets s to the inverse of a nonzero scalar v, and returns s.
+//
+// If t is zero, Invert returns zero.
+func (s *Scalar) Invert(t *Scalar) *Scalar {
+	// Uses a hardcoded sliding window of width 4.
+	var table [8]Scalar
+	var tt Scalar
+	tt.Multiply(t, t)
+	table[0] = *t
+	for i := 0; i < 7; i++ {
+		table[i+1].Multiply(&table[i], &tt)
+	}
+	// Now table = [t**1, t**3, t**5, t**7, t**9, t**11, t**13, t**15]
+	// so t**k = t[k/2] for odd k
+
+	// To compute the sliding window digits, use the following Sage script:
+
+	// sage: import itertools
+	// sage: def sliding_window(w,k):
+	// ....:     digits = []
+	// ....:     while k > 0:
+	// ....:         if k % 2 == 1:
+	// ....:             kmod = k % (2**w)
+	// ....:             digits.append(kmod)
+	// ....:             k = k - kmod
+	// ....:         else:
+	// ....:             digits.append(0)
+	// ....:         k = k // 2
+	// ....:     return digits
+
+	// Now we can compute s roughly as follows:
+
+	// sage: s = 1
+	// sage: for coeff in reversed(sliding_window(4,l-2)):
+	// ....:     s = s*s
+	// ....:     if coeff > 0 :
+	// ....:         s = s*t**coeff
+
+	// This works on one bit at a time, with many runs of zeros.
+	// The digits can be collapsed into [(count, coeff)] as follows:
+
+	// sage: [(len(list(group)),d) for d,group in itertools.groupby(sliding_window(4,l-2))]
+
+	// Entries of the form (k, 0) turn into pow2k(k)
+	// Entries of the form (1, coeff) turn into a squaring and then a table lookup.
+	// We can fold the squaring into the previous pow2k(k) as pow2k(k+1).
+
+	*s = table[1/2]
+	s.pow2k(127 + 1)
+	s.Multiply(s, &table[1/2])
+	s.pow2k(4 + 1)
+	s.Multiply(s, &table[9/2])
+	s.pow2k(3 + 1)
+	s.Multiply(s, &table[11/2])
+	s.pow2k(3 + 1)
+	s.Multiply(s, &table[13/2])
+	s.pow2k(3 + 1)
+	s.Multiply(s, &table[15/2])
+	s.pow2k(4 + 1)
+	s.Multiply(s, &table[7/2])
+	s.pow2k(4 + 1)
+	s.Multiply(s, &table[15/2])
+	s.pow2k(3 + 1)
+	s.Multiply(s, &table[5/2])
+	s.pow2k(3 + 1)
+	s.Multiply(s, &table[1/2])
+	s.pow2k(4 + 1)
+	s.Multiply(s, &table[15/2])
+	s.pow2k(4 + 1)
+	s.Multiply(s, &table[15/2])
+	s.pow2k(4 + 1)
+	s.Multiply(s, &table[7/2])
+	s.pow2k(3 + 1)
+	s.Multiply(s, &table[3/2])
+	s.pow2k(4 + 1)
+	s.Multiply(s, &table[11/2])
+	s.pow2k(5 + 1)
+	s.Multiply(s, &table[11/2])
+	s.pow2k(9 + 1)
+	s.Multiply(s, &table[9/2])
+	s.pow2k(3 + 1)
+	s.Multiply(s, &table[3/2])
+	s.pow2k(4 + 1)
+	s.Multiply(s, &table[3/2])
+	s.pow2k(4 + 1)
+	s.Multiply(s, &table[3/2])
+	s.pow2k(4 + 1)
+	s.Multiply(s, &table[9/2])
+	s.pow2k(3 + 1)
+	s.Multiply(s, &table[7/2])
+	s.pow2k(3 + 1)
+	s.Multiply(s, &table[3/2])
+	s.pow2k(3 + 1)
+	s.Multiply(s, &table[13/2])
+	s.pow2k(3 + 1)
+	s.Multiply(s, &table[7/2])
+	s.pow2k(4 + 1)
+	s.Multiply(s, &table[9/2])
+	s.pow2k(3 + 1)
+	s.Multiply(s, &table[15/2])
+	s.pow2k(4 + 1)
+	s.Multiply(s, &table[11/2])
+
+	return s
+}
+
+// MultiScalarMult sets v = sum(scalars[i] * points[i]), and returns v.
+//
+// Execution time depends only on the lengths of the two slices, which must match.
+func (v *Point) MultiScalarMult(scalars []*Scalar, points []*Point) *Point {
+	if len(scalars) != len(points) {
+		panic("edwards25519: called MultiScalarMult with different size inputs")
+	}
+	checkInitialized(points...)
+
+	// Proceed as in the single-base case, but share doublings
+	// between each point in the multiscalar equation.
+
+	// Build lookup tables for each point
+	tables := make([]projLookupTable, len(points))
+	for i := range tables {
+		tables[i].FromP3(points[i])
+	}
+	// Compute signed radix-16 digits for each scalar
+	digits := make([][64]int8, len(scalars))
+	for i := range digits {
+		digits[i] = scalars[i].signedRadix16()
+	}
+
+	// Unwrap first loop iteration to save computing 16*identity
+	multiple := &projCached{}
+	tmp1 := &projP1xP1{}
+	tmp2 := &projP2{}
+	// Lookup-and-add the appropriate multiple of each input point
+	for j := range tables {
+		tables[j].SelectInto(multiple, digits[j][63])
+		tmp1.Add(v, multiple) // tmp1 = v + x_(j,63)*Q in P1xP1 coords
+		v.fromP1xP1(tmp1)     // update v
+	}
+	tmp2.FromP3(v) // set up tmp2 = v in P2 coords for next iteration
+	for i := 62; i >= 0; i-- {
+		tmp1.Double(tmp2)    // tmp1 =  2*(prev) in P1xP1 coords
+		tmp2.FromP1xP1(tmp1) // tmp2 =  2*(prev) in P2 coords
+		tmp1.Double(tmp2)    // tmp1 =  4*(prev) in P1xP1 coords
+		tmp2.FromP1xP1(tmp1) // tmp2 =  4*(prev) in P2 coords
+		tmp1.Double(tmp2)    // tmp1 =  8*(prev) in P1xP1 coords
+		tmp2.FromP1xP1(tmp1) // tmp2 =  8*(prev) in P2 coords
+		tmp1.Double(tmp2)    // tmp1 = 16*(prev) in P1xP1 coords
+		v.fromP1xP1(tmp1)    //    v = 16*(prev) in P3 coords
+		// Lookup-and-add the appropriate multiple of each input point
+		for j := range tables {
+			tables[j].SelectInto(multiple, digits[j][i])
+			tmp1.Add(v, multiple) // tmp1 = v + x_(j,i)*Q in P1xP1 coords
+			v.fromP1xP1(tmp1)     // update v
+		}
+		tmp2.FromP3(v) // set up tmp2 = v in P2 coords for next iteration
+	}
+	return v
+}
+
+// VarTimeMultiScalarMult sets v = sum(scalars[i] * points[i]), and returns v.
+//
+// Execution time depends on the inputs.
+func (v *Point) VarTimeMultiScalarMult(scalars []*Scalar, points []*Point) *Point {
+	if len(scalars) != len(points) {
+		panic("edwards25519: called VarTimeMultiScalarMult with different size inputs")
+	}
+	checkInitialized(points...)
+
+	// Generalize double-base NAF computation to arbitrary sizes.
+	// Here all the points are dynamic, so we only use the smaller
+	// tables.
+
+	// Build lookup tables for each point
+	tables := make([]nafLookupTable5, len(points))
+	for i := range tables {
+		tables[i].FromP3(points[i])
+	}
+	// Compute a NAF for each scalar
+	nafs := make([][256]int8, len(scalars))
+	for i := range nafs {
+		nafs[i] = scalars[i].nonAdjacentForm(5)
+	}
+
+	multiple := &projCached{}
+	tmp1 := &projP1xP1{}
+	tmp2 := &projP2{}
+	tmp2.Zero()
+
+	// Move from high to low bits, doubling the accumulator
+	// at each iteration and checking whether there is a nonzero
+	// coefficient to look up a multiple of.
+	//
+	// Skip trying to find the first nonzero coefficent, because
+	// searching might be more work than a few extra doublings.
+	for i := 255; i >= 0; i-- {
+		tmp1.Double(tmp2)
+
+		for j := range nafs {
+			if nafs[j][i] > 0 {
+				v.fromP1xP1(tmp1)
+				tables[j].SelectInto(multiple, nafs[j][i])
+				tmp1.Add(v, multiple)
+			} else if nafs[j][i] < 0 {
+				v.fromP1xP1(tmp1)
+				tables[j].SelectInto(multiple, -nafs[j][i])
+				tmp1.Sub(v, multiple)
+			}
+		}
+
+		tmp2.FromP1xP1(tmp1)
+	}
+
+	v.fromP2(tmp2)
+	return v
+}

+ 420 - 0
vendor/filippo.io/edwards25519/field/fe.go

@@ -0,0 +1,420 @@
+// Copyright (c) 2017 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 field implements fast arithmetic modulo 2^255-19.
+package field
+
+import (
+	"crypto/subtle"
+	"encoding/binary"
+	"errors"
+	"math/bits"
+)
+
+// Element represents an element of the field GF(2^255-19). Note that this
+// is not a cryptographically secure group, and should only be used to interact
+// with edwards25519.Point coordinates.
+//
+// This type works similarly to math/big.Int, and all arguments and receivers
+// are allowed to alias.
+//
+// The zero value is a valid zero element.
+type Element struct {
+	// An element t represents the integer
+	//     t.l0 + t.l1*2^51 + t.l2*2^102 + t.l3*2^153 + t.l4*2^204
+	//
+	// Between operations, all limbs are expected to be lower than 2^52.
+	l0 uint64
+	l1 uint64
+	l2 uint64
+	l3 uint64
+	l4 uint64
+}
+
+const maskLow51Bits uint64 = (1 << 51) - 1
+
+var feZero = &Element{0, 0, 0, 0, 0}
+
+// Zero sets v = 0, and returns v.
+func (v *Element) Zero() *Element {
+	*v = *feZero
+	return v
+}
+
+var feOne = &Element{1, 0, 0, 0, 0}
+
+// One sets v = 1, and returns v.
+func (v *Element) One() *Element {
+	*v = *feOne
+	return v
+}
+
+// reduce reduces v modulo 2^255 - 19 and returns it.
+func (v *Element) reduce() *Element {
+	v.carryPropagate()
+
+	// After the light reduction we now have a field element representation
+	// v < 2^255 + 2^13 * 19, but need v < 2^255 - 19.
+
+	// If v >= 2^255 - 19, then v + 19 >= 2^255, which would overflow 2^255 - 1,
+	// generating a carry. That is, c will be 0 if v < 2^255 - 19, and 1 otherwise.
+	c := (v.l0 + 19) >> 51
+	c = (v.l1 + c) >> 51
+	c = (v.l2 + c) >> 51
+	c = (v.l3 + c) >> 51
+	c = (v.l4 + c) >> 51
+
+	// If v < 2^255 - 19 and c = 0, this will be a no-op. Otherwise, it's
+	// effectively applying the reduction identity to the carry.
+	v.l0 += 19 * c
+
+	v.l1 += v.l0 >> 51
+	v.l0 = v.l0 & maskLow51Bits
+	v.l2 += v.l1 >> 51
+	v.l1 = v.l1 & maskLow51Bits
+	v.l3 += v.l2 >> 51
+	v.l2 = v.l2 & maskLow51Bits
+	v.l4 += v.l3 >> 51
+	v.l3 = v.l3 & maskLow51Bits
+	// no additional carry
+	v.l4 = v.l4 & maskLow51Bits
+
+	return v
+}
+
+// Add sets v = a + b, and returns v.
+func (v *Element) Add(a, b *Element) *Element {
+	v.l0 = a.l0 + b.l0
+	v.l1 = a.l1 + b.l1
+	v.l2 = a.l2 + b.l2
+	v.l3 = a.l3 + b.l3
+	v.l4 = a.l4 + b.l4
+	// Using the generic implementation here is actually faster than the
+	// assembly. Probably because the body of this function is so simple that
+	// the compiler can figure out better optimizations by inlining the carry
+	// propagation.
+	return v.carryPropagateGeneric()
+}
+
+// Subtract sets v = a - b, and returns v.
+func (v *Element) Subtract(a, b *Element) *Element {
+	// We first add 2 * p, to guarantee the subtraction won't underflow, and
+	// then subtract b (which can be up to 2^255 + 2^13 * 19).
+	v.l0 = (a.l0 + 0xFFFFFFFFFFFDA) - b.l0
+	v.l1 = (a.l1 + 0xFFFFFFFFFFFFE) - b.l1
+	v.l2 = (a.l2 + 0xFFFFFFFFFFFFE) - b.l2
+	v.l3 = (a.l3 + 0xFFFFFFFFFFFFE) - b.l3
+	v.l4 = (a.l4 + 0xFFFFFFFFFFFFE) - b.l4
+	return v.carryPropagate()
+}
+
+// Negate sets v = -a, and returns v.
+func (v *Element) Negate(a *Element) *Element {
+	return v.Subtract(feZero, a)
+}
+
+// Invert sets v = 1/z mod p, and returns v.
+//
+// If z == 0, Invert returns v = 0.
+func (v *Element) Invert(z *Element) *Element {
+	// Inversion is implemented as exponentiation with exponent p − 2. It uses the
+	// same sequence of 255 squarings and 11 multiplications as [Curve25519].
+	var z2, z9, z11, z2_5_0, z2_10_0, z2_20_0, z2_50_0, z2_100_0, t Element
+
+	z2.Square(z)             // 2
+	t.Square(&z2)            // 4
+	t.Square(&t)             // 8
+	z9.Multiply(&t, z)       // 9
+	z11.Multiply(&z9, &z2)   // 11
+	t.Square(&z11)           // 22
+	z2_5_0.Multiply(&t, &z9) // 31 = 2^5 - 2^0
+
+	t.Square(&z2_5_0) // 2^6 - 2^1
+	for i := 0; i < 4; i++ {
+		t.Square(&t) // 2^10 - 2^5
+	}
+	z2_10_0.Multiply(&t, &z2_5_0) // 2^10 - 2^0
+
+	t.Square(&z2_10_0) // 2^11 - 2^1
+	for i := 0; i < 9; i++ {
+		t.Square(&t) // 2^20 - 2^10
+	}
+	z2_20_0.Multiply(&t, &z2_10_0) // 2^20 - 2^0
+
+	t.Square(&z2_20_0) // 2^21 - 2^1
+	for i := 0; i < 19; i++ {
+		t.Square(&t) // 2^40 - 2^20
+	}
+	t.Multiply(&t, &z2_20_0) // 2^40 - 2^0
+
+	t.Square(&t) // 2^41 - 2^1
+	for i := 0; i < 9; i++ {
+		t.Square(&t) // 2^50 - 2^10
+	}
+	z2_50_0.Multiply(&t, &z2_10_0) // 2^50 - 2^0
+
+	t.Square(&z2_50_0) // 2^51 - 2^1
+	for i := 0; i < 49; i++ {
+		t.Square(&t) // 2^100 - 2^50
+	}
+	z2_100_0.Multiply(&t, &z2_50_0) // 2^100 - 2^0
+
+	t.Square(&z2_100_0) // 2^101 - 2^1
+	for i := 0; i < 99; i++ {
+		t.Square(&t) // 2^200 - 2^100
+	}
+	t.Multiply(&t, &z2_100_0) // 2^200 - 2^0
+
+	t.Square(&t) // 2^201 - 2^1
+	for i := 0; i < 49; i++ {
+		t.Square(&t) // 2^250 - 2^50
+	}
+	t.Multiply(&t, &z2_50_0) // 2^250 - 2^0
+
+	t.Square(&t) // 2^251 - 2^1
+	t.Square(&t) // 2^252 - 2^2
+	t.Square(&t) // 2^253 - 2^3
+	t.Square(&t) // 2^254 - 2^4
+	t.Square(&t) // 2^255 - 2^5
+
+	return v.Multiply(&t, &z11) // 2^255 - 21
+}
+
+// Set sets v = a, and returns v.
+func (v *Element) Set(a *Element) *Element {
+	*v = *a
+	return v
+}
+
+// SetBytes sets v to x, where x is a 32-byte little-endian encoding. If x is
+// not of the right length, SetBytes returns nil and an error, and the
+// receiver is unchanged.
+//
+// Consistent with RFC 7748, the most significant bit (the high bit of the
+// last byte) is ignored, and non-canonical values (2^255-19 through 2^255-1)
+// are accepted. Note that this is laxer than specified by RFC 8032, but
+// consistent with most Ed25519 implementations.
+func (v *Element) SetBytes(x []byte) (*Element, error) {
+	if len(x) != 32 {
+		return nil, errors.New("edwards25519: invalid field element input size")
+	}
+
+	// Bits 0:51 (bytes 0:8, bits 0:64, shift 0, mask 51).
+	v.l0 = binary.LittleEndian.Uint64(x[0:8])
+	v.l0 &= maskLow51Bits
+	// Bits 51:102 (bytes 6:14, bits 48:112, shift 3, mask 51).
+	v.l1 = binary.LittleEndian.Uint64(x[6:14]) >> 3
+	v.l1 &= maskLow51Bits
+	// Bits 102:153 (bytes 12:20, bits 96:160, shift 6, mask 51).
+	v.l2 = binary.LittleEndian.Uint64(x[12:20]) >> 6
+	v.l2 &= maskLow51Bits
+	// Bits 153:204 (bytes 19:27, bits 152:216, shift 1, mask 51).
+	v.l3 = binary.LittleEndian.Uint64(x[19:27]) >> 1
+	v.l3 &= maskLow51Bits
+	// Bits 204:255 (bytes 24:32, bits 192:256, shift 12, mask 51).
+	// Note: not bytes 25:33, shift 4, to avoid overread.
+	v.l4 = binary.LittleEndian.Uint64(x[24:32]) >> 12
+	v.l4 &= maskLow51Bits
+
+	return v, nil
+}
+
+// Bytes returns the canonical 32-byte little-endian encoding of v.
+func (v *Element) Bytes() []byte {
+	// This function is outlined to make the allocations inline in the caller
+	// rather than happen on the heap.
+	var out [32]byte
+	return v.bytes(&out)
+}
+
+func (v *Element) bytes(out *[32]byte) []byte {
+	t := *v
+	t.reduce()
+
+	var buf [8]byte
+	for i, l := range [5]uint64{t.l0, t.l1, t.l2, t.l3, t.l4} {
+		bitsOffset := i * 51
+		binary.LittleEndian.PutUint64(buf[:], l<<uint(bitsOffset%8))
+		for i, bb := range buf {
+			off := bitsOffset/8 + i
+			if off >= len(out) {
+				break
+			}
+			out[off] |= bb
+		}
+	}
+
+	return out[:]
+}
+
+// Equal returns 1 if v and u are equal, and 0 otherwise.
+func (v *Element) Equal(u *Element) int {
+	sa, sv := u.Bytes(), v.Bytes()
+	return subtle.ConstantTimeCompare(sa, sv)
+}
+
+// mask64Bits returns 0xffffffff if cond is 1, and 0 otherwise.
+func mask64Bits(cond int) uint64 { return ^(uint64(cond) - 1) }
+
+// Select sets v to a if cond == 1, and to b if cond == 0.
+func (v *Element) Select(a, b *Element, cond int) *Element {
+	m := mask64Bits(cond)
+	v.l0 = (m & a.l0) | (^m & b.l0)
+	v.l1 = (m & a.l1) | (^m & b.l1)
+	v.l2 = (m & a.l2) | (^m & b.l2)
+	v.l3 = (m & a.l3) | (^m & b.l3)
+	v.l4 = (m & a.l4) | (^m & b.l4)
+	return v
+}
+
+// Swap swaps v and u if cond == 1 or leaves them unchanged if cond == 0, and returns v.
+func (v *Element) Swap(u *Element, cond int) {
+	m := mask64Bits(cond)
+	t := m & (v.l0 ^ u.l0)
+	v.l0 ^= t
+	u.l0 ^= t
+	t = m & (v.l1 ^ u.l1)
+	v.l1 ^= t
+	u.l1 ^= t
+	t = m & (v.l2 ^ u.l2)
+	v.l2 ^= t
+	u.l2 ^= t
+	t = m & (v.l3 ^ u.l3)
+	v.l3 ^= t
+	u.l3 ^= t
+	t = m & (v.l4 ^ u.l4)
+	v.l4 ^= t
+	u.l4 ^= t
+}
+
+// IsNegative returns 1 if v is negative, and 0 otherwise.
+func (v *Element) IsNegative() int {
+	return int(v.Bytes()[0] & 1)
+}
+
+// Absolute sets v to |u|, and returns v.
+func (v *Element) Absolute(u *Element) *Element {
+	return v.Select(new(Element).Negate(u), u, u.IsNegative())
+}
+
+// Multiply sets v = x * y, and returns v.
+func (v *Element) Multiply(x, y *Element) *Element {
+	feMul(v, x, y)
+	return v
+}
+
+// Square sets v = x * x, and returns v.
+func (v *Element) Square(x *Element) *Element {
+	feSquare(v, x)
+	return v
+}
+
+// Mult32 sets v = x * y, and returns v.
+func (v *Element) Mult32(x *Element, y uint32) *Element {
+	x0lo, x0hi := mul51(x.l0, y)
+	x1lo, x1hi := mul51(x.l1, y)
+	x2lo, x2hi := mul51(x.l2, y)
+	x3lo, x3hi := mul51(x.l3, y)
+	x4lo, x4hi := mul51(x.l4, y)
+	v.l0 = x0lo + 19*x4hi // carried over per the reduction identity
+	v.l1 = x1lo + x0hi
+	v.l2 = x2lo + x1hi
+	v.l3 = x3lo + x2hi
+	v.l4 = x4lo + x3hi
+	// The hi portions are going to be only 32 bits, plus any previous excess,
+	// so we can skip the carry propagation.
+	return v
+}
+
+// mul51 returns lo + hi * 2⁵¹ = a * b.
+func mul51(a uint64, b uint32) (lo uint64, hi uint64) {
+	mh, ml := bits.Mul64(a, uint64(b))
+	lo = ml & maskLow51Bits
+	hi = (mh << 13) | (ml >> 51)
+	return
+}
+
+// Pow22523 set v = x^((p-5)/8), and returns v. (p-5)/8 is 2^252-3.
+func (v *Element) Pow22523(x *Element) *Element {
+	var t0, t1, t2 Element
+
+	t0.Square(x)             // x^2
+	t1.Square(&t0)           // x^4
+	t1.Square(&t1)           // x^8
+	t1.Multiply(x, &t1)      // x^9
+	t0.Multiply(&t0, &t1)    // x^11
+	t0.Square(&t0)           // x^22
+	t0.Multiply(&t1, &t0)    // x^31
+	t1.Square(&t0)           // x^62
+	for i := 1; i < 5; i++ { // x^992
+		t1.Square(&t1)
+	}
+	t0.Multiply(&t1, &t0)     // x^1023 -> 1023 = 2^10 - 1
+	t1.Square(&t0)            // 2^11 - 2
+	for i := 1; i < 10; i++ { // 2^20 - 2^10
+		t1.Square(&t1)
+	}
+	t1.Multiply(&t1, &t0)     // 2^20 - 1
+	t2.Square(&t1)            // 2^21 - 2
+	for i := 1; i < 20; i++ { // 2^40 - 2^20
+		t2.Square(&t2)
+	}
+	t1.Multiply(&t2, &t1)     // 2^40 - 1
+	t1.Square(&t1)            // 2^41 - 2
+	for i := 1; i < 10; i++ { // 2^50 - 2^10
+		t1.Square(&t1)
+	}
+	t0.Multiply(&t1, &t0)     // 2^50 - 1
+	t1.Square(&t0)            // 2^51 - 2
+	for i := 1; i < 50; i++ { // 2^100 - 2^50
+		t1.Square(&t1)
+	}
+	t1.Multiply(&t1, &t0)      // 2^100 - 1
+	t2.Square(&t1)             // 2^101 - 2
+	for i := 1; i < 100; i++ { // 2^200 - 2^100
+		t2.Square(&t2)
+	}
+	t1.Multiply(&t2, &t1)     // 2^200 - 1
+	t1.Square(&t1)            // 2^201 - 2
+	for i := 1; i < 50; i++ { // 2^250 - 2^50
+		t1.Square(&t1)
+	}
+	t0.Multiply(&t1, &t0)     // 2^250 - 1
+	t0.Square(&t0)            // 2^251 - 2
+	t0.Square(&t0)            // 2^252 - 4
+	return v.Multiply(&t0, x) // 2^252 - 3 -> x^(2^252-3)
+}
+
+// sqrtM1 is 2^((p-1)/4), which squared is equal to -1 by Euler's Criterion.
+var sqrtM1 = &Element{1718705420411056, 234908883556509,
+	2233514472574048, 2117202627021982, 765476049583133}
+
+// SqrtRatio sets r to the non-negative square root of the ratio of u and v.
+//
+// If u/v is square, SqrtRatio returns r and 1. If u/v is not square, SqrtRatio
+// sets r according to Section 4.3 of draft-irtf-cfrg-ristretto255-decaf448-00,
+// and returns r and 0.
+func (r *Element) SqrtRatio(u, v *Element) (R *Element, wasSquare int) {
+	t0 := new(Element)
+
+	// r = (u * v3) * (u * v7)^((p-5)/8)
+	v2 := new(Element).Square(v)
+	uv3 := new(Element).Multiply(u, t0.Multiply(v2, v))
+	uv7 := new(Element).Multiply(uv3, t0.Square(v2))
+	rr := new(Element).Multiply(uv3, t0.Pow22523(uv7))
+
+	check := new(Element).Multiply(v, t0.Square(rr)) // check = v * r^2
+
+	uNeg := new(Element).Negate(u)
+	correctSignSqrt := check.Equal(u)
+	flippedSignSqrt := check.Equal(uNeg)
+	flippedSignSqrtI := check.Equal(t0.Multiply(uNeg, sqrtM1))
+
+	rPrime := new(Element).Multiply(rr, sqrtM1) // r_prime = SQRT_M1 * r
+	// r = CT_SELECT(r_prime IF flipped_sign_sqrt | flipped_sign_sqrt_i ELSE r)
+	rr.Select(rPrime, rr, flippedSignSqrt|flippedSignSqrtI)
+
+	r.Absolute(rr) // Choose the nonnegative square root.
+	return r, correctSignSqrt | flippedSignSqrt
+}

+ 16 - 0
vendor/filippo.io/edwards25519/field/fe_amd64.go

@@ -0,0 +1,16 @@
+// Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT.
+
+//go:build amd64 && gc && !purego
+// +build amd64,gc,!purego
+
+package field
+
+// feMul sets out = a * b. It works like feMulGeneric.
+//
+//go:noescape
+func feMul(out *Element, a *Element, b *Element)
+
+// feSquare sets out = a * a. It works like feSquareGeneric.
+//
+//go:noescape
+func feSquare(out *Element, a *Element)

+ 379 - 0
vendor/filippo.io/edwards25519/field/fe_amd64.s

@@ -0,0 +1,379 @@
+// Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT.
+
+//go:build amd64 && gc && !purego
+// +build amd64,gc,!purego
+
+#include "textflag.h"
+
+// func feMul(out *Element, a *Element, b *Element)
+TEXT ·feMul(SB), NOSPLIT, $0-24
+	MOVQ a+8(FP), CX
+	MOVQ b+16(FP), BX
+
+	// r0 = a0×b0
+	MOVQ (CX), AX
+	MULQ (BX)
+	MOVQ AX, DI
+	MOVQ DX, SI
+
+	// r0 += 19×a1×b4
+	MOVQ   8(CX), AX
+	IMUL3Q $0x13, AX, AX
+	MULQ   32(BX)
+	ADDQ   AX, DI
+	ADCQ   DX, SI
+
+	// r0 += 19×a2×b3
+	MOVQ   16(CX), AX
+	IMUL3Q $0x13, AX, AX
+	MULQ   24(BX)
+	ADDQ   AX, DI
+	ADCQ   DX, SI
+
+	// r0 += 19×a3×b2
+	MOVQ   24(CX), AX
+	IMUL3Q $0x13, AX, AX
+	MULQ   16(BX)
+	ADDQ   AX, DI
+	ADCQ   DX, SI
+
+	// r0 += 19×a4×b1
+	MOVQ   32(CX), AX
+	IMUL3Q $0x13, AX, AX
+	MULQ   8(BX)
+	ADDQ   AX, DI
+	ADCQ   DX, SI
+
+	// r1 = a0×b1
+	MOVQ (CX), AX
+	MULQ 8(BX)
+	MOVQ AX, R9
+	MOVQ DX, R8
+
+	// r1 += a1×b0
+	MOVQ 8(CX), AX
+	MULQ (BX)
+	ADDQ AX, R9
+	ADCQ DX, R8
+
+	// r1 += 19×a2×b4
+	MOVQ   16(CX), AX
+	IMUL3Q $0x13, AX, AX
+	MULQ   32(BX)
+	ADDQ   AX, R9
+	ADCQ   DX, R8
+
+	// r1 += 19×a3×b3
+	MOVQ   24(CX), AX
+	IMUL3Q $0x13, AX, AX
+	MULQ   24(BX)
+	ADDQ   AX, R9
+	ADCQ   DX, R8
+
+	// r1 += 19×a4×b2
+	MOVQ   32(CX), AX
+	IMUL3Q $0x13, AX, AX
+	MULQ   16(BX)
+	ADDQ   AX, R9
+	ADCQ   DX, R8
+
+	// r2 = a0×b2
+	MOVQ (CX), AX
+	MULQ 16(BX)
+	MOVQ AX, R11
+	MOVQ DX, R10
+
+	// r2 += a1×b1
+	MOVQ 8(CX), AX
+	MULQ 8(BX)
+	ADDQ AX, R11
+	ADCQ DX, R10
+
+	// r2 += a2×b0
+	MOVQ 16(CX), AX
+	MULQ (BX)
+	ADDQ AX, R11
+	ADCQ DX, R10
+
+	// r2 += 19×a3×b4
+	MOVQ   24(CX), AX
+	IMUL3Q $0x13, AX, AX
+	MULQ   32(BX)
+	ADDQ   AX, R11
+	ADCQ   DX, R10
+
+	// r2 += 19×a4×b3
+	MOVQ   32(CX), AX
+	IMUL3Q $0x13, AX, AX
+	MULQ   24(BX)
+	ADDQ   AX, R11
+	ADCQ   DX, R10
+
+	// r3 = a0×b3
+	MOVQ (CX), AX
+	MULQ 24(BX)
+	MOVQ AX, R13
+	MOVQ DX, R12
+
+	// r3 += a1×b2
+	MOVQ 8(CX), AX
+	MULQ 16(BX)
+	ADDQ AX, R13
+	ADCQ DX, R12
+
+	// r3 += a2×b1
+	MOVQ 16(CX), AX
+	MULQ 8(BX)
+	ADDQ AX, R13
+	ADCQ DX, R12
+
+	// r3 += a3×b0
+	MOVQ 24(CX), AX
+	MULQ (BX)
+	ADDQ AX, R13
+	ADCQ DX, R12
+
+	// r3 += 19×a4×b4
+	MOVQ   32(CX), AX
+	IMUL3Q $0x13, AX, AX
+	MULQ   32(BX)
+	ADDQ   AX, R13
+	ADCQ   DX, R12
+
+	// r4 = a0×b4
+	MOVQ (CX), AX
+	MULQ 32(BX)
+	MOVQ AX, R15
+	MOVQ DX, R14
+
+	// r4 += a1×b3
+	MOVQ 8(CX), AX
+	MULQ 24(BX)
+	ADDQ AX, R15
+	ADCQ DX, R14
+
+	// r4 += a2×b2
+	MOVQ 16(CX), AX
+	MULQ 16(BX)
+	ADDQ AX, R15
+	ADCQ DX, R14
+
+	// r4 += a3×b1
+	MOVQ 24(CX), AX
+	MULQ 8(BX)
+	ADDQ AX, R15
+	ADCQ DX, R14
+
+	// r4 += a4×b0
+	MOVQ 32(CX), AX
+	MULQ (BX)
+	ADDQ AX, R15
+	ADCQ DX, R14
+
+	// First reduction chain
+	MOVQ   $0x0007ffffffffffff, AX
+	SHLQ   $0x0d, DI, SI
+	SHLQ   $0x0d, R9, R8
+	SHLQ   $0x0d, R11, R10
+	SHLQ   $0x0d, R13, R12
+	SHLQ   $0x0d, R15, R14
+	ANDQ   AX, DI
+	IMUL3Q $0x13, R14, R14
+	ADDQ   R14, DI
+	ANDQ   AX, R9
+	ADDQ   SI, R9
+	ANDQ   AX, R11
+	ADDQ   R8, R11
+	ANDQ   AX, R13
+	ADDQ   R10, R13
+	ANDQ   AX, R15
+	ADDQ   R12, R15
+
+	// Second reduction chain (carryPropagate)
+	MOVQ   DI, SI
+	SHRQ   $0x33, SI
+	MOVQ   R9, R8
+	SHRQ   $0x33, R8
+	MOVQ   R11, R10
+	SHRQ   $0x33, R10
+	MOVQ   R13, R12
+	SHRQ   $0x33, R12
+	MOVQ   R15, R14
+	SHRQ   $0x33, R14
+	ANDQ   AX, DI
+	IMUL3Q $0x13, R14, R14
+	ADDQ   R14, DI
+	ANDQ   AX, R9
+	ADDQ   SI, R9
+	ANDQ   AX, R11
+	ADDQ   R8, R11
+	ANDQ   AX, R13
+	ADDQ   R10, R13
+	ANDQ   AX, R15
+	ADDQ   R12, R15
+
+	// Store output
+	MOVQ out+0(FP), AX
+	MOVQ DI, (AX)
+	MOVQ R9, 8(AX)
+	MOVQ R11, 16(AX)
+	MOVQ R13, 24(AX)
+	MOVQ R15, 32(AX)
+	RET
+
+// func feSquare(out *Element, a *Element)
+TEXT ·feSquare(SB), NOSPLIT, $0-16
+	MOVQ a+8(FP), CX
+
+	// r0 = l0×l0
+	MOVQ (CX), AX
+	MULQ (CX)
+	MOVQ AX, SI
+	MOVQ DX, BX
+
+	// r0 += 38×l1×l4
+	MOVQ   8(CX), AX
+	IMUL3Q $0x26, AX, AX
+	MULQ   32(CX)
+	ADDQ   AX, SI
+	ADCQ   DX, BX
+
+	// r0 += 38×l2×l3
+	MOVQ   16(CX), AX
+	IMUL3Q $0x26, AX, AX
+	MULQ   24(CX)
+	ADDQ   AX, SI
+	ADCQ   DX, BX
+
+	// r1 = 2×l0×l1
+	MOVQ (CX), AX
+	SHLQ $0x01, AX
+	MULQ 8(CX)
+	MOVQ AX, R8
+	MOVQ DX, DI
+
+	// r1 += 38×l2×l4
+	MOVQ   16(CX), AX
+	IMUL3Q $0x26, AX, AX
+	MULQ   32(CX)
+	ADDQ   AX, R8
+	ADCQ   DX, DI
+
+	// r1 += 19×l3×l3
+	MOVQ   24(CX), AX
+	IMUL3Q $0x13, AX, AX
+	MULQ   24(CX)
+	ADDQ   AX, R8
+	ADCQ   DX, DI
+
+	// r2 = 2×l0×l2
+	MOVQ (CX), AX
+	SHLQ $0x01, AX
+	MULQ 16(CX)
+	MOVQ AX, R10
+	MOVQ DX, R9
+
+	// r2 += l1×l1
+	MOVQ 8(CX), AX
+	MULQ 8(CX)
+	ADDQ AX, R10
+	ADCQ DX, R9
+
+	// r2 += 38×l3×l4
+	MOVQ   24(CX), AX
+	IMUL3Q $0x26, AX, AX
+	MULQ   32(CX)
+	ADDQ   AX, R10
+	ADCQ   DX, R9
+
+	// r3 = 2×l0×l3
+	MOVQ (CX), AX
+	SHLQ $0x01, AX
+	MULQ 24(CX)
+	MOVQ AX, R12
+	MOVQ DX, R11
+
+	// r3 += 2×l1×l2
+	MOVQ   8(CX), AX
+	IMUL3Q $0x02, AX, AX
+	MULQ   16(CX)
+	ADDQ   AX, R12
+	ADCQ   DX, R11
+
+	// r3 += 19×l4×l4
+	MOVQ   32(CX), AX
+	IMUL3Q $0x13, AX, AX
+	MULQ   32(CX)
+	ADDQ   AX, R12
+	ADCQ   DX, R11
+
+	// r4 = 2×l0×l4
+	MOVQ (CX), AX
+	SHLQ $0x01, AX
+	MULQ 32(CX)
+	MOVQ AX, R14
+	MOVQ DX, R13
+
+	// r4 += 2×l1×l3
+	MOVQ   8(CX), AX
+	IMUL3Q $0x02, AX, AX
+	MULQ   24(CX)
+	ADDQ   AX, R14
+	ADCQ   DX, R13
+
+	// r4 += l2×l2
+	MOVQ 16(CX), AX
+	MULQ 16(CX)
+	ADDQ AX, R14
+	ADCQ DX, R13
+
+	// First reduction chain
+	MOVQ   $0x0007ffffffffffff, AX
+	SHLQ   $0x0d, SI, BX
+	SHLQ   $0x0d, R8, DI
+	SHLQ   $0x0d, R10, R9
+	SHLQ   $0x0d, R12, R11
+	SHLQ   $0x0d, R14, R13
+	ANDQ   AX, SI
+	IMUL3Q $0x13, R13, R13
+	ADDQ   R13, SI
+	ANDQ   AX, R8
+	ADDQ   BX, R8
+	ANDQ   AX, R10
+	ADDQ   DI, R10
+	ANDQ   AX, R12
+	ADDQ   R9, R12
+	ANDQ   AX, R14
+	ADDQ   R11, R14
+
+	// Second reduction chain (carryPropagate)
+	MOVQ   SI, BX
+	SHRQ   $0x33, BX
+	MOVQ   R8, DI
+	SHRQ   $0x33, DI
+	MOVQ   R10, R9
+	SHRQ   $0x33, R9
+	MOVQ   R12, R11
+	SHRQ   $0x33, R11
+	MOVQ   R14, R13
+	SHRQ   $0x33, R13
+	ANDQ   AX, SI
+	IMUL3Q $0x13, R13, R13
+	ADDQ   R13, SI
+	ANDQ   AX, R8
+	ADDQ   BX, R8
+	ANDQ   AX, R10
+	ADDQ   DI, R10
+	ANDQ   AX, R12
+	ADDQ   R9, R12
+	ANDQ   AX, R14
+	ADDQ   R11, R14
+
+	// Store output
+	MOVQ out+0(FP), AX
+	MOVQ SI, (AX)
+	MOVQ R8, 8(AX)
+	MOVQ R10, 16(AX)
+	MOVQ R12, 24(AX)
+	MOVQ R14, 32(AX)
+	RET

+ 12 - 0
vendor/filippo.io/edwards25519/field/fe_amd64_noasm.go

@@ -0,0 +1,12 @@
+// Copyright (c) 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.
+
+//go:build !amd64 || !gc || purego
+// +build !amd64 !gc purego
+
+package field
+
+func feMul(v, x, y *Element) { feMulGeneric(v, x, y) }
+
+func feSquare(v, x *Element) { feSquareGeneric(v, x) }

+ 16 - 0
vendor/filippo.io/edwards25519/field/fe_arm64.go

@@ -0,0 +1,16 @@
+// Copyright (c) 2020 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.
+
+//go:build arm64 && gc && !purego
+// +build arm64,gc,!purego
+
+package field
+
+//go:noescape
+func carryPropagate(v *Element)
+
+func (v *Element) carryPropagate() *Element {
+	carryPropagate(v)
+	return v
+}

+ 42 - 0
vendor/filippo.io/edwards25519/field/fe_arm64.s

@@ -0,0 +1,42 @@
+// Copyright (c) 2020 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.
+
+//go:build arm64 && gc && !purego
+
+#include "textflag.h"
+
+// carryPropagate works exactly like carryPropagateGeneric and uses the
+// same AND, ADD, and LSR+MADD instructions emitted by the compiler, but
+// avoids loading R0-R4 twice and uses LDP and STP.
+//
+// See https://golang.org/issues/43145 for the main compiler issue.
+//
+// func carryPropagate(v *Element)
+TEXT ·carryPropagate(SB),NOFRAME|NOSPLIT,$0-8
+	MOVD v+0(FP), R20
+
+	LDP 0(R20), (R0, R1)
+	LDP 16(R20), (R2, R3)
+	MOVD 32(R20), R4
+
+	AND $0x7ffffffffffff, R0, R10
+	AND $0x7ffffffffffff, R1, R11
+	AND $0x7ffffffffffff, R2, R12
+	AND $0x7ffffffffffff, R3, R13
+	AND $0x7ffffffffffff, R4, R14
+
+	ADD R0>>51, R11, R11
+	ADD R1>>51, R12, R12
+	ADD R2>>51, R13, R13
+	ADD R3>>51, R14, R14
+	// R4>>51 * 19 + R10 -> R10
+	LSR $51, R4, R21
+	MOVD $19, R22
+	MADD R22, R10, R21, R10
+
+	STP (R10, R11), 0(R20)
+	STP (R12, R13), 16(R20)
+	MOVD R14, 32(R20)
+
+	RET

+ 12 - 0
vendor/filippo.io/edwards25519/field/fe_arm64_noasm.go

@@ -0,0 +1,12 @@
+// Copyright (c) 2021 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.
+
+//go:build !arm64 || !gc || purego
+// +build !arm64 !gc purego
+
+package field
+
+func (v *Element) carryPropagate() *Element {
+	return v.carryPropagateGeneric()
+}

+ 50 - 0
vendor/filippo.io/edwards25519/field/fe_extra.go

@@ -0,0 +1,50 @@
+// Copyright (c) 2021 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 field
+
+import "errors"
+
+// This file contains additional functionality that is not included in the
+// upstream crypto/ed25519/edwards25519/field package.
+
+// SetWideBytes sets v to x, where x is a 64-byte little-endian encoding, which
+// is reduced modulo the field order. If x is not of the right length,
+// SetWideBytes returns nil and an error, and the receiver is unchanged.
+//
+// SetWideBytes is not necessary to select a uniformly distributed value, and is
+// only provided for compatibility: SetBytes can be used instead as the chance
+// of bias is less than 2⁻²⁵⁰.
+func (v *Element) SetWideBytes(x []byte) (*Element, error) {
+	if len(x) != 64 {
+		return nil, errors.New("edwards25519: invalid SetWideBytes input size")
+	}
+
+	// Split the 64 bytes into two elements, and extract the most significant
+	// bit of each, which is ignored by SetBytes.
+	lo, _ := new(Element).SetBytes(x[:32])
+	loMSB := uint64(x[31] >> 7)
+	hi, _ := new(Element).SetBytes(x[32:])
+	hiMSB := uint64(x[63] >> 7)
+
+	// The output we want is
+	//
+	//   v = lo + loMSB * 2²⁵⁵ + hi * 2²⁵⁶ + hiMSB * 2⁵¹¹
+	//
+	// which applying the reduction identity comes out to
+	//
+	//   v = lo + loMSB * 19 + hi * 2 * 19 + hiMSB * 2 * 19²
+	//
+	// l0 will be the sum of a 52 bits value (lo.l0), plus a 5 bits value
+	// (loMSB * 19), a 6 bits value (hi.l0 * 2 * 19), and a 10 bits value
+	// (hiMSB * 2 * 19²), so it fits in a uint64.
+
+	v.l0 = lo.l0 + loMSB*19 + hi.l0*2*19 + hiMSB*2*19*19
+	v.l1 = lo.l1 + hi.l1*2*19
+	v.l2 = lo.l2 + hi.l2*2*19
+	v.l3 = lo.l3 + hi.l3*2*19
+	v.l4 = lo.l4 + hi.l4*2*19
+
+	return v.carryPropagate(), nil
+}

+ 266 - 0
vendor/filippo.io/edwards25519/field/fe_generic.go

@@ -0,0 +1,266 @@
+// Copyright (c) 2017 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 field
+
+import "math/bits"
+
+// uint128 holds a 128-bit number as two 64-bit limbs, for use with the
+// bits.Mul64 and bits.Add64 intrinsics.
+type uint128 struct {
+	lo, hi uint64
+}
+
+// mul64 returns a * b.
+func mul64(a, b uint64) uint128 {
+	hi, lo := bits.Mul64(a, b)
+	return uint128{lo, hi}
+}
+
+// addMul64 returns v + a * b.
+func addMul64(v uint128, a, b uint64) uint128 {
+	hi, lo := bits.Mul64(a, b)
+	lo, c := bits.Add64(lo, v.lo, 0)
+	hi, _ = bits.Add64(hi, v.hi, c)
+	return uint128{lo, hi}
+}
+
+// shiftRightBy51 returns a >> 51. a is assumed to be at most 115 bits.
+func shiftRightBy51(a uint128) uint64 {
+	return (a.hi << (64 - 51)) | (a.lo >> 51)
+}
+
+func feMulGeneric(v, a, b *Element) {
+	a0 := a.l0
+	a1 := a.l1
+	a2 := a.l2
+	a3 := a.l3
+	a4 := a.l4
+
+	b0 := b.l0
+	b1 := b.l1
+	b2 := b.l2
+	b3 := b.l3
+	b4 := b.l4
+
+	// Limb multiplication works like pen-and-paper columnar multiplication, but
+	// with 51-bit limbs instead of digits.
+	//
+	//                          a4   a3   a2   a1   a0  x
+	//                          b4   b3   b2   b1   b0  =
+	//                         ------------------------
+	//                        a4b0 a3b0 a2b0 a1b0 a0b0  +
+	//                   a4b1 a3b1 a2b1 a1b1 a0b1       +
+	//              a4b2 a3b2 a2b2 a1b2 a0b2            +
+	//         a4b3 a3b3 a2b3 a1b3 a0b3                 +
+	//    a4b4 a3b4 a2b4 a1b4 a0b4                      =
+	//   ----------------------------------------------
+	//      r8   r7   r6   r5   r4   r3   r2   r1   r0
+	//
+	// We can then use the reduction identity (a * 2²⁵⁵ + b = a * 19 + b) to
+	// reduce the limbs that would overflow 255 bits. r5 * 2²⁵⁵ becomes 19 * r5,
+	// r6 * 2³⁰⁶ becomes 19 * r6 * 2⁵¹, etc.
+	//
+	// Reduction can be carried out simultaneously to multiplication. For
+	// example, we do not compute r5: whenever the result of a multiplication
+	// belongs to r5, like a1b4, we multiply it by 19 and add the result to r0.
+	//
+	//            a4b0    a3b0    a2b0    a1b0    a0b0  +
+	//            a3b1    a2b1    a1b1    a0b1 19×a4b1  +
+	//            a2b2    a1b2    a0b2 19×a4b2 19×a3b2  +
+	//            a1b3    a0b3 19×a4b3 19×a3b3 19×a2b3  +
+	//            a0b4 19×a4b4 19×a3b4 19×a2b4 19×a1b4  =
+	//           --------------------------------------
+	//              r4      r3      r2      r1      r0
+	//
+	// Finally we add up the columns into wide, overlapping limbs.
+
+	a1_19 := a1 * 19
+	a2_19 := a2 * 19
+	a3_19 := a3 * 19
+	a4_19 := a4 * 19
+
+	// r0 = a0×b0 + 19×(a1×b4 + a2×b3 + a3×b2 + a4×b1)
+	r0 := mul64(a0, b0)
+	r0 = addMul64(r0, a1_19, b4)
+	r0 = addMul64(r0, a2_19, b3)
+	r0 = addMul64(r0, a3_19, b2)
+	r0 = addMul64(r0, a4_19, b1)
+
+	// r1 = a0×b1 + a1×b0 + 19×(a2×b4 + a3×b3 + a4×b2)
+	r1 := mul64(a0, b1)
+	r1 = addMul64(r1, a1, b0)
+	r1 = addMul64(r1, a2_19, b4)
+	r1 = addMul64(r1, a3_19, b3)
+	r1 = addMul64(r1, a4_19, b2)
+
+	// r2 = a0×b2 + a1×b1 + a2×b0 + 19×(a3×b4 + a4×b3)
+	r2 := mul64(a0, b2)
+	r2 = addMul64(r2, a1, b1)
+	r2 = addMul64(r2, a2, b0)
+	r2 = addMul64(r2, a3_19, b4)
+	r2 = addMul64(r2, a4_19, b3)
+
+	// r3 = a0×b3 + a1×b2 + a2×b1 + a3×b0 + 19×a4×b4
+	r3 := mul64(a0, b3)
+	r3 = addMul64(r3, a1, b2)
+	r3 = addMul64(r3, a2, b1)
+	r3 = addMul64(r3, a3, b0)
+	r3 = addMul64(r3, a4_19, b4)
+
+	// r4 = a0×b4 + a1×b3 + a2×b2 + a3×b1 + a4×b0
+	r4 := mul64(a0, b4)
+	r4 = addMul64(r4, a1, b3)
+	r4 = addMul64(r4, a2, b2)
+	r4 = addMul64(r4, a3, b1)
+	r4 = addMul64(r4, a4, b0)
+
+	// After the multiplication, we need to reduce (carry) the five coefficients
+	// to obtain a result with limbs that are at most slightly larger than 2⁵¹,
+	// to respect the Element invariant.
+	//
+	// Overall, the reduction works the same as carryPropagate, except with
+	// wider inputs: we take the carry for each coefficient by shifting it right
+	// by 51, and add it to the limb above it. The top carry is multiplied by 19
+	// according to the reduction identity and added to the lowest limb.
+	//
+	// The largest coefficient (r0) will be at most 111 bits, which guarantees
+	// that all carries are at most 111 - 51 = 60 bits, which fits in a uint64.
+	//
+	//     r0 = a0×b0 + 19×(a1×b4 + a2×b3 + a3×b2 + a4×b1)
+	//     r0 < 2⁵²×2⁵² + 19×(2⁵²×2⁵² + 2⁵²×2⁵² + 2⁵²×2⁵² + 2⁵²×2⁵²)
+	//     r0 < (1 + 19 × 4) × 2⁵² × 2⁵²
+	//     r0 < 2⁷ × 2⁵² × 2⁵²
+	//     r0 < 2¹¹¹
+	//
+	// Moreover, the top coefficient (r4) is at most 107 bits, so c4 is at most
+	// 56 bits, and c4 * 19 is at most 61 bits, which again fits in a uint64 and
+	// allows us to easily apply the reduction identity.
+	//
+	//     r4 = a0×b4 + a1×b3 + a2×b2 + a3×b1 + a4×b0
+	//     r4 < 5 × 2⁵² × 2⁵²
+	//     r4 < 2¹⁰⁷
+	//
+
+	c0 := shiftRightBy51(r0)
+	c1 := shiftRightBy51(r1)
+	c2 := shiftRightBy51(r2)
+	c3 := shiftRightBy51(r3)
+	c4 := shiftRightBy51(r4)
+
+	rr0 := r0.lo&maskLow51Bits + c4*19
+	rr1 := r1.lo&maskLow51Bits + c0
+	rr2 := r2.lo&maskLow51Bits + c1
+	rr3 := r3.lo&maskLow51Bits + c2
+	rr4 := r4.lo&maskLow51Bits + c3
+
+	// Now all coefficients fit into 64-bit registers but are still too large to
+	// be passed around as an Element. We therefore do one last carry chain,
+	// where the carries will be small enough to fit in the wiggle room above 2⁵¹.
+	*v = Element{rr0, rr1, rr2, rr3, rr4}
+	v.carryPropagate()
+}
+
+func feSquareGeneric(v, a *Element) {
+	l0 := a.l0
+	l1 := a.l1
+	l2 := a.l2
+	l3 := a.l3
+	l4 := a.l4
+
+	// Squaring works precisely like multiplication above, but thanks to its
+	// symmetry we get to group a few terms together.
+	//
+	//                          l4   l3   l2   l1   l0  x
+	//                          l4   l3   l2   l1   l0  =
+	//                         ------------------------
+	//                        l4l0 l3l0 l2l0 l1l0 l0l0  +
+	//                   l4l1 l3l1 l2l1 l1l1 l0l1       +
+	//              l4l2 l3l2 l2l2 l1l2 l0l2            +
+	//         l4l3 l3l3 l2l3 l1l3 l0l3                 +
+	//    l4l4 l3l4 l2l4 l1l4 l0l4                      =
+	//   ----------------------------------------------
+	//      r8   r7   r6   r5   r4   r3   r2   r1   r0
+	//
+	//            l4l0    l3l0    l2l0    l1l0    l0l0  +
+	//            l3l1    l2l1    l1l1    l0l1 19×l4l1  +
+	//            l2l2    l1l2    l0l2 19×l4l2 19×l3l2  +
+	//            l1l3    l0l3 19×l4l3 19×l3l3 19×l2l3  +
+	//            l0l4 19×l4l4 19×l3l4 19×l2l4 19×l1l4  =
+	//           --------------------------------------
+	//              r4      r3      r2      r1      r0
+	//
+	// With precomputed 2×, 19×, and 2×19× terms, we can compute each limb with
+	// only three Mul64 and four Add64, instead of five and eight.
+
+	l0_2 := l0 * 2
+	l1_2 := l1 * 2
+
+	l1_38 := l1 * 38
+	l2_38 := l2 * 38
+	l3_38 := l3 * 38
+
+	l3_19 := l3 * 19
+	l4_19 := l4 * 19
+
+	// r0 = l0×l0 + 19×(l1×l4 + l2×l3 + l3×l2 + l4×l1) = l0×l0 + 19×2×(l1×l4 + l2×l3)
+	r0 := mul64(l0, l0)
+	r0 = addMul64(r0, l1_38, l4)
+	r0 = addMul64(r0, l2_38, l3)
+
+	// r1 = l0×l1 + l1×l0 + 19×(l2×l4 + l3×l3 + l4×l2) = 2×l0×l1 + 19×2×l2×l4 + 19×l3×l3
+	r1 := mul64(l0_2, l1)
+	r1 = addMul64(r1, l2_38, l4)
+	r1 = addMul64(r1, l3_19, l3)
+
+	// r2 = l0×l2 + l1×l1 + l2×l0 + 19×(l3×l4 + l4×l3) = 2×l0×l2 + l1×l1 + 19×2×l3×l4
+	r2 := mul64(l0_2, l2)
+	r2 = addMul64(r2, l1, l1)
+	r2 = addMul64(r2, l3_38, l4)
+
+	// r3 = l0×l3 + l1×l2 + l2×l1 + l3×l0 + 19×l4×l4 = 2×l0×l3 + 2×l1×l2 + 19×l4×l4
+	r3 := mul64(l0_2, l3)
+	r3 = addMul64(r3, l1_2, l2)
+	r3 = addMul64(r3, l4_19, l4)
+
+	// r4 = l0×l4 + l1×l3 + l2×l2 + l3×l1 + l4×l0 = 2×l0×l4 + 2×l1×l3 + l2×l2
+	r4 := mul64(l0_2, l4)
+	r4 = addMul64(r4, l1_2, l3)
+	r4 = addMul64(r4, l2, l2)
+
+	c0 := shiftRightBy51(r0)
+	c1 := shiftRightBy51(r1)
+	c2 := shiftRightBy51(r2)
+	c3 := shiftRightBy51(r3)
+	c4 := shiftRightBy51(r4)
+
+	rr0 := r0.lo&maskLow51Bits + c4*19
+	rr1 := r1.lo&maskLow51Bits + c0
+	rr2 := r2.lo&maskLow51Bits + c1
+	rr3 := r3.lo&maskLow51Bits + c2
+	rr4 := r4.lo&maskLow51Bits + c3
+
+	*v = Element{rr0, rr1, rr2, rr3, rr4}
+	v.carryPropagate()
+}
+
+// carryPropagateGeneric brings the limbs below 52 bits by applying the reduction
+// identity (a * 2²⁵⁵ + b = a * 19 + b) to the l4 carry.
+func (v *Element) carryPropagateGeneric() *Element {
+	c0 := v.l0 >> 51
+	c1 := v.l1 >> 51
+	c2 := v.l2 >> 51
+	c3 := v.l3 >> 51
+	c4 := v.l4 >> 51
+
+	// c4 is at most 64 - 51 = 13 bits, so c4*19 is at most 18 bits, and
+	// the final l0 will be at most 52 bits. Similarly for the rest.
+	v.l0 = v.l0&maskLow51Bits + c4*19
+	v.l1 = v.l1&maskLow51Bits + c0
+	v.l2 = v.l2&maskLow51Bits + c1
+	v.l3 = v.l3&maskLow51Bits + c2
+	v.l4 = v.l4&maskLow51Bits + c3
+
+	return v
+}

+ 343 - 0
vendor/filippo.io/edwards25519/scalar.go

@@ -0,0 +1,343 @@
+// Copyright (c) 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 edwards25519
+
+import (
+	"encoding/binary"
+	"errors"
+)
+
+// A Scalar is an integer modulo
+//
+//	l = 2^252 + 27742317777372353535851937790883648493
+//
+// which is the prime order of the edwards25519 group.
+//
+// This type works similarly to math/big.Int, and all arguments and
+// receivers are allowed to alias.
+//
+// The zero value is a valid zero element.
+type Scalar struct {
+	// s is the scalar in the Montgomery domain, in the format of the
+	// fiat-crypto implementation.
+	s fiatScalarMontgomeryDomainFieldElement
+}
+
+// The field implementation in scalar_fiat.go is generated by the fiat-crypto
+// project (https://github.com/mit-plv/fiat-crypto) at version v0.0.9 (23d2dbc)
+// from a formally verified model.
+//
+// fiat-crypto code comes under the following license.
+//
+//     Copyright (c) 2015-2020 The fiat-crypto Authors. All rights reserved.
+//
+//     Redistribution and use in source and binary forms, with or without
+//     modification, are permitted provided that the following conditions are
+//     met:
+//
+//         1. Redistributions of source code must retain the above copyright
+//         notice, this list of conditions and the following disclaimer.
+//
+//     THIS SOFTWARE IS PROVIDED BY the fiat-crypto authors "AS IS"
+//     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+//     THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+//     PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design,
+//     Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+//     EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+//     PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+//     PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+//     LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+//     NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+//     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+// NewScalar returns a new zero Scalar.
+func NewScalar() *Scalar {
+	return &Scalar{}
+}
+
+// MultiplyAdd sets s = x * y + z mod l, and returns s. It is equivalent to
+// using Multiply and then Add.
+func (s *Scalar) MultiplyAdd(x, y, z *Scalar) *Scalar {
+	// Make a copy of z in case it aliases s.
+	zCopy := new(Scalar).Set(z)
+	return s.Multiply(x, y).Add(s, zCopy)
+}
+
+// Add sets s = x + y mod l, and returns s.
+func (s *Scalar) Add(x, y *Scalar) *Scalar {
+	// s = 1 * x + y mod l
+	fiatScalarAdd(&s.s, &x.s, &y.s)
+	return s
+}
+
+// Subtract sets s = x - y mod l, and returns s.
+func (s *Scalar) Subtract(x, y *Scalar) *Scalar {
+	// s = -1 * y + x mod l
+	fiatScalarSub(&s.s, &x.s, &y.s)
+	return s
+}
+
+// Negate sets s = -x mod l, and returns s.
+func (s *Scalar) Negate(x *Scalar) *Scalar {
+	// s = -1 * x + 0 mod l
+	fiatScalarOpp(&s.s, &x.s)
+	return s
+}
+
+// Multiply sets s = x * y mod l, and returns s.
+func (s *Scalar) Multiply(x, y *Scalar) *Scalar {
+	// s = x * y + 0 mod l
+	fiatScalarMul(&s.s, &x.s, &y.s)
+	return s
+}
+
+// Set sets s = x, and returns s.
+func (s *Scalar) Set(x *Scalar) *Scalar {
+	*s = *x
+	return s
+}
+
+// SetUniformBytes sets s = x mod l, where x is a 64-byte little-endian integer.
+// If x is not of the right length, SetUniformBytes returns nil and an error,
+// and the receiver is unchanged.
+//
+// SetUniformBytes can be used to set s to a uniformly distributed value given
+// 64 uniformly distributed random bytes.
+func (s *Scalar) SetUniformBytes(x []byte) (*Scalar, error) {
+	if len(x) != 64 {
+		return nil, errors.New("edwards25519: invalid SetUniformBytes input length")
+	}
+
+	// We have a value x of 512 bits, but our fiatScalarFromBytes function
+	// expects an input lower than l, which is a little over 252 bits.
+	//
+	// Instead of writing a reduction function that operates on wider inputs, we
+	// can interpret x as the sum of three shorter values a, b, and c.
+	//
+	//    x = a + b * 2^168 + c * 2^336  mod l
+	//
+	// We then precompute 2^168 and 2^336 modulo l, and perform the reduction
+	// with two multiplications and two additions.
+
+	s.setShortBytes(x[:21])
+	t := new(Scalar).setShortBytes(x[21:42])
+	s.Add(s, t.Multiply(t, scalarTwo168))
+	t.setShortBytes(x[42:])
+	s.Add(s, t.Multiply(t, scalarTwo336))
+
+	return s, nil
+}
+
+// scalarTwo168 and scalarTwo336 are 2^168 and 2^336 modulo l, encoded as a
+// fiatScalarMontgomeryDomainFieldElement, which is a little-endian 4-limb value
+// in the 2^256 Montgomery domain.
+var scalarTwo168 = &Scalar{s: [4]uint64{0x5b8ab432eac74798, 0x38afddd6de59d5d7,
+	0xa2c131b399411b7c, 0x6329a7ed9ce5a30}}
+var scalarTwo336 = &Scalar{s: [4]uint64{0xbd3d108e2b35ecc5, 0x5c3a3718bdf9c90b,
+	0x63aa97a331b4f2ee, 0x3d217f5be65cb5c}}
+
+// setShortBytes sets s = x mod l, where x is a little-endian integer shorter
+// than 32 bytes.
+func (s *Scalar) setShortBytes(x []byte) *Scalar {
+	if len(x) >= 32 {
+		panic("edwards25519: internal error: setShortBytes called with a long string")
+	}
+	var buf [32]byte
+	copy(buf[:], x)
+	fiatScalarFromBytes((*[4]uint64)(&s.s), &buf)
+	fiatScalarToMontgomery(&s.s, (*fiatScalarNonMontgomeryDomainFieldElement)(&s.s))
+	return s
+}
+
+// SetCanonicalBytes sets s = x, where x is a 32-byte little-endian encoding of
+// s, and returns s. If x is not a canonical encoding of s, SetCanonicalBytes
+// returns nil and an error, and the receiver is unchanged.
+func (s *Scalar) SetCanonicalBytes(x []byte) (*Scalar, error) {
+	if len(x) != 32 {
+		return nil, errors.New("invalid scalar length")
+	}
+	if !isReduced(x) {
+		return nil, errors.New("invalid scalar encoding")
+	}
+
+	fiatScalarFromBytes((*[4]uint64)(&s.s), (*[32]byte)(x))
+	fiatScalarToMontgomery(&s.s, (*fiatScalarNonMontgomeryDomainFieldElement)(&s.s))
+
+	return s, nil
+}
+
+// scalarMinusOneBytes is l - 1 in little endian.
+var scalarMinusOneBytes = [32]byte{236, 211, 245, 92, 26, 99, 18, 88, 214, 156, 247, 162, 222, 249, 222, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16}
+
+// isReduced returns whether the given scalar in 32-byte little endian encoded
+// form is reduced modulo l.
+func isReduced(s []byte) bool {
+	if len(s) != 32 {
+		return false
+	}
+
+	for i := len(s) - 1; i >= 0; i-- {
+		switch {
+		case s[i] > scalarMinusOneBytes[i]:
+			return false
+		case s[i] < scalarMinusOneBytes[i]:
+			return true
+		}
+	}
+	return true
+}
+
+// SetBytesWithClamping applies the buffer pruning described in RFC 8032,
+// Section 5.1.5 (also known as clamping) and sets s to the result. The input
+// must be 32 bytes, and it is not modified. If x is not of the right length,
+// SetBytesWithClamping returns nil and an error, and the receiver is unchanged.
+//
+// Note that since Scalar values are always reduced modulo the prime order of
+// the curve, the resulting value will not preserve any of the cofactor-clearing
+// properties that clamping is meant to provide. It will however work as
+// expected as long as it is applied to points on the prime order subgroup, like
+// in Ed25519. In fact, it is lost to history why RFC 8032 adopted the
+// irrelevant RFC 7748 clamping, but it is now required for compatibility.
+func (s *Scalar) SetBytesWithClamping(x []byte) (*Scalar, error) {
+	// The description above omits the purpose of the high bits of the clamping
+	// for brevity, but those are also lost to reductions, and are also
+	// irrelevant to edwards25519 as they protect against a specific
+	// implementation bug that was once observed in a generic Montgomery ladder.
+	if len(x) != 32 {
+		return nil, errors.New("edwards25519: invalid SetBytesWithClamping input length")
+	}
+
+	// We need to use the wide reduction from SetUniformBytes, since clamping
+	// sets the 2^254 bit, making the value higher than the order.
+	var wideBytes [64]byte
+	copy(wideBytes[:], x[:])
+	wideBytes[0] &= 248
+	wideBytes[31] &= 63
+	wideBytes[31] |= 64
+	return s.SetUniformBytes(wideBytes[:])
+}
+
+// Bytes returns the canonical 32-byte little-endian encoding of s.
+func (s *Scalar) Bytes() []byte {
+	// This function is outlined to make the allocations inline in the caller
+	// rather than happen on the heap.
+	var encoded [32]byte
+	return s.bytes(&encoded)
+}
+
+func (s *Scalar) bytes(out *[32]byte) []byte {
+	var ss fiatScalarNonMontgomeryDomainFieldElement
+	fiatScalarFromMontgomery(&ss, &s.s)
+	fiatScalarToBytes(out, (*[4]uint64)(&ss))
+	return out[:]
+}
+
+// Equal returns 1 if s and t are equal, and 0 otherwise.
+func (s *Scalar) Equal(t *Scalar) int {
+	var diff fiatScalarMontgomeryDomainFieldElement
+	fiatScalarSub(&diff, &s.s, &t.s)
+	var nonzero uint64
+	fiatScalarNonzero(&nonzero, (*[4]uint64)(&diff))
+	nonzero |= nonzero >> 32
+	nonzero |= nonzero >> 16
+	nonzero |= nonzero >> 8
+	nonzero |= nonzero >> 4
+	nonzero |= nonzero >> 2
+	nonzero |= nonzero >> 1
+	return int(^nonzero) & 1
+}
+
+// nonAdjacentForm computes a width-w non-adjacent form for this scalar.
+//
+// w must be between 2 and 8, or nonAdjacentForm will panic.
+func (s *Scalar) nonAdjacentForm(w uint) [256]int8 {
+	// This implementation is adapted from the one
+	// in curve25519-dalek and is documented there:
+	// https://github.com/dalek-cryptography/curve25519-dalek/blob/f630041af28e9a405255f98a8a93adca18e4315b/src/scalar.rs#L800-L871
+	b := s.Bytes()
+	if b[31] > 127 {
+		panic("scalar has high bit set illegally")
+	}
+	if w < 2 {
+		panic("w must be at least 2 by the definition of NAF")
+	} else if w > 8 {
+		panic("NAF digits must fit in int8")
+	}
+
+	var naf [256]int8
+	var digits [5]uint64
+
+	for i := 0; i < 4; i++ {
+		digits[i] = binary.LittleEndian.Uint64(b[i*8:])
+	}
+
+	width := uint64(1 << w)
+	windowMask := uint64(width - 1)
+
+	pos := uint(0)
+	carry := uint64(0)
+	for pos < 256 {
+		indexU64 := pos / 64
+		indexBit := pos % 64
+		var bitBuf uint64
+		if indexBit < 64-w {
+			// This window's bits are contained in a single u64
+			bitBuf = digits[indexU64] >> indexBit
+		} else {
+			// Combine the current 64 bits with bits from the next 64
+			bitBuf = (digits[indexU64] >> indexBit) | (digits[1+indexU64] << (64 - indexBit))
+		}
+
+		// Add carry into the current window
+		window := carry + (bitBuf & windowMask)
+
+		if window&1 == 0 {
+			// If the window value is even, preserve the carry and continue.
+			// Why is the carry preserved?
+			// If carry == 0 and window & 1 == 0,
+			//    then the next carry should be 0
+			// If carry == 1 and window & 1 == 0,
+			//    then bit_buf & 1 == 1 so the next carry should be 1
+			pos += 1
+			continue
+		}
+
+		if window < width/2 {
+			carry = 0
+			naf[pos] = int8(window)
+		} else {
+			carry = 1
+			naf[pos] = int8(window) - int8(width)
+		}
+
+		pos += w
+	}
+	return naf
+}
+
+func (s *Scalar) signedRadix16() [64]int8 {
+	b := s.Bytes()
+	if b[31] > 127 {
+		panic("scalar has high bit set illegally")
+	}
+
+	var digits [64]int8
+
+	// Compute unsigned radix-16 digits:
+	for i := 0; i < 32; i++ {
+		digits[2*i] = int8(b[i] & 15)
+		digits[2*i+1] = int8((b[i] >> 4) & 15)
+	}
+
+	// Recenter coefficients:
+	for i := 0; i < 63; i++ {
+		carry := (digits[i] + 8) >> 4
+		digits[i] -= carry << 4
+		digits[i+1] += carry
+	}
+
+	return digits
+}

+ 1147 - 0
vendor/filippo.io/edwards25519/scalar_fiat.go

@@ -0,0 +1,1147 @@
+// Code generated by Fiat Cryptography. DO NOT EDIT.
+//
+// Autogenerated: word_by_word_montgomery --lang Go --cmovznz-by-mul --relax-primitive-carry-to-bitwidth 32,64 --public-function-case camelCase --public-type-case camelCase --private-function-case camelCase --private-type-case camelCase --doc-text-before-function-name '' --doc-newline-before-package-declaration --doc-prepend-header 'Code generated by Fiat Cryptography. DO NOT EDIT.' --package-name edwards25519 Scalar 64 '2^252 + 27742317777372353535851937790883648493' mul add sub opp nonzero from_montgomery to_montgomery to_bytes from_bytes
+//
+// curve description: Scalar
+//
+// machine_wordsize = 64 (from "64")
+//
+// requested operations: mul, add, sub, opp, nonzero, from_montgomery, to_montgomery, to_bytes, from_bytes
+//
+// m = 0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed (from "2^252 + 27742317777372353535851937790883648493")
+//
+//
+//
+// NOTE: In addition to the bounds specified above each function, all
+//
+//   functions synthesized for this Montgomery arithmetic require the
+//
+//   input to be strictly less than the prime modulus (m), and also
+//
+//   require the input to be in the unique saturated representation.
+//
+//   All functions also ensure that these two properties are true of
+//
+//   return values.
+//
+//
+//
+// Computed values:
+//
+//   eval z = z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192)
+//
+//   bytes_eval z = z[0] + (z[1] << 8) + (z[2] << 16) + (z[3] << 24) + (z[4] << 32) + (z[5] << 40) + (z[6] << 48) + (z[7] << 56) + (z[8] << 64) + (z[9] << 72) + (z[10] << 80) + (z[11] << 88) + (z[12] << 96) + (z[13] << 104) + (z[14] << 112) + (z[15] << 120) + (z[16] << 128) + (z[17] << 136) + (z[18] << 144) + (z[19] << 152) + (z[20] << 160) + (z[21] << 168) + (z[22] << 176) + (z[23] << 184) + (z[24] << 192) + (z[25] << 200) + (z[26] << 208) + (z[27] << 216) + (z[28] << 224) + (z[29] << 232) + (z[30] << 240) + (z[31] << 248)
+//
+//   twos_complement_eval z = let x1 := z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192) in
+//
+//                            if x1 & (2^256-1) < 2^255 then x1 & (2^256-1) else (x1 & (2^256-1)) - 2^256
+
+package edwards25519
+
+import "math/bits"
+
+type fiatScalarUint1 uint64 // We use uint64 instead of a more narrow type for performance reasons; see https://github.com/mit-plv/fiat-crypto/pull/1006#issuecomment-892625927
+type fiatScalarInt1 int64   // We use uint64 instead of a more narrow type for performance reasons; see https://github.com/mit-plv/fiat-crypto/pull/1006#issuecomment-892625927
+
+// The type fiatScalarMontgomeryDomainFieldElement is a field element in the Montgomery domain.
+//
+// Bounds: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
+type fiatScalarMontgomeryDomainFieldElement [4]uint64
+
+// The type fiatScalarNonMontgomeryDomainFieldElement is a field element NOT in the Montgomery domain.
+//
+// Bounds: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
+type fiatScalarNonMontgomeryDomainFieldElement [4]uint64
+
+// fiatScalarCmovznzU64 is a single-word conditional move.
+//
+// Postconditions:
+//
+//	out1 = (if arg1 = 0 then arg2 else arg3)
+//
+// Input Bounds:
+//
+//	arg1: [0x0 ~> 0x1]
+//	arg2: [0x0 ~> 0xffffffffffffffff]
+//	arg3: [0x0 ~> 0xffffffffffffffff]
+//
+// Output Bounds:
+//
+//	out1: [0x0 ~> 0xffffffffffffffff]
+func fiatScalarCmovznzU64(out1 *uint64, arg1 fiatScalarUint1, arg2 uint64, arg3 uint64) {
+	x1 := (uint64(arg1) * 0xffffffffffffffff)
+	x2 := ((x1 & arg3) | ((^x1) & arg2))
+	*out1 = x2
+}
+
+// fiatScalarMul multiplies two field elements in the Montgomery domain.
+//
+// Preconditions:
+//
+//	0 ≤ eval arg1 < m
+//	0 ≤ eval arg2 < m
+//
+// Postconditions:
+//
+//	eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) * eval (from_montgomery arg2)) mod m
+//	0 ≤ eval out1 < m
+func fiatScalarMul(out1 *fiatScalarMontgomeryDomainFieldElement, arg1 *fiatScalarMontgomeryDomainFieldElement, arg2 *fiatScalarMontgomeryDomainFieldElement) {
+	x1 := arg1[1]
+	x2 := arg1[2]
+	x3 := arg1[3]
+	x4 := arg1[0]
+	var x5 uint64
+	var x6 uint64
+	x6, x5 = bits.Mul64(x4, arg2[3])
+	var x7 uint64
+	var x8 uint64
+	x8, x7 = bits.Mul64(x4, arg2[2])
+	var x9 uint64
+	var x10 uint64
+	x10, x9 = bits.Mul64(x4, arg2[1])
+	var x11 uint64
+	var x12 uint64
+	x12, x11 = bits.Mul64(x4, arg2[0])
+	var x13 uint64
+	var x14 uint64
+	x13, x14 = bits.Add64(x12, x9, uint64(0x0))
+	var x15 uint64
+	var x16 uint64
+	x15, x16 = bits.Add64(x10, x7, uint64(fiatScalarUint1(x14)))
+	var x17 uint64
+	var x18 uint64
+	x17, x18 = bits.Add64(x8, x5, uint64(fiatScalarUint1(x16)))
+	x19 := (uint64(fiatScalarUint1(x18)) + x6)
+	var x20 uint64
+	_, x20 = bits.Mul64(x11, 0xd2b51da312547e1b)
+	var x22 uint64
+	var x23 uint64
+	x23, x22 = bits.Mul64(x20, 0x1000000000000000)
+	var x24 uint64
+	var x25 uint64
+	x25, x24 = bits.Mul64(x20, 0x14def9dea2f79cd6)
+	var x26 uint64
+	var x27 uint64
+	x27, x26 = bits.Mul64(x20, 0x5812631a5cf5d3ed)
+	var x28 uint64
+	var x29 uint64
+	x28, x29 = bits.Add64(x27, x24, uint64(0x0))
+	x30 := (uint64(fiatScalarUint1(x29)) + x25)
+	var x32 uint64
+	_, x32 = bits.Add64(x11, x26, uint64(0x0))
+	var x33 uint64
+	var x34 uint64
+	x33, x34 = bits.Add64(x13, x28, uint64(fiatScalarUint1(x32)))
+	var x35 uint64
+	var x36 uint64
+	x35, x36 = bits.Add64(x15, x30, uint64(fiatScalarUint1(x34)))
+	var x37 uint64
+	var x38 uint64
+	x37, x38 = bits.Add64(x17, x22, uint64(fiatScalarUint1(x36)))
+	var x39 uint64
+	var x40 uint64
+	x39, x40 = bits.Add64(x19, x23, uint64(fiatScalarUint1(x38)))
+	var x41 uint64
+	var x42 uint64
+	x42, x41 = bits.Mul64(x1, arg2[3])
+	var x43 uint64
+	var x44 uint64
+	x44, x43 = bits.Mul64(x1, arg2[2])
+	var x45 uint64
+	var x46 uint64
+	x46, x45 = bits.Mul64(x1, arg2[1])
+	var x47 uint64
+	var x48 uint64
+	x48, x47 = bits.Mul64(x1, arg2[0])
+	var x49 uint64
+	var x50 uint64
+	x49, x50 = bits.Add64(x48, x45, uint64(0x0))
+	var x51 uint64
+	var x52 uint64
+	x51, x52 = bits.Add64(x46, x43, uint64(fiatScalarUint1(x50)))
+	var x53 uint64
+	var x54 uint64
+	x53, x54 = bits.Add64(x44, x41, uint64(fiatScalarUint1(x52)))
+	x55 := (uint64(fiatScalarUint1(x54)) + x42)
+	var x56 uint64
+	var x57 uint64
+	x56, x57 = bits.Add64(x33, x47, uint64(0x0))
+	var x58 uint64
+	var x59 uint64
+	x58, x59 = bits.Add64(x35, x49, uint64(fiatScalarUint1(x57)))
+	var x60 uint64
+	var x61 uint64
+	x60, x61 = bits.Add64(x37, x51, uint64(fiatScalarUint1(x59)))
+	var x62 uint64
+	var x63 uint64
+	x62, x63 = bits.Add64(x39, x53, uint64(fiatScalarUint1(x61)))
+	var x64 uint64
+	var x65 uint64
+	x64, x65 = bits.Add64(uint64(fiatScalarUint1(x40)), x55, uint64(fiatScalarUint1(x63)))
+	var x66 uint64
+	_, x66 = bits.Mul64(x56, 0xd2b51da312547e1b)
+	var x68 uint64
+	var x69 uint64
+	x69, x68 = bits.Mul64(x66, 0x1000000000000000)
+	var x70 uint64
+	var x71 uint64
+	x71, x70 = bits.Mul64(x66, 0x14def9dea2f79cd6)
+	var x72 uint64
+	var x73 uint64
+	x73, x72 = bits.Mul64(x66, 0x5812631a5cf5d3ed)
+	var x74 uint64
+	var x75 uint64
+	x74, x75 = bits.Add64(x73, x70, uint64(0x0))
+	x76 := (uint64(fiatScalarUint1(x75)) + x71)
+	var x78 uint64
+	_, x78 = bits.Add64(x56, x72, uint64(0x0))
+	var x79 uint64
+	var x80 uint64
+	x79, x80 = bits.Add64(x58, x74, uint64(fiatScalarUint1(x78)))
+	var x81 uint64
+	var x82 uint64
+	x81, x82 = bits.Add64(x60, x76, uint64(fiatScalarUint1(x80)))
+	var x83 uint64
+	var x84 uint64
+	x83, x84 = bits.Add64(x62, x68, uint64(fiatScalarUint1(x82)))
+	var x85 uint64
+	var x86 uint64
+	x85, x86 = bits.Add64(x64, x69, uint64(fiatScalarUint1(x84)))
+	x87 := (uint64(fiatScalarUint1(x86)) + uint64(fiatScalarUint1(x65)))
+	var x88 uint64
+	var x89 uint64
+	x89, x88 = bits.Mul64(x2, arg2[3])
+	var x90 uint64
+	var x91 uint64
+	x91, x90 = bits.Mul64(x2, arg2[2])
+	var x92 uint64
+	var x93 uint64
+	x93, x92 = bits.Mul64(x2, arg2[1])
+	var x94 uint64
+	var x95 uint64
+	x95, x94 = bits.Mul64(x2, arg2[0])
+	var x96 uint64
+	var x97 uint64
+	x96, x97 = bits.Add64(x95, x92, uint64(0x0))
+	var x98 uint64
+	var x99 uint64
+	x98, x99 = bits.Add64(x93, x90, uint64(fiatScalarUint1(x97)))
+	var x100 uint64
+	var x101 uint64
+	x100, x101 = bits.Add64(x91, x88, uint64(fiatScalarUint1(x99)))
+	x102 := (uint64(fiatScalarUint1(x101)) + x89)
+	var x103 uint64
+	var x104 uint64
+	x103, x104 = bits.Add64(x79, x94, uint64(0x0))
+	var x105 uint64
+	var x106 uint64
+	x105, x106 = bits.Add64(x81, x96, uint64(fiatScalarUint1(x104)))
+	var x107 uint64
+	var x108 uint64
+	x107, x108 = bits.Add64(x83, x98, uint64(fiatScalarUint1(x106)))
+	var x109 uint64
+	var x110 uint64
+	x109, x110 = bits.Add64(x85, x100, uint64(fiatScalarUint1(x108)))
+	var x111 uint64
+	var x112 uint64
+	x111, x112 = bits.Add64(x87, x102, uint64(fiatScalarUint1(x110)))
+	var x113 uint64
+	_, x113 = bits.Mul64(x103, 0xd2b51da312547e1b)
+	var x115 uint64
+	var x116 uint64
+	x116, x115 = bits.Mul64(x113, 0x1000000000000000)
+	var x117 uint64
+	var x118 uint64
+	x118, x117 = bits.Mul64(x113, 0x14def9dea2f79cd6)
+	var x119 uint64
+	var x120 uint64
+	x120, x119 = bits.Mul64(x113, 0x5812631a5cf5d3ed)
+	var x121 uint64
+	var x122 uint64
+	x121, x122 = bits.Add64(x120, x117, uint64(0x0))
+	x123 := (uint64(fiatScalarUint1(x122)) + x118)
+	var x125 uint64
+	_, x125 = bits.Add64(x103, x119, uint64(0x0))
+	var x126 uint64
+	var x127 uint64
+	x126, x127 = bits.Add64(x105, x121, uint64(fiatScalarUint1(x125)))
+	var x128 uint64
+	var x129 uint64
+	x128, x129 = bits.Add64(x107, x123, uint64(fiatScalarUint1(x127)))
+	var x130 uint64
+	var x131 uint64
+	x130, x131 = bits.Add64(x109, x115, uint64(fiatScalarUint1(x129)))
+	var x132 uint64
+	var x133 uint64
+	x132, x133 = bits.Add64(x111, x116, uint64(fiatScalarUint1(x131)))
+	x134 := (uint64(fiatScalarUint1(x133)) + uint64(fiatScalarUint1(x112)))
+	var x135 uint64
+	var x136 uint64
+	x136, x135 = bits.Mul64(x3, arg2[3])
+	var x137 uint64
+	var x138 uint64
+	x138, x137 = bits.Mul64(x3, arg2[2])
+	var x139 uint64
+	var x140 uint64
+	x140, x139 = bits.Mul64(x3, arg2[1])
+	var x141 uint64
+	var x142 uint64
+	x142, x141 = bits.Mul64(x3, arg2[0])
+	var x143 uint64
+	var x144 uint64
+	x143, x144 = bits.Add64(x142, x139, uint64(0x0))
+	var x145 uint64
+	var x146 uint64
+	x145, x146 = bits.Add64(x140, x137, uint64(fiatScalarUint1(x144)))
+	var x147 uint64
+	var x148 uint64
+	x147, x148 = bits.Add64(x138, x135, uint64(fiatScalarUint1(x146)))
+	x149 := (uint64(fiatScalarUint1(x148)) + x136)
+	var x150 uint64
+	var x151 uint64
+	x150, x151 = bits.Add64(x126, x141, uint64(0x0))
+	var x152 uint64
+	var x153 uint64
+	x152, x153 = bits.Add64(x128, x143, uint64(fiatScalarUint1(x151)))
+	var x154 uint64
+	var x155 uint64
+	x154, x155 = bits.Add64(x130, x145, uint64(fiatScalarUint1(x153)))
+	var x156 uint64
+	var x157 uint64
+	x156, x157 = bits.Add64(x132, x147, uint64(fiatScalarUint1(x155)))
+	var x158 uint64
+	var x159 uint64
+	x158, x159 = bits.Add64(x134, x149, uint64(fiatScalarUint1(x157)))
+	var x160 uint64
+	_, x160 = bits.Mul64(x150, 0xd2b51da312547e1b)
+	var x162 uint64
+	var x163 uint64
+	x163, x162 = bits.Mul64(x160, 0x1000000000000000)
+	var x164 uint64
+	var x165 uint64
+	x165, x164 = bits.Mul64(x160, 0x14def9dea2f79cd6)
+	var x166 uint64
+	var x167 uint64
+	x167, x166 = bits.Mul64(x160, 0x5812631a5cf5d3ed)
+	var x168 uint64
+	var x169 uint64
+	x168, x169 = bits.Add64(x167, x164, uint64(0x0))
+	x170 := (uint64(fiatScalarUint1(x169)) + x165)
+	var x172 uint64
+	_, x172 = bits.Add64(x150, x166, uint64(0x0))
+	var x173 uint64
+	var x174 uint64
+	x173, x174 = bits.Add64(x152, x168, uint64(fiatScalarUint1(x172)))
+	var x175 uint64
+	var x176 uint64
+	x175, x176 = bits.Add64(x154, x170, uint64(fiatScalarUint1(x174)))
+	var x177 uint64
+	var x178 uint64
+	x177, x178 = bits.Add64(x156, x162, uint64(fiatScalarUint1(x176)))
+	var x179 uint64
+	var x180 uint64
+	x179, x180 = bits.Add64(x158, x163, uint64(fiatScalarUint1(x178)))
+	x181 := (uint64(fiatScalarUint1(x180)) + uint64(fiatScalarUint1(x159)))
+	var x182 uint64
+	var x183 uint64
+	x182, x183 = bits.Sub64(x173, 0x5812631a5cf5d3ed, uint64(0x0))
+	var x184 uint64
+	var x185 uint64
+	x184, x185 = bits.Sub64(x175, 0x14def9dea2f79cd6, uint64(fiatScalarUint1(x183)))
+	var x186 uint64
+	var x187 uint64
+	x186, x187 = bits.Sub64(x177, uint64(0x0), uint64(fiatScalarUint1(x185)))
+	var x188 uint64
+	var x189 uint64
+	x188, x189 = bits.Sub64(x179, 0x1000000000000000, uint64(fiatScalarUint1(x187)))
+	var x191 uint64
+	_, x191 = bits.Sub64(x181, uint64(0x0), uint64(fiatScalarUint1(x189)))
+	var x192 uint64
+	fiatScalarCmovznzU64(&x192, fiatScalarUint1(x191), x182, x173)
+	var x193 uint64
+	fiatScalarCmovznzU64(&x193, fiatScalarUint1(x191), x184, x175)
+	var x194 uint64
+	fiatScalarCmovznzU64(&x194, fiatScalarUint1(x191), x186, x177)
+	var x195 uint64
+	fiatScalarCmovznzU64(&x195, fiatScalarUint1(x191), x188, x179)
+	out1[0] = x192
+	out1[1] = x193
+	out1[2] = x194
+	out1[3] = x195
+}
+
+// fiatScalarAdd adds two field elements in the Montgomery domain.
+//
+// Preconditions:
+//
+//	0 ≤ eval arg1 < m
+//	0 ≤ eval arg2 < m
+//
+// Postconditions:
+//
+//	eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) + eval (from_montgomery arg2)) mod m
+//	0 ≤ eval out1 < m
+func fiatScalarAdd(out1 *fiatScalarMontgomeryDomainFieldElement, arg1 *fiatScalarMontgomeryDomainFieldElement, arg2 *fiatScalarMontgomeryDomainFieldElement) {
+	var x1 uint64
+	var x2 uint64
+	x1, x2 = bits.Add64(arg1[0], arg2[0], uint64(0x0))
+	var x3 uint64
+	var x4 uint64
+	x3, x4 = bits.Add64(arg1[1], arg2[1], uint64(fiatScalarUint1(x2)))
+	var x5 uint64
+	var x6 uint64
+	x5, x6 = bits.Add64(arg1[2], arg2[2], uint64(fiatScalarUint1(x4)))
+	var x7 uint64
+	var x8 uint64
+	x7, x8 = bits.Add64(arg1[3], arg2[3], uint64(fiatScalarUint1(x6)))
+	var x9 uint64
+	var x10 uint64
+	x9, x10 = bits.Sub64(x1, 0x5812631a5cf5d3ed, uint64(0x0))
+	var x11 uint64
+	var x12 uint64
+	x11, x12 = bits.Sub64(x3, 0x14def9dea2f79cd6, uint64(fiatScalarUint1(x10)))
+	var x13 uint64
+	var x14 uint64
+	x13, x14 = bits.Sub64(x5, uint64(0x0), uint64(fiatScalarUint1(x12)))
+	var x15 uint64
+	var x16 uint64
+	x15, x16 = bits.Sub64(x7, 0x1000000000000000, uint64(fiatScalarUint1(x14)))
+	var x18 uint64
+	_, x18 = bits.Sub64(uint64(fiatScalarUint1(x8)), uint64(0x0), uint64(fiatScalarUint1(x16)))
+	var x19 uint64
+	fiatScalarCmovznzU64(&x19, fiatScalarUint1(x18), x9, x1)
+	var x20 uint64
+	fiatScalarCmovznzU64(&x20, fiatScalarUint1(x18), x11, x3)
+	var x21 uint64
+	fiatScalarCmovznzU64(&x21, fiatScalarUint1(x18), x13, x5)
+	var x22 uint64
+	fiatScalarCmovznzU64(&x22, fiatScalarUint1(x18), x15, x7)
+	out1[0] = x19
+	out1[1] = x20
+	out1[2] = x21
+	out1[3] = x22
+}
+
+// fiatScalarSub subtracts two field elements in the Montgomery domain.
+//
+// Preconditions:
+//
+//	0 ≤ eval arg1 < m
+//	0 ≤ eval arg2 < m
+//
+// Postconditions:
+//
+//	eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) - eval (from_montgomery arg2)) mod m
+//	0 ≤ eval out1 < m
+func fiatScalarSub(out1 *fiatScalarMontgomeryDomainFieldElement, arg1 *fiatScalarMontgomeryDomainFieldElement, arg2 *fiatScalarMontgomeryDomainFieldElement) {
+	var x1 uint64
+	var x2 uint64
+	x1, x2 = bits.Sub64(arg1[0], arg2[0], uint64(0x0))
+	var x3 uint64
+	var x4 uint64
+	x3, x4 = bits.Sub64(arg1[1], arg2[1], uint64(fiatScalarUint1(x2)))
+	var x5 uint64
+	var x6 uint64
+	x5, x6 = bits.Sub64(arg1[2], arg2[2], uint64(fiatScalarUint1(x4)))
+	var x7 uint64
+	var x8 uint64
+	x7, x8 = bits.Sub64(arg1[3], arg2[3], uint64(fiatScalarUint1(x6)))
+	var x9 uint64
+	fiatScalarCmovznzU64(&x9, fiatScalarUint1(x8), uint64(0x0), 0xffffffffffffffff)
+	var x10 uint64
+	var x11 uint64
+	x10, x11 = bits.Add64(x1, (x9 & 0x5812631a5cf5d3ed), uint64(0x0))
+	var x12 uint64
+	var x13 uint64
+	x12, x13 = bits.Add64(x3, (x9 & 0x14def9dea2f79cd6), uint64(fiatScalarUint1(x11)))
+	var x14 uint64
+	var x15 uint64
+	x14, x15 = bits.Add64(x5, uint64(0x0), uint64(fiatScalarUint1(x13)))
+	var x16 uint64
+	x16, _ = bits.Add64(x7, (x9 & 0x1000000000000000), uint64(fiatScalarUint1(x15)))
+	out1[0] = x10
+	out1[1] = x12
+	out1[2] = x14
+	out1[3] = x16
+}
+
+// fiatScalarOpp negates a field element in the Montgomery domain.
+//
+// Preconditions:
+//
+//	0 ≤ eval arg1 < m
+//
+// Postconditions:
+//
+//	eval (from_montgomery out1) mod m = -eval (from_montgomery arg1) mod m
+//	0 ≤ eval out1 < m
+func fiatScalarOpp(out1 *fiatScalarMontgomeryDomainFieldElement, arg1 *fiatScalarMontgomeryDomainFieldElement) {
+	var x1 uint64
+	var x2 uint64
+	x1, x2 = bits.Sub64(uint64(0x0), arg1[0], uint64(0x0))
+	var x3 uint64
+	var x4 uint64
+	x3, x4 = bits.Sub64(uint64(0x0), arg1[1], uint64(fiatScalarUint1(x2)))
+	var x5 uint64
+	var x6 uint64
+	x5, x6 = bits.Sub64(uint64(0x0), arg1[2], uint64(fiatScalarUint1(x4)))
+	var x7 uint64
+	var x8 uint64
+	x7, x8 = bits.Sub64(uint64(0x0), arg1[3], uint64(fiatScalarUint1(x6)))
+	var x9 uint64
+	fiatScalarCmovznzU64(&x9, fiatScalarUint1(x8), uint64(0x0), 0xffffffffffffffff)
+	var x10 uint64
+	var x11 uint64
+	x10, x11 = bits.Add64(x1, (x9 & 0x5812631a5cf5d3ed), uint64(0x0))
+	var x12 uint64
+	var x13 uint64
+	x12, x13 = bits.Add64(x3, (x9 & 0x14def9dea2f79cd6), uint64(fiatScalarUint1(x11)))
+	var x14 uint64
+	var x15 uint64
+	x14, x15 = bits.Add64(x5, uint64(0x0), uint64(fiatScalarUint1(x13)))
+	var x16 uint64
+	x16, _ = bits.Add64(x7, (x9 & 0x1000000000000000), uint64(fiatScalarUint1(x15)))
+	out1[0] = x10
+	out1[1] = x12
+	out1[2] = x14
+	out1[3] = x16
+}
+
+// fiatScalarNonzero outputs a single non-zero word if the input is non-zero and zero otherwise.
+//
+// Preconditions:
+//
+//	0 ≤ eval arg1 < m
+//
+// Postconditions:
+//
+//	out1 = 0 ↔ eval (from_montgomery arg1) mod m = 0
+//
+// Input Bounds:
+//
+//	arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
+//
+// Output Bounds:
+//
+//	out1: [0x0 ~> 0xffffffffffffffff]
+func fiatScalarNonzero(out1 *uint64, arg1 *[4]uint64) {
+	x1 := (arg1[0] | (arg1[1] | (arg1[2] | arg1[3])))
+	*out1 = x1
+}
+
+// fiatScalarFromMontgomery translates a field element out of the Montgomery domain.
+//
+// Preconditions:
+//
+//	0 ≤ eval arg1 < m
+//
+// Postconditions:
+//
+//	eval out1 mod m = (eval arg1 * ((2^64)⁻¹ mod m)^4) mod m
+//	0 ≤ eval out1 < m
+func fiatScalarFromMontgomery(out1 *fiatScalarNonMontgomeryDomainFieldElement, arg1 *fiatScalarMontgomeryDomainFieldElement) {
+	x1 := arg1[0]
+	var x2 uint64
+	_, x2 = bits.Mul64(x1, 0xd2b51da312547e1b)
+	var x4 uint64
+	var x5 uint64
+	x5, x4 = bits.Mul64(x2, 0x1000000000000000)
+	var x6 uint64
+	var x7 uint64
+	x7, x6 = bits.Mul64(x2, 0x14def9dea2f79cd6)
+	var x8 uint64
+	var x9 uint64
+	x9, x8 = bits.Mul64(x2, 0x5812631a5cf5d3ed)
+	var x10 uint64
+	var x11 uint64
+	x10, x11 = bits.Add64(x9, x6, uint64(0x0))
+	var x13 uint64
+	_, x13 = bits.Add64(x1, x8, uint64(0x0))
+	var x14 uint64
+	var x15 uint64
+	x14, x15 = bits.Add64(uint64(0x0), x10, uint64(fiatScalarUint1(x13)))
+	var x16 uint64
+	var x17 uint64
+	x16, x17 = bits.Add64(x14, arg1[1], uint64(0x0))
+	var x18 uint64
+	_, x18 = bits.Mul64(x16, 0xd2b51da312547e1b)
+	var x20 uint64
+	var x21 uint64
+	x21, x20 = bits.Mul64(x18, 0x1000000000000000)
+	var x22 uint64
+	var x23 uint64
+	x23, x22 = bits.Mul64(x18, 0x14def9dea2f79cd6)
+	var x24 uint64
+	var x25 uint64
+	x25, x24 = bits.Mul64(x18, 0x5812631a5cf5d3ed)
+	var x26 uint64
+	var x27 uint64
+	x26, x27 = bits.Add64(x25, x22, uint64(0x0))
+	var x29 uint64
+	_, x29 = bits.Add64(x16, x24, uint64(0x0))
+	var x30 uint64
+	var x31 uint64
+	x30, x31 = bits.Add64((uint64(fiatScalarUint1(x17)) + (uint64(fiatScalarUint1(x15)) + (uint64(fiatScalarUint1(x11)) + x7))), x26, uint64(fiatScalarUint1(x29)))
+	var x32 uint64
+	var x33 uint64
+	x32, x33 = bits.Add64(x4, (uint64(fiatScalarUint1(x27)) + x23), uint64(fiatScalarUint1(x31)))
+	var x34 uint64
+	var x35 uint64
+	x34, x35 = bits.Add64(x5, x20, uint64(fiatScalarUint1(x33)))
+	var x36 uint64
+	var x37 uint64
+	x36, x37 = bits.Add64(x30, arg1[2], uint64(0x0))
+	var x38 uint64
+	var x39 uint64
+	x38, x39 = bits.Add64(x32, uint64(0x0), uint64(fiatScalarUint1(x37)))
+	var x40 uint64
+	var x41 uint64
+	x40, x41 = bits.Add64(x34, uint64(0x0), uint64(fiatScalarUint1(x39)))
+	var x42 uint64
+	_, x42 = bits.Mul64(x36, 0xd2b51da312547e1b)
+	var x44 uint64
+	var x45 uint64
+	x45, x44 = bits.Mul64(x42, 0x1000000000000000)
+	var x46 uint64
+	var x47 uint64
+	x47, x46 = bits.Mul64(x42, 0x14def9dea2f79cd6)
+	var x48 uint64
+	var x49 uint64
+	x49, x48 = bits.Mul64(x42, 0x5812631a5cf5d3ed)
+	var x50 uint64
+	var x51 uint64
+	x50, x51 = bits.Add64(x49, x46, uint64(0x0))
+	var x53 uint64
+	_, x53 = bits.Add64(x36, x48, uint64(0x0))
+	var x54 uint64
+	var x55 uint64
+	x54, x55 = bits.Add64(x38, x50, uint64(fiatScalarUint1(x53)))
+	var x56 uint64
+	var x57 uint64
+	x56, x57 = bits.Add64(x40, (uint64(fiatScalarUint1(x51)) + x47), uint64(fiatScalarUint1(x55)))
+	var x58 uint64
+	var x59 uint64
+	x58, x59 = bits.Add64((uint64(fiatScalarUint1(x41)) + (uint64(fiatScalarUint1(x35)) + x21)), x44, uint64(fiatScalarUint1(x57)))
+	var x60 uint64
+	var x61 uint64
+	x60, x61 = bits.Add64(x54, arg1[3], uint64(0x0))
+	var x62 uint64
+	var x63 uint64
+	x62, x63 = bits.Add64(x56, uint64(0x0), uint64(fiatScalarUint1(x61)))
+	var x64 uint64
+	var x65 uint64
+	x64, x65 = bits.Add64(x58, uint64(0x0), uint64(fiatScalarUint1(x63)))
+	var x66 uint64
+	_, x66 = bits.Mul64(x60, 0xd2b51da312547e1b)
+	var x68 uint64
+	var x69 uint64
+	x69, x68 = bits.Mul64(x66, 0x1000000000000000)
+	var x70 uint64
+	var x71 uint64
+	x71, x70 = bits.Mul64(x66, 0x14def9dea2f79cd6)
+	var x72 uint64
+	var x73 uint64
+	x73, x72 = bits.Mul64(x66, 0x5812631a5cf5d3ed)
+	var x74 uint64
+	var x75 uint64
+	x74, x75 = bits.Add64(x73, x70, uint64(0x0))
+	var x77 uint64
+	_, x77 = bits.Add64(x60, x72, uint64(0x0))
+	var x78 uint64
+	var x79 uint64
+	x78, x79 = bits.Add64(x62, x74, uint64(fiatScalarUint1(x77)))
+	var x80 uint64
+	var x81 uint64
+	x80, x81 = bits.Add64(x64, (uint64(fiatScalarUint1(x75)) + x71), uint64(fiatScalarUint1(x79)))
+	var x82 uint64
+	var x83 uint64
+	x82, x83 = bits.Add64((uint64(fiatScalarUint1(x65)) + (uint64(fiatScalarUint1(x59)) + x45)), x68, uint64(fiatScalarUint1(x81)))
+	x84 := (uint64(fiatScalarUint1(x83)) + x69)
+	var x85 uint64
+	var x86 uint64
+	x85, x86 = bits.Sub64(x78, 0x5812631a5cf5d3ed, uint64(0x0))
+	var x87 uint64
+	var x88 uint64
+	x87, x88 = bits.Sub64(x80, 0x14def9dea2f79cd6, uint64(fiatScalarUint1(x86)))
+	var x89 uint64
+	var x90 uint64
+	x89, x90 = bits.Sub64(x82, uint64(0x0), uint64(fiatScalarUint1(x88)))
+	var x91 uint64
+	var x92 uint64
+	x91, x92 = bits.Sub64(x84, 0x1000000000000000, uint64(fiatScalarUint1(x90)))
+	var x94 uint64
+	_, x94 = bits.Sub64(uint64(0x0), uint64(0x0), uint64(fiatScalarUint1(x92)))
+	var x95 uint64
+	fiatScalarCmovznzU64(&x95, fiatScalarUint1(x94), x85, x78)
+	var x96 uint64
+	fiatScalarCmovznzU64(&x96, fiatScalarUint1(x94), x87, x80)
+	var x97 uint64
+	fiatScalarCmovznzU64(&x97, fiatScalarUint1(x94), x89, x82)
+	var x98 uint64
+	fiatScalarCmovznzU64(&x98, fiatScalarUint1(x94), x91, x84)
+	out1[0] = x95
+	out1[1] = x96
+	out1[2] = x97
+	out1[3] = x98
+}
+
+// fiatScalarToMontgomery translates a field element into the Montgomery domain.
+//
+// Preconditions:
+//
+//	0 ≤ eval arg1 < m
+//
+// Postconditions:
+//
+//	eval (from_montgomery out1) mod m = eval arg1 mod m
+//	0 ≤ eval out1 < m
+func fiatScalarToMontgomery(out1 *fiatScalarMontgomeryDomainFieldElement, arg1 *fiatScalarNonMontgomeryDomainFieldElement) {
+	x1 := arg1[1]
+	x2 := arg1[2]
+	x3 := arg1[3]
+	x4 := arg1[0]
+	var x5 uint64
+	var x6 uint64
+	x6, x5 = bits.Mul64(x4, 0x399411b7c309a3d)
+	var x7 uint64
+	var x8 uint64
+	x8, x7 = bits.Mul64(x4, 0xceec73d217f5be65)
+	var x9 uint64
+	var x10 uint64
+	x10, x9 = bits.Mul64(x4, 0xd00e1ba768859347)
+	var x11 uint64
+	var x12 uint64
+	x12, x11 = bits.Mul64(x4, 0xa40611e3449c0f01)
+	var x13 uint64
+	var x14 uint64
+	x13, x14 = bits.Add64(x12, x9, uint64(0x0))
+	var x15 uint64
+	var x16 uint64
+	x15, x16 = bits.Add64(x10, x7, uint64(fiatScalarUint1(x14)))
+	var x17 uint64
+	var x18 uint64
+	x17, x18 = bits.Add64(x8, x5, uint64(fiatScalarUint1(x16)))
+	var x19 uint64
+	_, x19 = bits.Mul64(x11, 0xd2b51da312547e1b)
+	var x21 uint64
+	var x22 uint64
+	x22, x21 = bits.Mul64(x19, 0x1000000000000000)
+	var x23 uint64
+	var x24 uint64
+	x24, x23 = bits.Mul64(x19, 0x14def9dea2f79cd6)
+	var x25 uint64
+	var x26 uint64
+	x26, x25 = bits.Mul64(x19, 0x5812631a5cf5d3ed)
+	var x27 uint64
+	var x28 uint64
+	x27, x28 = bits.Add64(x26, x23, uint64(0x0))
+	var x30 uint64
+	_, x30 = bits.Add64(x11, x25, uint64(0x0))
+	var x31 uint64
+	var x32 uint64
+	x31, x32 = bits.Add64(x13, x27, uint64(fiatScalarUint1(x30)))
+	var x33 uint64
+	var x34 uint64
+	x33, x34 = bits.Add64(x15, (uint64(fiatScalarUint1(x28)) + x24), uint64(fiatScalarUint1(x32)))
+	var x35 uint64
+	var x36 uint64
+	x35, x36 = bits.Add64(x17, x21, uint64(fiatScalarUint1(x34)))
+	var x37 uint64
+	var x38 uint64
+	x38, x37 = bits.Mul64(x1, 0x399411b7c309a3d)
+	var x39 uint64
+	var x40 uint64
+	x40, x39 = bits.Mul64(x1, 0xceec73d217f5be65)
+	var x41 uint64
+	var x42 uint64
+	x42, x41 = bits.Mul64(x1, 0xd00e1ba768859347)
+	var x43 uint64
+	var x44 uint64
+	x44, x43 = bits.Mul64(x1, 0xa40611e3449c0f01)
+	var x45 uint64
+	var x46 uint64
+	x45, x46 = bits.Add64(x44, x41, uint64(0x0))
+	var x47 uint64
+	var x48 uint64
+	x47, x48 = bits.Add64(x42, x39, uint64(fiatScalarUint1(x46)))
+	var x49 uint64
+	var x50 uint64
+	x49, x50 = bits.Add64(x40, x37, uint64(fiatScalarUint1(x48)))
+	var x51 uint64
+	var x52 uint64
+	x51, x52 = bits.Add64(x31, x43, uint64(0x0))
+	var x53 uint64
+	var x54 uint64
+	x53, x54 = bits.Add64(x33, x45, uint64(fiatScalarUint1(x52)))
+	var x55 uint64
+	var x56 uint64
+	x55, x56 = bits.Add64(x35, x47, uint64(fiatScalarUint1(x54)))
+	var x57 uint64
+	var x58 uint64
+	x57, x58 = bits.Add64(((uint64(fiatScalarUint1(x36)) + (uint64(fiatScalarUint1(x18)) + x6)) + x22), x49, uint64(fiatScalarUint1(x56)))
+	var x59 uint64
+	_, x59 = bits.Mul64(x51, 0xd2b51da312547e1b)
+	var x61 uint64
+	var x62 uint64
+	x62, x61 = bits.Mul64(x59, 0x1000000000000000)
+	var x63 uint64
+	var x64 uint64
+	x64, x63 = bits.Mul64(x59, 0x14def9dea2f79cd6)
+	var x65 uint64
+	var x66 uint64
+	x66, x65 = bits.Mul64(x59, 0x5812631a5cf5d3ed)
+	var x67 uint64
+	var x68 uint64
+	x67, x68 = bits.Add64(x66, x63, uint64(0x0))
+	var x70 uint64
+	_, x70 = bits.Add64(x51, x65, uint64(0x0))
+	var x71 uint64
+	var x72 uint64
+	x71, x72 = bits.Add64(x53, x67, uint64(fiatScalarUint1(x70)))
+	var x73 uint64
+	var x74 uint64
+	x73, x74 = bits.Add64(x55, (uint64(fiatScalarUint1(x68)) + x64), uint64(fiatScalarUint1(x72)))
+	var x75 uint64
+	var x76 uint64
+	x75, x76 = bits.Add64(x57, x61, uint64(fiatScalarUint1(x74)))
+	var x77 uint64
+	var x78 uint64
+	x78, x77 = bits.Mul64(x2, 0x399411b7c309a3d)
+	var x79 uint64
+	var x80 uint64
+	x80, x79 = bits.Mul64(x2, 0xceec73d217f5be65)
+	var x81 uint64
+	var x82 uint64
+	x82, x81 = bits.Mul64(x2, 0xd00e1ba768859347)
+	var x83 uint64
+	var x84 uint64
+	x84, x83 = bits.Mul64(x2, 0xa40611e3449c0f01)
+	var x85 uint64
+	var x86 uint64
+	x85, x86 = bits.Add64(x84, x81, uint64(0x0))
+	var x87 uint64
+	var x88 uint64
+	x87, x88 = bits.Add64(x82, x79, uint64(fiatScalarUint1(x86)))
+	var x89 uint64
+	var x90 uint64
+	x89, x90 = bits.Add64(x80, x77, uint64(fiatScalarUint1(x88)))
+	var x91 uint64
+	var x92 uint64
+	x91, x92 = bits.Add64(x71, x83, uint64(0x0))
+	var x93 uint64
+	var x94 uint64
+	x93, x94 = bits.Add64(x73, x85, uint64(fiatScalarUint1(x92)))
+	var x95 uint64
+	var x96 uint64
+	x95, x96 = bits.Add64(x75, x87, uint64(fiatScalarUint1(x94)))
+	var x97 uint64
+	var x98 uint64
+	x97, x98 = bits.Add64(((uint64(fiatScalarUint1(x76)) + (uint64(fiatScalarUint1(x58)) + (uint64(fiatScalarUint1(x50)) + x38))) + x62), x89, uint64(fiatScalarUint1(x96)))
+	var x99 uint64
+	_, x99 = bits.Mul64(x91, 0xd2b51da312547e1b)
+	var x101 uint64
+	var x102 uint64
+	x102, x101 = bits.Mul64(x99, 0x1000000000000000)
+	var x103 uint64
+	var x104 uint64
+	x104, x103 = bits.Mul64(x99, 0x14def9dea2f79cd6)
+	var x105 uint64
+	var x106 uint64
+	x106, x105 = bits.Mul64(x99, 0x5812631a5cf5d3ed)
+	var x107 uint64
+	var x108 uint64
+	x107, x108 = bits.Add64(x106, x103, uint64(0x0))
+	var x110 uint64
+	_, x110 = bits.Add64(x91, x105, uint64(0x0))
+	var x111 uint64
+	var x112 uint64
+	x111, x112 = bits.Add64(x93, x107, uint64(fiatScalarUint1(x110)))
+	var x113 uint64
+	var x114 uint64
+	x113, x114 = bits.Add64(x95, (uint64(fiatScalarUint1(x108)) + x104), uint64(fiatScalarUint1(x112)))
+	var x115 uint64
+	var x116 uint64
+	x115, x116 = bits.Add64(x97, x101, uint64(fiatScalarUint1(x114)))
+	var x117 uint64
+	var x118 uint64
+	x118, x117 = bits.Mul64(x3, 0x399411b7c309a3d)
+	var x119 uint64
+	var x120 uint64
+	x120, x119 = bits.Mul64(x3, 0xceec73d217f5be65)
+	var x121 uint64
+	var x122 uint64
+	x122, x121 = bits.Mul64(x3, 0xd00e1ba768859347)
+	var x123 uint64
+	var x124 uint64
+	x124, x123 = bits.Mul64(x3, 0xa40611e3449c0f01)
+	var x125 uint64
+	var x126 uint64
+	x125, x126 = bits.Add64(x124, x121, uint64(0x0))
+	var x127 uint64
+	var x128 uint64
+	x127, x128 = bits.Add64(x122, x119, uint64(fiatScalarUint1(x126)))
+	var x129 uint64
+	var x130 uint64
+	x129, x130 = bits.Add64(x120, x117, uint64(fiatScalarUint1(x128)))
+	var x131 uint64
+	var x132 uint64
+	x131, x132 = bits.Add64(x111, x123, uint64(0x0))
+	var x133 uint64
+	var x134 uint64
+	x133, x134 = bits.Add64(x113, x125, uint64(fiatScalarUint1(x132)))
+	var x135 uint64
+	var x136 uint64
+	x135, x136 = bits.Add64(x115, x127, uint64(fiatScalarUint1(x134)))
+	var x137 uint64
+	var x138 uint64
+	x137, x138 = bits.Add64(((uint64(fiatScalarUint1(x116)) + (uint64(fiatScalarUint1(x98)) + (uint64(fiatScalarUint1(x90)) + x78))) + x102), x129, uint64(fiatScalarUint1(x136)))
+	var x139 uint64
+	_, x139 = bits.Mul64(x131, 0xd2b51da312547e1b)
+	var x141 uint64
+	var x142 uint64
+	x142, x141 = bits.Mul64(x139, 0x1000000000000000)
+	var x143 uint64
+	var x144 uint64
+	x144, x143 = bits.Mul64(x139, 0x14def9dea2f79cd6)
+	var x145 uint64
+	var x146 uint64
+	x146, x145 = bits.Mul64(x139, 0x5812631a5cf5d3ed)
+	var x147 uint64
+	var x148 uint64
+	x147, x148 = bits.Add64(x146, x143, uint64(0x0))
+	var x150 uint64
+	_, x150 = bits.Add64(x131, x145, uint64(0x0))
+	var x151 uint64
+	var x152 uint64
+	x151, x152 = bits.Add64(x133, x147, uint64(fiatScalarUint1(x150)))
+	var x153 uint64
+	var x154 uint64
+	x153, x154 = bits.Add64(x135, (uint64(fiatScalarUint1(x148)) + x144), uint64(fiatScalarUint1(x152)))
+	var x155 uint64
+	var x156 uint64
+	x155, x156 = bits.Add64(x137, x141, uint64(fiatScalarUint1(x154)))
+	x157 := ((uint64(fiatScalarUint1(x156)) + (uint64(fiatScalarUint1(x138)) + (uint64(fiatScalarUint1(x130)) + x118))) + x142)
+	var x158 uint64
+	var x159 uint64
+	x158, x159 = bits.Sub64(x151, 0x5812631a5cf5d3ed, uint64(0x0))
+	var x160 uint64
+	var x161 uint64
+	x160, x161 = bits.Sub64(x153, 0x14def9dea2f79cd6, uint64(fiatScalarUint1(x159)))
+	var x162 uint64
+	var x163 uint64
+	x162, x163 = bits.Sub64(x155, uint64(0x0), uint64(fiatScalarUint1(x161)))
+	var x164 uint64
+	var x165 uint64
+	x164, x165 = bits.Sub64(x157, 0x1000000000000000, uint64(fiatScalarUint1(x163)))
+	var x167 uint64
+	_, x167 = bits.Sub64(uint64(0x0), uint64(0x0), uint64(fiatScalarUint1(x165)))
+	var x168 uint64
+	fiatScalarCmovznzU64(&x168, fiatScalarUint1(x167), x158, x151)
+	var x169 uint64
+	fiatScalarCmovznzU64(&x169, fiatScalarUint1(x167), x160, x153)
+	var x170 uint64
+	fiatScalarCmovznzU64(&x170, fiatScalarUint1(x167), x162, x155)
+	var x171 uint64
+	fiatScalarCmovznzU64(&x171, fiatScalarUint1(x167), x164, x157)
+	out1[0] = x168
+	out1[1] = x169
+	out1[2] = x170
+	out1[3] = x171
+}
+
+// fiatScalarToBytes serializes a field element NOT in the Montgomery domain to bytes in little-endian order.
+//
+// Preconditions:
+//
+//	0 ≤ eval arg1 < m
+//
+// Postconditions:
+//
+//	out1 = map (λ x, ⌊((eval arg1 mod m) mod 2^(8 * (x + 1))) / 2^(8 * x)⌋) [0..31]
+//
+// Input Bounds:
+//
+//	arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0x1fffffffffffffff]]
+//
+// Output Bounds:
+//
+//	out1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0x1f]]
+func fiatScalarToBytes(out1 *[32]uint8, arg1 *[4]uint64) {
+	x1 := arg1[3]
+	x2 := arg1[2]
+	x3 := arg1[1]
+	x4 := arg1[0]
+	x5 := (uint8(x4) & 0xff)
+	x6 := (x4 >> 8)
+	x7 := (uint8(x6) & 0xff)
+	x8 := (x6 >> 8)
+	x9 := (uint8(x8) & 0xff)
+	x10 := (x8 >> 8)
+	x11 := (uint8(x10) & 0xff)
+	x12 := (x10 >> 8)
+	x13 := (uint8(x12) & 0xff)
+	x14 := (x12 >> 8)
+	x15 := (uint8(x14) & 0xff)
+	x16 := (x14 >> 8)
+	x17 := (uint8(x16) & 0xff)
+	x18 := uint8((x16 >> 8))
+	x19 := (uint8(x3) & 0xff)
+	x20 := (x3 >> 8)
+	x21 := (uint8(x20) & 0xff)
+	x22 := (x20 >> 8)
+	x23 := (uint8(x22) & 0xff)
+	x24 := (x22 >> 8)
+	x25 := (uint8(x24) & 0xff)
+	x26 := (x24 >> 8)
+	x27 := (uint8(x26) & 0xff)
+	x28 := (x26 >> 8)
+	x29 := (uint8(x28) & 0xff)
+	x30 := (x28 >> 8)
+	x31 := (uint8(x30) & 0xff)
+	x32 := uint8((x30 >> 8))
+	x33 := (uint8(x2) & 0xff)
+	x34 := (x2 >> 8)
+	x35 := (uint8(x34) & 0xff)
+	x36 := (x34 >> 8)
+	x37 := (uint8(x36) & 0xff)
+	x38 := (x36 >> 8)
+	x39 := (uint8(x38) & 0xff)
+	x40 := (x38 >> 8)
+	x41 := (uint8(x40) & 0xff)
+	x42 := (x40 >> 8)
+	x43 := (uint8(x42) & 0xff)
+	x44 := (x42 >> 8)
+	x45 := (uint8(x44) & 0xff)
+	x46 := uint8((x44 >> 8))
+	x47 := (uint8(x1) & 0xff)
+	x48 := (x1 >> 8)
+	x49 := (uint8(x48) & 0xff)
+	x50 := (x48 >> 8)
+	x51 := (uint8(x50) & 0xff)
+	x52 := (x50 >> 8)
+	x53 := (uint8(x52) & 0xff)
+	x54 := (x52 >> 8)
+	x55 := (uint8(x54) & 0xff)
+	x56 := (x54 >> 8)
+	x57 := (uint8(x56) & 0xff)
+	x58 := (x56 >> 8)
+	x59 := (uint8(x58) & 0xff)
+	x60 := uint8((x58 >> 8))
+	out1[0] = x5
+	out1[1] = x7
+	out1[2] = x9
+	out1[3] = x11
+	out1[4] = x13
+	out1[5] = x15
+	out1[6] = x17
+	out1[7] = x18
+	out1[8] = x19
+	out1[9] = x21
+	out1[10] = x23
+	out1[11] = x25
+	out1[12] = x27
+	out1[13] = x29
+	out1[14] = x31
+	out1[15] = x32
+	out1[16] = x33
+	out1[17] = x35
+	out1[18] = x37
+	out1[19] = x39
+	out1[20] = x41
+	out1[21] = x43
+	out1[22] = x45
+	out1[23] = x46
+	out1[24] = x47
+	out1[25] = x49
+	out1[26] = x51
+	out1[27] = x53
+	out1[28] = x55
+	out1[29] = x57
+	out1[30] = x59
+	out1[31] = x60
+}
+
+// fiatScalarFromBytes deserializes a field element NOT in the Montgomery domain from bytes in little-endian order.
+//
+// Preconditions:
+//
+//	0 ≤ bytes_eval arg1 < m
+//
+// Postconditions:
+//
+//	eval out1 mod m = bytes_eval arg1 mod m
+//	0 ≤ eval out1 < m
+//
+// Input Bounds:
+//
+//	arg1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0x1f]]
+//
+// Output Bounds:
+//
+//	out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0x1fffffffffffffff]]
+func fiatScalarFromBytes(out1 *[4]uint64, arg1 *[32]uint8) {
+	x1 := (uint64(arg1[31]) << 56)
+	x2 := (uint64(arg1[30]) << 48)
+	x3 := (uint64(arg1[29]) << 40)
+	x4 := (uint64(arg1[28]) << 32)
+	x5 := (uint64(arg1[27]) << 24)
+	x6 := (uint64(arg1[26]) << 16)
+	x7 := (uint64(arg1[25]) << 8)
+	x8 := arg1[24]
+	x9 := (uint64(arg1[23]) << 56)
+	x10 := (uint64(arg1[22]) << 48)
+	x11 := (uint64(arg1[21]) << 40)
+	x12 := (uint64(arg1[20]) << 32)
+	x13 := (uint64(arg1[19]) << 24)
+	x14 := (uint64(arg1[18]) << 16)
+	x15 := (uint64(arg1[17]) << 8)
+	x16 := arg1[16]
+	x17 := (uint64(arg1[15]) << 56)
+	x18 := (uint64(arg1[14]) << 48)
+	x19 := (uint64(arg1[13]) << 40)
+	x20 := (uint64(arg1[12]) << 32)
+	x21 := (uint64(arg1[11]) << 24)
+	x22 := (uint64(arg1[10]) << 16)
+	x23 := (uint64(arg1[9]) << 8)
+	x24 := arg1[8]
+	x25 := (uint64(arg1[7]) << 56)
+	x26 := (uint64(arg1[6]) << 48)
+	x27 := (uint64(arg1[5]) << 40)
+	x28 := (uint64(arg1[4]) << 32)
+	x29 := (uint64(arg1[3]) << 24)
+	x30 := (uint64(arg1[2]) << 16)
+	x31 := (uint64(arg1[1]) << 8)
+	x32 := arg1[0]
+	x33 := (x31 + uint64(x32))
+	x34 := (x30 + x33)
+	x35 := (x29 + x34)
+	x36 := (x28 + x35)
+	x37 := (x27 + x36)
+	x38 := (x26 + x37)
+	x39 := (x25 + x38)
+	x40 := (x23 + uint64(x24))
+	x41 := (x22 + x40)
+	x42 := (x21 + x41)
+	x43 := (x20 + x42)
+	x44 := (x19 + x43)
+	x45 := (x18 + x44)
+	x46 := (x17 + x45)
+	x47 := (x15 + uint64(x16))
+	x48 := (x14 + x47)
+	x49 := (x13 + x48)
+	x50 := (x12 + x49)
+	x51 := (x11 + x50)
+	x52 := (x10 + x51)
+	x53 := (x9 + x52)
+	x54 := (x7 + uint64(x8))
+	x55 := (x6 + x54)
+	x56 := (x5 + x55)
+	x57 := (x4 + x56)
+	x58 := (x3 + x57)
+	x59 := (x2 + x58)
+	x60 := (x1 + x59)
+	out1[0] = x39
+	out1[1] = x46
+	out1[2] = x53
+	out1[3] = x60
+}

+ 214 - 0
vendor/filippo.io/edwards25519/scalarmult.go

@@ -0,0 +1,214 @@
+// Copyright (c) 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.
+
+package edwards25519
+
+import "sync"
+
+// basepointTable is a set of 32 affineLookupTables, where table i is generated
+// from 256i * basepoint. It is precomputed the first time it's used.
+func basepointTable() *[32]affineLookupTable {
+	basepointTablePrecomp.initOnce.Do(func() {
+		p := NewGeneratorPoint()
+		for i := 0; i < 32; i++ {
+			basepointTablePrecomp.table[i].FromP3(p)
+			for j := 0; j < 8; j++ {
+				p.Add(p, p)
+			}
+		}
+	})
+	return &basepointTablePrecomp.table
+}
+
+var basepointTablePrecomp struct {
+	table    [32]affineLookupTable
+	initOnce sync.Once
+}
+
+// ScalarBaseMult sets v = x * B, where B is the canonical generator, and
+// returns v.
+//
+// The scalar multiplication is done in constant time.
+func (v *Point) ScalarBaseMult(x *Scalar) *Point {
+	basepointTable := basepointTable()
+
+	// Write x = sum(x_i * 16^i) so  x*B = sum( B*x_i*16^i )
+	// as described in the Ed25519 paper
+	//
+	// Group even and odd coefficients
+	// x*B     = x_0*16^0*B + x_2*16^2*B + ... + x_62*16^62*B
+	//         + x_1*16^1*B + x_3*16^3*B + ... + x_63*16^63*B
+	// x*B     = x_0*16^0*B + x_2*16^2*B + ... + x_62*16^62*B
+	//    + 16*( x_1*16^0*B + x_3*16^2*B + ... + x_63*16^62*B)
+	//
+	// We use a lookup table for each i to get x_i*16^(2*i)*B
+	// and do four doublings to multiply by 16.
+	digits := x.signedRadix16()
+
+	multiple := &affineCached{}
+	tmp1 := &projP1xP1{}
+	tmp2 := &projP2{}
+
+	// Accumulate the odd components first
+	v.Set(NewIdentityPoint())
+	for i := 1; i < 64; i += 2 {
+		basepointTable[i/2].SelectInto(multiple, digits[i])
+		tmp1.AddAffine(v, multiple)
+		v.fromP1xP1(tmp1)
+	}
+
+	// Multiply by 16
+	tmp2.FromP3(v)       // tmp2 =    v in P2 coords
+	tmp1.Double(tmp2)    // tmp1 =  2*v in P1xP1 coords
+	tmp2.FromP1xP1(tmp1) // tmp2 =  2*v in P2 coords
+	tmp1.Double(tmp2)    // tmp1 =  4*v in P1xP1 coords
+	tmp2.FromP1xP1(tmp1) // tmp2 =  4*v in P2 coords
+	tmp1.Double(tmp2)    // tmp1 =  8*v in P1xP1 coords
+	tmp2.FromP1xP1(tmp1) // tmp2 =  8*v in P2 coords
+	tmp1.Double(tmp2)    // tmp1 = 16*v in P1xP1 coords
+	v.fromP1xP1(tmp1)    // now v = 16*(odd components)
+
+	// Accumulate the even components
+	for i := 0; i < 64; i += 2 {
+		basepointTable[i/2].SelectInto(multiple, digits[i])
+		tmp1.AddAffine(v, multiple)
+		v.fromP1xP1(tmp1)
+	}
+
+	return v
+}
+
+// ScalarMult sets v = x * q, and returns v.
+//
+// The scalar multiplication is done in constant time.
+func (v *Point) ScalarMult(x *Scalar, q *Point) *Point {
+	checkInitialized(q)
+
+	var table projLookupTable
+	table.FromP3(q)
+
+	// Write x = sum(x_i * 16^i)
+	// so  x*Q = sum( Q*x_i*16^i )
+	//         = Q*x_0 + 16*(Q*x_1 + 16*( ... + Q*x_63) ... )
+	//           <------compute inside out---------
+	//
+	// We use the lookup table to get the x_i*Q values
+	// and do four doublings to compute 16*Q
+	digits := x.signedRadix16()
+
+	// Unwrap first loop iteration to save computing 16*identity
+	multiple := &projCached{}
+	tmp1 := &projP1xP1{}
+	tmp2 := &projP2{}
+	table.SelectInto(multiple, digits[63])
+
+	v.Set(NewIdentityPoint())
+	tmp1.Add(v, multiple) // tmp1 = x_63*Q in P1xP1 coords
+	for i := 62; i >= 0; i-- {
+		tmp2.FromP1xP1(tmp1) // tmp2 =    (prev) in P2 coords
+		tmp1.Double(tmp2)    // tmp1 =  2*(prev) in P1xP1 coords
+		tmp2.FromP1xP1(tmp1) // tmp2 =  2*(prev) in P2 coords
+		tmp1.Double(tmp2)    // tmp1 =  4*(prev) in P1xP1 coords
+		tmp2.FromP1xP1(tmp1) // tmp2 =  4*(prev) in P2 coords
+		tmp1.Double(tmp2)    // tmp1 =  8*(prev) in P1xP1 coords
+		tmp2.FromP1xP1(tmp1) // tmp2 =  8*(prev) in P2 coords
+		tmp1.Double(tmp2)    // tmp1 = 16*(prev) in P1xP1 coords
+		v.fromP1xP1(tmp1)    //    v = 16*(prev) in P3 coords
+		table.SelectInto(multiple, digits[i])
+		tmp1.Add(v, multiple) // tmp1 = x_i*Q + 16*(prev) in P1xP1 coords
+	}
+	v.fromP1xP1(tmp1)
+	return v
+}
+
+// basepointNafTable is the nafLookupTable8 for the basepoint.
+// It is precomputed the first time it's used.
+func basepointNafTable() *nafLookupTable8 {
+	basepointNafTablePrecomp.initOnce.Do(func() {
+		basepointNafTablePrecomp.table.FromP3(NewGeneratorPoint())
+	})
+	return &basepointNafTablePrecomp.table
+}
+
+var basepointNafTablePrecomp struct {
+	table    nafLookupTable8
+	initOnce sync.Once
+}
+
+// VarTimeDoubleScalarBaseMult sets v = a * A + b * B, where B is the canonical
+// generator, and returns v.
+//
+// Execution time depends on the inputs.
+func (v *Point) VarTimeDoubleScalarBaseMult(a *Scalar, A *Point, b *Scalar) *Point {
+	checkInitialized(A)
+
+	// Similarly to the single variable-base approach, we compute
+	// digits and use them with a lookup table.  However, because
+	// we are allowed to do variable-time operations, we don't
+	// need constant-time lookups or constant-time digit
+	// computations.
+	//
+	// So we use a non-adjacent form of some width w instead of
+	// radix 16.  This is like a binary representation (one digit
+	// for each binary place) but we allow the digits to grow in
+	// magnitude up to 2^{w-1} so that the nonzero digits are as
+	// sparse as possible.  Intuitively, this "condenses" the
+	// "mass" of the scalar onto sparse coefficients (meaning
+	// fewer additions).
+
+	basepointNafTable := basepointNafTable()
+	var aTable nafLookupTable5
+	aTable.FromP3(A)
+	// Because the basepoint is fixed, we can use a wider NAF
+	// corresponding to a bigger table.
+	aNaf := a.nonAdjacentForm(5)
+	bNaf := b.nonAdjacentForm(8)
+
+	// Find the first nonzero coefficient.
+	i := 255
+	for j := i; j >= 0; j-- {
+		if aNaf[j] != 0 || bNaf[j] != 0 {
+			break
+		}
+	}
+
+	multA := &projCached{}
+	multB := &affineCached{}
+	tmp1 := &projP1xP1{}
+	tmp2 := &projP2{}
+	tmp2.Zero()
+
+	// Move from high to low bits, doubling the accumulator
+	// at each iteration and checking whether there is a nonzero
+	// coefficient to look up a multiple of.
+	for ; i >= 0; i-- {
+		tmp1.Double(tmp2)
+
+		// Only update v if we have a nonzero coeff to add in.
+		if aNaf[i] > 0 {
+			v.fromP1xP1(tmp1)
+			aTable.SelectInto(multA, aNaf[i])
+			tmp1.Add(v, multA)
+		} else if aNaf[i] < 0 {
+			v.fromP1xP1(tmp1)
+			aTable.SelectInto(multA, -aNaf[i])
+			tmp1.Sub(v, multA)
+		}
+
+		if bNaf[i] > 0 {
+			v.fromP1xP1(tmp1)
+			basepointNafTable.SelectInto(multB, bNaf[i])
+			tmp1.AddAffine(v, multB)
+		} else if bNaf[i] < 0 {
+			v.fromP1xP1(tmp1)
+			basepointNafTable.SelectInto(multB, -bNaf[i])
+			tmp1.SubAffine(v, multB)
+		}
+
+		tmp2.FromP1xP1(tmp1)
+	}
+
+	v.fromP2(tmp2)
+	return v
+}

+ 129 - 0
vendor/filippo.io/edwards25519/tables.go

@@ -0,0 +1,129 @@
+// Copyright (c) 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.
+
+package edwards25519
+
+import (
+	"crypto/subtle"
+)
+
+// A dynamic lookup table for variable-base, constant-time scalar muls.
+type projLookupTable struct {
+	points [8]projCached
+}
+
+// A precomputed lookup table for fixed-base, constant-time scalar muls.
+type affineLookupTable struct {
+	points [8]affineCached
+}
+
+// A dynamic lookup table for variable-base, variable-time scalar muls.
+type nafLookupTable5 struct {
+	points [8]projCached
+}
+
+// A precomputed lookup table for fixed-base, variable-time scalar muls.
+type nafLookupTable8 struct {
+	points [64]affineCached
+}
+
+// Constructors.
+
+// Builds a lookup table at runtime. Fast.
+func (v *projLookupTable) FromP3(q *Point) {
+	// Goal: v.points[i] = (i+1)*Q, i.e., Q, 2Q, ..., 8Q
+	// This allows lookup of -8Q, ..., -Q, 0, Q, ..., 8Q
+	v.points[0].FromP3(q)
+	tmpP3 := Point{}
+	tmpP1xP1 := projP1xP1{}
+	for i := 0; i < 7; i++ {
+		// Compute (i+1)*Q as Q + i*Q and convert to a projCached
+		// This is needlessly complicated because the API has explicit
+		// receivers instead of creating stack objects and relying on RVO
+		v.points[i+1].FromP3(tmpP3.fromP1xP1(tmpP1xP1.Add(q, &v.points[i])))
+	}
+}
+
+// This is not optimised for speed; fixed-base tables should be precomputed.
+func (v *affineLookupTable) FromP3(q *Point) {
+	// Goal: v.points[i] = (i+1)*Q, i.e., Q, 2Q, ..., 8Q
+	// This allows lookup of -8Q, ..., -Q, 0, Q, ..., 8Q
+	v.points[0].FromP3(q)
+	tmpP3 := Point{}
+	tmpP1xP1 := projP1xP1{}
+	for i := 0; i < 7; i++ {
+		// Compute (i+1)*Q as Q + i*Q and convert to affineCached
+		v.points[i+1].FromP3(tmpP3.fromP1xP1(tmpP1xP1.AddAffine(q, &v.points[i])))
+	}
+}
+
+// Builds a lookup table at runtime. Fast.
+func (v *nafLookupTable5) FromP3(q *Point) {
+	// Goal: v.points[i] = (2*i+1)*Q, i.e., Q, 3Q, 5Q, ..., 15Q
+	// This allows lookup of -15Q, ..., -3Q, -Q, 0, Q, 3Q, ..., 15Q
+	v.points[0].FromP3(q)
+	q2 := Point{}
+	q2.Add(q, q)
+	tmpP3 := Point{}
+	tmpP1xP1 := projP1xP1{}
+	for i := 0; i < 7; i++ {
+		v.points[i+1].FromP3(tmpP3.fromP1xP1(tmpP1xP1.Add(&q2, &v.points[i])))
+	}
+}
+
+// This is not optimised for speed; fixed-base tables should be precomputed.
+func (v *nafLookupTable8) FromP3(q *Point) {
+	v.points[0].FromP3(q)
+	q2 := Point{}
+	q2.Add(q, q)
+	tmpP3 := Point{}
+	tmpP1xP1 := projP1xP1{}
+	for i := 0; i < 63; i++ {
+		v.points[i+1].FromP3(tmpP3.fromP1xP1(tmpP1xP1.AddAffine(&q2, &v.points[i])))
+	}
+}
+
+// Selectors.
+
+// Set dest to x*Q, where -8 <= x <= 8, in constant time.
+func (v *projLookupTable) SelectInto(dest *projCached, x int8) {
+	// Compute xabs = |x|
+	xmask := x >> 7
+	xabs := uint8((x + xmask) ^ xmask)
+
+	dest.Zero()
+	for j := 1; j <= 8; j++ {
+		// Set dest = j*Q if |x| = j
+		cond := subtle.ConstantTimeByteEq(xabs, uint8(j))
+		dest.Select(&v.points[j-1], dest, cond)
+	}
+	// Now dest = |x|*Q, conditionally negate to get x*Q
+	dest.CondNeg(int(xmask & 1))
+}
+
+// Set dest to x*Q, where -8 <= x <= 8, in constant time.
+func (v *affineLookupTable) SelectInto(dest *affineCached, x int8) {
+	// Compute xabs = |x|
+	xmask := x >> 7
+	xabs := uint8((x + xmask) ^ xmask)
+
+	dest.Zero()
+	for j := 1; j <= 8; j++ {
+		// Set dest = j*Q if |x| = j
+		cond := subtle.ConstantTimeByteEq(xabs, uint8(j))
+		dest.Select(&v.points[j-1], dest, cond)
+	}
+	// Now dest = |x|*Q, conditionally negate to get x*Q
+	dest.CondNeg(int(xmask & 1))
+}
+
+// Given odd x with 0 < x < 2^4, return x*Q (in variable time).
+func (v *nafLookupTable5) SelectInto(dest *projCached, x int8) {
+	*dest = v.points[x/2]
+}
+
+// Given odd x with 0 < x < 2^7, return x*Q (in variable time).
+func (v *nafLookupTable8) SelectInto(dest *affineCached, x int8) {
+	*dest = v.points[x/2]
+}

+ 16 - 15
vendor/github.com/IBM/sarama/.golangci.yml

@@ -19,61 +19,62 @@ linters-settings:
   misspell:
     locale: US
   goimports:
-    local-prefixes: github.com/Shopify/sarama
+    local-prefixes: github.com/IBM/sarama
   gocritic:
     enabled-tags:
       - diagnostic
+      - performance
       # - experimental
       # - opinionated
-      # - performance
       # - style
+    enabled-checks:
+      - importShadow
+      - nestingReduce
+      - stringsCompare
+      # - unnamedResult
+      # - whyNoLint
     disabled-checks:
       - assignOp
       - appendAssign
       - commentedOutCode
+      - hugeParam
       - ifElseChain
       - singleCaseSwitch
       - sloppyReassign
-      - wrapperFunc
   funlen:
     lines: 300
     statements: 300
 
+  depguard:
+    rules:
+      main:
+        deny:
+          - pkg: "io/ioutil"
+            desc: Use the "io" and "os" packages instead.
+
 linters:
   disable-all: true
   enable:
     - bodyclose
-    - deadcode
     - depguard
     - exportloopref
     - dogsled
-    # - dupl
     - errcheck
     - errorlint
     - funlen
     - gochecknoinits
-    # - goconst
     - gocritic
     - gocyclo
     - gofmt
     - goimports
-    # - golint
     - gosec
-    # - gosimple
     - govet
-    # - ineffassign
     - misspell
-    # - nakedret
     - nilerr
-    # - paralleltest
-    # - scopelint
     - staticcheck
-    - structcheck
-    # - stylecheck
     - typecheck
     - unconvert
     - unused
-    - varcheck
     - whitespace
 
 issues:

+ 41 - 0
vendor/github.com/IBM/sarama/.pre-commit-config.yaml

@@ -0,0 +1,41 @@
+fail_fast: false
+default_install_hook_types: [pre-commit, commit-msg]
+repos:
+  - repo: https://github.com/pre-commit/pre-commit-hooks
+    rev: v4.4.0
+    hooks:
+      - id: check-merge-conflict
+      - id: check-yaml
+      - id: end-of-file-fixer
+      - id: fix-byte-order-marker
+      - id: mixed-line-ending
+      - id: trailing-whitespace
+  - repo: local
+    hooks:
+      - id: conventional-commit-msg-validation
+        name: commit message conventional validation
+        language: pygrep
+        entry: '^(?:fixup! )?(breaking|build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test){1}(\([\w\-\.]+\))?(!)?: ([\w `])+([\s\S]*)'
+        args: [--multiline, --negate]
+        stages: [commit-msg]
+      - id: commit-msg-needs-to-be-signed-off
+        name: commit message needs to be signed off
+        language: pygrep
+        entry: "^Signed-off-by:"
+        args: [--multiline, --negate]
+        stages: [commit-msg]
+      - id: gofmt
+        name: gofmt
+        description: Format files with gofmt.
+        entry: gofmt -l
+        language: golang
+        files: \.go$
+        args: []
+  - repo: https://github.com/gitleaks/gitleaks
+    rev: v8.16.3
+    hooks:
+      - id: gitleaks
+  - repo: https://github.com/golangci/golangci-lint
+    rev: v1.52.2
+    hooks:
+      - id: golangci-lint

+ 286 - 0
vendor/github.com/IBM/sarama/CHANGELOG.md

@@ -1,5 +1,291 @@
 # Changelog
 
+## Version 1.42.2 (2024-02-09)
+
+## What's Changed
+
+⚠️ The go.mod directive has been bumped to 1.18 as the minimum version of Go required for the module. This was necessary to continue to receive updates from some of the third party dependencies that Sarama makes use of for compression.
+
+### :tada: New Features / Improvements
+* feat: update go directive to 1.18 by @dnwe in https://github.com/IBM/sarama/pull/2713
+* feat: return KError instead of errors in AlterConfigs and DescribeConfig by @zhuliquan in https://github.com/IBM/sarama/pull/2472
+### :bug: Fixes
+* fix: don't waste time for backoff on member id required error by @lzakharov in https://github.com/IBM/sarama/pull/2759
+* fix: prevent ConsumerGroup.Close infinitely locking by @maqdev in https://github.com/IBM/sarama/pull/2717
+### :package: Dependency updates
+* chore(deps): bump golang.org/x/net from 0.17.0 to 0.18.0 by @dependabot in https://github.com/IBM/sarama/pull/2716
+* chore(deps): bump golang.org/x/sync to v0.5.0 by @dependabot in https://github.com/IBM/sarama/pull/2718
+* chore(deps): bump github.com/pierrec/lz4/v4 from 4.1.18 to 4.1.19 by @dependabot in https://github.com/IBM/sarama/pull/2739
+* chore(deps): bump golang.org/x/crypto from 0.15.0 to 0.17.0 by @dependabot in https://github.com/IBM/sarama/pull/2748
+* chore(deps): bump the golang-org-x group with 1 update by @dependabot in https://github.com/IBM/sarama/pull/2734
+* chore(deps): bump the golang-org-x group with 2 updates by @dependabot in https://github.com/IBM/sarama/pull/2764
+* chore(deps): bump github.com/pierrec/lz4/v4 from 4.1.19 to 4.1.21 by @dependabot in https://github.com/IBM/sarama/pull/2763
+* chore(deps): bump golang.org/x/crypto from 0.15.0 to 0.17.0 in /examples/exactly_once by @dependabot in https://github.com/IBM/sarama/pull/2749
+* chore(deps): bump golang.org/x/crypto from 0.15.0 to 0.17.0 in /examples/consumergroup by @dependabot in https://github.com/IBM/sarama/pull/2750
+* chore(deps): bump golang.org/x/crypto from 0.15.0 to 0.17.0 in /examples/sasl_scram_client by @dependabot in https://github.com/IBM/sarama/pull/2751
+* chore(deps): bump golang.org/x/crypto from 0.15.0 to 0.17.0 in /examples/interceptors by @dependabot in https://github.com/IBM/sarama/pull/2752
+* chore(deps): bump golang.org/x/crypto from 0.15.0 to 0.17.0 in /examples/http_server by @dependabot in https://github.com/IBM/sarama/pull/2753
+* chore(deps): bump github.com/eapache/go-resiliency from 1.4.0 to 1.5.0 by @dependabot in https://github.com/IBM/sarama/pull/2745
+* chore(deps): bump golang.org/x/crypto from 0.15.0 to 0.17.0 in /examples/txn_producer by @dependabot in https://github.com/IBM/sarama/pull/2754
+* chore(deps): bump go.opentelemetry.io/otel/sdk from 1.19.0 to 1.22.0 in /examples/interceptors by @dependabot in https://github.com/IBM/sarama/pull/2767
+* chore(deps): bump the golang-org-x group with 1 update by @dependabot in https://github.com/IBM/sarama/pull/2793
+* chore(deps): bump go.opentelemetry.io/otel/exporters/stdout/stdoutmetric from 0.42.0 to 1.23.1 in /examples/interceptors by @dependabot in https://github.com/IBM/sarama/pull/2792
+### :wrench: Maintenance
+* fix(examples): housekeeping of code and deps by @dnwe in https://github.com/IBM/sarama/pull/2720
+### :heavy_plus_sign: Other Changes
+* fix(test): retry MockBroker Listen for EADDRINUSE by @dnwe in https://github.com/IBM/sarama/pull/2721
+
+## New Contributors
+* @maqdev made their first contribution in https://github.com/IBM/sarama/pull/2717
+* @zhuliquan made their first contribution in https://github.com/IBM/sarama/pull/2472
+
+**Full Changelog**: https://github.com/IBM/sarama/compare/v1.42.1...v1.42.2
+
+## Version 1.42.1 (2023-11-07)
+
+## What's Changed
+### :bug: Fixes
+* fix: make fetchInitialOffset use correct protocol by @dnwe in https://github.com/IBM/sarama/pull/2705
+* fix(config): relax ClientID validation after 1.0.0 by @dnwe in https://github.com/IBM/sarama/pull/2706
+
+**Full Changelog**: https://github.com/IBM/sarama/compare/v1.42.0...v1.42.1
+
+## Version 1.42.0 (2023-11-02)
+
+## What's Changed
+### :bug: Fixes
+* Asynchronously close brokers during a RefreshBrokers by @bmassemin in https://github.com/IBM/sarama/pull/2693
+* Fix data race on Broker.done channel by @prestona in https://github.com/IBM/sarama/pull/2698
+* fix: data race in Broker.AsyncProduce by @lzakharov in https://github.com/IBM/sarama/pull/2678
+* Fix default retention time value in offset commit by @prestona in https://github.com/IBM/sarama/pull/2700
+* fix(txmgr): ErrOffsetsLoadInProgress is retriable by @dnwe in https://github.com/IBM/sarama/pull/2701
+### :wrench: Maintenance
+* chore(ci): improve ossf scorecard result by @dnwe in https://github.com/IBM/sarama/pull/2685
+* chore(ci): add kafka 3.6.0 to FVT and versions by @dnwe in https://github.com/IBM/sarama/pull/2692
+### :heavy_plus_sign: Other Changes
+* chore(ci): ossf scorecard.yml by @dnwe in https://github.com/IBM/sarama/pull/2683
+* fix(ci): always run CodeQL on every commit by @dnwe in https://github.com/IBM/sarama/pull/2689
+* chore(doc): add OpenSSF Scorecard badge by @dnwe in https://github.com/IBM/sarama/pull/2691
+
+## New Contributors
+* @bmassemin made their first contribution in https://github.com/IBM/sarama/pull/2693
+* @lzakharov made their first contribution in https://github.com/IBM/sarama/pull/2678
+
+**Full Changelog**: https://github.com/IBM/sarama/compare/v1.41.3...v1.42.0
+
+## Version 1.41.3 (2023-10-17)
+
+## What's Changed
+### :bug: Fixes
+* fix: pre-compile regex for parsing kafka version by @qshuai in https://github.com/IBM/sarama/pull/2663
+* fix(client): ignore empty Metadata responses when refreshing by @HaoSunUber in https://github.com/IBM/sarama/pull/2672
+### :package: Dependency updates
+* chore(deps): bump the golang-org-x group with 2 updates by @dependabot in https://github.com/IBM/sarama/pull/2661
+* chore(deps): bump golang.org/x/net from 0.16.0 to 0.17.0 by @dependabot in https://github.com/IBM/sarama/pull/2671
+### :memo: Documentation
+* fix(docs): correct topic name in rebalancing strategy example by @maksadbek in https://github.com/IBM/sarama/pull/2657
+
+## New Contributors
+* @maksadbek made their first contribution in https://github.com/IBM/sarama/pull/2657
+* @qshuai made their first contribution in https://github.com/IBM/sarama/pull/2663
+
+**Full Changelog**: https://github.com/IBM/sarama/compare/v1.41.2...v1.41.3
+
+## Version 1.41.2 (2023-09-12)
+
+## What's Changed
+### :tada: New Features / Improvements
+* perf: Alloc records in batch by @ronanh in https://github.com/IBM/sarama/pull/2646
+### :bug: Fixes
+* fix(consumer): guard against nil client by @dnwe in https://github.com/IBM/sarama/pull/2636
+* fix(consumer): don't retry session if ctx canceled by @dnwe in https://github.com/IBM/sarama/pull/2642
+* fix: use least loaded broker to refresh metadata by @HaoSunUber in https://github.com/IBM/sarama/pull/2645
+### :package: Dependency updates
+* chore(deps): bump the golang-org-x group with 1 update by @dependabot in https://github.com/IBM/sarama/pull/2641
+
+## New Contributors
+* @HaoSunUber made their first contribution in https://github.com/IBM/sarama/pull/2645
+
+**Full Changelog**: https://github.com/IBM/sarama/compare/v1.41.1...v1.41.2
+
+## Version 1.41.1 (2023-08-30)
+
+## What's Changed
+### :bug: Fixes
+* fix(proto): handle V3 member metadata and empty owned partitions by @dnwe in https://github.com/IBM/sarama/pull/2618
+* fix: make clear that error is configuration issue not server error by @hindessm in https://github.com/IBM/sarama/pull/2628
+* fix(client): force Event Hubs to use V1_0_0_0 by @dnwe in https://github.com/IBM/sarama/pull/2633
+* fix: add retries to alter user scram creds by @hindessm in https://github.com/IBM/sarama/pull/2632
+### :wrench: Maintenance
+* chore(lint): bump golangci-lint and tweak config by @dnwe in https://github.com/IBM/sarama/pull/2620
+### :memo: Documentation
+* fix(doc): add missing doc for mock consumer by @hsweif in https://github.com/IBM/sarama/pull/2386
+* chore(proto): doc CreateTopics/JoinGroup fields by @dnwe in https://github.com/IBM/sarama/pull/2627
+### :heavy_plus_sign: Other Changes
+* chore(gh): add new style issue templates by @dnwe in https://github.com/IBM/sarama/pull/2624
+
+
+**Full Changelog**: https://github.com/IBM/sarama/compare/v1.41.0...v1.41.1
+
+## Version 1.41.0 (2023-08-21)
+
+## What's Changed
+### :rotating_light: Breaking Changes
+
+Note: this version of Sarama has had a big overhaul in its adherence to the use of the right Kafka protocol versions for the given Config Version. It has also bumped the default Version set in Config (where one is not supplied) to 2.1.0. This is in preparation for Kafka 4.0 dropping support for protocol versions older than 2.1. If you are using Sarama against Kafka clusters older than v2.1.0, or using it against Azure EventHubs then you will likely have to change your application code to pin to the appropriate Version.
+
+* chore(config): make DefaultVersion V2_0_0_0 by @dnwe in https://github.com/IBM/sarama/pull/2572
+* chore(config): make DefaultVersion V2_1_0_0 by @dnwe in https://github.com/IBM/sarama/pull/2574
+### :tada: New Features / Improvements
+* Implement resolve_canonical_bootstrap_servers_only by @gebn in https://github.com/IBM/sarama/pull/2156
+* feat: sleep when throttled (KIP-219) by @hindessm in https://github.com/IBM/sarama/pull/2536
+* feat: add isValidVersion to protocol types by @dnwe in https://github.com/IBM/sarama/pull/2538
+* fix(consumer): use newer LeaveGroup as appropriate by @dnwe in https://github.com/IBM/sarama/pull/2544
+* Add support for up to version 4 List Groups API by @prestona in https://github.com/IBM/sarama/pull/2541
+* fix(producer): use newer ProduceReq as appropriate by @dnwe in https://github.com/IBM/sarama/pull/2546
+* fix(proto): ensure req+resp requiredVersion match by @dnwe in https://github.com/IBM/sarama/pull/2548
+* chore(proto): permit CreatePartitionsRequest V1 by @dnwe in https://github.com/IBM/sarama/pull/2549
+* chore(proto): permit AlterConfigsRequest V1 by @dnwe in https://github.com/IBM/sarama/pull/2550
+* chore(proto): permit DeleteGroupsRequest V1 by @dnwe in https://github.com/IBM/sarama/pull/2551
+* fix(proto): correct JoinGroup usage for wider version range by @dnwe in https://github.com/IBM/sarama/pull/2553
+* fix(consumer): use full range of FetchRequest vers by @dnwe in https://github.com/IBM/sarama/pull/2554
+* fix(proto): use range of OffsetCommitRequest vers by @dnwe in https://github.com/IBM/sarama/pull/2555
+* fix(proto): use full range of MetadataRequest by @dnwe in https://github.com/IBM/sarama/pull/2556
+* fix(proto): use fuller ranges of supported proto by @dnwe in https://github.com/IBM/sarama/pull/2558
+* fix(proto): use full range of SyncGroupRequest by @dnwe in https://github.com/IBM/sarama/pull/2565
+* fix(proto): use full range of ListGroupsRequest by @dnwe in https://github.com/IBM/sarama/pull/2568
+* feat(proto): support for Metadata V6-V10 by @dnwe in https://github.com/IBM/sarama/pull/2566
+* fix(proto): use full ranges for remaining proto by @dnwe in https://github.com/IBM/sarama/pull/2570
+* feat(proto): add remaining protocol for V2.1 by @dnwe in https://github.com/IBM/sarama/pull/2573
+* feat: add new error for MockDeleteTopicsResponse by @javiercri in https://github.com/IBM/sarama/pull/2475
+* feat(gzip): switch to klauspost/compress gzip by @dnwe in https://github.com/IBM/sarama/pull/2600
+### :bug: Fixes
+* fix: correct unsupported version check by @hindessm in https://github.com/IBM/sarama/pull/2528
+* fix: avoiding burning cpu if all partitions are paused by @napallday in https://github.com/IBM/sarama/pull/2532
+* extend throttling metric scope by @hindessm in https://github.com/IBM/sarama/pull/2533
+* Fix printing of final metrics by @prestona in https://github.com/IBM/sarama/pull/2545
+* fix(consumer): cannot automatically fetch newly-added partitions unless restart by @napallday in https://github.com/IBM/sarama/pull/2563
+* bug: implement unsigned modulus for partitioning with crc32 hashing by @csm8118 in https://github.com/IBM/sarama/pull/2560
+* fix: avoid logging value of proxy.Dialer by @prestona in https://github.com/IBM/sarama/pull/2569
+* fix(test): add missing closes to admin client tests by @dnwe in https://github.com/IBM/sarama/pull/2594
+* fix(test): ensure some more clients are closed by @dnwe in https://github.com/IBM/sarama/pull/2595
+* fix(examples): sync exactly_once and consumergroup by @dnwe in https://github.com/IBM/sarama/pull/2614
+* fix(fvt): fresh metrics registry for each test by @dnwe in https://github.com/IBM/sarama/pull/2616
+* fix(test): flaky test TestFuncOffsetManager by @napallday in https://github.com/IBM/sarama/pull/2609
+### :package: Dependency updates
+* chore(deps): bump the golang-org-x group with 1 update by @dependabot in https://github.com/IBM/sarama/pull/2542
+* chore(deps): bump the golang-org-x group with 1 update by @dependabot in https://github.com/IBM/sarama/pull/2561
+* chore(deps): bump module github.com/pierrec/lz4/v4 to v4.1.18 by @dnwe in https://github.com/IBM/sarama/pull/2589
+* chore(deps): bump module github.com/jcmturner/gokrb5/v8 to v8.4.4 by @dnwe in https://github.com/IBM/sarama/pull/2587
+* chore(deps): bump github.com/eapache/go-xerial-snappy digest to c322873 by @dnwe in https://github.com/IBM/sarama/pull/2586
+* chore(deps): bump module github.com/klauspost/compress to v1.16.7 by @dnwe in https://github.com/IBM/sarama/pull/2588
+* chore(deps): bump github.com/eapache/go-resiliency from 1.3.0 to 1.4.0 by @dependabot in https://github.com/IBM/sarama/pull/2598
+### :wrench: Maintenance
+* fix(fvt): ensure fully-replicated at test start by @hindessm in https://github.com/IBM/sarama/pull/2531
+* chore: rollup fvt kafka to latest three by @dnwe in https://github.com/IBM/sarama/pull/2537
+* Merge the two CONTRIBUTING.md's by @prestona in https://github.com/IBM/sarama/pull/2543
+* fix(test): test timing error by @hindessm in https://github.com/IBM/sarama/pull/2552
+* chore(ci): tidyup and improve actions workflows by @dnwe in https://github.com/IBM/sarama/pull/2557
+* fix(test): shutdown MockBroker by @dnwe in https://github.com/IBM/sarama/pull/2571
+* chore(proto): match HeartbeatResponse version by @dnwe in https://github.com/IBM/sarama/pull/2576
+* chore(test): ensure MockBroker closed within test by @dnwe in https://github.com/IBM/sarama/pull/2575
+* chore(test): ensure all mockresponses use version by @dnwe in https://github.com/IBM/sarama/pull/2578
+* chore(ci): use latest Go in actions by @dnwe in https://github.com/IBM/sarama/pull/2580
+* chore(test): speedup some slow tests by @dnwe in https://github.com/IBM/sarama/pull/2579
+* chore(test): use modern protocol versions in FVT by @dnwe in https://github.com/IBM/sarama/pull/2581
+* chore(test): fix a couple of leaks by @dnwe in https://github.com/IBM/sarama/pull/2591
+* feat(fvt): experiment with per-kafka-version image by @dnwe in https://github.com/IBM/sarama/pull/2592
+* chore(ci): replace toxiproxy client dep by @dnwe in https://github.com/IBM/sarama/pull/2593
+* feat(fvt): add healthcheck, depends_on and --wait by @dnwe in https://github.com/IBM/sarama/pull/2601
+* fix(fvt): handle msgset vs batchset by @dnwe in https://github.com/IBM/sarama/pull/2603
+* fix(fvt): Metadata version in ensureFullyReplicated by @dnwe in https://github.com/IBM/sarama/pull/2612
+* fix(fvt): versioned cfg for invalid topic producer by @dnwe in https://github.com/IBM/sarama/pull/2613
+* chore(fvt): tweak to work across more versions by @dnwe in https://github.com/IBM/sarama/pull/2615
+* feat(fvt): test wider range of kafkas by @dnwe in https://github.com/IBM/sarama/pull/2605
+### :memo: Documentation
+* fix(example): check if msg channel is closed by @ioanzicu in https://github.com/IBM/sarama/pull/2479
+* chore: use go install for installing sarama tools by @vigith in https://github.com/IBM/sarama/pull/2599
+
+## New Contributors
+* @gebn made their first contribution in https://github.com/IBM/sarama/pull/2156
+* @prestona made their first contribution in https://github.com/IBM/sarama/pull/2543
+* @ioanzicu made their first contribution in https://github.com/IBM/sarama/pull/2479
+* @csm8118 made their first contribution in https://github.com/IBM/sarama/pull/2560
+* @javiercri made their first contribution in https://github.com/IBM/sarama/pull/2475
+* @vigith made their first contribution in https://github.com/IBM/sarama/pull/2599
+
+**Full Changelog**: https://github.com/IBM/sarama/compare/v1.40.1...v1.41.0
+
+## Version 1.40.1 (2023-07-27)
+
+## What's Changed
+### :tada: New Features / Improvements
+* Use buffer pools for decompression by @ronanh in https://github.com/IBM/sarama/pull/2484
+* feat: support for Kerberos authentication with a credentials cache. by @mrogaski in https://github.com/IBM/sarama/pull/2457
+### :bug: Fixes
+* Fix some retry issues by @hindessm in https://github.com/IBM/sarama/pull/2517
+* fix: admin retry logic by @hindessm in https://github.com/IBM/sarama/pull/2519
+* Add some retry logic to more admin client functions by @hindessm in https://github.com/IBM/sarama/pull/2520
+* fix: concurrent issue on updateMetadataMs by @napallday in https://github.com/IBM/sarama/pull/2522
+* fix(test): allow testing of skipped test without IsTransactional panic by @hindessm in https://github.com/IBM/sarama/pull/2525
+### :package: Dependency updates
+* chore(deps): bump the golang-org-x group with 2 updates by @dependabot in https://github.com/IBM/sarama/pull/2509
+* chore(deps): bump github.com/klauspost/compress from 1.15.14 to 1.16.6 by @dependabot in https://github.com/IBM/sarama/pull/2513
+* chore(deps): bump github.com/stretchr/testify from 1.8.1 to 1.8.3 by @dependabot in https://github.com/IBM/sarama/pull/2512
+### :wrench: Maintenance
+* chore(ci): migrate probot-stale to actions/stale by @dnwe in https://github.com/IBM/sarama/pull/2496
+* chore(ci): bump golangci version, cleanup, depguard config by @EladLeev in https://github.com/IBM/sarama/pull/2504
+* Clean up some typos and docs/help mistakes by @hindessm in https://github.com/IBM/sarama/pull/2514
+### :heavy_plus_sign: Other Changes
+* chore(ci): add simple apidiff workflow by @dnwe in https://github.com/IBM/sarama/pull/2497
+* chore(ci): bump actions/setup-go from 3 to 4 by @dependabot in https://github.com/IBM/sarama/pull/2508
+* fix(comments): PauseAll and ResumeAll by @napallday in https://github.com/IBM/sarama/pull/2523
+
+## New Contributors
+* @EladLeev made their first contribution in https://github.com/IBM/sarama/pull/2504
+* @hindessm made their first contribution in https://github.com/IBM/sarama/pull/2514
+* @ronanh made their first contribution in https://github.com/IBM/sarama/pull/2484
+* @mrogaski made their first contribution in https://github.com/IBM/sarama/pull/2457
+
+**Full Changelog**: https://github.com/IBM/sarama/compare/v1.40.0...v1.40.1
+
+## Version 1.40.0 (2023-07-17)
+
+## What's Changed
+
+Note: this is the first release after the transition of Sarama ownership from Shopify to IBM in https://github.com/IBM/sarama/issues/2461
+
+### :rotating_light: Breaking Changes
+
+- chore: migrate module to github.com/IBM/sarama by @dnwe in https://github.com/IBM/sarama/pull/2492
+- fix: restore (\*OffsetCommitRequest) AddBlock func by @dnwe in https://github.com/IBM/sarama/pull/2494
+
+### :bug: Fixes
+
+- fix(consumer): don't retry FindCoordinator forever by @dnwe in https://github.com/IBM/sarama/pull/2427
+- fix(metrics): fix race condition when calling Broker.Open() twice by @vincentbernat in https://github.com/IBM/sarama/pull/2428
+- fix: use version 4 of DescribeGroupsRequest only if kafka broker vers… …ion is >= 2.4 by @faillefer in https://github.com/IBM/sarama/pull/2451
+- Fix HighWaterMarkOffset of mocks partition consumer by @gr8web in https://github.com/IBM/sarama/pull/2447
+- fix: prevent data race in balance strategy by @napallday in https://github.com/IBM/sarama/pull/2453
+
+### :package: Dependency updates
+
+- chore(deps): bump golang.org/x/net from 0.5.0 to 0.7.0 by @dependabot in https://github.com/IBM/sarama/pull/2452
+
+### :wrench: Maintenance
+
+- chore: add kafka 3.3.2 by @dnwe in https://github.com/IBM/sarama/pull/2434
+- chore(ci): remove Shopify/shopify-cla-action by @dnwe in https://github.com/IBM/sarama/pull/2489
+- chore: bytes.Equal instead bytes.Compare by @testwill in https://github.com/IBM/sarama/pull/2485
+
+## New Contributors
+
+- @dependabot made their first contribution in https://github.com/IBM/sarama/pull/2452
+- @gr8web made their first contribution in https://github.com/IBM/sarama/pull/2447
+- @testwill made their first contribution in https://github.com/IBM/sarama/pull/2485
+
+**Full Changelog**: https://github.com/IBM/sarama/compare/v1.38.1...v1.40.0
+
 ## Version 1.38.1 (2023-01-22)
 
 ## What's Changed

+ 128 - 0
vendor/github.com/IBM/sarama/CODE_OF_CONDUCT.md

@@ -0,0 +1,128 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+We as members, contributors, and leaders pledge to make participation in our
+community a harassment-free experience for everyone, regardless of age, body
+size, visible or invisible disability, ethnicity, sex characteristics, gender
+identity and expression, level of experience, education, socio-economic status,
+nationality, personal appearance, race, religion, or sexual identity
+and orientation.
+
+We pledge to act and interact in ways that contribute to an open, welcoming,
+diverse, inclusive, and healthy community.
+
+## Our Standards
+
+Examples of behavior that contributes to a positive environment for our
+community include:
+
+* Demonstrating empathy and kindness toward other people
+* Being respectful of differing opinions, viewpoints, and experiences
+* Giving and gracefully accepting constructive feedback
+* Accepting responsibility and apologizing to those affected by our mistakes,
+  and learning from the experience
+* Focusing on what is best not just for us as individuals, but for the
+  overall community
+
+Examples of unacceptable behavior include:
+
+* The use of sexualized language or imagery, and sexual attention or
+  advances of any kind
+* Trolling, insulting or derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or email
+  address, without their explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+  professional setting
+
+## Enforcement Responsibilities
+
+Community leaders are responsible for clarifying and enforcing our standards of
+acceptable behavior and will take appropriate and fair corrective action in
+response to any behavior that they deem inappropriate, threatening, offensive,
+or harmful.
+
+Community leaders have the right and responsibility to remove, edit, or reject
+comments, commits, code, wiki edits, issues, and other contributions that are
+not aligned to this Code of Conduct, and will communicate reasons for moderation
+decisions when appropriate.
+
+## Scope
+
+This Code of Conduct applies within all community spaces, and also applies when
+an individual is officially representing the community in public spaces.
+Examples of representing our community include using an official e-mail address,
+posting via an official social media account, or acting as an appointed
+representative at an online or offline event.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported to the community leaders responsible for enforcement at
+dominic.evans@uk.ibm.com.
+All complaints will be reviewed and investigated promptly and fairly.
+
+All community leaders are obligated to respect the privacy and security of the
+reporter of any incident.
+
+## Enforcement Guidelines
+
+Community leaders will follow these Community Impact Guidelines in determining
+the consequences for any action they deem in violation of this Code of Conduct:
+
+### 1. Correction
+
+**Community Impact**: Use of inappropriate language or other behavior deemed
+unprofessional or unwelcome in the community.
+
+**Consequence**: A private, written warning from community leaders, providing
+clarity around the nature of the violation and an explanation of why the
+behavior was inappropriate. A public apology may be requested.
+
+### 2. Warning
+
+**Community Impact**: A violation through a single incident or series
+of actions.
+
+**Consequence**: A warning with consequences for continued behavior. No
+interaction with the people involved, including unsolicited interaction with
+those enforcing the Code of Conduct, for a specified period of time. This
+includes avoiding interactions in community spaces as well as external channels
+like social media. Violating these terms may lead to a temporary or
+permanent ban.
+
+### 3. Temporary Ban
+
+**Community Impact**: A serious violation of community standards, including
+sustained inappropriate behavior.
+
+**Consequence**: A temporary ban from any sort of interaction or public
+communication with the community for a specified period of time. No public or
+private interaction with the people involved, including unsolicited interaction
+with those enforcing the Code of Conduct, is allowed during this period.
+Violating these terms may lead to a permanent ban.
+
+### 4. Permanent Ban
+
+**Community Impact**: Demonstrating a pattern of violation of community
+standards, including sustained inappropriate behavior,  harassment of an
+individual, or aggression toward or disparagement of classes of individuals.
+
+**Consequence**: A permanent ban from any sort of public interaction within
+the community.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage],
+version 2.0, available at
+https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
+
+Community Impact Guidelines were inspired by [Mozilla's code of conduct
+enforcement ladder](https://github.com/mozilla/diversity).
+
+[homepage]: https://www.contributor-covenant.org
+
+For answers to common questions about this code of conduct, see the FAQ at
+https://www.contributor-covenant.org/faq. Translations are available at
+https://www.contributor-covenant.org/translations.

+ 34 - 3
vendor/github.com/IBM/sarama/CONTRIBUTING.md

@@ -1,11 +1,28 @@
-## Contributing
+# Contributing
 
 [fork]: https://github.com/IBM/sarama/fork
 [pr]: https://github.com/IBM/sarama/compare
 [released]: https://help.github.com/articles/github-terms-of-service/#6-contributions-under-repository-license
 
 Hi there! We are thrilled that you would like to contribute to Sarama.
-Your help is essential for keeping it great.
+Contributions are always welcome, both reporting issues and submitting pull requests!
+
+## Reporting issues
+
+Please make sure to include any potentially useful information in the issue, so we can pinpoint the issue faster without going back and forth.
+
+- What SHA of Sarama are you running? If this is not the latest SHA on the main branch, please try if the problem persists with the latest version.
+- You can set `sarama.Logger` to a [log.Logger](http://golang.org/pkg/log/#Logger) instance to capture debug output. Please include it in your issue description.
+- Also look at the logs of the Kafka broker you are connected to. If you see anything out of the ordinary, please include it.
+
+Also, please include the following information about your environment, so we can help you faster:
+
+- What version of Kafka are you using?
+- What version of Go are you using?
+- What are the values of your Producer/Consumer/Client configuration?
+
+
+## Contributing a change
 
 Contributions to this project are [released][released] to the public under the project's [opensource license](LICENSE.md).
 By contributing to this project you agree to the [Developer Certificate of Origin](https://developercertificate.org/) (DCO).
@@ -19,12 +36,26 @@ feat: this is my commit message
 Signed-off-by: Random J Developer <random@developer.example.org>
 ```
 
-Git even has a `-s` command line option to append this automatically to your commit message:
+Git even has a `-s` command line option to append this automatically to your
+commit message:
 
 ```
 $ git commit -s -m 'This is my commit message'
 ```
 
+Because this library is in production use by many people and applications, we code review all additions.
+To make the review process go as smooth as possible, please consider the following.
+
+- If you plan to work on something major, please open an issue to discuss the design first.
+- Don't break backwards compatibility. If you really have to, open an issue to discuss this first.
+- Make sure to use the `go fmt` command to format your code according to the standards. Even better, set up your editor to do this for you when saving.
+- Run [go vet](https://golang.org/cmd/vet/) to detect any suspicious constructs in your code that could be bugs.
+- Explicitly handle all error return values. If you really want to ignore an error value, you can assign it to `_`. You can use [errcheck](https://github.com/kisielk/errcheck) to verify whether you have handled all errors.
+- You may also want to run [golint](https://github.com/golang/lint) as well to detect style problems.
+- Add tests that cover the changes you made. Make sure to run `go test` with the `-race` argument to test for race conditions.
+- Make sure your code is supported by all the Go versions we support.
+  You can rely on GitHub Actions for testing older Go versions.
+
 ## Submitting a pull request
 
 0. [Fork][fork] and clone the repository

+ 32 - 12
vendor/github.com/IBM/sarama/Dockerfile.kafka

@@ -1,27 +1,47 @@
-FROM registry.access.redhat.com/ubi8/ubi-minimal:latest
+FROM registry.access.redhat.com/ubi8/ubi-minimal:8.9@sha256:f30dbf77b075215f6c827c269c073b5e0973e5cea8dacdf7ecb6a19c868f37f2
 
 USER root
 
-RUN microdnf update \
-    && microdnf install curl gzip java-11-openjdk-headless tar \
-    && microdnf clean all
+RUN microdnf update -y \
+ && microdnf install -y curl gzip java-11-openjdk-headless tar tzdata-java \
+ && microdnf reinstall -y tzdata \
+ && microdnf clean all
 
 ENV JAVA_HOME=/usr/lib/jvm/jre-11
 
 # https://docs.oracle.com/javase/7/docs/technotes/guides/net/properties.html
 # Ensure Java doesn't cache any dns results
 RUN cd /etc/java/java-11-openjdk/*/conf/security \
-  && sed -e '/networkaddress.cache.ttl/d' -e '/networkaddress.cache.negative.ttl/d' -i java.security \
-  && echo 'networkaddress.cache.ttl=0' >> java.security \
-  && echo 'networkaddress.cache.negative.ttl=0' >> java.security
+ && sed -e '/networkaddress.cache.ttl/d' -e '/networkaddress.cache.negative.ttl/d' -i java.security \
+ && echo 'networkaddress.cache.ttl=0' >> java.security \
+ && echo 'networkaddress.cache.negative.ttl=0' >> java.security
 
-# https://github.com/apache/kafka/blob/53eeaad946cd053e9eb1a762972d4efeacb8e4fc/tests/docker/Dockerfile#L65-L69
+ARG SCALA_VERSION="2.13"
+ARG KAFKA_VERSION="3.6.0"
+
+# https://github.com/apache/kafka/blob/9989b68d0d38c8f1357f78bf9d53a58c1476188d/tests/docker/Dockerfile#L46-L72
 ARG KAFKA_MIRROR="https://s3-us-west-2.amazonaws.com/kafka-packages"
-RUN mkdir -p "/opt/kafka-2.8.2" && chmod a+rw /opt/kafka-2.8.2 && curl -s "$KAFKA_MIRROR/kafka_2.12-2.8.2.tgz" | tar xz --strip-components=1 -C "/opt/kafka-2.8.2"
-RUN mkdir -p "/opt/kafka-3.1.2" && chmod a+rw /opt/kafka-3.1.2 && curl -s "$KAFKA_MIRROR/kafka_2.12-3.1.2.tgz" | tar xz --strip-components=1 -C "/opt/kafka-3.1.2"
-RUN mkdir -p "/opt/kafka-3.2.3" && chmod a+rw /opt/kafka-3.2.3 && curl -s "$KAFKA_MIRROR/kafka_2.12-3.2.3.tgz" | tar xz --strip-components=1 -C "/opt/kafka-3.2.3"
-RUN mkdir -p "/opt/kafka-3.3.2" && chmod a+rw /opt/kafka-3.3.2 && curl -s "$KAFKA_MIRROR/kafka_2.12-3.3.2.tgz" | tar xz --strip-components=1 -C "/opt/kafka-3.3.2"
+SHELL ["/bin/bash", "-o", "pipefail", "-c"]
+RUN mkdir -p "/opt/kafka-${KAFKA_VERSION}" \
+ && chmod a+rw "/opt/kafka-${KAFKA_VERSION}" \
+ && curl -s "$KAFKA_MIRROR/kafka_${SCALA_VERSION}-${KAFKA_VERSION}.tgz" | tar xz --strip-components=1 -C "/opt/kafka-${KAFKA_VERSION}"
+
+# older kafka versions depend upon jaxb-api being bundled with the JDK, but it
+# was removed from Java 11 so work around that by including it in the kafka
+# libs dir regardless
+WORKDIR /tmp
+RUN curl -sLO "https://repo1.maven.org/maven2/javax/xml/bind/jaxb-api/2.3.0/jaxb-api-2.3.0.jar" \
+ && for DIR in /opt/kafka-*; do cp -v jaxb-api-2.3.0.jar $DIR/libs/ ; done \
+ && rm -f jaxb-api-2.3.0.jar
+
+WORKDIR /opt/kafka-${KAFKA_VERSION}
+
+ENV JAVA_MAJOR_VERSION=11
+
+RUN sed -e "s/JAVA_MAJOR_VERSION=.*/JAVA_MAJOR_VERSION=${JAVA_MAJOR_VERSION}/" -i"" ./bin/kafka-run-class.sh
 
 COPY entrypoint.sh /
 
+USER 65534:65534
+
 ENTRYPOINT ["/entrypoint.sh"]

+ 1 - 0
vendor/github.com/IBM/sarama/LICENSE.md

@@ -1,6 +1,7 @@
 # MIT License
 
 Copyright (c) 2013 Shopify
+
 Copyright (c) 2023 IBM Corporation
 
 Permission is hereby granted, free of charge, to any person obtaining

+ 6 - 3
vendor/github.com/IBM/sarama/README.md

@@ -1,6 +1,8 @@
 # sarama
 
 [![Go Reference](https://pkg.go.dev/badge/github.com/IBM/sarama.svg)](https://pkg.go.dev/github.com/IBM/sarama)
+[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/IBM/sarama/badge?style=flat)](https://securityscorecards.dev/viewer/?uri=github.com/IBM/sarama)
+[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/7996/badge)](https://www.bestpractices.dev/projects/7996)
 
 Sarama is an MIT-licensed Go client library for [Apache Kafka](https://kafka.apache.org/).
 
@@ -19,13 +21,14 @@ Sarama provides a "2 releases + 2 months" compatibility guarantee: we support
 the two latest stable releases of Kafka and Go, and we provide a two month
 grace period for older releases. However, older releases of Kafka are still likely to work.
 
-Sarama follows semantic versioning and provides API stability via the gopkg.in service.
-You can import a version with a guaranteed stable API via http://gopkg.in/IBM/sarama.v1.
+Sarama follows semantic versioning and provides API stability via the standard Go
+[module version numbering](https://go.dev/doc/modules/version-numbers) scheme.
+
 A changelog is available [here](CHANGELOG.md).
 
 ## Contributing
 
-- Get started by checking our [contribution guidelines](https://github.com/IBM/sarama/blob/main/.github/CONTRIBUTING.md).
+- Get started by checking our [contribution guidelines](https://github.com/IBM/sarama/blob/main/CONTRIBUTING.md).
 - Read the [Sarama wiki](https://github.com/IBM/sarama/wiki) for more technical and design details.
 - The [Kafka Protocol Specification](https://cwiki.apache.org/confluence/display/KAFKA/A+Guide+To+The+Kafka+Protocol) contains a wealth of useful information.
 - For more general issues, there is [a google group](https://groups.google.com/forum/#!forum/kafka-clients) for Kafka client developers.

+ 11 - 0
vendor/github.com/IBM/sarama/SECURITY.md

@@ -0,0 +1,11 @@
+# Security
+
+## Reporting Security Issues
+
+**Please do not report security vulnerabilities through public GitHub issues.**
+
+The easiest way to report a security issue is privately through GitHub [here](https://github.com/IBM/sarama/security/advisories/new).
+
+See [Privately reporting a security vulnerability](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing/privately-reporting-a-security-vulnerability) for full instructions.
+
+Alternatively, you can report them via e-mail or anonymous form to the IBM Product Security Incident Response Team (PSIRT) following the guidelines under the [IBM Security Vulnerability Management](https://www.ibm.com/support/pages/ibm-security-vulnerability-management) pages.

+ 4 - 0
vendor/github.com/IBM/sarama/acl_create_request.go

@@ -51,6 +51,10 @@ func (c *CreateAclsRequest) headerVersion() int16 {
 	return 1
 }
 
+func (c *CreateAclsRequest) isValidVersion() bool {
+	return c.Version >= 0 && c.Version <= 1
+}
+
 func (c *CreateAclsRequest) requiredVersion() KafkaVersion {
 	switch c.Version {
 	case 1:

+ 16 - 2
vendor/github.com/IBM/sarama/acl_create_response.go

@@ -4,6 +4,7 @@ import "time"
 
 // CreateAclsResponse is a an acl response creation type
 type CreateAclsResponse struct {
+	Version              int16
 	ThrottleTime         time.Duration
 	AclCreationResponses []*AclCreationResponse
 }
@@ -52,15 +53,28 @@ func (c *CreateAclsResponse) key() int16 {
 }
 
 func (c *CreateAclsResponse) version() int16 {
-	return 0
+	return c.Version
 }
 
 func (c *CreateAclsResponse) headerVersion() int16 {
 	return 0
 }
 
+func (c *CreateAclsResponse) isValidVersion() bool {
+	return c.Version >= 0 && c.Version <= 1
+}
+
 func (c *CreateAclsResponse) requiredVersion() KafkaVersion {
-	return V0_11_0_0
+	switch c.Version {
+	case 1:
+		return V2_0_0_0
+	default:
+		return V0_11_0_0
+	}
+}
+
+func (r *CreateAclsResponse) throttleTime() time.Duration {
+	return r.ThrottleTime
 }
 
 // AclCreationResponse is an acl creation response type

+ 4 - 0
vendor/github.com/IBM/sarama/acl_delete_request.go

@@ -52,6 +52,10 @@ func (d *DeleteAclsRequest) headerVersion() int16 {
 	return 1
 }
 
+func (d *DeleteAclsRequest) isValidVersion() bool {
+	return d.Version >= 0 && d.Version <= 1
+}
+
 func (d *DeleteAclsRequest) requiredVersion() KafkaVersion {
 	switch d.Version {
 	case 1:

+ 14 - 1
vendor/github.com/IBM/sarama/acl_delete_response.go

@@ -60,8 +60,21 @@ func (d *DeleteAclsResponse) headerVersion() int16 {
 	return 0
 }
 
+func (d *DeleteAclsResponse) isValidVersion() bool {
+	return d.Version >= 0 && d.Version <= 1
+}
+
 func (d *DeleteAclsResponse) requiredVersion() KafkaVersion {
-	return V0_11_0_0
+	switch d.Version {
+	case 1:
+		return V2_0_0_0
+	default:
+		return V0_11_0_0
+	}
+}
+
+func (r *DeleteAclsResponse) throttleTime() time.Duration {
+	return r.ThrottleTime
 }
 
 // FilterResponse is a filter response type

+ 5 - 1
vendor/github.com/IBM/sarama/acl_describe_request.go

@@ -1,6 +1,6 @@
 package sarama
 
-// DescribeAclsRequest is a secribe acl request type
+// DescribeAclsRequest is a describe acl request type
 type DescribeAclsRequest struct {
 	Version int
 	AclFilter
@@ -29,6 +29,10 @@ func (d *DescribeAclsRequest) headerVersion() int16 {
 	return 1
 }
 
+func (d *DescribeAclsRequest) isValidVersion() bool {
+	return d.Version >= 0 && d.Version <= 1
+}
+
 func (d *DescribeAclsRequest) requiredVersion() KafkaVersion {
 	switch d.Version {
 	case 1:

+ 8 - 0
vendor/github.com/IBM/sarama/acl_describe_response.go

@@ -81,6 +81,10 @@ func (d *DescribeAclsResponse) headerVersion() int16 {
 	return 0
 }
 
+func (d *DescribeAclsResponse) isValidVersion() bool {
+	return d.Version >= 0 && d.Version <= 1
+}
+
 func (d *DescribeAclsResponse) requiredVersion() KafkaVersion {
 	switch d.Version {
 	case 1:
@@ -89,3 +93,7 @@ func (d *DescribeAclsResponse) requiredVersion() KafkaVersion {
 		return V0_11_0_0
 	}
 }
+
+func (r *DescribeAclsResponse) throttleTime() time.Duration {
+	return r.ThrottleTime
+}

+ 4 - 4
vendor/github.com/IBM/sarama/acl_types.go

@@ -60,7 +60,7 @@ func (a *AclOperation) MarshalText() ([]byte, error) {
 	return []byte(a.String()), nil
 }
 
-// UnmarshalText takes a text reprentation of the operation and converts it to an AclOperation
+// UnmarshalText takes a text representation of the operation and converts it to an AclOperation
 func (a *AclOperation) UnmarshalText(text []byte) error {
 	normalized := strings.ToLower(string(text))
 	mapping := map[string]AclOperation{
@@ -114,7 +114,7 @@ func (a *AclPermissionType) MarshalText() ([]byte, error) {
 	return []byte(a.String()), nil
 }
 
-// UnmarshalText takes a text reprentation of the permission type and converts it to an AclPermissionType
+// UnmarshalText takes a text representation of the permission type and converts it to an AclPermissionType
 func (a *AclPermissionType) UnmarshalText(text []byte) error {
 	normalized := strings.ToLower(string(text))
 	mapping := map[string]AclPermissionType{
@@ -166,7 +166,7 @@ func (a *AclResourceType) MarshalText() ([]byte, error) {
 	return []byte(a.String()), nil
 }
 
-// UnmarshalText takes a text reprentation of the resource type and converts it to an AclResourceType
+// UnmarshalText takes a text representation of the resource type and converts it to an AclResourceType
 func (a *AclResourceType) UnmarshalText(text []byte) error {
 	normalized := strings.ToLower(string(text))
 	mapping := map[string]AclResourceType{
@@ -217,7 +217,7 @@ func (a *AclResourcePatternType) MarshalText() ([]byte, error) {
 	return []byte(a.String()), nil
 }
 
-// UnmarshalText takes a text reprentation of the resource pattern type and converts it to an AclResourcePatternType
+// UnmarshalText takes a text representation of the resource pattern type and converts it to an AclResourcePatternType
 func (a *AclResourcePatternType) UnmarshalText(text []byte) error {
 	normalized := strings.ToLower(string(text))
 	mapping := map[string]AclResourcePatternType{

+ 16 - 2
vendor/github.com/IBM/sarama/add_offsets_to_txn_request.go

@@ -2,6 +2,7 @@ package sarama
 
 // AddOffsetsToTxnRequest adds offsets to a transaction request
 type AddOffsetsToTxnRequest struct {
+	Version         int16
 	TransactionalID string
 	ProducerID      int64
 	ProducerEpoch   int16
@@ -45,13 +46,26 @@ func (a *AddOffsetsToTxnRequest) key() int16 {
 }
 
 func (a *AddOffsetsToTxnRequest) version() int16 {
-	return 0
+	return a.Version
 }
 
 func (a *AddOffsetsToTxnRequest) headerVersion() int16 {
 	return 1
 }
 
+func (a *AddOffsetsToTxnRequest) isValidVersion() bool {
+	return a.Version >= 0 && a.Version <= 2
+}
+
 func (a *AddOffsetsToTxnRequest) requiredVersion() KafkaVersion {
-	return V0_11_0_0
+	switch a.Version {
+	case 2:
+		return V2_7_0_0
+	case 1:
+		return V2_0_0_0
+	case 0:
+		return V0_11_0_0
+	default:
+		return V2_7_0_0
+	}
 }

+ 20 - 2
vendor/github.com/IBM/sarama/add_offsets_to_txn_response.go

@@ -6,6 +6,7 @@ import (
 
 // AddOffsetsToTxnResponse is a response type for adding offsets to txns
 type AddOffsetsToTxnResponse struct {
+	Version      int16
 	ThrottleTime time.Duration
 	Err          KError
 }
@@ -37,13 +38,30 @@ func (a *AddOffsetsToTxnResponse) key() int16 {
 }
 
 func (a *AddOffsetsToTxnResponse) version() int16 {
-	return 0
+	return a.Version
 }
 
 func (a *AddOffsetsToTxnResponse) headerVersion() int16 {
 	return 0
 }
 
+func (a *AddOffsetsToTxnResponse) isValidVersion() bool {
+	return a.Version >= 0 && a.Version <= 2
+}
+
 func (a *AddOffsetsToTxnResponse) requiredVersion() KafkaVersion {
-	return V0_11_0_0
+	switch a.Version {
+	case 2:
+		return V2_7_0_0
+	case 1:
+		return V2_0_0_0
+	case 0:
+		return V0_11_0_0
+	default:
+		return V2_7_0_0
+	}
+}
+
+func (r *AddOffsetsToTxnResponse) throttleTime() time.Duration {
+	return r.ThrottleTime
 }

+ 15 - 3
vendor/github.com/IBM/sarama/add_partitions_to_txn_request.go

@@ -1,7 +1,8 @@
 package sarama
 
-// AddPartitionsToTxnRequest is a add paartition request
+// AddPartitionsToTxnRequest is a add partition request
 type AddPartitionsToTxnRequest struct {
+	Version         int16
 	TransactionalID string
 	ProducerID      int64
 	ProducerEpoch   int16
@@ -69,13 +70,24 @@ func (a *AddPartitionsToTxnRequest) key() int16 {
 }
 
 func (a *AddPartitionsToTxnRequest) version() int16 {
-	return 0
+	return a.Version
 }
 
 func (a *AddPartitionsToTxnRequest) headerVersion() int16 {
 	return 1
 }
 
+func (a *AddPartitionsToTxnRequest) isValidVersion() bool {
+	return a.Version >= 0 && a.Version <= 2
+}
+
 func (a *AddPartitionsToTxnRequest) requiredVersion() KafkaVersion {
-	return V0_11_0_0
+	switch a.Version {
+	case 2:
+		return V2_7_0_0
+	case 1:
+		return V2_0_0_0
+	default:
+		return V0_11_0_0
+	}
 }

+ 19 - 2
vendor/github.com/IBM/sarama/add_partitions_to_txn_response.go

@@ -6,6 +6,7 @@ import (
 
 // AddPartitionsToTxnResponse is a partition errors to transaction type
 type AddPartitionsToTxnResponse struct {
+	Version      int16
 	ThrottleTime time.Duration
 	Errors       map[string][]*PartitionError
 }
@@ -34,6 +35,7 @@ func (a *AddPartitionsToTxnResponse) encode(pe packetEncoder) error {
 }
 
 func (a *AddPartitionsToTxnResponse) decode(pd packetDecoder, version int16) (err error) {
+	a.Version = version
 	throttleTime, err := pd.getInt32()
 	if err != nil {
 		return err
@@ -76,15 +78,30 @@ func (a *AddPartitionsToTxnResponse) key() int16 {
 }
 
 func (a *AddPartitionsToTxnResponse) version() int16 {
-	return 0
+	return a.Version
 }
 
 func (a *AddPartitionsToTxnResponse) headerVersion() int16 {
 	return 0
 }
 
+func (a *AddPartitionsToTxnResponse) isValidVersion() bool {
+	return a.Version >= 0 && a.Version <= 2
+}
+
 func (a *AddPartitionsToTxnResponse) requiredVersion() KafkaVersion {
-	return V0_11_0_0
+	switch a.Version {
+	case 2:
+		return V2_7_0_0
+	case 1:
+		return V2_0_0_0
+	default:
+		return V0_11_0_0
+	}
+}
+
+func (r *AddPartitionsToTxnResponse) throttleTime() time.Duration {
+	return r.ThrottleTime
 }
 
 // PartitionError is a partition error type

+ 125 - 62
vendor/github.com/IBM/sarama/admin.go

@@ -196,9 +196,9 @@ func (ca *clusterAdmin) refreshController() (*Broker, error) {
 	return ca.client.RefreshController()
 }
 
-// isErrNoController returns `true` if the given error type unwraps to an
+// isErrNotController returns `true` if the given error type unwraps to an
 // `ErrNotController` response from Kafka
-func isErrNoController(err error) bool {
+func isErrNotController(err error) bool {
 	return errors.Is(err, ErrNotController)
 }
 
@@ -207,19 +207,17 @@ func isErrNoController(err error) bool {
 // provided retryable func) up to the maximum number of tries permitted by
 // the admin client configuration
 func (ca *clusterAdmin) retryOnError(retryable func(error) bool, fn func() error) error {
-	var err error
-	for attempt := 0; attempt < ca.conf.Admin.Retry.Max; attempt++ {
-		err = fn()
-		if err == nil || !retryable(err) {
+	for attemptsRemaining := ca.conf.Admin.Retry.Max + 1; ; {
+		err := fn()
+		attemptsRemaining--
+		if err == nil || attemptsRemaining <= 0 || !retryable(err) {
 			return err
 		}
 		Logger.Printf(
 			"admin/request retrying after %dms... (%d attempts remaining)\n",
-			ca.conf.Admin.Retry.Backoff/time.Millisecond, ca.conf.Admin.Retry.Max-attempt)
+			ca.conf.Admin.Retry.Backoff/time.Millisecond, attemptsRemaining)
 		time.Sleep(ca.conf.Admin.Retry.Backoff)
-		continue
 	}
-	return err
 }
 
 func (ca *clusterAdmin) CreateTopic(topic string, detail *TopicDetail, validateOnly bool) error {
@@ -240,14 +238,18 @@ func (ca *clusterAdmin) CreateTopic(topic string, detail *TopicDetail, validateO
 		Timeout:      ca.conf.Admin.Timeout,
 	}
 
-	if ca.conf.Version.IsAtLeast(V0_11_0_0) {
-		request.Version = 1
-	}
-	if ca.conf.Version.IsAtLeast(V1_0_0_0) {
+	if ca.conf.Version.IsAtLeast(V2_0_0_0) {
+		// Version 3 is the same as version 2 (brokers response before throttling)
+		request.Version = 3
+	} else if ca.conf.Version.IsAtLeast(V0_11_0_0) {
+		// Version 2 is the same as version 1 (response has ThrottleTime)
 		request.Version = 2
+	} else if ca.conf.Version.IsAtLeast(V0_10_2_0) {
+		// Version 1 adds validateOnly.
+		request.Version = 1
 	}
 
-	return ca.retryOnError(isErrNoController, func() error {
+	return ca.retryOnError(isErrNotController, func() error {
 		b, err := ca.Controller()
 		if err != nil {
 			return err
@@ -275,13 +277,19 @@ func (ca *clusterAdmin) CreateTopic(topic string, detail *TopicDetail, validateO
 }
 
 func (ca *clusterAdmin) DescribeTopics(topics []string) (metadata []*TopicMetadata, err error) {
-	controller, err := ca.Controller()
-	if err != nil {
-		return nil, err
-	}
-
-	request := NewMetadataRequest(ca.conf.Version, topics)
-	response, err := controller.GetMetadata(request)
+	var response *MetadataResponse
+	err = ca.retryOnError(isErrNotController, func() error {
+		controller, err := ca.Controller()
+		if err != nil {
+			return err
+		}
+		request := NewMetadataRequest(ca.conf.Version, topics)
+		response, err = controller.GetMetadata(request)
+		if isErrNotController(err) {
+			_, _ = ca.refreshController()
+		}
+		return err
+	})
 	if err != nil {
 		return nil, err
 	}
@@ -289,13 +297,20 @@ func (ca *clusterAdmin) DescribeTopics(topics []string) (metadata []*TopicMetada
 }
 
 func (ca *clusterAdmin) DescribeCluster() (brokers []*Broker, controllerID int32, err error) {
-	controller, err := ca.Controller()
-	if err != nil {
-		return nil, int32(0), err
-	}
+	var response *MetadataResponse
+	err = ca.retryOnError(isErrNotController, func() error {
+		controller, err := ca.Controller()
+		if err != nil {
+			return err
+		}
 
-	request := NewMetadataRequest(ca.conf.Version, nil)
-	response, err := controller.GetMetadata(request)
+		request := NewMetadataRequest(ca.conf.Version, nil)
+		response, err = controller.GetMetadata(request)
+		if isErrNotController(err) {
+			_, _ = ca.refreshController()
+		}
+		return err
+	})
 	if err != nil {
 		return nil, int32(0), err
 	}
@@ -389,6 +404,7 @@ func (ca *clusterAdmin) ListTopics() (map[string]TopicDetail, error) {
 		topicDetails.ConfigEntries = make(map[string]*string)
 
 		for _, entry := range resource.Configs {
+			entry := entry
 			// only include non-default non-sensitive config
 			// (don't actually think topic config will ever be sensitive)
 			if entry.Default || entry.Sensitive {
@@ -413,11 +429,16 @@ func (ca *clusterAdmin) DeleteTopic(topic string) error {
 		Timeout: ca.conf.Admin.Timeout,
 	}
 
-	if ca.conf.Version.IsAtLeast(V0_11_0_0) {
+	// Versions 0, 1, 2, and 3 are the same.
+	if ca.conf.Version.IsAtLeast(V2_1_0_0) {
+		request.Version = 3
+	} else if ca.conf.Version.IsAtLeast(V2_0_0_0) {
+		request.Version = 2
+	} else if ca.conf.Version.IsAtLeast(V0_11_0_0) {
 		request.Version = 1
 	}
 
-	return ca.retryOnError(isErrNoController, func() error {
+	return ca.retryOnError(isErrNotController, func() error {
 		b, err := ca.Controller()
 		if err != nil {
 			return err
@@ -457,8 +478,11 @@ func (ca *clusterAdmin) CreatePartitions(topic string, count int32, assignment [
 		Timeout:         ca.conf.Admin.Timeout,
 		ValidateOnly:    validateOnly,
 	}
+	if ca.conf.Version.IsAtLeast(V2_0_0_0) {
+		request.Version = 1
+	}
 
-	return ca.retryOnError(isErrNoController, func() error {
+	return ca.retryOnError(isErrNotController, func() error {
 		b, err := ca.Controller()
 		if err != nil {
 			return err
@@ -499,7 +523,7 @@ func (ca *clusterAdmin) AlterPartitionReassignments(topic string, assignment [][
 		request.AddBlock(topic, int32(i), assignment[i])
 	}
 
-	return ca.retryOnError(isErrNoController, func() error {
+	return ca.retryOnError(isErrNotController, func() error {
 		b, err := ca.Controller()
 		if err != nil {
 			return err
@@ -545,13 +569,20 @@ func (ca *clusterAdmin) ListPartitionReassignments(topic string, partitions []in
 
 	request.AddBlock(topic, partitions)
 
-	b, err := ca.Controller()
-	if err != nil {
-		return nil, err
-	}
-	_ = b.Open(ca.client.Config())
+	var rsp *ListPartitionReassignmentsResponse
+	err = ca.retryOnError(isErrNotController, func() error {
+		b, err := ca.Controller()
+		if err != nil {
+			return err
+		}
+		_ = b.Open(ca.client.Config())
 
-	rsp, err := b.ListPartitionReassignments(request)
+		rsp, err = b.ListPartitionReassignments(request)
+		if isErrNotController(err) {
+			_, _ = ca.refreshController()
+		}
+		return err
+	})
 
 	if err == nil && rsp != nil {
 		return rsp.TopicStatus, nil
@@ -587,6 +618,9 @@ func (ca *clusterAdmin) DeleteRecords(topic string, partitionOffsets map[int32]i
 			Topics:  topics,
 			Timeout: ca.conf.Admin.Timeout,
 		}
+		if ca.conf.Version.IsAtLeast(V2_0_0_0) {
+			request.Version = 1
+		}
 		rsp, err := broker.DeleteRecords(request)
 		if err != nil {
 			errs = append(errs, err)
@@ -666,11 +700,8 @@ func (ca *clusterAdmin) DescribeConfig(resource ConfigResource) ([]ConfigEntry,
 
 	for _, rspResource := range rsp.Resources {
 		if rspResource.Name == resource.Name {
-			if rspResource.ErrorMsg != "" {
-				return nil, errors.New(rspResource.ErrorMsg)
-			}
 			if rspResource.ErrorCode != 0 {
-				return nil, KError(rspResource.ErrorCode)
+				return nil, &DescribeConfigError{Err: KError(rspResource.ErrorCode), ErrMsg: rspResource.ErrorMsg}
 			}
 			for _, cfgEntry := range rspResource.Configs {
 				entries = append(entries, *cfgEntry)
@@ -692,6 +723,9 @@ func (ca *clusterAdmin) AlterConfig(resourceType ConfigResourceType, name string
 		Resources:    resources,
 		ValidateOnly: validateOnly,
 	}
+	if ca.conf.Version.IsAtLeast(V2_0_0_0) {
+		request.Version = 1
+	}
 
 	var (
 		b   *Broker
@@ -721,11 +755,8 @@ func (ca *clusterAdmin) AlterConfig(resourceType ConfigResourceType, name string
 
 	for _, rspResource := range rsp.Resources {
 		if rspResource.Name == name {
-			if rspResource.ErrorMsg != "" {
-				return errors.New(rspResource.ErrorMsg)
-			}
 			if rspResource.ErrorCode != 0 {
-				return KError(rspResource.ErrorCode)
+				return &AlterConfigError{Err: KError(rspResource.ErrorCode), ErrMsg: rspResource.ErrorMsg}
 			}
 		}
 	}
@@ -891,8 +922,19 @@ func (ca *clusterAdmin) DescribeConsumerGroups(groups []string) (result []*Group
 		describeReq := &DescribeGroupsRequest{
 			Groups: brokerGroups,
 		}
+
 		if ca.conf.Version.IsAtLeast(V2_4_0_0) {
+			// Starting in version 4, the response will include group.instance.id info for members.
 			describeReq.Version = 4
+		} else if ca.conf.Version.IsAtLeast(V2_3_0_0) {
+			// Starting in version 3, authorized operations can be requested.
+			describeReq.Version = 3
+		} else if ca.conf.Version.IsAtLeast(V2_0_0_0) {
+			// Version 2 is the same as version 0.
+			describeReq.Version = 2
+		} else if ca.conf.Version.IsAtLeast(V1_1_0_0) {
+			// Version 1 is the same as version 0.
+			describeReq.Version = 1
 		}
 		response, err := broker.DescribeGroups(describeReq)
 		if err != nil {
@@ -919,7 +961,22 @@ func (ca *clusterAdmin) ListConsumerGroups() (allGroups map[string]string, err e
 			defer wg.Done()
 			_ = b.Open(conf) // Ensure that broker is opened
 
-			response, err := b.ListGroups(&ListGroupsRequest{})
+			request := &ListGroupsRequest{}
+			if ca.conf.Version.IsAtLeast(V2_6_0_0) {
+				// Version 4 adds the StatesFilter field (KIP-518).
+				request.Version = 4
+			} else if ca.conf.Version.IsAtLeast(V2_4_0_0) {
+				// Version 3 is the first flexible version.
+				request.Version = 3
+			} else if ca.conf.Version.IsAtLeast(V2_0_0_0) {
+				// Version 2 is the same as version 0.
+				request.Version = 2
+			} else if ca.conf.Version.IsAtLeast(V0_11_0_0) {
+				// Version 1 is the same as version 0.
+				request.Version = 1
+			}
+
+			response, err := b.ListGroups(request)
 			if err != nil {
 				errChan <- err
 				return
@@ -955,16 +1012,7 @@ func (ca *clusterAdmin) ListConsumerGroupOffsets(group string, topicPartitions m
 		return nil, err
 	}
 
-	request := &OffsetFetchRequest{
-		ConsumerGroup: group,
-		partitions:    topicPartitions,
-	}
-
-	if ca.conf.Version.IsAtLeast(V0_10_2_0) {
-		request.Version = 2
-	} else if ca.conf.Version.IsAtLeast(V0_8_2_2) {
-		request.Version = 1
-	}
+	request := NewOffsetFetchRequest(ca.conf.Version, group, topicPartitions)
 
 	return coordinator.FetchOffset(request)
 }
@@ -1006,6 +1054,9 @@ func (ca *clusterAdmin) DeleteConsumerGroup(group string) error {
 	request := &DeleteGroupsRequest{
 		Groups: []string{group},
 	}
+	if ca.conf.Version.IsAtLeast(V2_0_0_0) {
+		request.Version = 1
+	}
 
 	resp, err := coordinator.DeleteGroups(request)
 	if err != nil {
@@ -1043,7 +1094,11 @@ func (ca *clusterAdmin) DescribeLogDirs(brokerIds []int32) (allLogDirs map[int32
 			defer wg.Done()
 			_ = b.Open(conf) // Ensure that broker is opened
 
-			response, err := b.DescribeLogDirs(&DescribeLogDirsRequest{})
+			request := &DescribeLogDirsRequest{}
+			if ca.conf.Version.IsAtLeast(V2_0_0_0) {
+				request.Version = 1
+			}
+			response, err := b.DescribeLogDirs(request)
 			if err != nil {
 				errChan <- err
 				return
@@ -1114,12 +1169,16 @@ func (ca *clusterAdmin) AlterUserScramCredentials(u []AlterUserScramCredentialsU
 		Upsertions: u,
 	}
 
-	b, err := ca.Controller()
-	if err != nil {
-		return nil, err
-	}
+	var rsp *AlterUserScramCredentialsResponse
+	err := ca.retryOnError(isErrNotController, func() error {
+		b, err := ca.Controller()
+		if err != nil {
+			return err
+		}
 
-	rsp, err := b.AlterUserScramCredentials(req)
+		rsp, err = b.AlterUserScramCredentials(req)
+		return err
+	})
 	if err != nil {
 		return nil, err
 	}
@@ -1190,6 +1249,10 @@ func (ca *clusterAdmin) AlterClientQuotas(entity []QuotaEntityComponent, op Clie
 }
 
 func (ca *clusterAdmin) RemoveMemberFromConsumerGroup(groupId string, groupInstanceIds []string) (*LeaveGroupResponse, error) {
+	if !ca.conf.Version.IsAtLeast(V2_4_0_0) {
+		return nil, ConfigurationError("Removing members from a consumer group headers requires Kafka version of at least v2.4.0")
+	}
+
 	controller, err := ca.client.Coordinator(groupId)
 	if err != nil {
 		return nil, err

+ 6 - 1
vendor/github.com/IBM/sarama/alter_client_quotas_request.go

@@ -12,6 +12,7 @@ package sarama
 //   validate_only => BOOLEAN
 
 type AlterClientQuotasRequest struct {
+	Version      int16
 	Entries      []AlterClientQuotasEntry // The quota configuration entries to alter.
 	ValidateOnly bool                     // Whether the alteration should be validated, but not performed.
 }
@@ -182,13 +183,17 @@ func (a *AlterClientQuotasRequest) key() int16 {
 }
 
 func (a *AlterClientQuotasRequest) version() int16 {
-	return 0
+	return a.Version
 }
 
 func (a *AlterClientQuotasRequest) headerVersion() int16 {
 	return 1
 }
 
+func (a *AlterClientQuotasRequest) isValidVersion() bool {
+	return a.Version == 0
+}
+
 func (a *AlterClientQuotasRequest) requiredVersion() KafkaVersion {
 	return V2_6_0_0
 }

+ 10 - 1
vendor/github.com/IBM/sarama/alter_client_quotas_response.go

@@ -14,6 +14,7 @@ import (
 //       entity_name => NULLABLE_STRING
 
 type AlterClientQuotasResponse struct {
+	Version      int16
 	ThrottleTime time.Duration                    // The duration in milliseconds for which the request was throttled due to a quota violation, or zero if the request did not violate any quota.
 	Entries      []AlterClientQuotasEntryResponse // The quota configuration entries altered.
 }
@@ -133,13 +134,21 @@ func (a *AlterClientQuotasResponse) key() int16 {
 }
 
 func (a *AlterClientQuotasResponse) version() int16 {
-	return 0
+	return a.Version
 }
 
 func (a *AlterClientQuotasResponse) headerVersion() int16 {
 	return 0
 }
 
+func (a *AlterClientQuotasResponse) isValidVersion() bool {
+	return a.Version == 0
+}
+
 func (a *AlterClientQuotasResponse) requiredVersion() KafkaVersion {
 	return V2_6_0_0
 }
+
+func (r *AlterClientQuotasResponse) throttleTime() time.Duration {
+	return r.ThrottleTime
+}

+ 14 - 2
vendor/github.com/IBM/sarama/alter_configs_request.go

@@ -2,6 +2,7 @@ package sarama
 
 // AlterConfigsRequest is an alter config request type
 type AlterConfigsRequest struct {
+	Version      int16
 	Resources    []*AlterConfigsResource
 	ValidateOnly bool
 }
@@ -114,13 +115,24 @@ func (a *AlterConfigsRequest) key() int16 {
 }
 
 func (a *AlterConfigsRequest) version() int16 {
-	return 0
+	return a.Version
 }
 
 func (a *AlterConfigsRequest) headerVersion() int16 {
 	return 1
 }
 
+func (a *AlterConfigsRequest) isValidVersion() bool {
+	return a.Version >= 0 && a.Version <= 1
+}
+
 func (a *AlterConfigsRequest) requiredVersion() KafkaVersion {
-	return V0_11_0_0
+	switch a.Version {
+	case 1:
+		return V2_0_0_0
+	case 0:
+		return V0_11_0_0
+	default:
+		return V2_0_0_0
+	}
 }

+ 36 - 4
vendor/github.com/IBM/sarama/alter_configs_response.go

@@ -1,13 +1,30 @@
 package sarama
 
-import "time"
+import (
+	"fmt"
+	"time"
+)
 
 // AlterConfigsResponse is a response type for alter config
 type AlterConfigsResponse struct {
+	Version      int16
 	ThrottleTime time.Duration
 	Resources    []*AlterConfigsResourceResponse
 }
 
+type AlterConfigError struct {
+	Err    KError
+	ErrMsg string
+}
+
+func (c *AlterConfigError) Error() string {
+	text := c.Err.Error()
+	if c.ErrMsg != "" {
+		text = fmt.Sprintf("%s - %s", text, c.ErrMsg)
+	}
+	return text
+}
+
 // AlterConfigsResourceResponse is a response type for alter config resource
 type AlterConfigsResourceResponse struct {
 	ErrorCode int16
@@ -100,17 +117,32 @@ func (a *AlterConfigsResourceResponse) decode(pd packetDecoder, version int16) e
 }
 
 func (a *AlterConfigsResponse) key() int16 {
-	return 32
+	return 33
 }
 
 func (a *AlterConfigsResponse) version() int16 {
-	return 0
+	return a.Version
 }
 
 func (a *AlterConfigsResponse) headerVersion() int16 {
 	return 0
 }
 
+func (a *AlterConfigsResponse) isValidVersion() bool {
+	return a.Version >= 0 && a.Version <= 1
+}
+
 func (a *AlterConfigsResponse) requiredVersion() KafkaVersion {
-	return V0_11_0_0
+	switch a.Version {
+	case 1:
+		return V2_0_0_0
+	case 0:
+		return V0_11_0_0
+	default:
+		return V2_0_0_0
+	}
+}
+
+func (r *AlterConfigsResponse) throttleTime() time.Duration {
+	return r.ThrottleTime
 }

+ 4 - 0
vendor/github.com/IBM/sarama/alter_partition_reassignments_request.go

@@ -113,6 +113,10 @@ func (r *AlterPartitionReassignmentsRequest) headerVersion() int16 {
 	return 2
 }
 
+func (r *AlterPartitionReassignmentsRequest) isValidVersion() bool {
+	return r.Version == 0
+}
+
 func (r *AlterPartitionReassignmentsRequest) requiredVersion() KafkaVersion {
 	return V2_4_0_0
 }

+ 10 - 0
vendor/github.com/IBM/sarama/alter_partition_reassignments_response.go

@@ -1,5 +1,7 @@
 package sarama
 
+import "time"
+
 type alterPartitionReassignmentsErrorBlock struct {
 	errorCode    KError
 	errorMessage *string
@@ -152,6 +154,14 @@ func (r *AlterPartitionReassignmentsResponse) headerVersion() int16 {
 	return 1
 }
 
+func (r *AlterPartitionReassignmentsResponse) isValidVersion() bool {
+	return r.Version == 0
+}
+
 func (r *AlterPartitionReassignmentsResponse) requiredVersion() KafkaVersion {
 	return V2_4_0_0
 }
+
+func (r *AlterPartitionReassignmentsResponse) throttleTime() time.Duration {
+	return time.Duration(r.ThrottleTimeMs) * time.Millisecond
+}

+ 4 - 0
vendor/github.com/IBM/sarama/alter_user_scram_credentials_request.go

@@ -137,6 +137,10 @@ func (r *AlterUserScramCredentialsRequest) headerVersion() int16 {
 	return 2
 }
 
+func (r *AlterUserScramCredentialsRequest) isValidVersion() bool {
+	return r.Version == 0
+}
+
 func (r *AlterUserScramCredentialsRequest) requiredVersion() KafkaVersion {
 	return V2_7_0_0
 }

+ 8 - 0
vendor/github.com/IBM/sarama/alter_user_scram_credentials_response.go

@@ -89,6 +89,14 @@ func (r *AlterUserScramCredentialsResponse) headerVersion() int16 {
 	return 2
 }
 
+func (r *AlterUserScramCredentialsResponse) isValidVersion() bool {
+	return r.Version == 0
+}
+
 func (r *AlterUserScramCredentialsResponse) requiredVersion() KafkaVersion {
 	return V2_7_0_0
 }
+
+func (r *AlterUserScramCredentialsResponse) throttleTime() time.Duration {
+	return r.ThrottleTime
+}

+ 11 - 3
vendor/github.com/IBM/sarama/api_versions_request.go

@@ -57,13 +57,21 @@ func (r *ApiVersionsRequest) headerVersion() int16 {
 	return 1
 }
 
+func (r *ApiVersionsRequest) isValidVersion() bool {
+	return r.Version >= 0 && r.Version <= 3
+}
+
 func (r *ApiVersionsRequest) requiredVersion() KafkaVersion {
 	switch r.Version {
-	case 0:
-		return V0_10_0_0
 	case 3:
 		return V2_4_0_0
-	default:
+	case 2:
+		return V2_0_0_0
+	case 1:
+		return V0_11_0_0
+	case 0:
 		return V0_10_0_0
+	default:
+		return V2_4_0_0
 	}
 }

+ 17 - 3
vendor/github.com/IBM/sarama/api_versions_response.go

@@ -1,5 +1,7 @@
 package sarama
 
+import "time"
+
 // ApiVersionsResponseKey contains the APIs supported by the broker.
 type ApiVersionsResponseKey struct {
 	// Version defines the protocol version to use for encode and decode
@@ -144,13 +146,25 @@ func (r *ApiVersionsResponse) headerVersion() int16 {
 	return 0
 }
 
+func (r *ApiVersionsResponse) isValidVersion() bool {
+	return r.Version >= 0 && r.Version <= 3
+}
+
 func (r *ApiVersionsResponse) requiredVersion() KafkaVersion {
 	switch r.Version {
-	case 0:
-		return V0_10_0_0
 	case 3:
 		return V2_4_0_0
-	default:
+	case 2:
+		return V2_0_0_0
+	case 1:
+		return V0_11_0_0
+	case 0:
 		return V0_10_0_0
+	default:
+		return V2_4_0_0
 	}
 }
+
+func (r *ApiVersionsResponse) throttleTime() time.Duration {
+	return time.Duration(r.ThrottleTimeMs) * time.Millisecond
+}

+ 9 - 8
vendor/github.com/IBM/sarama/async_producer.go

@@ -20,7 +20,6 @@ import (
 // leaks and message lost: it will not be garbage-collected automatically when it passes
 // out of scope and buffered messages may not be flushed.
 type AsyncProducer interface {
-
 	// AsyncClose triggers a shutdown of the producer. The shutdown has completed
 	// when both the Errors and Successes channels have been closed. When calling
 	// AsyncClose, you *must* continue to read from those channels in order to
@@ -50,7 +49,7 @@ type AsyncProducer interface {
 	// errors to be returned.
 	Errors() <-chan *ProducerError
 
-	// IsTransactional return true when current producer is is transactional.
+	// IsTransactional return true when current producer is transactional.
 	IsTransactional() bool
 
 	// TxnStatus return current producer transaction status.
@@ -366,17 +365,17 @@ func (p *asyncProducer) Close() error {
 		})
 	}
 
-	var errors ProducerErrors
+	var pErrs ProducerErrors
 	if p.conf.Producer.Return.Errors {
 		for event := range p.errors {
-			errors = append(errors, event)
+			pErrs = append(pErrs, event)
 		}
 	} else {
 		<-p.errors
 	}
 
-	if len(errors) > 0 {
-		return errors
+	if len(pErrs) > 0 {
+		return pErrs
 	}
 	return nil
 }
@@ -450,8 +449,10 @@ func (p *asyncProducer) dispatcher() {
 			p.returnError(msg, ConfigurationError("Producing headers requires Kafka at least v0.11"))
 			continue
 		}
-		if msg.ByteSize(version) > p.conf.Producer.MaxMessageBytes {
-			p.returnError(msg, ErrMessageSizeTooLarge)
+
+		size := msg.ByteSize(version)
+		if size > p.conf.Producer.MaxMessageBytes {
+			p.returnError(msg, ConfigurationError(fmt.Sprintf("Attempt to produce message larger than configured Producer.MaxMessageBytes: %d > %d", size, p.conf.Producer.MaxMessageBytes)))
 			continue
 		}
 

+ 16 - 15
vendor/github.com/IBM/sarama/balance_strategy.go

@@ -65,7 +65,7 @@ type BalanceStrategy interface {
 // Example with two topics T1 and T2 with six partitions each (0..5) and two members (M1, M2):
 //
 //	M1: {T1: [0, 1, 2], T2: [0, 1, 2]}
-//	M2: {T2: [3, 4, 5], T2: [3, 4, 5]}
+//	M2: {T1: [3, 4, 5], T2: [3, 4, 5]}
 func NewBalanceStrategyRange() BalanceStrategy {
 	return &balanceStrategy{
 		name: RangeBalanceStrategyName,
@@ -1004,20 +1004,21 @@ func (p *partitionMovements) isLinked(src, dst string, pairs []consumerPair, cur
 	}
 
 	for _, pair := range pairs {
-		if pair.SrcMemberID == src {
-			// create a deep copy of the pairs, excluding the current pair
-			reducedSet := make([]consumerPair, len(pairs)-1)
-			i := 0
-			for _, p := range pairs {
-				if p != pair {
-					reducedSet[i] = pair
-					i++
-				}
+		if pair.SrcMemberID != src {
+			continue
+		}
+		// create a deep copy of the pairs, excluding the current pair
+		reducedSet := make([]consumerPair, len(pairs)-1)
+		i := 0
+		for _, p := range pairs {
+			if p != pair {
+				reducedSet[i] = pair
+				i++
 			}
-
-			currentPath = append(currentPath, pair.SrcMemberID)
-			return p.isLinked(pair.DstMemberID, dst, reducedSet, currentPath)
 		}
+
+		currentPath = append(currentPath, pair.SrcMemberID)
+		return p.isLinked(pair.DstMemberID, dst, reducedSet, currentPath)
 	}
 	return currentPath, false
 }
@@ -1115,9 +1116,9 @@ type assignmentPriorityQueue []*consumerGroupMember
 func (pq assignmentPriorityQueue) Len() int { return len(pq) }
 
 func (pq assignmentPriorityQueue) Less(i, j int) bool {
-	// order asssignment priority queue in descending order using assignment-count/member-id
+	// order assignment priority queue in descending order using assignment-count/member-id
 	if len(pq[i].assignments) == len(pq[j].assignments) {
-		return strings.Compare(pq[i].id, pq[j].id) > 0
+		return pq[i].id > pq[j].id
 	}
 	return len(pq[i].assignments) > len(pq[j].assignments)
 }

+ 103 - 24
vendor/github.com/IBM/sarama/broker.go

@@ -58,6 +58,9 @@ type Broker struct {
 
 	kerberosAuthenticator               GSSAPIKerberosAuth
 	clientSessionReauthenticationTimeMs int64
+
+	throttleTimer     *time.Timer
+	throttleTimerLock sync.Mutex
 }
 
 // SASLMechanism specifies the SASL mechanism the client uses to authenticate with the broker
@@ -258,6 +261,7 @@ func (b *Broker) Open(conf *Config) error {
 			b.connErr = b.authenticateViaSASLv1()
 			if b.connErr != nil {
 				close(b.responses)
+				<-b.done
 				err = b.conn.Close()
 				if err == nil {
 					DebugLogger.Printf("Closed connection to broker %s\n", b.addr)
@@ -369,6 +373,7 @@ func (b *Broker) Rack() string {
 // GetMetadata send a metadata request and returns a metadata response or error
 func (b *Broker) GetMetadata(request *MetadataRequest) (*MetadataResponse, error) {
 	response := new(MetadataResponse)
+	response.Version = request.Version // Required to ensure use of the correct response header version
 
 	err := b.sendAndReceive(request, response)
 	if err != nil {
@@ -431,12 +436,16 @@ type ProduceCallback func(*ProduceResponse, error)
 //
 // Make sure not to Close the broker in the callback as it will lead to a deadlock.
 func (b *Broker) AsyncProduce(request *ProduceRequest, cb ProduceCallback) error {
-	metricRegistry := b.metricRegistry
+	b.lock.Lock()
+	defer b.lock.Unlock()
+
 	needAcks := request.RequiredAcks != NoResponse
 	// Use a nil promise when no acks is required
 	var promise *responsePromise
 
 	if needAcks {
+		metricRegistry := b.metricRegistry
+
 		// Create ProduceResponse early to provide the header version
 		res := new(ProduceResponse)
 		promise = &responsePromise{
@@ -455,15 +464,13 @@ func (b *Broker) AsyncProduce(request *ProduceRequest, cb ProduceCallback) error
 					return
 				}
 
-				// Wellformed response
-				b.updateThrottleMetric(res.ThrottleTime)
+				// Well-formed response
+				b.handleThrottledResponse(res)
 				cb(res, nil)
 			},
 		}
 	}
 
-	b.lock.Lock()
-	defer b.lock.Unlock()
 	return b.sendWithPromise(request, promise)
 }
 
@@ -479,7 +486,6 @@ func (b *Broker) Produce(request *ProduceRequest) (*ProduceResponse, error) {
 	} else {
 		response = new(ProduceResponse)
 		err = b.sendAndReceive(request, response)
-		b.updateThrottleMetric(response.ThrottleTime)
 	}
 
 	if err != nil {
@@ -586,6 +592,7 @@ func (b *Broker) Heartbeat(request *HeartbeatRequest) (*HeartbeatResponse, error
 // ListGroups return a list group response or error
 func (b *Broker) ListGroups(request *ListGroupsRequest) (*ListGroupsResponse, error) {
 	response := new(ListGroupsResponse)
+	response.Version = request.Version // Required to ensure use of the correct response header version
 
 	err := b.sendAndReceive(request, response)
 	if err != nil {
@@ -944,7 +951,7 @@ func (b *Broker) write(buf []byte) (n int, err error) {
 	return b.conn.Write(buf)
 }
 
-// b.lock must be haled by caller
+// b.lock must be held by caller
 func (b *Broker) send(rb protocolBody, promiseResponse bool, responseHeaderVersion int16) (*responsePromise, error) {
 	var promise *responsePromise
 	if promiseResponse {
@@ -1000,6 +1007,9 @@ func (b *Broker) sendInternal(rb protocolBody, promise *responsePromise) error {
 		return err
 	}
 
+	// check and wait if throttled
+	b.waitIfThrottled()
+
 	requestTime := time.Now()
 	// Will be decremented in responseReceiver (except error or request with NoResponse)
 	b.addRequestInFlightMetrics(1)
@@ -1042,7 +1052,14 @@ func (b *Broker) sendAndReceive(req protocolBody, res protocolBody) error {
 		return nil
 	}
 
-	return handleResponsePromise(req, res, promise, b.metricRegistry)
+	err = handleResponsePromise(req, res, promise, b.metricRegistry)
+	if err != nil {
+		return err
+	}
+	if res != nil {
+		b.handleThrottledResponse(res)
+	}
+	return nil
 }
 
 func handleResponsePromise(req protocolBody, res protocolBody, promise *responsePromise, metricRegistry metrics.Registry) error {
@@ -1060,7 +1077,12 @@ func (b *Broker) decode(pd packetDecoder, version int16) (err error) {
 		return err
 	}
 
-	host, err := pd.getString()
+	var host string
+	if version < 9 {
+		host, err = pd.getString()
+	} else {
+		host, err = pd.getCompactString()
+	}
 	if err != nil {
 		return err
 	}
@@ -1070,11 +1092,13 @@ func (b *Broker) decode(pd packetDecoder, version int16) (err error) {
 		return err
 	}
 
-	if version >= 1 {
+	if version >= 1 && version < 9 {
 		b.rack, err = pd.getNullableString()
-		if err != nil {
-			return err
-		}
+	} else if version >= 9 {
+		b.rack, err = pd.getCompactNullableString()
+	}
+	if err != nil {
+		return err
 	}
 
 	b.addr = net.JoinHostPort(host, fmt.Sprint(port))
@@ -1082,6 +1106,13 @@ func (b *Broker) decode(pd packetDecoder, version int16) (err error) {
 		return err
 	}
 
+	if version >= 9 {
+		_, err := pd.getEmptyTaggedFieldArray()
+		if err != nil {
+			return err
+		}
+	}
+
 	return nil
 }
 
@@ -1098,7 +1129,11 @@ func (b *Broker) encode(pe packetEncoder, version int16) (err error) {
 
 	pe.putInt32(b.id)
 
-	err = pe.putString(host)
+	if version < 9 {
+		err = pe.putString(host)
+	} else {
+		err = pe.putCompactString(host)
+	}
 	if err != nil {
 		return err
 	}
@@ -1106,12 +1141,20 @@ func (b *Broker) encode(pe packetEncoder, version int16) (err error) {
 	pe.putInt32(int32(port))
 
 	if version >= 1 {
-		err = pe.putNullableString(b.rack)
+		if version < 9 {
+			err = pe.putNullableString(b.rack)
+		} else {
+			err = pe.putNullableCompactString(b.rack)
+		}
 		if err != nil {
 			return err
 		}
 	}
 
+	if version >= 9 {
+		pe.putEmptyTaggedFieldArray()
+	}
+
 	return nil
 }
 
@@ -1441,7 +1484,7 @@ func (b *Broker) sendAndReceiveSASLSCRAMv0() error {
 		length := len(msg)
 		authBytes := make([]byte, length+4) // 4 byte length header + auth data
 		binary.BigEndian.PutUint32(authBytes, uint32(length))
-		copy(authBytes[4:], []byte(msg))
+		copy(authBytes[4:], msg)
 		_, err := b.write(authBytes)
 		b.updateOutgoingCommunicationMetrics(length + 4)
 		if err != nil {
@@ -1635,16 +1678,52 @@ func (b *Broker) updateProtocolMetrics(rb protocolBody) {
 	}
 }
 
-func (b *Broker) updateThrottleMetric(throttleTime time.Duration) {
-	if throttleTime != time.Duration(0) {
-		DebugLogger.Printf(
-			"producer/broker/%d ProduceResponse throttled %v\n",
-			b.ID(), throttleTime)
-		if b.brokerThrottleTime != nil {
-			throttleTimeInMs := int64(throttleTime / time.Millisecond)
-			b.brokerThrottleTime.Update(throttleTimeInMs)
+type throttleSupport interface {
+	throttleTime() time.Duration
+}
+
+func (b *Broker) handleThrottledResponse(resp protocolBody) {
+	throttledResponse, ok := resp.(throttleSupport)
+	if !ok {
+		return
+	}
+	throttleTime := throttledResponse.throttleTime()
+	if throttleTime == time.Duration(0) {
+		return
+	}
+	DebugLogger.Printf(
+		"broker/%d %T throttled %v\n", b.ID(), resp, throttleTime)
+	b.setThrottle(throttleTime)
+	b.updateThrottleMetric(throttleTime)
+}
+
+func (b *Broker) setThrottle(throttleTime time.Duration) {
+	b.throttleTimerLock.Lock()
+	defer b.throttleTimerLock.Unlock()
+	if b.throttleTimer != nil {
+		// if there is an existing timer stop/clear it
+		if !b.throttleTimer.Stop() {
+			<-b.throttleTimer.C
 		}
 	}
+	b.throttleTimer = time.NewTimer(throttleTime)
+}
+
+func (b *Broker) waitIfThrottled() {
+	b.throttleTimerLock.Lock()
+	defer b.throttleTimerLock.Unlock()
+	if b.throttleTimer != nil {
+		DebugLogger.Printf("broker/%d waiting for throttle timer\n", b.ID())
+		<-b.throttleTimer.C
+		b.throttleTimer = nil
+	}
+}
+
+func (b *Broker) updateThrottleMetric(throttleTime time.Duration) {
+	if b.brokerThrottleTime != nil {
+		throttleTimeInMs := int64(throttleTime / time.Millisecond)
+		b.brokerThrottleTime.Update(throttleTimeInMs)
+	}
 }
 
 func (b *Broker) registerMetrics() {

+ 149 - 62
vendor/github.com/IBM/sarama/client.go

@@ -1,13 +1,18 @@
 package sarama
 
 import (
+	"context"
 	"errors"
 	"math"
 	"math/rand"
+	"net"
 	"sort"
+	"strings"
 	"sync"
 	"sync/atomic"
 	"time"
+
+	"golang.org/x/net/proxy"
 )
 
 // Client is a generic Kafka client. It manages connections to one or more Kafka brokers.
@@ -50,7 +55,7 @@ type Client interface {
 	// topic/partition, as determined by querying the cluster metadata.
 	Leader(topic string, partitionID int32) (*Broker, error)
 
-	// LeaderAndEpoch returns the the leader and its epoch for the current
+	// LeaderAndEpoch returns the leader and its epoch for the current
 	// topic/partition, as determined by querying the cluster metadata.
 	LeaderAndEpoch(topic string, partitionID int32) (*Broker, int32, error)
 
@@ -132,10 +137,10 @@ const (
 )
 
 type client struct {
-	// updateMetaDataMs stores the time at which metadata was lasted updated.
+	// updateMetadataMs stores the time at which metadata was lasted updated.
 	// Note: this accessed atomically so must be the first word in the struct
 	// as per golang/go#41970
-	updateMetaDataMs int64
+	updateMetadataMs int64
 
 	conf           *Config
 	closer, closed chan none // for shutting down background metadata updater
@@ -158,7 +163,6 @@ type client struct {
 	cachedPartitionsResults map[string][maxPartitionIndex][]int32
 
 	lock sync.RWMutex // protects access to the maps that hold cluster state.
-
 }
 
 // NewClient creates a new Client. It connects to one of the given broker addresses
@@ -179,6 +183,13 @@ func NewClient(addrs []string, conf *Config) (Client, error) {
 		return nil, ConfigurationError("You must provide at least one broker address")
 	}
 
+	if strings.Contains(addrs[0], ".servicebus.windows.net") {
+		if conf.Version.IsAtLeast(V1_1_0_0) || !conf.Version.IsAtLeast(V0_11_0_0) {
+			Logger.Println("Connecting to Azure Event Hubs, forcing version to V1_0_0_0 for compatibility")
+			conf.Version = V1_0_0_0
+		}
+	}
+
 	client := &client{
 		conf:                    conf,
 		closer:                  make(chan none),
@@ -191,6 +202,14 @@ func NewClient(addrs []string, conf *Config) (Client, error) {
 		transactionCoordinators: make(map[string]int32),
 	}
 
+	if conf.Net.ResolveCanonicalBootstrapServers {
+		var err error
+		addrs, err = client.resolveCanonicalNames(addrs)
+		if err != nil {
+			return nil, err
+		}
+	}
+
 	client.randomizeSeedBrokers(addrs)
 
 	if conf.Metadata.Full {
@@ -239,12 +258,26 @@ func (client *client) Broker(brokerID int32) (*Broker, error) {
 }
 
 func (client *client) InitProducerID() (*InitProducerIDResponse, error) {
+	// FIXME: this InitProducerID seems to only be called from client_test.go (TestInitProducerIDConnectionRefused) and has been superceded by transaction_manager.go?
 	brokerErrors := make([]error, 0)
-	for broker := client.anyBroker(); broker != nil; broker = client.anyBroker() {
-		var response *InitProducerIDResponse
-		req := &InitProducerIDRequest{}
+	for broker := client.LeastLoadedBroker(); broker != nil; broker = client.LeastLoadedBroker() {
+		request := &InitProducerIDRequest{}
+
+		if client.conf.Version.IsAtLeast(V2_7_0_0) {
+			// Version 4 adds the support for new error code PRODUCER_FENCED.
+			request.Version = 4
+		} else if client.conf.Version.IsAtLeast(V2_5_0_0) {
+			// Version 3 adds ProducerId and ProducerEpoch, allowing producers to try to resume after an INVALID_PRODUCER_EPOCH error
+			request.Version = 3
+		} else if client.conf.Version.IsAtLeast(V2_4_0_0) {
+			// Version 2 is the first flexible version.
+			request.Version = 2
+		} else if client.conf.Version.IsAtLeast(V2_0_0_0) {
+			// Version 1 is the same as version 0.
+			request.Version = 1
+		}
 
-		response, err := broker.InitProducerID(req)
+		response, err := broker.InitProducerID(request)
 		if err == nil {
 			return response, nil
 		} else {
@@ -486,16 +519,16 @@ func (client *client) RefreshBrokers(addrs []string) error {
 	defer client.lock.Unlock()
 
 	for _, broker := range client.brokers {
-		_ = broker.Close()
-		delete(client.brokers, broker.ID())
+		safeAsyncClose(broker)
 	}
+	client.brokers = make(map[int32]*Broker)
 
 	for _, broker := range client.seedBrokers {
-		_ = broker.Close()
+		safeAsyncClose(broker)
 	}
 
 	for _, broker := range client.deadSeeds {
-		_ = broker.Close()
+		safeAsyncClose(broker)
 	}
 
 	client.seedBrokers = nil
@@ -527,17 +560,17 @@ func (client *client) RefreshMetadata(topics ...string) error {
 	return client.tryRefreshMetadata(topics, client.conf.Metadata.Retry.Max, deadline)
 }
 
-func (client *client) GetOffset(topic string, partitionID int32, time int64) (int64, error) {
+func (client *client) GetOffset(topic string, partitionID int32, timestamp int64) (int64, error) {
 	if client.Closed() {
 		return -1, ErrClosedClient
 	}
 
-	offset, err := client.getOffset(topic, partitionID, time)
+	offset, err := client.getOffset(topic, partitionID, timestamp)
 	if err != nil {
 		if err := client.RefreshMetadata(topic); err != nil {
 			return -1, err
 		}
-		return client.getOffset(topic, partitionID, time)
+		return client.getOffset(topic, partitionID, timestamp)
 	}
 
 	return offset, err
@@ -730,22 +763,21 @@ func (client *client) registerBroker(broker *Broker) {
 	}
 }
 
-// deregisterBroker removes a broker from the seedsBroker list, and if it's
-// not the seedbroker, removes it from brokers map completely.
+// deregisterBroker removes a broker from the broker list, and if it's
+// not in the broker list, removes it from seedBrokers.
 func (client *client) deregisterBroker(broker *Broker) {
 	client.lock.Lock()
 	defer client.lock.Unlock()
 
+	_, ok := client.brokers[broker.ID()]
+	if ok {
+		Logger.Printf("client/brokers deregistered broker #%d at %s", broker.ID(), broker.Addr())
+		delete(client.brokers, broker.ID())
+		return
+	}
 	if len(client.seedBrokers) > 0 && broker == client.seedBrokers[0] {
 		client.deadSeeds = append(client.deadSeeds, broker)
 		client.seedBrokers = client.seedBrokers[1:]
-	} else {
-		// we do this so that our loop in `tryRefreshMetadata` doesn't go on forever,
-		// but we really shouldn't have to; once that loop is made better this case can be
-		// removed, and the function generally can be renamed from `deregisterBroker` to
-		// `nextSeedBroker` or something
-		DebugLogger.Printf("client/brokers deregistered broker #%d at %s", broker.ID(), broker.Addr())
-		delete(client.brokers, broker.ID())
 	}
 }
 
@@ -758,33 +790,12 @@ func (client *client) resurrectDeadBrokers() {
 	client.deadSeeds = nil
 }
 
-func (client *client) anyBroker() *Broker {
-	client.lock.RLock()
-	defer client.lock.RUnlock()
-
-	if len(client.seedBrokers) > 0 {
-		_ = client.seedBrokers[0].Open(client.conf)
-		return client.seedBrokers[0]
-	}
-
-	// not guaranteed to be random *or* deterministic
-	for _, broker := range client.brokers {
-		_ = broker.Open(client.conf)
-		return broker
-	}
-
-	return nil
-}
-
+// LeastLoadedBroker returns the broker with the least pending requests.
+// Firstly, choose the broker from cached broker list. If the broker list is empty, choose from seed brokers.
 func (client *client) LeastLoadedBroker() *Broker {
 	client.lock.RLock()
 	defer client.lock.RUnlock()
 
-	if len(client.seedBrokers) > 0 {
-		_ = client.seedBrokers[0].Open(client.conf)
-		return client.seedBrokers[0]
-	}
-
 	var leastLoadedBroker *Broker
 	pendingRequests := math.MaxInt
 	for _, broker := range client.brokers {
@@ -793,10 +804,16 @@ func (client *client) LeastLoadedBroker() *Broker {
 			leastLoadedBroker = broker
 		}
 	}
-
 	if leastLoadedBroker != nil {
 		_ = leastLoadedBroker.Open(client.conf)
+		return leastLoadedBroker
+	}
+
+	if len(client.seedBrokers) > 0 {
+		_ = client.seedBrokers[0].Open(client.conf)
+		return client.seedBrokers[0]
 	}
+
 	return leastLoadedBroker
 }
 
@@ -879,17 +896,29 @@ func (client *client) cachedLeader(topic string, partitionID int32) (*Broker, in
 	return nil, -1, ErrUnknownTopicOrPartition
 }
 
-func (client *client) getOffset(topic string, partitionID int32, time int64) (int64, error) {
+func (client *client) getOffset(topic string, partitionID int32, timestamp int64) (int64, error) {
 	broker, err := client.Leader(topic, partitionID)
 	if err != nil {
 		return -1, err
 	}
 
 	request := &OffsetRequest{}
-	if client.conf.Version.IsAtLeast(V0_10_1_0) {
+	if client.conf.Version.IsAtLeast(V2_1_0_0) {
+		// Version 4 adds the current leader epoch, which is used for fencing.
+		request.Version = 4
+	} else if client.conf.Version.IsAtLeast(V2_0_0_0) {
+		// Version 3 is the same as version 2.
+		request.Version = 3
+	} else if client.conf.Version.IsAtLeast(V0_11_0_0) {
+		// Version 2 adds the isolation level, which is used for transactional reads.
+		request.Version = 2
+	} else if client.conf.Version.IsAtLeast(V0_10_1_0) {
+		// Version 1 removes MaxNumOffsets.  From this version forward, only a single
+		// offset can be returned.
 		request.Version = 1
 	}
-	request.AddBlock(topic, partitionID, time, 1)
+
+	request.AddBlock(topic, partitionID, timestamp, 1)
 
 	response, err := broker.GetAvailableOffsets(request)
 	if err != nil {
@@ -975,20 +1004,21 @@ func (client *client) tryRefreshMetadata(topics []string, attemptsRemaining int,
 				time.Sleep(backoff)
 			}
 
-			t := atomic.LoadInt64(&client.updateMetaDataMs)
-			if time.Since(time.Unix(t/1e3, 0)) < backoff {
+			t := atomic.LoadInt64(&client.updateMetadataMs)
+			if time.Since(time.UnixMilli(t)) < backoff {
 				return err
 			}
+			attemptsRemaining--
 			Logger.Printf("client/metadata retrying after %dms... (%d attempts remaining)\n", backoff/time.Millisecond, attemptsRemaining)
 
-			return client.tryRefreshMetadata(topics, attemptsRemaining-1, deadline)
+			return client.tryRefreshMetadata(topics, attemptsRemaining, deadline)
 		}
 		return err
 	}
 
-	broker := client.anyBroker()
+	broker := client.LeastLoadedBroker()
 	brokerErrors := make([]error, 0)
-	for ; broker != nil && !pastDeadline(0); broker = client.anyBroker() {
+	for ; broker != nil && !pastDeadline(0); broker = client.LeastLoadedBroker() {
 		allowAutoTopicCreation := client.conf.Metadata.AllowAutoTopicCreation
 		if len(topics) > 0 {
 			DebugLogger.Printf("client/metadata fetching metadata for %v from broker %s\n", topics, broker.addr)
@@ -999,15 +1029,19 @@ func (client *client) tryRefreshMetadata(topics []string, attemptsRemaining int,
 
 		req := NewMetadataRequest(client.conf.Version, topics)
 		req.AllowAutoTopicCreation = allowAutoTopicCreation
-		t := atomic.LoadInt64(&client.updateMetaDataMs)
-		if !atomic.CompareAndSwapInt64(&client.updateMetaDataMs, t, time.Now().UnixNano()/int64(time.Millisecond)) {
-			return nil
-		}
+		atomic.StoreInt64(&client.updateMetadataMs, time.Now().UnixMilli())
 
 		response, err := broker.GetMetadata(req)
 		var kerror KError
 		var packetEncodingError PacketEncodingError
 		if err == nil {
+			// When talking to the startup phase of a broker, it is possible to receive an empty metadata set. We should remove that broker and try next broker (https://issues.apache.org/jira/browse/KAFKA-7924).
+			if len(response.Brokers) == 0 {
+				Logger.Println("client/metadata receiving empty brokers from the metadata response when requesting the broker #%d at %s", broker.ID(), broker.addr)
+				_ = broker.Close()
+				client.deregisterBroker(broker)
+				continue
+			}
 			allKnownMetaData := len(topics) == 0
 			// valid response, use it
 			shouldRetry, err := client.updateMetadata(response, allKnownMetaData)
@@ -1160,24 +1194,30 @@ func (client *client) findCoordinator(coordinatorKey string, coordinatorType Coo
 	retry := func(err error) (*FindCoordinatorResponse, error) {
 		if attemptsRemaining > 0 {
 			backoff := client.computeBackoff(attemptsRemaining)
+			attemptsRemaining--
 			Logger.Printf("client/coordinator retrying after %dms... (%d attempts remaining)\n", backoff/time.Millisecond, attemptsRemaining)
 			time.Sleep(backoff)
-			return client.findCoordinator(coordinatorKey, coordinatorType, attemptsRemaining-1)
+			return client.findCoordinator(coordinatorKey, coordinatorType, attemptsRemaining)
 		}
 		return nil, err
 	}
 
 	brokerErrors := make([]error, 0)
-	for broker := client.anyBroker(); broker != nil; broker = client.anyBroker() {
+	for broker := client.LeastLoadedBroker(); broker != nil; broker = client.LeastLoadedBroker() {
 		DebugLogger.Printf("client/coordinator requesting coordinator for %s from %s\n", coordinatorKey, broker.Addr())
 
 		request := new(FindCoordinatorRequest)
 		request.CoordinatorKey = coordinatorKey
 		request.CoordinatorType = coordinatorType
 
+		// Version 1 adds KeyType.
 		if client.conf.Version.IsAtLeast(V0_11_0_0) {
 			request.Version = 1
 		}
+		// Version 2 is the same as version 1.
+		if client.conf.Version.IsAtLeast(V2_0_0_0) {
+			request.Version = 2
+		}
 
 		response, err := broker.FindCoordinator(request)
 		if err != nil {
@@ -1228,6 +1268,53 @@ func (client *client) findCoordinator(coordinatorKey string, coordinatorType Coo
 	return retry(Wrap(ErrOutOfBrokers, brokerErrors...))
 }
 
+func (client *client) resolveCanonicalNames(addrs []string) ([]string, error) {
+	ctx := context.Background()
+
+	dialer := client.Config().getDialer()
+	resolver := net.Resolver{
+		Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
+			// dial func should only be called once, so switching within is acceptable
+			switch d := dialer.(type) {
+			case proxy.ContextDialer:
+				return d.DialContext(ctx, network, address)
+			default:
+				// we have no choice but to ignore the context
+				return d.Dial(network, address)
+			}
+		},
+	}
+
+	canonicalAddrs := make(map[string]struct{}, len(addrs)) // dedupe as we go
+	for _, addr := range addrs {
+		host, port, err := net.SplitHostPort(addr)
+		if err != nil {
+			return nil, err // message includes addr
+		}
+
+		ips, err := resolver.LookupHost(ctx, host)
+		if err != nil {
+			return nil, err // message includes host
+		}
+		for _, ip := range ips {
+			ptrs, err := resolver.LookupAddr(ctx, ip)
+			if err != nil {
+				return nil, err // message includes ip
+			}
+
+			// unlike the Java client, we do not further check that PTRs resolve
+			ptr := strings.TrimSuffix(ptrs[0], ".") // trailing dot breaks GSSAPI
+			canonicalAddrs[net.JoinHostPort(ptr, port)] = struct{}{}
+		}
+	}
+
+	addrs = make([]string, 0, len(canonicalAddrs))
+	for addr := range canonicalAddrs {
+		addrs = append(addrs, addr)
+	}
+	return addrs, nil
+}
+
 // nopCloserClient embeds an existing Client, but disables
 // the Close method (yet all other methods pass
 // through unchanged). This is for use in larger structs

+ 1 - 1
vendor/github.com/IBM/sarama/compress.go

@@ -2,11 +2,11 @@ package sarama
 
 import (
 	"bytes"
-	"compress/gzip"
 	"fmt"
 	"sync"
 
 	snappy "github.com/eapache/go-xerial-snappy"
+	"github.com/klauspost/compress/gzip"
 	"github.com/pierrec/lz4/v4"
 )
 

+ 33 - 13
vendor/github.com/IBM/sarama/config.go

@@ -1,7 +1,6 @@
 package sarama
 
 import (
-	"compress/gzip"
 	"crypto/tls"
 	"fmt"
 	"io"
@@ -9,13 +8,16 @@ import (
 	"regexp"
 	"time"
 
+	"github.com/klauspost/compress/gzip"
 	"github.com/rcrowley/go-metrics"
 	"golang.org/x/net/proxy"
 )
 
 const defaultClientID = "sarama"
 
-var validID = regexp.MustCompile(`\A[A-Za-z0-9._-]+\z`)
+// validClientID specifies the permitted characters for a client.id when
+// connecting to Kafka versions before 1.0.0 (KIP-190)
+var validClientID = regexp.MustCompile(`\A[A-Za-z0-9._-]+\z`)
 
 // Config is used to pass multiple configuration options to Sarama's constructors.
 type Config struct {
@@ -50,6 +52,15 @@ type Config struct {
 		ReadTimeout  time.Duration // How long to wait for a response.
 		WriteTimeout time.Duration // How long to wait for a transmit.
 
+		// ResolveCanonicalBootstrapServers turns each bootstrap broker address
+		// into a set of IPs, then does a reverse lookup on each one to get its
+		// canonical hostname. This list of hostnames then replaces the
+		// original address list. Similar to the `client.dns.lookup` option in
+		// the JVM client, this is especially useful with GSSAPI, where it
+		// allows providing an alias record instead of individual broker
+		// hostnames. Defaults to false.
+		ResolveCanonicalBootstrapServers bool
+
 		TLS struct {
 			// Whether or not to use TLS when connecting to the broker
 			// (defaults to false).
@@ -272,7 +283,6 @@ type Config struct {
 	// Consumer is the namespace for configuration related to consuming messages,
 	// used by the Consumer.
 	Consumer struct {
-
 		// Group is the namespace for configuring consumer group.
 		Group struct {
 			Session struct {
@@ -505,7 +515,7 @@ func NewConfig() *Config {
 	c.Net.ReadTimeout = 30 * time.Second
 	c.Net.WriteTimeout = 30 * time.Second
 	c.Net.SASL.Handshake = true
-	c.Net.SASL.Version = SASLHandshakeV0
+	c.Net.SASL.Version = SASLHandshakeV1
 
 	c.Metadata.Retry.Max = 3
 	c.Metadata.Retry.Backoff = 250 * time.Millisecond
@@ -513,7 +523,7 @@ func NewConfig() *Config {
 	c.Metadata.Full = true
 	c.Metadata.AllowAutoTopicCreation = true
 
-	c.Producer.MaxMessageBytes = 1000000
+	c.Producer.MaxMessageBytes = 1024 * 1024
 	c.Producer.RequiredAcks = WaitForLocal
 	c.Producer.Timeout = 10 * time.Second
 	c.Producer.Partitioner = NewHashPartitioner
@@ -650,19 +660,26 @@ func (c *Config) Validate() error {
 				return ConfigurationError("Net.SASL.GSSAPI.ServiceName must not be empty when GSS-API mechanism is used")
 			}
 
-			if c.Net.SASL.GSSAPI.AuthType == KRB5_USER_AUTH {
+			switch c.Net.SASL.GSSAPI.AuthType {
+			case KRB5_USER_AUTH:
 				if c.Net.SASL.GSSAPI.Password == "" {
 					return ConfigurationError("Net.SASL.GSSAPI.Password must not be empty when GSS-API " +
 						"mechanism is used and Net.SASL.GSSAPI.AuthType = KRB5_USER_AUTH")
 				}
-			} else if c.Net.SASL.GSSAPI.AuthType == KRB5_KEYTAB_AUTH {
+			case KRB5_KEYTAB_AUTH:
 				if c.Net.SASL.GSSAPI.KeyTabPath == "" {
 					return ConfigurationError("Net.SASL.GSSAPI.KeyTabPath must not be empty when GSS-API mechanism is used" +
-						" and  Net.SASL.GSSAPI.AuthType = KRB5_KEYTAB_AUTH")
+						" and Net.SASL.GSSAPI.AuthType = KRB5_KEYTAB_AUTH")
+				}
+			case KRB5_CCACHE_AUTH:
+				if c.Net.SASL.GSSAPI.CCachePath == "" {
+					return ConfigurationError("Net.SASL.GSSAPI.CCachePath must not be empty when GSS-API mechanism is used" +
+						" and Net.SASL.GSSAPI.AuthType = KRB5_CCACHE_AUTH")
 				}
-			} else {
-				return ConfigurationError("Net.SASL.GSSAPI.AuthType is invalid. Possible values are KRB5_USER_AUTH and KRB5_KEYTAB_AUTH")
+			default:
+				return ConfigurationError("Net.SASL.GSSAPI.AuthType is invalid. Possible values are KRB5_USER_AUTH, KRB5_KEYTAB_AUTH, and KRB5_CCACHE_AUTH")
 			}
+
 			if c.Net.SASL.GSSAPI.KerberosConfigPath == "" {
 				return ConfigurationError("Net.SASL.GSSAPI.KerberosConfigPath must not be empty when GSS-API mechanism is used")
 			}
@@ -831,8 +848,11 @@ func (c *Config) Validate() error {
 	switch {
 	case c.ChannelBufferSize < 0:
 		return ConfigurationError("ChannelBufferSize must be >= 0")
-	case !validID.MatchString(c.ClientID):
-		return ConfigurationError("ClientID is invalid")
+	}
+
+	// only validate clientID locally for Kafka versions before KIP-190 was implemented
+	if !c.Version.IsAtLeast(V1_0_0_0) && !validClientID.MatchString(c.ClientID) {
+		return ConfigurationError(fmt.Sprintf("ClientID value %q is not valid for Kafka versions before 1.0.0", c.ClientID))
 	}
 
 	return nil
@@ -840,7 +860,7 @@ func (c *Config) Validate() error {
 
 func (c *Config) getDialer() proxy.Dialer {
 	if c.Net.Proxy.Enable {
-		Logger.Printf("using proxy %s", c.Net.Proxy.Dialer)
+		Logger.Println("using proxy")
 		return c.Net.Proxy.Dialer
 	} else {
 		return &net.Dialer{

+ 28 - 4
vendor/github.com/IBM/sarama/consumer.go

@@ -85,13 +85,13 @@ type Consumer interface {
 	// New calls to the broker will return records from these partitions if there are any to be fetched.
 	Resume(topicPartitions map[string][]int32)
 
-	// Pause suspends fetching from all partitions. Future calls to the broker will not return any
+	// PauseAll suspends fetching from all partitions. Future calls to the broker will not return any
 	// records from these partitions until they have been resumed using Resume()/ResumeAll().
 	// Note that this method does not affect partition subscription.
 	// In particular, it does not cause a group rebalance when automatic assignment is used.
 	PauseAll()
 
-	// Resume resumes all partitions which have been paused with Pause()/PauseAll().
+	// ResumeAll resumes all partitions which have been paused with Pause()/PauseAll().
 	// New calls to the broker will return records from these partitions if there are any to be fetched.
 	ResumeAll()
 }
@@ -920,7 +920,7 @@ func (bc *brokerConsumer) subscriptionManager() {
 }
 
 // subscriptionConsumer ensures we will get nil right away if no new subscriptions is available
-// this is a the main loop that fetches Kafka messages
+// this is the main loop that fetches Kafka messages
 func (bc *brokerConsumer) subscriptionConsumer() {
 	for newSubscriptions := range bc.newSubscriptions {
 		bc.updateSubscriptions(newSubscriptions)
@@ -942,6 +942,7 @@ func (bc *brokerConsumer) subscriptionConsumer() {
 		// if there isn't response, it means that not fetch was made
 		// so we don't need to handle any response
 		if response == nil {
+			time.Sleep(partitionConsumersBatchTimeout)
 			continue
 		}
 
@@ -1067,20 +1068,35 @@ func (bc *brokerConsumer) fetchNewMessages() (*FetchResponse, error) {
 		MinBytes:    bc.consumer.conf.Consumer.Fetch.Min,
 		MaxWaitTime: int32(bc.consumer.conf.Consumer.MaxWaitTime / time.Millisecond),
 	}
+	// Version 1 is the same as version 0.
 	if bc.consumer.conf.Version.IsAtLeast(V0_9_0_0) {
 		request.Version = 1
 	}
+	// Starting in Version 2, the requestor must be able to handle Kafka Log
+	// Message format version 1.
 	if bc.consumer.conf.Version.IsAtLeast(V0_10_0_0) {
 		request.Version = 2
 	}
+	// Version 3 adds MaxBytes.  Starting in version 3, the partition ordering in
+	// the request is now relevant.  Partitions will be processed in the order
+	// they appear in the request.
 	if bc.consumer.conf.Version.IsAtLeast(V0_10_1_0) {
 		request.Version = 3
 		request.MaxBytes = MaxResponseSize
 	}
+	// Version 4 adds IsolationLevel.  Starting in version 4, the reqestor must be
+	// able to handle Kafka log message format version 2.
+	// Version 5 adds LogStartOffset to indicate the earliest available offset of
+	// partition data that can be consumed.
 	if bc.consumer.conf.Version.IsAtLeast(V0_11_0_0) {
-		request.Version = 4
+		request.Version = 5
 		request.Isolation = bc.consumer.conf.Consumer.IsolationLevel
 	}
+	// Version 6 is the same as version 5.
+	if bc.consumer.conf.Version.IsAtLeast(V1_0_0_0) {
+		request.Version = 6
+	}
+	// Version 7 adds incremental fetch request support.
 	if bc.consumer.conf.Version.IsAtLeast(V1_1_0_0) {
 		request.Version = 7
 		// We do not currently implement KIP-227 FetchSessions. Setting the id to 0
@@ -1089,9 +1105,17 @@ func (bc *brokerConsumer) fetchNewMessages() (*FetchResponse, error) {
 		request.SessionID = 0
 		request.SessionEpoch = -1
 	}
+	// Version 8 is the same as version 7.
+	if bc.consumer.conf.Version.IsAtLeast(V2_0_0_0) {
+		request.Version = 8
+	}
+	// Version 9 adds CurrentLeaderEpoch, as described in KIP-320.
+	// Version 10 indicates that we can use the ZStd compression algorithm, as
+	// described in KIP-110.
 	if bc.consumer.conf.Version.IsAtLeast(V2_1_0_0) {
 		request.Version = 10
 	}
+	// Version 11 adds RackID for KIP-392 fetch from closest replica
 	if bc.consumer.conf.Version.IsAtLeast(V2_3_0_0) {
 		request.Version = 11
 		request.RackID = bc.consumer.conf.RackID

+ 137 - 56
vendor/github.com/IBM/sarama/consumer_group.go

@@ -114,6 +114,9 @@ func NewConsumerGroup(addrs []string, groupID string, config *Config) (ConsumerG
 // necessary to call Close() on the underlying client when shutting down this consumer.
 // PLEASE NOTE: consumer groups can only re-use but not share clients.
 func NewConsumerGroupFromClient(groupID string, client Client) (ConsumerGroup, error) {
+	if client == nil {
+		return nil, ConfigurationError("client must not be nil")
+	}
 	// For clients passed in by the client, ensure we don't
 	// call Close() on it.
 	cli := &nopCloserClient{client}
@@ -141,8 +144,8 @@ func newConsumerGroup(groupID string, client Client) (ConsumerGroup, error) {
 		userData:       config.Consumer.Group.Member.UserData,
 		metricRegistry: newCleanupRegistry(config.MetricRegistry),
 	}
-	if client.Config().Consumer.Group.InstanceId != "" && config.Version.IsAtLeast(V2_3_0_0) {
-		cg.groupInstanceId = &client.Config().Consumer.Group.InstanceId
+	if config.Consumer.Group.InstanceId != "" && config.Version.IsAtLeast(V2_3_0_0) {
+		cg.groupInstanceId = &config.Consumer.Group.InstanceId
 	}
 	return cg, nil
 }
@@ -210,13 +213,11 @@ func (c *consumerGroup) Consume(ctx context.Context, topics []string, handler Co
 		return err
 	}
 
-	// loop check topic partition numbers changed
-	// will trigger rebalance when any topic partitions number had changed
-	// avoid Consume function called again that will generate more than loopCheckPartitionNumbers coroutine
-	go c.loopCheckPartitionNumbers(topics, sess)
-
-	// Wait for session exit signal
-	<-sess.ctx.Done()
+	// Wait for session exit signal or Close() call
+	select {
+	case <-c.closed:
+	case <-sess.ctx.Done():
+	}
 
 	// Gracefully release session claims
 	return sess.release(true)
@@ -244,6 +245,8 @@ func (c *consumerGroup) ResumeAll() {
 
 func (c *consumerGroup) retryNewSession(ctx context.Context, topics []string, handler ConsumerGroupHandler, retries int, refreshCoordinator bool) (*consumerGroupSession, error) {
 	select {
+	case <-ctx.Done():
+		return nil, ctx.Err()
 	case <-c.closed:
 		return nil, ErrClosedConsumerGroup
 	case <-time.After(c.config.Consumer.Group.Rebalance.Retry.Backoff):
@@ -263,6 +266,9 @@ func (c *consumerGroup) retryNewSession(ctx context.Context, topics []string, ha
 }
 
 func (c *consumerGroup) newSession(ctx context.Context, topics []string, handler ConsumerGroupHandler, retries int) (*consumerGroupSession, error) {
+	if ctx.Err() != nil {
+		return nil, ctx.Err()
+	}
 	coordinator, err := c.client.Coordinator(c.groupID)
 	if err != nil {
 		if retries <= 0 {
@@ -318,10 +324,12 @@ func (c *consumerGroup) newSession(ctx context.Context, topics []string, handler
 		}
 		return c.retryNewSession(ctx, topics, handler, retries, true)
 	case ErrMemberIdRequired:
-		// from JoinGroupRequest v4, if client start with empty member id,
-		// it need to get member id from response and send another join request to join group
+		// from JoinGroupRequest v4 onwards (due to KIP-394) if the client starts
+		// with an empty member id, it needs to get the assigned id from the
+		// response and send another join request with that id to actually join the
+		// group
 		c.memberID = join.MemberId
-		return c.retryNewSession(ctx, topics, handler, retries+1 /*keep retry time*/, false)
+		return c.newSession(ctx, topics, handler, retries)
 	case ErrFencedInstancedId:
 		if c.groupInstanceId != nil {
 			Logger.Printf("JoinGroup failed: group instance id %s has been fenced\n", *c.groupInstanceId)
@@ -345,13 +353,15 @@ func (c *consumerGroup) newSession(ctx context.Context, topics []string, handler
 	// Prepare distribution plan if we joined as the leader
 	var plan BalanceStrategyPlan
 	var members map[string]ConsumerGroupMemberMetadata
+	var allSubscribedTopicPartitions map[string][]int32
+	var allSubscribedTopics []string
 	if join.LeaderId == join.MemberId {
 		members, err = join.GetMembers()
 		if err != nil {
 			return nil, err
 		}
 
-		plan, err = c.balance(strategy, members)
+		allSubscribedTopicPartitions, allSubscribedTopics, plan, err = c.balance(strategy, members)
 		if err != nil {
 			return nil, err
 		}
@@ -406,7 +416,7 @@ func (c *consumerGroup) newSession(ctx context.Context, topics []string, handler
 		claims = members.Topics
 
 		// in the case of stateful balance strategies, hold on to the returned
-		// assignment metadata, otherwise, reset the statically defined conusmer
+		// assignment metadata, otherwise, reset the statically defined consumer
 		// group metadata
 		if members.UserData != nil {
 			c.userData = members.UserData
@@ -419,7 +429,17 @@ func (c *consumerGroup) newSession(ctx context.Context, topics []string, handler
 		}
 	}
 
-	return newConsumerGroupSession(ctx, c, claims, join.MemberId, join.GenerationId, handler)
+	session, err := newConsumerGroupSession(ctx, c, claims, join.MemberId, join.GenerationId, handler)
+	if err != nil {
+		return nil, err
+	}
+
+	// only the leader needs to check whether there are newly-added partitions in order to trigger a rebalance
+	if join.LeaderId == join.MemberId {
+		go c.loopCheckPartitionNumbers(allSubscribedTopicPartitions, allSubscribedTopics, session)
+	}
+
+	return session, err
 }
 
 func (c *consumerGroup) joinGroupRequest(coordinator *Broker, topics []string) (*JoinGroupResponse, error) {
@@ -433,7 +453,23 @@ func (c *consumerGroup) joinGroupRequest(coordinator *Broker, topics []string) (
 		req.Version = 1
 		req.RebalanceTimeout = int32(c.config.Consumer.Group.Rebalance.Timeout / time.Millisecond)
 	}
-	if c.groupInstanceId != nil {
+	if c.config.Version.IsAtLeast(V0_11_0_0) {
+		req.Version = 2
+	}
+	if c.config.Version.IsAtLeast(V0_11_0_0) {
+		req.Version = 2
+	}
+	if c.config.Version.IsAtLeast(V2_0_0_0) {
+		req.Version = 3
+	}
+	// from JoinGroupRequest v4 onwards (due to KIP-394) the client will actually
+	// send two JoinGroupRequests, once with the empty member id, and then again
+	// with the assigned id from the first response. This is handled via the
+	// ErrMemberIdRequired case.
+	if c.config.Version.IsAtLeast(V2_2_0_0) {
+		req.Version = 4
+	}
+	if c.config.Version.IsAtLeast(V2_3_0_0) {
 		req.Version = 5
 		req.GroupInstanceId = c.groupInstanceId
 	}
@@ -482,12 +518,19 @@ func (c *consumerGroup) syncGroupRequest(
 		GenerationId: generationID,
 	}
 
+	// Versions 1 and 2 are the same as version 0.
+	if c.config.Version.IsAtLeast(V0_11_0_0) {
+		req.Version = 1
+	}
+	if c.config.Version.IsAtLeast(V2_0_0_0) {
+		req.Version = 2
+	}
+	// Starting from version 3, we add a new field called groupInstanceId to indicate member identity across restarts.
 	if c.config.Version.IsAtLeast(V2_3_0_0) {
 		req.Version = 3
-	}
-	if c.groupInstanceId != nil {
 		req.GroupInstanceId = c.groupInstanceId
 	}
+
 	for memberID, topics := range plan {
 		assignment := &ConsumerGroupMemberAssignment{Topics: topics}
 		userDataBytes, err := strategy.AssignmentData(memberID, topics, generationID)
@@ -516,7 +559,16 @@ func (c *consumerGroup) heartbeatRequest(coordinator *Broker, memberID string, g
 		MemberId:     memberID,
 		GenerationId: generationID,
 	}
-	if c.groupInstanceId != nil {
+
+	// Version 1 and version 2 are the same as version 0.
+	if c.config.Version.IsAtLeast(V0_11_0_0) {
+		req.Version = 1
+	}
+	if c.config.Version.IsAtLeast(V2_0_0_0) {
+		req.Version = 2
+	}
+	// Starting from version 3, we add a new field called groupInstanceId to indicate member identity across restarts.
+	if c.config.Version.IsAtLeast(V2_3_0_0) {
 		req.Version = 3
 		req.GroupInstanceId = c.groupInstanceId
 	}
@@ -524,23 +576,36 @@ func (c *consumerGroup) heartbeatRequest(coordinator *Broker, memberID string, g
 	return coordinator.Heartbeat(req)
 }
 
-func (c *consumerGroup) balance(strategy BalanceStrategy, members map[string]ConsumerGroupMemberMetadata) (BalanceStrategyPlan, error) {
-	topics := make(map[string][]int32)
+func (c *consumerGroup) balance(strategy BalanceStrategy, members map[string]ConsumerGroupMemberMetadata) (map[string][]int32, []string, BalanceStrategyPlan, error) {
+	topicPartitions := make(map[string][]int32)
 	for _, meta := range members {
 		for _, topic := range meta.Topics {
-			topics[topic] = nil
+			topicPartitions[topic] = nil
 		}
 	}
 
-	for topic := range topics {
+	allSubscribedTopics := make([]string, 0, len(topicPartitions))
+	for topic := range topicPartitions {
+		allSubscribedTopics = append(allSubscribedTopics, topic)
+	}
+
+	// refresh metadata for all the subscribed topics in the consumer group
+	// to avoid using stale metadata to assigning partitions
+	err := c.client.RefreshMetadata(allSubscribedTopics...)
+	if err != nil {
+		return nil, nil, nil, err
+	}
+
+	for topic := range topicPartitions {
 		partitions, err := c.client.Partitions(topic)
 		if err != nil {
-			return nil, err
+			return nil, nil, nil, err
 		}
-		topics[topic] = partitions
+		topicPartitions[topic] = partitions
 	}
 
-	return strategy.Plan(members, topics)
+	plan, err := strategy.Plan(members, topicPartitions)
+	return topicPartitions, allSubscribedTopics, plan, err
 }
 
 // Leaves the cluster, called by Close.
@@ -556,32 +621,43 @@ func (c *consumerGroup) leave() error {
 		return err
 	}
 
-	// KIP-345 if groupInstanceId is set, don not leave group when consumer closed.
-	// Since we do not discover ApiVersion for brokers, LeaveGroupRequest still use the old version request for now
-	if c.groupInstanceId == nil {
-		resp, err := coordinator.LeaveGroup(&LeaveGroupRequest{
-			GroupId:  c.groupID,
+	// as per KIP-345 if groupInstanceId is set, i.e. static membership is in action, then do not leave group when consumer closed, just clear memberID
+	if c.groupInstanceId != nil {
+		c.memberID = ""
+		return nil
+	}
+	req := &LeaveGroupRequest{
+		GroupId:  c.groupID,
+		MemberId: c.memberID,
+	}
+	if c.config.Version.IsAtLeast(V0_11_0_0) {
+		req.Version = 1
+	}
+	if c.config.Version.IsAtLeast(V2_0_0_0) {
+		req.Version = 2
+	}
+	if c.config.Version.IsAtLeast(V2_4_0_0) {
+		req.Version = 3
+		req.Members = append(req.Members, MemberIdentity{
 			MemberId: c.memberID,
 		})
-		if err != nil {
-			_ = coordinator.Close()
-			return err
-		}
+	}
 
-		// Unset memberID
-		c.memberID = ""
+	resp, err := coordinator.LeaveGroup(req)
+	if err != nil {
+		_ = coordinator.Close()
+		return err
+	}
 
-		// Check response
-		switch resp.Err {
-		case ErrRebalanceInProgress, ErrUnknownMemberId, ErrNoError:
-			return nil
-		default:
-			return resp.Err
-		}
-	} else {
-		c.memberID = ""
+	// clear the memberID
+	c.memberID = ""
+
+	switch resp.Err {
+	case ErrRebalanceInProgress, ErrUnknownMemberId, ErrNoError:
+		return nil
+	default:
+		return resp.Err
 	}
-	return nil
 }
 
 func (c *consumerGroup) handleError(err error, topic string, partition int32) {
@@ -615,24 +691,29 @@ func (c *consumerGroup) handleError(err error, topic string, partition int32) {
 	}
 }
 
-func (c *consumerGroup) loopCheckPartitionNumbers(topics []string, session *consumerGroupSession) {
+func (c *consumerGroup) loopCheckPartitionNumbers(allSubscribedTopicPartitions map[string][]int32, topics []string, session *consumerGroupSession) {
 	if c.config.Metadata.RefreshFrequency == time.Duration(0) {
 		return
 	}
-	pause := time.NewTicker(c.config.Metadata.RefreshFrequency)
+
 	defer session.cancel()
-	defer pause.Stop()
-	var oldTopicToPartitionNum map[string]int
-	var err error
-	if oldTopicToPartitionNum, err = c.topicToPartitionNumbers(topics); err != nil {
-		return
+
+	oldTopicToPartitionNum := make(map[string]int, len(allSubscribedTopicPartitions))
+	for topic, partitions := range allSubscribedTopicPartitions {
+		oldTopicToPartitionNum[topic] = len(partitions)
 	}
+
+	pause := time.NewTicker(c.config.Metadata.RefreshFrequency)
+	defer pause.Stop()
 	for {
 		if newTopicToPartitionNum, err := c.topicToPartitionNumbers(topics); err != nil {
 			return
 		} else {
 			for topic, num := range oldTopicToPartitionNum {
 				if newTopicToPartitionNum[topic] != num {
+					Logger.Printf(
+						"consumergroup/%s loop check partition number goroutine find partitions in topics %s changed from %d to %d\n",
+						c.groupID, topics, num, newTopicToPartitionNum[topic])
 					return // trigger the end of the session on exit
 				}
 			}
@@ -641,7 +722,7 @@ func (c *consumerGroup) loopCheckPartitionNumbers(topics []string, session *cons
 		case <-pause.C:
 		case <-session.ctx.Done():
 			Logger.Printf(
-				"consumergroup/%s loop check partition number coroutine will exit, topics %s\n",
+				"consumergroup/%s loop check partition number goroutine will exit, topics %s\n",
 				c.groupID, topics)
 			// if session closed by other, should be exited
 			return
@@ -1016,7 +1097,7 @@ type ConsumerGroupClaim interface {
 	// InitialOffset returns the initial offset that was used as a starting point for this claim.
 	InitialOffset() int64
 
-	// HighWaterMarkOffset returns the high water mark offset of the partition,
+	// HighWaterMarkOffset returns the high watermark offset of the partition,
 	// i.e. the offset that will be used for the next message that will be produced.
 	// You can use this to determine how far behind the processing is.
 	HighWaterMarkOffset() int64

+ 52 - 8
vendor/github.com/IBM/sarama/consumer_group_members.go

@@ -9,6 +9,8 @@ type ConsumerGroupMemberMetadata struct {
 	Topics          []string
 	UserData        []byte
 	OwnedPartitions []*OwnedPartition
+	GenerationID    int32
+	RackID          *string
 }
 
 func (m *ConsumerGroupMemberMetadata) encode(pe packetEncoder) error {
@@ -22,6 +24,27 @@ func (m *ConsumerGroupMemberMetadata) encode(pe packetEncoder) error {
 		return err
 	}
 
+	if m.Version >= 1 {
+		if err := pe.putArrayLength(len(m.OwnedPartitions)); err != nil {
+			return err
+		}
+		for _, op := range m.OwnedPartitions {
+			if err := op.encode(pe); err != nil {
+				return err
+			}
+		}
+	}
+
+	if m.Version >= 2 {
+		pe.putInt32(m.GenerationID)
+	}
+
+	if m.Version >= 3 {
+		if err := pe.putNullableString(m.RackID); err != nil {
+			return err
+		}
+	}
+
 	return nil
 }
 
@@ -48,18 +71,29 @@ func (m *ConsumerGroupMemberMetadata) decode(pd packetDecoder) (err error) {
 			}
 			return err
 		}
-		if n == 0 {
-			return nil
-		}
-		m.OwnedPartitions = make([]*OwnedPartition, n)
-		for i := 0; i < n; i++ {
-			m.OwnedPartitions[i] = &OwnedPartition{}
-			if err := m.OwnedPartitions[i].decode(pd); err != nil {
-				return err
+		if n > 0 {
+			m.OwnedPartitions = make([]*OwnedPartition, n)
+			for i := 0; i < n; i++ {
+				m.OwnedPartitions[i] = &OwnedPartition{}
+				if err := m.OwnedPartitions[i].decode(pd); err != nil {
+					return err
+				}
 			}
 		}
 	}
 
+	if m.Version >= 2 {
+		if m.GenerationID, err = pd.getInt32(); err != nil {
+			return err
+		}
+	}
+
+	if m.Version >= 3 {
+		if m.RackID, err = pd.getNullableString(); err != nil {
+			return err
+		}
+	}
+
 	return nil
 }
 
@@ -68,6 +102,16 @@ type OwnedPartition struct {
 	Partitions []int32
 }
 
+func (m *OwnedPartition) encode(pe packetEncoder) error {
+	if err := pe.putString(m.Topic); err != nil {
+		return err
+	}
+	if err := pe.putInt32Array(m.Partitions); err != nil {
+		return err
+	}
+	return nil
+}
+
 func (m *OwnedPartition) decode(pd packetDecoder) (err error) {
 	if m.Topic, err = pd.getString(); err != nil {
 		return err

+ 15 - 2
vendor/github.com/IBM/sarama/consumer_metadata_request.go

@@ -2,6 +2,7 @@ package sarama
 
 // ConsumerMetadataRequest is used for metadata requests
 type ConsumerMetadataRequest struct {
+	Version       int16
 	ConsumerGroup string
 }
 
@@ -9,6 +10,7 @@ func (r *ConsumerMetadataRequest) encode(pe packetEncoder) error {
 	tmp := new(FindCoordinatorRequest)
 	tmp.CoordinatorKey = r.ConsumerGroup
 	tmp.CoordinatorType = CoordinatorGroup
+	tmp.Version = r.Version
 	return tmp.encode(pe)
 }
 
@@ -26,13 +28,24 @@ func (r *ConsumerMetadataRequest) key() int16 {
 }
 
 func (r *ConsumerMetadataRequest) version() int16 {
-	return 0
+	return r.Version
 }
 
 func (r *ConsumerMetadataRequest) headerVersion() int16 {
 	return 1
 }
 
+func (r *ConsumerMetadataRequest) isValidVersion() bool {
+	return r.Version >= 0 && r.Version <= 2
+}
+
 func (r *ConsumerMetadataRequest) requiredVersion() KafkaVersion {
-	return V0_8_2_0
+	switch r.Version {
+	case 2:
+		return V2_0_0_0
+	case 1:
+		return V0_11_0_0
+	default:
+		return V0_8_2_0
+	}
 }

+ 15 - 3
vendor/github.com/IBM/sarama/consumer_metadata_response.go

@@ -7,6 +7,7 @@ import (
 
 // ConsumerMetadataResponse holds the response for a consumer group meta data requests
 type ConsumerMetadataResponse struct {
+	Version         int16
 	Err             KError
 	Coordinator     *Broker
 	CoordinatorID   int32  // deprecated: use Coordinator.ID()
@@ -53,7 +54,7 @@ func (r *ConsumerMetadataResponse) encode(pe packetEncoder) error {
 	}
 
 	tmp := &FindCoordinatorResponse{
-		Version:     0,
+		Version:     r.Version,
 		Err:         r.Err,
 		Coordinator: r.Coordinator,
 	}
@@ -70,13 +71,24 @@ func (r *ConsumerMetadataResponse) key() int16 {
 }
 
 func (r *ConsumerMetadataResponse) version() int16 {
-	return 0
+	return r.Version
 }
 
 func (r *ConsumerMetadataResponse) headerVersion() int16 {
 	return 0
 }
 
+func (r *ConsumerMetadataResponse) isValidVersion() bool {
+	return r.Version >= 0 && r.Version <= 2
+}
+
 func (r *ConsumerMetadataResponse) requiredVersion() KafkaVersion {
-	return V0_8_2_0
+	switch r.Version {
+	case 2:
+		return V2_0_0_0
+	case 1:
+		return V0_11_0_0
+	default:
+		return V0_8_2_0
+	}
 }

+ 14 - 2
vendor/github.com/IBM/sarama/create_partitions_request.go

@@ -3,6 +3,7 @@ package sarama
 import "time"
 
 type CreatePartitionsRequest struct {
+	Version         int16
 	TopicPartitions map[string]*TopicPartition
 	Timeout         time.Duration
 	ValidateOnly    bool
@@ -64,15 +65,26 @@ func (r *CreatePartitionsRequest) key() int16 {
 }
 
 func (r *CreatePartitionsRequest) version() int16 {
-	return 0
+	return r.Version
 }
 
 func (r *CreatePartitionsRequest) headerVersion() int16 {
 	return 1
 }
 
+func (r *CreatePartitionsRequest) isValidVersion() bool {
+	return r.Version >= 0 && r.Version <= 1
+}
+
 func (r *CreatePartitionsRequest) requiredVersion() KafkaVersion {
-	return V1_0_0_0
+	switch r.Version {
+	case 1:
+		return V2_0_0_0
+	case 0:
+		return V1_0_0_0
+	default:
+		return V2_0_0_0
+	}
 }
 
 type TopicPartition struct {

+ 18 - 2
vendor/github.com/IBM/sarama/create_partitions_response.go

@@ -6,6 +6,7 @@ import (
 )
 
 type CreatePartitionsResponse struct {
+	Version              int16
 	ThrottleTime         time.Duration
 	TopicPartitionErrors map[string]*TopicPartitionError
 }
@@ -60,15 +61,30 @@ func (r *CreatePartitionsResponse) key() int16 {
 }
 
 func (r *CreatePartitionsResponse) version() int16 {
-	return 0
+	return r.Version
 }
 
 func (r *CreatePartitionsResponse) headerVersion() int16 {
 	return 0
 }
 
+func (r *CreatePartitionsResponse) isValidVersion() bool {
+	return r.Version >= 0 && r.Version <= 1
+}
+
 func (r *CreatePartitionsResponse) requiredVersion() KafkaVersion {
-	return V1_0_0_0
+	switch r.Version {
+	case 1:
+		return V2_0_0_0
+	case 0:
+		return V1_0_0_0
+	default:
+		return V2_0_0_0
+	}
+}
+
+func (r *CreatePartitionsResponse) throttleTime() time.Duration {
+	return r.ThrottleTime
 }
 
 type TopicPartitionError struct {

+ 28 - 7
vendor/github.com/IBM/sarama/create_topics_request.go

@@ -5,10 +5,14 @@ import (
 )
 
 type CreateTopicsRequest struct {
+	// Version defines the protocol version to use for encode and decode
 	Version int16
-
+	// TopicDetails contains the topics to create.
 	TopicDetails map[string]*TopicDetail
-	Timeout      time.Duration
+	// Timeout contains how long to wait before timing out the request.
+	Timeout time.Duration
+	// ValidateOnly if true, check that the topics can be created as specified,
+	// but don't create anything.
 	ValidateOnly bool
 }
 
@@ -83,22 +87,39 @@ func (r *CreateTopicsRequest) headerVersion() int16 {
 	return 1
 }
 
+func (c *CreateTopicsRequest) isValidVersion() bool {
+	return c.Version >= 0 && c.Version <= 3
+}
+
 func (c *CreateTopicsRequest) requiredVersion() KafkaVersion {
 	switch c.Version {
+	case 3:
+		return V2_0_0_0
 	case 2:
-		return V1_0_0_0
-	case 1:
 		return V0_11_0_0
-	default:
+	case 1:
+		return V0_10_2_0
+	case 0:
 		return V0_10_1_0
+	default:
+		return V2_8_0_0
 	}
 }
 
 type TopicDetail struct {
-	NumPartitions     int32
+	// NumPartitions contains the number of partitions to create in the topic, or
+	// -1 if we are either specifying a manual partition assignment or using the
+	// default partitions.
+	NumPartitions int32
+	// ReplicationFactor contains the number of replicas to create for each
+	// partition in the topic, or -1 if we are either specifying a manual
+	// partition assignment or using the default replication factor.
 	ReplicationFactor int16
+	// ReplicaAssignment contains the manual partition assignment, or the empty
+	// array if we are using automatic assignment.
 	ReplicaAssignment map[int32][]int32
-	ConfigEntries     map[string]*string
+	// ConfigEntries contains the custom topic configurations to set.
+	ConfigEntries map[string]*string
 }
 
 func (t *TopicDetail) encode(pe packetEncoder) error {

+ 21 - 5
vendor/github.com/IBM/sarama/create_topics_response.go

@@ -6,9 +6,13 @@ import (
 )
 
 type CreateTopicsResponse struct {
-	Version      int16
+	// Version defines the protocol version to use for encode and decode
+	Version int16
+	// ThrottleTime contains the duration for which the request was throttled due
+	// to a quota violation, or zero if the request did not violate any quota.
 	ThrottleTime time.Duration
-	TopicErrors  map[string]*TopicError
+	// TopicErrors contains a map of any errors for the topics we tried to create.
+	TopicErrors map[string]*TopicError
 }
 
 func (c *CreateTopicsResponse) encode(pe packetEncoder) error {
@@ -74,17 +78,29 @@ func (c *CreateTopicsResponse) headerVersion() int16 {
 	return 0
 }
 
+func (c *CreateTopicsResponse) isValidVersion() bool {
+	return c.Version >= 0 && c.Version <= 3
+}
+
 func (c *CreateTopicsResponse) requiredVersion() KafkaVersion {
 	switch c.Version {
+	case 3:
+		return V2_0_0_0
 	case 2:
-		return V1_0_0_0
-	case 1:
 		return V0_11_0_0
-	default:
+	case 1:
+		return V0_10_2_0
+	case 0:
 		return V0_10_1_0
+	default:
+		return V2_8_0_0
 	}
 }
 
+func (r *CreateTopicsResponse) throttleTime() time.Duration {
+	return r.ThrottleTime
+}
+
 type TopicError struct {
 	Err    KError
 	ErrMsg *string

+ 44 - 7
vendor/github.com/IBM/sarama/decompress.go

@@ -2,12 +2,11 @@ package sarama
 
 import (
 	"bytes"
-	"compress/gzip"
 	"fmt"
-	"io"
 	"sync"
 
 	snappy "github.com/eapache/go-xerial-snappy"
+	"github.com/klauspost/compress/gzip"
 	"github.com/pierrec/lz4/v4"
 )
 
@@ -19,6 +18,19 @@ var (
 	}
 
 	gzipReaderPool sync.Pool
+
+	bufferPool = sync.Pool{
+		New: func() interface{} {
+			return new(bytes.Buffer)
+		},
+	}
+
+	bytesPool = sync.Pool{
+		New: func() interface{} {
+			res := make([]byte, 0, 4096)
+			return &res
+		},
+	}
 )
 
 func decompress(cc CompressionCodec, data []byte) ([]byte, error) {
@@ -38,9 +50,17 @@ func decompress(cc CompressionCodec, data []byte) ([]byte, error) {
 			return nil, err
 		}
 
-		defer gzipReaderPool.Put(reader)
+		buffer := bufferPool.Get().(*bytes.Buffer)
+		_, err = buffer.ReadFrom(reader)
+		// copy the buffer to a new slice with the correct length
+		// reuse gzipReader and buffer
+		gzipReaderPool.Put(reader)
+		res := make([]byte, buffer.Len())
+		copy(res, buffer.Bytes())
+		buffer.Reset()
+		bufferPool.Put(buffer)
 
-		return io.ReadAll(reader)
+		return res, err
 	case CompressionSnappy:
 		return snappy.Decode(data)
 	case CompressionLZ4:
@@ -50,11 +70,28 @@ func decompress(cc CompressionCodec, data []byte) ([]byte, error) {
 		} else {
 			reader.Reset(bytes.NewReader(data))
 		}
-		defer lz4ReaderPool.Put(reader)
+		buffer := bufferPool.Get().(*bytes.Buffer)
+		_, err := buffer.ReadFrom(reader)
+		// copy the buffer to a new slice with the correct length
+		// reuse lz4Reader and buffer
+		lz4ReaderPool.Put(reader)
+		res := make([]byte, buffer.Len())
+		copy(res, buffer.Bytes())
+		buffer.Reset()
+		bufferPool.Put(buffer)
 
-		return io.ReadAll(reader)
+		return res, err
 	case CompressionZSTD:
-		return zstdDecompress(ZstdDecoderParams{}, nil, data)
+		buffer := *bytesPool.Get().(*[]byte)
+		var err error
+		buffer, err = zstdDecompress(ZstdDecoderParams{}, buffer, data)
+		// copy the buffer to a new slice with the correct length and reuse buffer
+		res := make([]byte, len(buffer))
+		copy(res, buffer)
+		buffer = buffer[:0]
+		bytesPool.Put(&buffer)
+
+		return res, err
 	default:
 		return nil, PacketDecodingError{fmt.Sprintf("invalid compression specified (%d)", cc)}
 	}

+ 15 - 3
vendor/github.com/IBM/sarama/delete_groups_request.go

@@ -1,7 +1,8 @@
 package sarama
 
 type DeleteGroupsRequest struct {
-	Groups []string
+	Version int16
+	Groups  []string
 }
 
 func (r *DeleteGroupsRequest) encode(pe packetEncoder) error {
@@ -18,15 +19,26 @@ func (r *DeleteGroupsRequest) key() int16 {
 }
 
 func (r *DeleteGroupsRequest) version() int16 {
-	return 0
+	return r.Version
 }
 
 func (r *DeleteGroupsRequest) headerVersion() int16 {
 	return 1
 }
 
+func (r *DeleteGroupsRequest) isValidVersion() bool {
+	return r.Version >= 0 && r.Version <= 1
+}
+
 func (r *DeleteGroupsRequest) requiredVersion() KafkaVersion {
-	return V1_1_0_0
+	switch r.Version {
+	case 1:
+		return V2_0_0_0
+	case 0:
+		return V1_1_0_0
+	default:
+		return V2_0_0_0
+	}
 }
 
 func (r *DeleteGroupsRequest) AddGroup(group string) {

+ 18 - 2
vendor/github.com/IBM/sarama/delete_groups_response.go

@@ -5,6 +5,7 @@ import (
 )
 
 type DeleteGroupsResponse struct {
+	Version         int16
 	ThrottleTime    time.Duration
 	GroupErrorCodes map[string]KError
 }
@@ -62,13 +63,28 @@ func (r *DeleteGroupsResponse) key() int16 {
 }
 
 func (r *DeleteGroupsResponse) version() int16 {
-	return 0
+	return r.Version
 }
 
 func (r *DeleteGroupsResponse) headerVersion() int16 {
 	return 0
 }
 
+func (r *DeleteGroupsResponse) isValidVersion() bool {
+	return r.Version >= 0 && r.Version <= 1
+}
+
 func (r *DeleteGroupsResponse) requiredVersion() KafkaVersion {
-	return V1_1_0_0
+	switch r.Version {
+	case 1:
+		return V2_0_0_0
+	case 0:
+		return V1_1_0_0
+	default:
+		return V2_0_0_0
+	}
+}
+
+func (r *DeleteGroupsResponse) throttleTime() time.Duration {
+	return r.ThrottleTime
 }

+ 6 - 1
vendor/github.com/IBM/sarama/delete_offsets_request.go

@@ -1,6 +1,7 @@
 package sarama
 
 type DeleteOffsetsRequest struct {
+	Version    int16
 	Group      string
 	partitions map[string][]int32
 }
@@ -72,13 +73,17 @@ func (r *DeleteOffsetsRequest) key() int16 {
 }
 
 func (r *DeleteOffsetsRequest) version() int16 {
-	return 0
+	return r.Version
 }
 
 func (r *DeleteOffsetsRequest) headerVersion() int16 {
 	return 1
 }
 
+func (r *DeleteOffsetsRequest) isValidVersion() bool {
+	return r.Version == 0
+}
+
 func (r *DeleteOffsetsRequest) requiredVersion() KafkaVersion {
 	return V2_4_0_0
 }

+ 10 - 1
vendor/github.com/IBM/sarama/delete_offsets_response.go

@@ -5,6 +5,7 @@ import (
 )
 
 type DeleteOffsetsResponse struct {
+	Version int16
 	// The top-level error code, or 0 if there was no error.
 	ErrorCode    KError
 	ThrottleTime time.Duration
@@ -100,13 +101,21 @@ func (r *DeleteOffsetsResponse) key() int16 {
 }
 
 func (r *DeleteOffsetsResponse) version() int16 {
-	return 0
+	return r.Version
 }
 
 func (r *DeleteOffsetsResponse) headerVersion() int16 {
 	return 0
 }
 
+func (r *DeleteOffsetsResponse) isValidVersion() bool {
+	return r.Version == 0
+}
+
 func (r *DeleteOffsetsResponse) requiredVersion() KafkaVersion {
 	return V2_4_0_0
 }
+
+func (r *DeleteOffsetsResponse) throttleTime() time.Duration {
+	return r.ThrottleTime
+}

+ 12 - 2
vendor/github.com/IBM/sarama/delete_records_request.go

@@ -13,6 +13,7 @@ import (
 //  id(int32) offset(int64)
 
 type DeleteRecordsRequest struct {
+	Version int16
 	Topics  map[string]*DeleteRecordsRequestTopic
 	Timeout time.Duration
 }
@@ -74,15 +75,24 @@ func (d *DeleteRecordsRequest) key() int16 {
 }
 
 func (d *DeleteRecordsRequest) version() int16 {
-	return 0
+	return d.Version
 }
 
 func (d *DeleteRecordsRequest) headerVersion() int16 {
 	return 1
 }
 
+func (d *DeleteRecordsRequest) isValidVersion() bool {
+	return d.Version >= 0 && d.Version <= 1
+}
+
 func (d *DeleteRecordsRequest) requiredVersion() KafkaVersion {
-	return V0_11_0_0
+	switch d.Version {
+	case 1:
+		return V2_0_0_0
+	default:
+		return V0_11_0_0
+	}
 }
 
 type DeleteRecordsRequestTopic struct {

+ 15 - 2
vendor/github.com/IBM/sarama/delete_records_response.go

@@ -77,15 +77,28 @@ func (d *DeleteRecordsResponse) key() int16 {
 }
 
 func (d *DeleteRecordsResponse) version() int16 {
-	return 0
+	return d.Version
 }
 
 func (d *DeleteRecordsResponse) headerVersion() int16 {
 	return 0
 }
 
+func (d *DeleteRecordsResponse) isValidVersion() bool {
+	return d.Version >= 0 && d.Version <= 1
+}
+
 func (d *DeleteRecordsResponse) requiredVersion() KafkaVersion {
-	return V0_11_0_0
+	switch d.Version {
+	case 1:
+		return V2_0_0_0
+	default:
+		return V0_11_0_0
+	}
+}
+
+func (r *DeleteRecordsResponse) throttleTime() time.Duration {
+	return r.ThrottleTime
 }
 
 type DeleteRecordsResponseTopic struct {

+ 11 - 1
vendor/github.com/IBM/sarama/delete_topics_request.go

@@ -42,11 +42,21 @@ func (d *DeleteTopicsRequest) headerVersion() int16 {
 	return 1
 }
 
+func (d *DeleteTopicsRequest) isValidVersion() bool {
+	return d.Version >= 0 && d.Version <= 3
+}
+
 func (d *DeleteTopicsRequest) requiredVersion() KafkaVersion {
 	switch d.Version {
+	case 3:
+		return V2_1_0_0
+	case 2:
+		return V2_0_0_0
 	case 1:
 		return V0_11_0_0
-	default:
+	case 0:
 		return V0_10_1_0
+	default:
+		return V2_2_0_0
 	}
 }

+ 15 - 1
vendor/github.com/IBM/sarama/delete_topics_response.go

@@ -72,11 +72,25 @@ func (d *DeleteTopicsResponse) headerVersion() int16 {
 	return 0
 }
 
+func (d *DeleteTopicsResponse) isValidVersion() bool {
+	return d.Version >= 0 && d.Version <= 3
+}
+
 func (d *DeleteTopicsResponse) requiredVersion() KafkaVersion {
 	switch d.Version {
+	case 3:
+		return V2_1_0_0
+	case 2:
+		return V2_0_0_0
 	case 1:
 		return V0_11_0_0
-	default:
+	case 0:
 		return V0_10_1_0
+	default:
+		return V2_2_0_0
 	}
 }
+
+func (r *DeleteTopicsResponse) throttleTime() time.Duration {
+	return r.ThrottleTime
+}

+ 6 - 1
vendor/github.com/IBM/sarama/describe_client_quotas_request.go

@@ -11,6 +11,7 @@ package sarama
 // Components: the components to filter on
 // Strict: whether the filter only includes specified components
 type DescribeClientQuotasRequest struct {
+	Version    int16
 	Components []QuotaFilterComponent
 	Strict     bool
 }
@@ -129,13 +130,17 @@ func (d *DescribeClientQuotasRequest) key() int16 {
 }
 
 func (d *DescribeClientQuotasRequest) version() int16 {
-	return 0
+	return d.Version
 }
 
 func (d *DescribeClientQuotasRequest) headerVersion() int16 {
 	return 1
 }
 
+func (d *DescribeClientQuotasRequest) isValidVersion() bool {
+	return d.Version == 0
+}
+
 func (d *DescribeClientQuotasRequest) requiredVersion() KafkaVersion {
 	return V2_6_0_0
 }

+ 10 - 1
vendor/github.com/IBM/sarama/describe_client_quotas_response.go

@@ -17,6 +17,7 @@ import (
 //       value => FLOAT64
 
 type DescribeClientQuotasResponse struct {
+	Version      int16
 	ThrottleTime time.Duration               // The duration in milliseconds for which the request was throttled due to a quota violation, or zero if the request did not violate any quota.
 	ErrorCode    KError                      // The error code, or `0` if the quota description succeeded.
 	ErrorMsg     *string                     // The error message, or `null` if the quota description succeeded.
@@ -223,13 +224,21 @@ func (d *DescribeClientQuotasResponse) key() int16 {
 }
 
 func (d *DescribeClientQuotasResponse) version() int16 {
-	return 0
+	return d.Version
 }
 
 func (d *DescribeClientQuotasResponse) headerVersion() int16 {
 	return 0
 }
 
+func (d *DescribeClientQuotasResponse) isValidVersion() bool {
+	return d.Version == 0
+}
+
 func (d *DescribeClientQuotasResponse) requiredVersion() KafkaVersion {
 	return V2_6_0_0
 }
+
+func (r *DescribeClientQuotasResponse) throttleTime() time.Duration {
+	return r.ThrottleTime
+}

+ 9 - 3
vendor/github.com/IBM/sarama/describe_configs_request.go

@@ -103,13 +103,19 @@ func (r *DescribeConfigsRequest) headerVersion() int16 {
 	return 1
 }
 
+func (r *DescribeConfigsRequest) isValidVersion() bool {
+	return r.Version >= 0 && r.Version <= 2
+}
+
 func (r *DescribeConfigsRequest) requiredVersion() KafkaVersion {
 	switch r.Version {
-	case 1:
-		return V1_1_0_0
 	case 2:
 		return V2_0_0_0
-	default:
+	case 1:
+		return V1_1_0_0
+	case 0:
 		return V0_11_0_0
+	default:
+		return V2_0_0_0
 	}
 }

+ 26 - 3
vendor/github.com/IBM/sarama/describe_configs_response.go

@@ -34,6 +34,19 @@ const (
 	SourceDefault
 )
 
+type DescribeConfigError struct {
+	Err    KError
+	ErrMsg string
+}
+
+func (c *DescribeConfigError) Error() string {
+	text := c.Err.Error()
+	if c.ErrMsg != "" {
+		text = fmt.Sprintf("%s - %s", text, c.ErrMsg)
+	}
+	return text
+}
+
 type DescribeConfigsResponse struct {
 	Version      int16
 	ThrottleTime time.Duration
@@ -116,17 +129,27 @@ func (r *DescribeConfigsResponse) headerVersion() int16 {
 	return 0
 }
 
+func (r *DescribeConfigsResponse) isValidVersion() bool {
+	return r.Version >= 0 && r.Version <= 2
+}
+
 func (r *DescribeConfigsResponse) requiredVersion() KafkaVersion {
 	switch r.Version {
-	case 1:
-		return V1_0_0_0
 	case 2:
 		return V2_0_0_0
-	default:
+	case 1:
+		return V1_1_0_0
+	case 0:
 		return V0_11_0_0
+	default:
+		return V2_0_0_0
 	}
 }
 
+func (r *DescribeConfigsResponse) throttleTime() time.Duration {
+	return r.ThrottleTime
+}
+
 func (r *ResourceResponse) encode(pe packetEncoder, version int16) (err error) {
 	pe.putInt16(r.ErrorCode)
 

+ 13 - 6
vendor/github.com/IBM/sarama/describe_groups_request.go

@@ -42,18 +42,25 @@ func (r *DescribeGroupsRequest) headerVersion() int16 {
 	return 1
 }
 
+func (r *DescribeGroupsRequest) isValidVersion() bool {
+	return r.Version >= 0 && r.Version <= 4
+}
+
 func (r *DescribeGroupsRequest) requiredVersion() KafkaVersion {
 	switch r.Version {
-	case 1:
-		return V1_1_0_0
-	case 2:
-		return V2_0_0_0
+	case 4:
+		return V2_4_0_0
 	case 3:
 		return V2_3_0_0
-	case 4:
+	case 2:
+		return V2_0_0_0
+	case 1:
+		return V0_11_0_0
+	case 0:
+		return V0_9_0_0
+	default:
 		return V2_4_0_0
 	}
-	return V0_9_0_0
 }
 
 func (r *DescribeGroupsRequest) AddGroup(group string) {

+ 19 - 6
vendor/github.com/IBM/sarama/describe_groups_response.go

@@ -1,5 +1,7 @@
 package sarama
 
+import "time"
+
 type DescribeGroupsResponse struct {
 	// Version defines the protocol version to use for encode and decode
 	Version int16
@@ -63,18 +65,29 @@ func (r *DescribeGroupsResponse) headerVersion() int16 {
 	return 0
 }
 
+func (r *DescribeGroupsResponse) isValidVersion() bool {
+	return r.Version >= 0 && r.Version <= 4
+}
+
 func (r *DescribeGroupsResponse) requiredVersion() KafkaVersion {
 	switch r.Version {
-	case 1:
-		return V1_1_0_0
-	case 2:
-		return V2_0_0_0
+	case 4:
+		return V2_4_0_0
 	case 3:
 		return V2_3_0_0
-	case 4:
+	case 2:
+		return V2_0_0_0
+	case 1:
+		return V0_11_0_0
+	case 0:
+		return V0_9_0_0
+	default:
 		return V2_4_0_0
 	}
-	return V0_9_0_0
+}
+
+func (r *DescribeGroupsResponse) throttleTime() time.Duration {
+	return time.Duration(r.ThrottleTimeMs) * time.Millisecond
 }
 
 // GroupDescription contains each described group.

+ 7 - 0
vendor/github.com/IBM/sarama/describe_log_dirs_request.go

@@ -82,6 +82,13 @@ func (r *DescribeLogDirsRequest) headerVersion() int16 {
 	return 1
 }
 
+func (r *DescribeLogDirsRequest) isValidVersion() bool {
+	return r.Version >= 0 && r.Version <= 1
+}
+
 func (r *DescribeLogDirsRequest) requiredVersion() KafkaVersion {
+	if r.Version > 0 {
+		return V2_0_0_0
+	}
 	return V1_0_0_0
 }

+ 11 - 0
vendor/github.com/IBM/sarama/describe_log_dirs_response.go

@@ -65,10 +65,21 @@ func (r *DescribeLogDirsResponse) headerVersion() int16 {
 	return 0
 }
 
+func (r *DescribeLogDirsResponse) isValidVersion() bool {
+	return r.Version >= 0 && r.Version <= 1
+}
+
 func (r *DescribeLogDirsResponse) requiredVersion() KafkaVersion {
+	if r.Version > 0 {
+		return V2_0_0_0
+	}
 	return V1_0_0_0
 }
 
+func (r *DescribeLogDirsResponse) throttleTime() time.Duration {
+	return r.ThrottleTime
+}
+
 type DescribeLogDirsResponseDirMetadata struct {
 	ErrorCode KError
 

+ 4 - 0
vendor/github.com/IBM/sarama/describe_user_scram_credentials_request.go

@@ -65,6 +65,10 @@ func (r *DescribeUserScramCredentialsRequest) headerVersion() int16 {
 	return 2
 }
 
+func (r *DescribeUserScramCredentialsRequest) isValidVersion() bool {
+	return r.Version == 0
+}
+
 func (r *DescribeUserScramCredentialsRequest) requiredVersion() KafkaVersion {
 	return V2_7_0_0
 }

+ 8 - 0
vendor/github.com/IBM/sarama/describe_user_scram_credentials_response.go

@@ -163,6 +163,14 @@ func (r *DescribeUserScramCredentialsResponse) headerVersion() int16 {
 	return 2
 }
 
+func (r *DescribeUserScramCredentialsResponse) isValidVersion() bool {
+	return r.Version == 0
+}
+
 func (r *DescribeUserScramCredentialsResponse) requiredVersion() KafkaVersion {
 	return V2_7_0_0
 }
+
+func (r *DescribeUserScramCredentialsResponse) throttleTime() time.Duration {
+	return r.ThrottleTime
+}

+ 146 - 11
vendor/github.com/IBM/sarama/docker-compose.yml

@@ -1,7 +1,9 @@
-version: '3.7'
+version: '3.9'
 services:
   zookeeper-1:
+    hostname: 'zookeeper-1'
     image: 'docker.io/library/zookeeper:3.6.3'
+    init: true
     restart: always
     environment:
       ZOO_MY_ID: '1'
@@ -12,7 +14,9 @@ services:
       ZOO_MAX_CLIENT_CNXNS: '0'
       ZOO_4LW_COMMANDS_WHITELIST: 'mntr,conf,ruok'
   zookeeper-2:
+    hostname: 'zookeeper-2'
     image: 'docker.io/library/zookeeper:3.6.3'
+    init: true
     restart: always
     environment:
       ZOO_MY_ID: '2'
@@ -23,7 +27,9 @@ services:
       ZOO_MAX_CLIENT_CNXNS: '0'
       ZOO_4LW_COMMANDS_WHITELIST: 'mntr,conf,ruok'
   zookeeper-3:
+    hostname: 'zookeeper-3'
     image: 'docker.io/library/zookeeper:3.6.3'
+    init: true
     restart: always
     environment:
       ZOO_MY_ID: '3'
@@ -34,13 +40,35 @@ services:
       ZOO_MAX_CLIENT_CNXNS: '0'
       ZOO_4LW_COMMANDS_WHITELIST: 'mntr,conf,ruok'
   kafka-1:
-    image: 'sarama/fv-kafka'
+    hostname: 'kafka-1'
+    image: 'sarama/fv-kafka-${KAFKA_VERSION:-3.6.0}'
+    init: true
     build:
       context: .
       dockerfile: Dockerfile.kafka
+      args:
+        KAFKA_VERSION: ${KAFKA_VERSION:-3.6.0}
+        SCALA_VERSION: ${SCALA_VERSION:-2.13}
+    healthcheck:
+      test:
+        [
+          'CMD',
+          '/opt/kafka-${KAFKA_VERSION:-3.6.0}/bin/kafka-broker-api-versions.sh',
+          '--bootstrap-server',
+          'kafka-1:9091',
+        ]
+      interval: 15s
+      timeout: 15s
+      retries: 10
+      start_period: 360s
+    depends_on:
+      - zookeeper-1
+      - zookeeper-2
+      - zookeeper-3
+      - toxiproxy
     restart: always
     environment:
-      KAFKA_VERSION: ${KAFKA_VERSION:-3.3.2}
+      KAFKA_VERSION: ${KAFKA_VERSION:-3.6.0}
       KAFKA_CFG_ZOOKEEPER_CONNECT: 'zookeeper-1:2181,zookeeper-2:2181,zookeeper-3:2181'
       KAFKA_CFG_LISTENERS: 'LISTENER_INTERNAL://:9091,LISTENER_LOCAL://:29091'
       KAFKA_CFG_ADVERTISED_LISTENERS: 'LISTENER_INTERNAL://kafka-1:9091,LISTENER_LOCAL://localhost:29091'
@@ -55,14 +83,38 @@ services:
       KAFKA_CFG_REPLICA_SELECTOR_CLASS: 'org.apache.kafka.common.replica.RackAwareReplicaSelector'
       KAFKA_CFG_DELETE_TOPIC_ENABLE: 'true'
       KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE: 'false'
+      KAFKA_CFG_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
+      KAFKA_JVM_PERFORMANCE_OPTS: "-XX:+IgnoreUnrecognizedVMOptions"
   kafka-2:
-    image: 'sarama/fv-kafka'
+    hostname: 'kafka-2'
+    image: 'sarama/fv-kafka-${KAFKA_VERSION:-3.6.0}'
+    init: true
     build:
       context: .
       dockerfile: Dockerfile.kafka
+      args:
+        KAFKA_VERSION: ${KAFKA_VERSION:-3.6.0}
+        SCALA_VERSION: ${SCALA_VERSION:-2.13}
+    healthcheck:
+      test:
+        [
+          'CMD',
+          '/opt/kafka-${KAFKA_VERSION:-3.6.0}/bin/kafka-broker-api-versions.sh',
+          '--bootstrap-server',
+          'kafka-2:9091',
+        ]
+      interval: 15s
+      timeout: 15s
+      retries: 10
+      start_period: 360s
+    depends_on:
+      - zookeeper-1
+      - zookeeper-2
+      - zookeeper-3
+      - toxiproxy
     restart: always
     environment:
-      KAFKA_VERSION: ${KAFKA_VERSION:-3.3.2}
+      KAFKA_VERSION: ${KAFKA_VERSION:-3.6.0}
       KAFKA_CFG_ZOOKEEPER_CONNECT: 'zookeeper-1:2181,zookeeper-2:2181,zookeeper-3:2181'
       KAFKA_CFG_LISTENERS: 'LISTENER_INTERNAL://:9091,LISTENER_LOCAL://:29092'
       KAFKA_CFG_ADVERTISED_LISTENERS: 'LISTENER_INTERNAL://kafka-2:9091,LISTENER_LOCAL://localhost:29092'
@@ -77,14 +129,38 @@ services:
       KAFKA_CFG_REPLICA_SELECTOR_CLASS: 'org.apache.kafka.common.replica.RackAwareReplicaSelector'
       KAFKA_CFG_DELETE_TOPIC_ENABLE: 'true'
       KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE: 'false'
+      KAFKA_CFG_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
+      KAFKA_JVM_PERFORMANCE_OPTS: "-XX:+IgnoreUnrecognizedVMOptions"
   kafka-3:
-    image: 'sarama/fv-kafka'
+    hostname: 'kafka-3'
+    image: 'sarama/fv-kafka-${KAFKA_VERSION:-3.6.0}'
+    init: true
     build:
       context: .
       dockerfile: Dockerfile.kafka
+      args:
+        KAFKA_VERSION: ${KAFKA_VERSION:-3.6.0}
+        SCALA_VERSION: ${SCALA_VERSION:-2.13}
+    healthcheck:
+      test:
+        [
+          'CMD',
+          '/opt/kafka-${KAFKA_VERSION:-3.6.0}/bin/kafka-broker-api-versions.sh',
+          '--bootstrap-server',
+          'kafka-3:9091',
+        ]
+      interval: 15s
+      timeout: 15s
+      retries: 10
+      start_period: 360s
+    depends_on:
+      - zookeeper-1
+      - zookeeper-2
+      - zookeeper-3
+      - toxiproxy
     restart: always
     environment:
-      KAFKA_VERSION: ${KAFKA_VERSION:-3.3.2}
+      KAFKA_VERSION: ${KAFKA_VERSION:-3.6.0}
       KAFKA_CFG_ZOOKEEPER_CONNECT: 'zookeeper-1:2181,zookeeper-2:2181,zookeeper-3:2181'
       KAFKA_CFG_LISTENERS: 'LISTENER_INTERNAL://:9091,LISTENER_LOCAL://:29093'
       KAFKA_CFG_ADVERTISED_LISTENERS: 'LISTENER_INTERNAL://kafka-3:9091,LISTENER_LOCAL://localhost:29093'
@@ -99,14 +175,38 @@ services:
       KAFKA_CFG_REPLICA_SELECTOR_CLASS: 'org.apache.kafka.common.replica.RackAwareReplicaSelector'
       KAFKA_CFG_DELETE_TOPIC_ENABLE: 'true'
       KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE: 'false'
+      KAFKA_CFG_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
+      KAFKA_JVM_PERFORMANCE_OPTS: "-XX:+IgnoreUnrecognizedVMOptions"
   kafka-4:
-    image: 'sarama/fv-kafka'
+    hostname: 'kafka-4'
+    image: 'sarama/fv-kafka-${KAFKA_VERSION:-3.6.0}'
+    init: true
     build:
       context: .
       dockerfile: Dockerfile.kafka
+      args:
+        KAFKA_VERSION: ${KAFKA_VERSION:-3.6.0}
+        SCALA_VERSION: ${SCALA_VERSION:-2.13}
+    healthcheck:
+      test:
+        [
+          'CMD',
+          '/opt/kafka-${KAFKA_VERSION:-3.6.0}/bin/kafka-broker-api-versions.sh',
+          '--bootstrap-server',
+          'kafka-4:9091',
+        ]
+      interval: 15s
+      timeout: 15s
+      retries: 10
+      start_period: 360s
+    depends_on:
+      - zookeeper-1
+      - zookeeper-2
+      - zookeeper-3
+      - toxiproxy
     restart: always
     environment:
-      KAFKA_VERSION: ${KAFKA_VERSION:-3.3.2}
+      KAFKA_VERSION: ${KAFKA_VERSION:-3.6.0}
       KAFKA_CFG_ZOOKEEPER_CONNECT: 'zookeeper-1:2181,zookeeper-2:2181,zookeeper-3:2181'
       KAFKA_CFG_LISTENERS: 'LISTENER_INTERNAL://:9091,LISTENER_LOCAL://:29094'
       KAFKA_CFG_ADVERTISED_LISTENERS: 'LISTENER_INTERNAL://kafka-4:9091,LISTENER_LOCAL://localhost:29094'
@@ -121,14 +221,38 @@ services:
       KAFKA_CFG_REPLICA_SELECTOR_CLASS: 'org.apache.kafka.common.replica.RackAwareReplicaSelector'
       KAFKA_CFG_DELETE_TOPIC_ENABLE: 'true'
       KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE: 'false'
+      KAFKA_CFG_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
+      KAFKA_JVM_PERFORMANCE_OPTS: "-XX:+IgnoreUnrecognizedVMOptions"
   kafka-5:
-    image: 'sarama/fv-kafka'
+    hostname: 'kafka-5'
+    image: 'sarama/fv-kafka-${KAFKA_VERSION:-3.6.0}'
+    init: true
     build:
       context: .
       dockerfile: Dockerfile.kafka
+      args:
+        KAFKA_VERSION: ${KAFKA_VERSION:-3.6.0}
+        SCALA_VERSION: ${SCALA_VERSION:-2.13}
+    healthcheck:
+      test:
+        [
+          'CMD',
+          '/opt/kafka-${KAFKA_VERSION:-3.6.0}/bin/kafka-broker-api-versions.sh',
+          '--bootstrap-server',
+          'kafka-5:9091',
+        ]
+      interval: 15s
+      timeout: 15s
+      retries: 10
+      start_period: 360s
+    depends_on:
+      - zookeeper-1
+      - zookeeper-2
+      - zookeeper-3
+      - toxiproxy
     restart: always
     environment:
-      KAFKA_VERSION: ${KAFKA_VERSION:-3.3.2}
+      KAFKA_VERSION: ${KAFKA_VERSION:-3.6.0}
       KAFKA_CFG_ZOOKEEPER_CONNECT: 'zookeeper-1:2181,zookeeper-2:2181,zookeeper-3:2181'
       KAFKA_CFG_LISTENERS: 'LISTENER_INTERNAL://:9091,LISTENER_LOCAL://:29095'
       KAFKA_CFG_ADVERTISED_LISTENERS: 'LISTENER_INTERNAL://kafka-5:9091,LISTENER_LOCAL://localhost:29095'
@@ -143,8 +267,18 @@ services:
       KAFKA_CFG_REPLICA_SELECTOR_CLASS: 'org.apache.kafka.common.replica.RackAwareReplicaSelector'
       KAFKA_CFG_DELETE_TOPIC_ENABLE: 'true'
       KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE: 'false'
+      KAFKA_CFG_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
+      KAFKA_JVM_PERFORMANCE_OPTS: "-XX:+IgnoreUnrecognizedVMOptions"
   toxiproxy:
+    hostname: 'toxiproxy'
     image: 'ghcr.io/shopify/toxiproxy:2.4.0'
+    init: true
+    healthcheck:
+      test: ['CMD', '/toxiproxy-cli', 'l']
+      interval: 15s
+      timeout: 15s
+      retries: 3
+      start_period: 30s
     ports:
       # The tests themselves actually start the proxies on these ports
       - '29091:29091'
@@ -152,5 +286,6 @@ services:
       - '29093:29093'
       - '29094:29094'
       - '29095:29095'
+
       # This is the toxiproxy API port
       - '8474:8474'

+ 14 - 2
vendor/github.com/IBM/sarama/end_txn_request.go

@@ -1,6 +1,7 @@
 package sarama
 
 type EndTxnRequest struct {
+	Version           int16
 	TransactionalID   string
 	ProducerID        int64
 	ProducerEpoch     int16
@@ -42,13 +43,24 @@ func (a *EndTxnRequest) key() int16 {
 }
 
 func (a *EndTxnRequest) version() int16 {
-	return 0
+	return a.Version
 }
 
 func (r *EndTxnRequest) headerVersion() int16 {
 	return 1
 }
 
+func (a *EndTxnRequest) isValidVersion() bool {
+	return a.Version >= 0 && a.Version <= 2
+}
+
 func (a *EndTxnRequest) requiredVersion() KafkaVersion {
-	return V0_11_0_0
+	switch a.Version {
+	case 2:
+		return V2_7_0_0
+	case 1:
+		return V2_0_0_0
+	default:
+		return V0_11_0_0
+	}
 }

+ 18 - 2
vendor/github.com/IBM/sarama/end_txn_response.go

@@ -5,6 +5,7 @@ import (
 )
 
 type EndTxnResponse struct {
+	Version      int16
 	ThrottleTime time.Duration
 	Err          KError
 }
@@ -36,13 +37,28 @@ func (e *EndTxnResponse) key() int16 {
 }
 
 func (e *EndTxnResponse) version() int16 {
-	return 0
+	return e.Version
 }
 
 func (r *EndTxnResponse) headerVersion() int16 {
 	return 0
 }
 
+func (e *EndTxnResponse) isValidVersion() bool {
+	return e.Version >= 0 && e.Version <= 2
+}
+
 func (e *EndTxnResponse) requiredVersion() KafkaVersion {
-	return V0_11_0_0
+	switch e.Version {
+	case 2:
+		return V2_7_0_0
+	case 1:
+		return V2_0_0_0
+	default:
+		return V0_11_0_0
+	}
+}
+
+func (r *EndTxnResponse) throttleTime() time.Duration {
+	return r.ThrottleTime
 }

+ 12 - 7
vendor/github.com/IBM/sarama/entrypoint.sh

@@ -1,6 +1,9 @@
 #!/bin/bash
 
-KAFKA_VERSION="${KAFKA_VERSION:-3.3.2}"
+set -eu
+set -o pipefail
+
+KAFKA_VERSION="${KAFKA_VERSION:-3.6.0}"
 KAFKA_HOME="/opt/kafka-${KAFKA_VERSION}"
 
 if [ ! -d "${KAFKA_HOME}" ]; then
@@ -10,17 +13,19 @@ fi
 
 cd "${KAFKA_HOME}" || exit 1
 
-# discard all empty/commented lines
-sed -e '/^#/d' -e '/^$/d' -i"" config/server.properties
+# discard all empty/commented lines from default config and copy to /tmp
+sed -e '/^#/d' -e '/^$/d' config/server.properties >/tmp/server.properties
+
+echo "########################################################################" >>/tmp/server.properties
 
 # emulate kafka_configure_from_environment_variables from bitnami/bitnami-docker-kafka
 for var in "${!KAFKA_CFG_@}"; do
     key="$(echo "$var" | sed -e 's/^KAFKA_CFG_//g' -e 's/_/\./g' -e 's/.*/\L&/')"
-    sed -e '/^'$key'/d' -i"" config/server.properties
+    sed -e '/^'$key'/d' -i"" /tmp/server.properties
     value="${!var}"
-    echo "$key=$value" >>config/server.properties
+    echo "$key=$value" >>/tmp/server.properties
 done
 
-sort config/server.properties
+sort /tmp/server.properties
 
-exec bin/kafka-server-start.sh config/server.properties
+exec bin/kafka-server-start.sh /tmp/server.properties

+ 95 - 95
vendor/github.com/IBM/sarama/errors.go

@@ -79,7 +79,7 @@ var ErrTransactionNotReady = errors.New("transaction manager: transaction is not
 // ErrNonTransactedProducer when calling BeginTxn, CommitTxn or AbortTxn on a non transactional producer.
 var ErrNonTransactedProducer = errors.New("transaction manager: you need to add TransactionalID to producer")
 
-// ErrTransitionNotAllowed when txnmgr state transiion is not valid.
+// ErrTransitionNotAllowed when txnmgr state transition is not valid.
 var ErrTransitionNotAllowed = errors.New("transaction manager: invalid transition attempted")
 
 // ErrCannotTransitionNilError when transition is attempted with an nil error.
@@ -89,7 +89,7 @@ var ErrCannotTransitionNilError = errors.New("transaction manager: cannot transi
 var ErrTxnUnableToParseResponse = errors.New("transaction manager: unable to parse response")
 
 // MultiErrorFormat specifies the formatter applied to format multierrors. The
-// default implementation is a consensed version of the hashicorp/go-multierror
+// default implementation is a condensed version of the hashicorp/go-multierror
 // default one
 var MultiErrorFormat multierror.ErrorFormatFunc = func(es []error) string {
 	if len(es) == 1 {
@@ -173,98 +173,98 @@ type KError int16
 
 // Numeric error codes returned by the Kafka server.
 const (
-	ErrNoError                            KError = 0
-	ErrUnknown                            KError = -1
-	ErrOffsetOutOfRange                   KError = 1
-	ErrInvalidMessage                     KError = 2
-	ErrUnknownTopicOrPartition            KError = 3
-	ErrInvalidMessageSize                 KError = 4
-	ErrLeaderNotAvailable                 KError = 5
-	ErrNotLeaderForPartition              KError = 6
-	ErrRequestTimedOut                    KError = 7
-	ErrBrokerNotAvailable                 KError = 8
-	ErrReplicaNotAvailable                KError = 9
-	ErrMessageSizeTooLarge                KError = 10
-	ErrStaleControllerEpochCode           KError = 11
-	ErrOffsetMetadataTooLarge             KError = 12
-	ErrNetworkException                   KError = 13
-	ErrOffsetsLoadInProgress              KError = 14
-	ErrConsumerCoordinatorNotAvailable    KError = 15
-	ErrNotCoordinatorForConsumer          KError = 16
-	ErrInvalidTopic                       KError = 17
-	ErrMessageSetSizeTooLarge             KError = 18
-	ErrNotEnoughReplicas                  KError = 19
-	ErrNotEnoughReplicasAfterAppend       KError = 20
-	ErrInvalidRequiredAcks                KError = 21
-	ErrIllegalGeneration                  KError = 22
-	ErrInconsistentGroupProtocol          KError = 23
-	ErrInvalidGroupId                     KError = 24
-	ErrUnknownMemberId                    KError = 25
-	ErrInvalidSessionTimeout              KError = 26
-	ErrRebalanceInProgress                KError = 27
-	ErrInvalidCommitOffsetSize            KError = 28
-	ErrTopicAuthorizationFailed           KError = 29
-	ErrGroupAuthorizationFailed           KError = 30
-	ErrClusterAuthorizationFailed         KError = 31
-	ErrInvalidTimestamp                   KError = 32
-	ErrUnsupportedSASLMechanism           KError = 33
-	ErrIllegalSASLState                   KError = 34
-	ErrUnsupportedVersion                 KError = 35
-	ErrTopicAlreadyExists                 KError = 36
-	ErrInvalidPartitions                  KError = 37
-	ErrInvalidReplicationFactor           KError = 38
-	ErrInvalidReplicaAssignment           KError = 39
-	ErrInvalidConfig                      KError = 40
-	ErrNotController                      KError = 41
-	ErrInvalidRequest                     KError = 42
-	ErrUnsupportedForMessageFormat        KError = 43
-	ErrPolicyViolation                    KError = 44
-	ErrOutOfOrderSequenceNumber           KError = 45
-	ErrDuplicateSequenceNumber            KError = 46
-	ErrInvalidProducerEpoch               KError = 47
-	ErrInvalidTxnState                    KError = 48
-	ErrInvalidProducerIDMapping           KError = 49
-	ErrInvalidTransactionTimeout          KError = 50
-	ErrConcurrentTransactions             KError = 51
-	ErrTransactionCoordinatorFenced       KError = 52
-	ErrTransactionalIDAuthorizationFailed KError = 53
-	ErrSecurityDisabled                   KError = 54
-	ErrOperationNotAttempted              KError = 55
-	ErrKafkaStorageError                  KError = 56
-	ErrLogDirNotFound                     KError = 57
-	ErrSASLAuthenticationFailed           KError = 58
-	ErrUnknownProducerID                  KError = 59
-	ErrReassignmentInProgress             KError = 60
-	ErrDelegationTokenAuthDisabled        KError = 61
-	ErrDelegationTokenNotFound            KError = 62
-	ErrDelegationTokenOwnerMismatch       KError = 63
-	ErrDelegationTokenRequestNotAllowed   KError = 64
-	ErrDelegationTokenAuthorizationFailed KError = 65
-	ErrDelegationTokenExpired             KError = 66
-	ErrInvalidPrincipalType               KError = 67
-	ErrNonEmptyGroup                      KError = 68
-	ErrGroupIDNotFound                    KError = 69
-	ErrFetchSessionIDNotFound             KError = 70
-	ErrInvalidFetchSessionEpoch           KError = 71
-	ErrListenerNotFound                   KError = 72
-	ErrTopicDeletionDisabled              KError = 73
-	ErrFencedLeaderEpoch                  KError = 74
-	ErrUnknownLeaderEpoch                 KError = 75
-	ErrUnsupportedCompressionType         KError = 76
-	ErrStaleBrokerEpoch                   KError = 77
-	ErrOffsetNotAvailable                 KError = 78
-	ErrMemberIdRequired                   KError = 79
-	ErrPreferredLeaderNotAvailable        KError = 80
-	ErrGroupMaxSizeReached                KError = 81
-	ErrFencedInstancedId                  KError = 82
-	ErrEligibleLeadersNotAvailable        KError = 83
-	ErrElectionNotNeeded                  KError = 84
-	ErrNoReassignmentInProgress           KError = 85
-	ErrGroupSubscribedToTopic             KError = 86
-	ErrInvalidRecord                      KError = 87
-	ErrUnstableOffsetCommit               KError = 88
-	ErrThrottlingQuotaExceeded            KError = 89
-	ErrProducerFenced                     KError = 90
+	ErrUnknown                            KError = -1 // Errors.UNKNOWN_SERVER_ERROR
+	ErrNoError                            KError = 0  // Errors.NONE
+	ErrOffsetOutOfRange                   KError = 1  // Errors.OFFSET_OUT_OF_RANGE
+	ErrInvalidMessage                     KError = 2  // Errors.CORRUPT_MESSAGE
+	ErrUnknownTopicOrPartition            KError = 3  // Errors.UNKNOWN_TOPIC_OR_PARTITION
+	ErrInvalidMessageSize                 KError = 4  // Errors.INVALID_FETCH_SIZE
+	ErrLeaderNotAvailable                 KError = 5  // Errors.LEADER_NOT_AVAILABLE
+	ErrNotLeaderForPartition              KError = 6  // Errors.NOT_LEADER_OR_FOLLOWER
+	ErrRequestTimedOut                    KError = 7  // Errors.REQUEST_TIMED_OUT
+	ErrBrokerNotAvailable                 KError = 8  // Errors.BROKER_NOT_AVAILABLE
+	ErrReplicaNotAvailable                KError = 9  // Errors.REPLICA_NOT_AVAILABLE
+	ErrMessageSizeTooLarge                KError = 10 // Errors.MESSAGE_TOO_LARGE
+	ErrStaleControllerEpochCode           KError = 11 // Errors.STALE_CONTROLLER_EPOCH
+	ErrOffsetMetadataTooLarge             KError = 12 // Errors.OFFSET_METADATA_TOO_LARGE
+	ErrNetworkException                   KError = 13 // Errors.NETWORK_EXCEPTION
+	ErrOffsetsLoadInProgress              KError = 14 // Errors.COORDINATOR_LOAD_IN_PROGRESS
+	ErrConsumerCoordinatorNotAvailable    KError = 15 // Errors.COORDINATOR_NOT_AVAILABLE
+	ErrNotCoordinatorForConsumer          KError = 16 // Errors.NOT_COORDINATOR
+	ErrInvalidTopic                       KError = 17 // Errors.INVALID_TOPIC_EXCEPTION
+	ErrMessageSetSizeTooLarge             KError = 18 // Errors.RECORD_LIST_TOO_LARGE
+	ErrNotEnoughReplicas                  KError = 19 // Errors.NOT_ENOUGH_REPLICAS
+	ErrNotEnoughReplicasAfterAppend       KError = 20 // Errors.NOT_ENOUGH_REPLICAS_AFTER_APPEND
+	ErrInvalidRequiredAcks                KError = 21 // Errors.INVALID_REQUIRED_ACKS
+	ErrIllegalGeneration                  KError = 22 // Errors.ILLEGAL_GENERATION
+	ErrInconsistentGroupProtocol          KError = 23 // Errors.INCONSISTENT_GROUP_PROTOCOL
+	ErrInvalidGroupId                     KError = 24 // Errors.INVALID_GROUP_ID
+	ErrUnknownMemberId                    KError = 25 // Errors.UNKNOWN_MEMBER_ID
+	ErrInvalidSessionTimeout              KError = 26 // Errors.INVALID_SESSION_TIMEOUT
+	ErrRebalanceInProgress                KError = 27 // Errors.REBALANCE_IN_PROGRESS
+	ErrInvalidCommitOffsetSize            KError = 28 // Errors.INVALID_COMMIT_OFFSET_SIZE
+	ErrTopicAuthorizationFailed           KError = 29 // Errors.TOPIC_AUTHORIZATION_FAILED
+	ErrGroupAuthorizationFailed           KError = 30 // Errors.GROUP_AUTHORIZATION_FAILED
+	ErrClusterAuthorizationFailed         KError = 31 // Errors.CLUSTER_AUTHORIZATION_FAILED
+	ErrInvalidTimestamp                   KError = 32 // Errors.INVALID_TIMESTAMP
+	ErrUnsupportedSASLMechanism           KError = 33 // Errors.UNSUPPORTED_SASL_MECHANISM
+	ErrIllegalSASLState                   KError = 34 // Errors.ILLEGAL_SASL_STATE
+	ErrUnsupportedVersion                 KError = 35 // Errors.UNSUPPORTED_VERSION
+	ErrTopicAlreadyExists                 KError = 36 // Errors.TOPIC_ALREADY_EXISTS
+	ErrInvalidPartitions                  KError = 37 // Errors.INVALID_PARTITIONS
+	ErrInvalidReplicationFactor           KError = 38 // Errors.INVALID_REPLICATION_FACTOR
+	ErrInvalidReplicaAssignment           KError = 39 // Errors.INVALID_REPLICA_ASSIGNMENT
+	ErrInvalidConfig                      KError = 40 // Errors.INVALID_CONFIG
+	ErrNotController                      KError = 41 // Errors.NOT_CONTROLLER
+	ErrInvalidRequest                     KError = 42 // Errors.INVALID_REQUEST
+	ErrUnsupportedForMessageFormat        KError = 43 // Errors.UNSUPPORTED_FOR_MESSAGE_FORMAT
+	ErrPolicyViolation                    KError = 44 // Errors.POLICY_VIOLATION
+	ErrOutOfOrderSequenceNumber           KError = 45 // Errors.OUT_OF_ORDER_SEQUENCE_NUMBER
+	ErrDuplicateSequenceNumber            KError = 46 // Errors.DUPLICATE_SEQUENCE_NUMBER
+	ErrInvalidProducerEpoch               KError = 47 // Errors.INVALID_PRODUCER_EPOCH
+	ErrInvalidTxnState                    KError = 48 // Errors.INVALID_TXN_STATE
+	ErrInvalidProducerIDMapping           KError = 49 // Errors.INVALID_PRODUCER_ID_MAPPING
+	ErrInvalidTransactionTimeout          KError = 50 // Errors.INVALID_TRANSACTION_TIMEOUT
+	ErrConcurrentTransactions             KError = 51 // Errors.CONCURRENT_TRANSACTIONS
+	ErrTransactionCoordinatorFenced       KError = 52 // Errors.TRANSACTION_COORDINATOR_FENCED
+	ErrTransactionalIDAuthorizationFailed KError = 53 // Errors.TRANSACTIONAL_ID_AUTHORIZATION_FAILED
+	ErrSecurityDisabled                   KError = 54 // Errors.SECURITY_DISABLED
+	ErrOperationNotAttempted              KError = 55 // Errors.OPERATION_NOT_ATTEMPTED
+	ErrKafkaStorageError                  KError = 56 // Errors.KAFKA_STORAGE_ERROR
+	ErrLogDirNotFound                     KError = 57 // Errors.LOG_DIR_NOT_FOUND
+	ErrSASLAuthenticationFailed           KError = 58 // Errors.SASL_AUTHENTICATION_FAILED
+	ErrUnknownProducerID                  KError = 59 // Errors.UNKNOWN_PRODUCER_ID
+	ErrReassignmentInProgress             KError = 60 // Errors.REASSIGNMENT_IN_PROGRESS
+	ErrDelegationTokenAuthDisabled        KError = 61 // Errors.DELEGATION_TOKEN_AUTH_DISABLED
+	ErrDelegationTokenNotFound            KError = 62 // Errors.DELEGATION_TOKEN_NOT_FOUND
+	ErrDelegationTokenOwnerMismatch       KError = 63 // Errors.DELEGATION_TOKEN_OWNER_MISMATCH
+	ErrDelegationTokenRequestNotAllowed   KError = 64 // Errors.DELEGATION_TOKEN_REQUEST_NOT_ALLOWED
+	ErrDelegationTokenAuthorizationFailed KError = 65 // Errors.DELEGATION_TOKEN_AUTHORIZATION_FAILED
+	ErrDelegationTokenExpired             KError = 66 // Errors.DELEGATION_TOKEN_EXPIRED
+	ErrInvalidPrincipalType               KError = 67 // Errors.INVALID_PRINCIPAL_TYPE
+	ErrNonEmptyGroup                      KError = 68 // Errors.NON_EMPTY_GROUP
+	ErrGroupIDNotFound                    KError = 69 // Errors.GROUP_ID_NOT_FOUND
+	ErrFetchSessionIDNotFound             KError = 70 // Errors.FETCH_SESSION_ID_NOT_FOUND
+	ErrInvalidFetchSessionEpoch           KError = 71 // Errors.INVALID_FETCH_SESSION_EPOCH
+	ErrListenerNotFound                   KError = 72 // Errors.LISTENER_NOT_FOUND
+	ErrTopicDeletionDisabled              KError = 73 // Errors.TOPIC_DELETION_DISABLED
+	ErrFencedLeaderEpoch                  KError = 74 // Errors.FENCED_LEADER_EPOCH
+	ErrUnknownLeaderEpoch                 KError = 75 // Errors.UNKNOWN_LEADER_EPOCH
+	ErrUnsupportedCompressionType         KError = 76 // Errors.UNSUPPORTED_COMPRESSION_TYPE
+	ErrStaleBrokerEpoch                   KError = 77 // Errors.STALE_BROKER_EPOCH
+	ErrOffsetNotAvailable                 KError = 78 // Errors.OFFSET_NOT_AVAILABLE
+	ErrMemberIdRequired                   KError = 79 // Errors.MEMBER_ID_REQUIRED
+	ErrPreferredLeaderNotAvailable        KError = 80 // Errors.PREFERRED_LEADER_NOT_AVAILABLE
+	ErrGroupMaxSizeReached                KError = 81 // Errors.GROUP_MAX_SIZE_REACHED
+	ErrFencedInstancedId                  KError = 82 // Errors.FENCED_INSTANCE_ID
+	ErrEligibleLeadersNotAvailable        KError = 83 // Errors.ELIGIBLE_LEADERS_NOT_AVAILABLE
+	ErrElectionNotNeeded                  KError = 84 // Errors.ELECTION_NOT_NEEDED
+	ErrNoReassignmentInProgress           KError = 85 // Errors.NO_REASSIGNMENT_IN_PROGRESS
+	ErrGroupSubscribedToTopic             KError = 86 // Errors.GROUP_SUBSCRIBED_TO_TOPIC
+	ErrInvalidRecord                      KError = 87 // Errors.INVALID_RECORD
+	ErrUnstableOffsetCommit               KError = 88 // Errors.UNSTABLE_OFFSET_COMMIT
+	ErrThrottlingQuotaExceeded            KError = 89 // Errors.THROTTLING_QUOTA_EXCEEDED
+	ErrProducerFenced                     KError = 90 // Errors.PRODUCER_FENCED
 )
 
 func (err KError) Error() string {
@@ -302,7 +302,7 @@ func (err KError) Error() string {
 	case ErrNetworkException:
 		return "kafka server: The server disconnected before a response was received"
 	case ErrOffsetsLoadInProgress:
-		return "kafka server: The broker is still loading offsets after a leader change for that offset's topic partition"
+		return "kafka server: The coordinator is still loading offsets and cannot currently process requests"
 	case ErrConsumerCoordinatorNotAvailable:
 		return "kafka server: Offset's topic has not yet been created"
 	case ErrNotCoordinatorForConsumer:

+ 28 - 19
vendor/github.com/IBM/sarama/fetch_request.go

@@ -1,5 +1,7 @@
 package sarama
 
+import "fmt"
+
 type fetchRequestBlock struct {
 	Version int16
 	// currentLeaderEpoch contains the current leader epoch of the partition.
@@ -241,6 +243,9 @@ func (r *FetchRequest) decode(pd packetDecoder, version int16) (err error) {
 			if err != nil {
 				return err
 			}
+			if partitionCount < 0 {
+				return fmt.Errorf("partitionCount %d is invalid", partitionCount)
+			}
 			r.forgotten[topic] = make([]int32, partitionCount)
 
 			for j := 0; j < partitionCount; j++ {
@@ -275,30 +280,34 @@ func (r *FetchRequest) headerVersion() int16 {
 	return 1
 }
 
+func (r *FetchRequest) isValidVersion() bool {
+	return r.Version >= 0 && r.Version <= 11
+}
+
 func (r *FetchRequest) requiredVersion() KafkaVersion {
 	switch r.Version {
-	case 0:
-		return MinVersion
-	case 1:
-		return V0_9_0_0
-	case 2:
-		return V0_10_0_0
-	case 3:
-		return V0_10_1_0
-	case 4, 5:
-		return V0_11_0_0
-	case 6:
-		return V1_0_0_0
-	case 7:
-		return V1_1_0_0
-	case 8:
-		return V2_0_0_0
-	case 9, 10:
-		return V2_1_0_0
 	case 11:
 		return V2_3_0_0
+	case 9, 10:
+		return V2_1_0_0
+	case 8:
+		return V2_0_0_0
+	case 7:
+		return V1_1_0_0
+	case 6:
+		return V1_0_0_0
+	case 4, 5:
+		return V0_11_0_0
+	case 3:
+		return V0_10_1_0
+	case 2:
+		return V0_10_0_0
+	case 1:
+		return V0_9_0_0
+	case 0:
+		return V0_8_2_0
 	default:
-		return MaxVersion
+		return V2_3_0_0
 	}
 }
 

+ 27 - 19
vendor/github.com/IBM/sarama/fetch_response.go

@@ -386,33 +386,41 @@ func (r *FetchResponse) headerVersion() int16 {
 	return 0
 }
 
+func (r *FetchResponse) isValidVersion() bool {
+	return r.Version >= 0 && r.Version <= 11
+}
+
 func (r *FetchResponse) requiredVersion() KafkaVersion {
 	switch r.Version {
-	case 0:
-		return MinVersion
-	case 1:
-		return V0_9_0_0
-	case 2:
-		return V0_10_0_0
-	case 3:
-		return V0_10_1_0
-	case 4, 5:
-		return V0_11_0_0
-	case 6:
-		return V1_0_0_0
-	case 7:
-		return V1_1_0_0
-	case 8:
-		return V2_0_0_0
-	case 9, 10:
-		return V2_1_0_0
 	case 11:
 		return V2_3_0_0
+	case 9, 10:
+		return V2_1_0_0
+	case 8:
+		return V2_0_0_0
+	case 7:
+		return V1_1_0_0
+	case 6:
+		return V1_0_0_0
+	case 4, 5:
+		return V0_11_0_0
+	case 3:
+		return V0_10_1_0
+	case 2:
+		return V0_10_0_0
+	case 1:
+		return V0_9_0_0
+	case 0:
+		return V0_8_2_0
 	default:
-		return MaxVersion
+		return V2_3_0_0
 	}
 }
 
+func (r *FetchResponse) throttleTime() time.Duration {
+	return r.ThrottleTime
+}
+
 func (r *FetchResponse) GetBlock(topic string, partition int32) *FetchResponseBlock {
 	if r.Blocks == nil {
 		return nil

+ 6 - 0
vendor/github.com/IBM/sarama/find_coordinator_request.go

@@ -55,8 +55,14 @@ func (r *FindCoordinatorRequest) headerVersion() int16 {
 	return 1
 }
 
+func (f *FindCoordinatorRequest) isValidVersion() bool {
+	return f.Version >= 0 && f.Version <= 2
+}
+
 func (f *FindCoordinatorRequest) requiredVersion() KafkaVersion {
 	switch f.Version {
+	case 2:
+		return V2_0_0_0
 	case 1:
 		return V0_11_0_0
 	default:

+ 10 - 0
vendor/github.com/IBM/sarama/find_coordinator_response.go

@@ -86,11 +86,21 @@ func (r *FindCoordinatorResponse) headerVersion() int16 {
 	return 0
 }
 
+func (f *FindCoordinatorResponse) isValidVersion() bool {
+	return f.Version >= 0 && f.Version <= 2
+}
+
 func (f *FindCoordinatorResponse) requiredVersion() KafkaVersion {
 	switch f.Version {
+	case 2:
+		return V2_0_0_0
 	case 1:
 		return V0_11_0_0
 	default:
 		return V0_8_2_0
 	}
 }
+
+func (r *FindCoordinatorResponse) throttleTime() time.Duration {
+	return r.ThrottleTime
+}

+ 12 - 2
vendor/github.com/IBM/sarama/gssapi_kerberos.go

@@ -23,6 +23,7 @@ const (
 	GSS_API_GENERIC_TAG = 0x60
 	KRB5_USER_AUTH      = 1
 	KRB5_KEYTAB_AUTH    = 2
+	KRB5_CCACHE_AUTH    = 3
 	GSS_API_INITIAL     = 1
 	GSS_API_VERIFY      = 2
 	GSS_API_FINISH      = 3
@@ -31,12 +32,14 @@ const (
 type GSSAPIConfig struct {
 	AuthType           int
 	KeyTabPath         string
+	CCachePath         string
 	KerberosConfigPath string
 	ServiceName        string
 	Username           string
 	Password           string
 	Realm              string
 	DisablePAFXFAST    bool
+	BuildSpn           BuildSpnFunc
 }
 
 type GSSAPIKerberosAuth struct {
@@ -55,6 +58,8 @@ type KerberosClient interface {
 	Destroy()
 }
 
+type BuildSpnFunc func(serviceName, host string) string
+
 // writePackage appends length in big endian before the payload, and sends it to kafka
 func (krbAuth *GSSAPIKerberosAuth) writePackage(broker *Broker, payload []byte) (int, error) {
 	length := uint64(len(payload))
@@ -209,10 +214,15 @@ func (krbAuth *GSSAPIKerberosAuth) Authorize(broker *Broker) error {
 		return err
 	}
 	// Construct SPN using serviceName and host
-	// SPN format: <SERVICE>/<FQDN>
+	// default SPN format: <SERVICE>/<FQDN>
 
 	host := strings.SplitN(broker.addr, ":", 2)[0] // Strip port part
-	spn := fmt.Sprintf("%s/%s", broker.conf.Net.SASL.GSSAPI.ServiceName, host)
+	var spn string
+	if krbAuth.Config.BuildSpn != nil {
+		spn = krbAuth.Config.BuildSpn(broker.conf.Net.SASL.GSSAPI.ServiceName, host)
+	} else {
+		spn = fmt.Sprintf("%s/%s", broker.conf.Net.SASL.GSSAPI.ServiceName, host)
+	}
 
 	ticket, encKey, err := kerberosClient.GetServiceTicket(spn)
 	if err != nil {

+ 14 - 3
vendor/github.com/IBM/sarama/heartbeat_request.go

@@ -60,10 +60,21 @@ func (r *HeartbeatRequest) headerVersion() int16 {
 	return 1
 }
 
+func (r *HeartbeatRequest) isValidVersion() bool {
+	return r.Version >= 0 && r.Version <= 3
+}
+
 func (r *HeartbeatRequest) requiredVersion() KafkaVersion {
-	switch {
-	case r.Version >= 3:
+	switch r.Version {
+	case 3:
+		return V2_3_0_0
+	case 2:
+		return V2_0_0_0
+	case 1:
+		return V0_11_0_0
+	case 0:
+		return V0_8_2_0
+	default:
 		return V2_3_0_0
 	}
-	return V0_9_0_0
 }

+ 19 - 2
vendor/github.com/IBM/sarama/heartbeat_response.go

@@ -1,5 +1,7 @@
 package sarama
 
+import "time"
+
 type HeartbeatResponse struct {
 	Version      int16
 	ThrottleTime int32
@@ -43,10 +45,25 @@ func (r *HeartbeatResponse) headerVersion() int16 {
 	return 0
 }
 
+func (r *HeartbeatResponse) isValidVersion() bool {
+	return r.Version >= 0 && r.Version <= 3
+}
+
 func (r *HeartbeatResponse) requiredVersion() KafkaVersion {
 	switch r.Version {
-	case 1, 2, 3:
+	case 3:
+		return V2_3_0_0
+	case 2:
+		return V2_0_0_0
+	case 1:
+		return V0_11_0_0
+	case 0:
+		return V0_8_2_0
+	default:
 		return V2_3_0_0
 	}
-	return V0_9_0_0
+}
+
+func (r *HeartbeatResponse) throttleTime() time.Duration {
+	return time.Duration(r.ThrottleTime) * time.Millisecond
 }

+ 6 - 1
vendor/github.com/IBM/sarama/incremental_alter_configs_request.go

@@ -11,6 +11,7 @@ const (
 
 // IncrementalAlterConfigsRequest is an incremental alter config request type
 type IncrementalAlterConfigsRequest struct {
+	Version      int16
 	Resources    []*IncrementalAlterConfigsResource
 	ValidateOnly bool
 }
@@ -161,13 +162,17 @@ func (a *IncrementalAlterConfigsRequest) key() int16 {
 }
 
 func (a *IncrementalAlterConfigsRequest) version() int16 {
-	return 0
+	return a.Version
 }
 
 func (a *IncrementalAlterConfigsRequest) headerVersion() int16 {
 	return 1
 }
 
+func (a *IncrementalAlterConfigsRequest) isValidVersion() bool {
+	return a.Version == 0
+}
+
 func (a *IncrementalAlterConfigsRequest) requiredVersion() KafkaVersion {
 	return V2_3_0_0
 }

+ 10 - 1
vendor/github.com/IBM/sarama/incremental_alter_configs_response.go

@@ -4,6 +4,7 @@ import "time"
 
 // IncrementalAlterConfigsResponse is a response type for incremental alter config
 type IncrementalAlterConfigsResponse struct {
+	Version      int16
 	ThrottleTime time.Duration
 	Resources    []*AlterConfigsResourceResponse
 }
@@ -54,13 +55,21 @@ func (a *IncrementalAlterConfigsResponse) key() int16 {
 }
 
 func (a *IncrementalAlterConfigsResponse) version() int16 {
-	return 0
+	return a.Version
 }
 
 func (a *IncrementalAlterConfigsResponse) headerVersion() int16 {
 	return 0
 }
 
+func (a *IncrementalAlterConfigsResponse) isValidVersion() bool {
+	return a.Version == 0
+}
+
 func (a *IncrementalAlterConfigsResponse) requiredVersion() KafkaVersion {
 	return V2_3_0_0
 }
+
+func (r *IncrementalAlterConfigsResponse) throttleTime() time.Duration {
+	return r.ThrottleTime
+}

Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff