From 10f7480a0e3c2e95d86d76df6eddbff0372a233f Mon Sep 17 00:00:00 2001 From: Michael Matloob Date: Fri, 3 Jul 2026 17:04:08 -0400 Subject: [PATCH 1/4] cmd/go: split build_overlay script test to improve parallelism For #78152 Change-Id: I910830b8439a63697ccc4f01dc19f2776a6a6964 Reviewed-on: https://go-review.googlesource.com/c/go/+/798320 Reviewed-by: David Chase LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com Reviewed-by: Dmitri Shuralyov Reviewed-by: Dmitri Shuralyov --- src/cmd/go/testdata/script/build_overlay.txt | 143 +----------- .../go/testdata/script/build_overlay_cgo.txt | 128 +++++++++++ .../testdata/script/build_overlay_gccgo.txt | 209 ++++++++++++++++++ 3 files changed, 338 insertions(+), 142 deletions(-) create mode 100644 src/cmd/go/testdata/script/build_overlay_cgo.txt create mode 100644 src/cmd/go/testdata/script/build_overlay_gccgo.txt diff --git a/src/cmd/go/testdata/script/build_overlay.txt b/src/cmd/go/testdata/script/build_overlay.txt index 1111d119ba2841..fe6ddadaaaa112 100644 --- a/src/cmd/go/testdata/script/build_overlay.txt +++ b/src/cmd/go/testdata/script/build_overlay.txt @@ -33,28 +33,10 @@ exec ./print_trimpath_two_files$GOEXE stdout $WORK[/\\]gopath[/\\]src[/\\]m[/\\]printpath[/\\]main.go stdout $WORK[/\\]gopath[/\\]src[/\\]m[/\\]printpath[/\\]other.go -[cgo] go build -overlay overlay.json -o main_cgo_replace$GOEXE ./cgo_hello_replace -[cgo] exec ./main_cgo_replace$GOEXE -[cgo] stdout '^hello cgo\r?\n' - -[cgo] go build -overlay overlay.json -o main_cgo_quote$GOEXE ./cgo_hello_quote -[cgo] exec ./main_cgo_quote$GOEXE -[cgo] stdout '^hello cgo\r?\n' - -[cgo] go build -overlay overlay.json -o main_cgo_angle$GOEXE ./cgo_hello_angle -[cgo] exec ./main_cgo_angle$GOEXE -[cgo] stdout '^hello cgo\r?\n' - go build -overlay overlay.json -o main_call_asm$GOEXE ./call_asm exec ./main_call_asm$GOEXE ! stdout . -[cgo] go list -compiled -overlay overlay.json -f '{{range .CompiledGoFiles}}{{. | printf "%s\n"}}{{end}}' ./cgo_hello_replace -[cgo] cp stdout compiled_cgo_sources.txt -[cgo] go run ../print_line_comments.go compiled_cgo_sources.txt -[cgo] stdout $GOPATH[/\\]src[/\\]m[/\\]cgo_hello_replace[/\\]cgo_hello_replace.go -[cgo] ! stdout $GOPATH[/\\]src[/\\]m[/\\]overlay[/\\]hello.c - # Change the contents of a file in the overlay and ensure that makes the target stale env OLD_GOCACHE=$GOCACHE env GOCACHE=$WORK/cache # use a fresh cache so that multiple runs of the test don't interfere @@ -67,42 +49,6 @@ go build -x -overlay overlay.json ./test_cache stderr '(compile|gccgo)( |\.exe).*test_cache.go' # not cached env CACHE=$OLD_GOCACHE -# Run same tests but with gccgo. -env GO111MODULE=off -[!exec:gccgo] stop -[cross] stop # gccgo can't necessarily cross-compile - -! go build -compiler=gccgo . -go build -compiler=gccgo -overlay overlay.json -o main_gccgo$GOEXE . -exec ./main_gccgo$goexe -stdout '^hello$' - -go build -compiler=gccgo -overlay overlay.json -o print_abspath_gccgo$GOEXE ./printpath -exec ./print_abspath_gccgo$GOEXE -stdout $WORK[/\\]gopath[/\\]src[/\\]m[/\\]printpath[/\\]main.go - -go build -compiler=gccgo -overlay overlay.json -o print_trimpath_gccgo$GOEXE -trimpath ./printpath -exec ./print_trimpath_gccgo$GOEXE -stdout ^\.[/\\]printpath[/\\]main.go - - -go build -compiler=gccgo -overlay overlay.json -o main_cgo_replace_gccgo$GOEXE ./cgo_hello_replace -exec ./main_cgo_replace_gccgo$GOEXE -stdout '^hello cgo\r?\n' - -go build -compiler=gccgo -overlay overlay.json -o main_cgo_quote_gccgo$GOEXE ./cgo_hello_quote -exec ./main_cgo_quote_gccgo$GOEXE -stdout '^hello cgo\r?\n' - -go build -compiler=gccgo -overlay overlay.json -o main_cgo_angle_gccgo$GOEXE ./cgo_hello_angle -exec ./main_cgo_angle_gccgo$GOEXE -stdout '^hello cgo\r?\n' - -go build -compiler=gccgo -overlay overlay.json -o main_call_asm_gccgo$GOEXE ./call_asm -exec ./main_call_asm_gccgo$GOEXE -! stdout . - - -- m/go.mod -- // TODO(matloob): how do overlays work with go.mod (especially if mod=readonly) module m @@ -131,33 +77,9 @@ the actual code is in the overlay "printpath/other.go": "overlay2/printpath2.go", "call_asm/asm_gc.s": "overlay/asm_gc.s", "call_asm/asm_gccgo.s": "overlay/asm_gccgo.s", - "test_cache/main.go": "overlay/test_cache.go", - "cgo_hello_replace/cgo_header.h": "overlay/cgo_head.h", - "cgo_hello_replace/hello.c": "overlay/hello.c", - "cgo_hello_quote/cgo_hello.go": "overlay/cgo_hello_quote.go", - "cgo_hello_quote/cgo_header.h": "overlay/cgo_head.h", - "cgo_hello_angle/cgo_hello.go": "overlay/cgo_hello_angle.go", - "cgo_hello_angle/cgo_header.h": "overlay/cgo_head.h" + "test_cache/main.go": "overlay/test_cache.go" } } --- m/cgo_hello_replace/cgo_hello_replace.go -- -package main - -// #include "cgo_header.h" -import "C" - -func main() { - C.say_hello() -} --- m/cgo_hello_replace/cgo_header.h -- - // Test that this header is replaced with one that has the proper declaration. -void say_goodbye(); - --- m/cgo_hello_replace/hello.c -- -#include - -void say_goodbye() { puts("goodbye cgo\n"); fflush(stdout); } - -- m/overlay/f.go -- package main @@ -220,30 +142,6 @@ import "m/dir" func printMessage() { dir.PrintMessage() } --- m/overlay/cgo_hello_quote.go -- -package main - -// #include "cgo_header.h" -import "C" - -func main() { - C.say_hello() -} --- m/overlay/cgo_hello_angle.go -- -package main - -// #include -import "C" - -func main() { - C.say_hello() -} --- m/overlay/cgo_head.h -- -void say_hello(); --- m/overlay/hello.c -- -#include - -void say_hello() { puts("hello cgo\n"); fflush(stdout); } -- m/overlay/asm_gc.s -- // +build gc @@ -274,42 +172,3 @@ import "fmt" func bar() { fmt.Println("different") } --- m/cgo_hello_quote/hello.c -- -#include - -void say_hello() { puts("hello cgo\n"); fflush(stdout); } --- m/cgo_hello_angle/hello.c -- -#include - -void say_hello() { puts("hello cgo\n"); fflush(stdout); } - --- print_line_comments.go -- -package main - -import ( - "fmt" - "io/ioutil" - "log" - "os" - "strings" -) - -func main() { - compiledGoFilesArg := os.Args[1] - b, err := ioutil.ReadFile(compiledGoFilesArg) - if err != nil { - log.Fatal(err) - } - compiledGoFiles := strings.Split(strings.TrimSpace(string(b)), "\n") - for _, f := range compiledGoFiles { - b, err := ioutil.ReadFile(f) - if err != nil { - log.Fatal(err) - } - for _, line := range strings.Split(string(b), "\n") { - if strings.HasPrefix(line, "#line") || strings.HasPrefix(line, "//line") { - fmt.Println(line) - } - } - } -} diff --git a/src/cmd/go/testdata/script/build_overlay_cgo.txt b/src/cmd/go/testdata/script/build_overlay_cgo.txt new file mode 100644 index 00000000000000..c5b6bf3bbf53ab --- /dev/null +++ b/src/cmd/go/testdata/script/build_overlay_cgo.txt @@ -0,0 +1,128 @@ +[short] skip +[!cgo] skip + +# Test building cgo packages in overlays. + +cd m + +go build -overlay overlay.json -o main_cgo_replace$GOEXE ./cgo_hello_replace +exec ./main_cgo_replace$GOEXE +stdout '^hello cgo\r?\n' + +go build -overlay overlay.json -o main_cgo_quote$GOEXE ./cgo_hello_quote +exec ./main_cgo_quote$GOEXE +stdout '^hello cgo\r?\n' + +go build -overlay overlay.json -o main_cgo_angle$GOEXE ./cgo_hello_angle +exec ./main_cgo_angle$GOEXE +stdout '^hello cgo\r?\n' + +go list -compiled -overlay overlay.json -f '{{range .CompiledGoFiles}}{{. | printf "%s\n"}}{{end}}' ./cgo_hello_replace +cp stdout compiled_cgo_sources.txt +go run ../print_line_comments.go compiled_cgo_sources.txt +stdout $GOPATH[/\\]src[/\\]m[/\\]cgo_hello_replace[/\\]cgo_hello_replace.go +! stdout $GOPATH[/\\]src[/\\]m[/\\]overlay[/\\]hello.c + +-- m/go.mod -- +// TODO(matloob): how do overlays work with go.mod (especially if mod=readonly) +module m + +go 1.16 + +-- m/overlay.json -- +{ + "Replace": { + "printpath/main.go": "overlay/printpath.go", + "printpath/other.go": "overlay2/printpath2.go", + "call_asm/asm_gc.s": "overlay/asm_gc.s", + "call_asm/asm_gccgo.s": "overlay/asm_gccgo.s", + "test_cache/main.go": "overlay/test_cache.go", + "cgo_hello_replace/cgo_header.h": "overlay/cgo_head.h", + "cgo_hello_replace/hello.c": "overlay/hello.c", + "cgo_hello_quote/cgo_hello.go": "overlay/cgo_hello_quote.go", + "cgo_hello_quote/cgo_header.h": "overlay/cgo_head.h", + "cgo_hello_angle/cgo_hello.go": "overlay/cgo_hello_angle.go", + "cgo_hello_angle/cgo_header.h": "overlay/cgo_head.h" + } +} +-- m/cgo_hello_replace/cgo_hello_replace.go -- +package main + +// #include "cgo_header.h" +import "C" + +func main() { + C.say_hello() +} +-- m/cgo_hello_replace/cgo_header.h -- + // Test that this header is replaced with one that has the proper declaration. +void say_goodbye(); + +-- m/cgo_hello_replace/hello.c -- +#include + +void say_goodbye() { puts("goodbye cgo\n"); fflush(stdout); } + +-- m/overlay/cgo_hello_quote.go -- +package main + +// #include "cgo_header.h" +import "C" + +func main() { + C.say_hello() +} +-- m/overlay/cgo_hello_angle.go -- +package main + +// #include +import "C" + +func main() { + C.say_hello() +} +-- m/overlay/cgo_head.h -- +void say_hello(); +-- m/overlay/hello.c -- +#include + +void say_hello() { puts("hello cgo\n"); fflush(stdout); } +-- m/cgo_hello_quote/hello.c -- +#include + +void say_hello() { puts("hello cgo\n"); fflush(stdout); } +-- m/cgo_hello_angle/hello.c -- +#include + +void say_hello() { puts("hello cgo\n"); fflush(stdout); } + +-- print_line_comments.go -- +package main + +import ( + "fmt" + "io/ioutil" + "log" + "os" + "strings" +) + +func main() { + compiledGoFilesArg := os.Args[1] + b, err := ioutil.ReadFile(compiledGoFilesArg) + if err != nil { + log.Fatal(err) + } + compiledGoFiles := strings.Split(strings.TrimSpace(string(b)), "\n") + for _, f := range compiledGoFiles { + b, err := ioutil.ReadFile(f) + if err != nil { + log.Fatal(err) + } + for _, line := range strings.Split(string(b), "\n") { + if strings.HasPrefix(line, "#line") || strings.HasPrefix(line, "//line") { + fmt.Println(line) + } + } + } +} diff --git a/src/cmd/go/testdata/script/build_overlay_gccgo.txt b/src/cmd/go/testdata/script/build_overlay_gccgo.txt new file mode 100644 index 00000000000000..4cc0c49ac547a2 --- /dev/null +++ b/src/cmd/go/testdata/script/build_overlay_gccgo.txt @@ -0,0 +1,209 @@ +[short] skip +[!exec:gccgo] skip +[cross] skip # gccgo can't necessarily cross-compile + +# Test building in overlays with gccgo. +# TODO(#39958): add a test that both gc and gccgo assembly files can include .h +# files. + +# The main package (m) is contained in an overlay. It imports m/dir2 which has one +# file in an overlay and one file outside the overlay, which in turn imports m/dir, +# which only has source files in the overlay. + +env GO111MODULE=off + +cd m + +! go build -compiler=gccgo . +go build -compiler=gccgo -overlay overlay.json -o main_gccgo$GOEXE . +exec ./main_gccgo$goexe +stdout '^hello$' + +go build -compiler=gccgo -overlay overlay.json -o print_abspath_gccgo$GOEXE ./printpath +exec ./print_abspath_gccgo$GOEXE +stdout $WORK[/\\]gopath[/\\]src[/\\]m[/\\]printpath[/\\]main.go + +go build -compiler=gccgo -overlay overlay.json -o print_trimpath_gccgo$GOEXE -trimpath ./printpath +exec ./print_trimpath_gccgo$GOEXE +stdout ^\.[/\\]printpath[/\\]main.go + + +go build -compiler=gccgo -overlay overlay.json -o main_cgo_replace_gccgo$GOEXE ./cgo_hello_replace +exec ./main_cgo_replace_gccgo$GOEXE +stdout '^hello cgo\r?\n' + +go build -compiler=gccgo -overlay overlay.json -o main_cgo_quote_gccgo$GOEXE ./cgo_hello_quote +exec ./main_cgo_quote_gccgo$GOEXE +stdout '^hello cgo\r?\n' + +go build -compiler=gccgo -overlay overlay.json -o main_cgo_angle_gccgo$GOEXE ./cgo_hello_angle +exec ./main_cgo_angle_gccgo$GOEXE +stdout '^hello cgo\r?\n' + +go build -compiler=gccgo -overlay overlay.json -o main_call_asm_gccgo$GOEXE ./call_asm +exec ./main_call_asm_gccgo$GOEXE +! stdout . + +-- m/go.mod -- +// TODO(matloob): how do overlays work with go.mod (especially if mod=readonly) +module m + +go 1.16 + +-- m/dir2/h.go -- +package dir2 + +func PrintMessage() { + printMessage() +} +-- m/dir/foo.txt -- +The build action code currently expects the package directory +to exist, so it can run the compiler in that directory. +TODO(matloob): Remove this requirement. +-- m/printpath/about.txt -- +the actual code is in the overlay +-- m/overlay.json -- +{ + "Replace": { + "f.go": "overlay/f.go", + "dir/g.go": "overlay/dir_g.go", + "dir2/i.go": "overlay/dir2_i.go", + "printpath/main.go": "overlay/printpath.go", + "printpath/other.go": "overlay2/printpath2.go", + "call_asm/asm_gc.s": "overlay/asm_gc.s", + "call_asm/asm_gccgo.s": "overlay/asm_gccgo.s", + "test_cache/main.go": "overlay/test_cache.go", + "cgo_hello_replace/cgo_header.h": "overlay/cgo_head.h", + "cgo_hello_replace/hello.c": "overlay/hello.c", + "cgo_hello_quote/cgo_hello.go": "overlay/cgo_hello_quote.go", + "cgo_hello_quote/cgo_header.h": "overlay/cgo_head.h", + "cgo_hello_angle/cgo_hello.go": "overlay/cgo_hello_angle.go", + "cgo_hello_angle/cgo_header.h": "overlay/cgo_head.h" + } +} +-- m/cgo_hello_replace/cgo_hello_replace.go -- +package main + +// #include "cgo_header.h" +import "C" + +func main() { + C.say_hello() +} +-- m/cgo_hello_replace/cgo_header.h -- + // Test that this header is replaced with one that has the proper declaration. +void say_goodbye(); + +-- m/cgo_hello_replace/hello.c -- +#include + +void say_goodbye() { puts("goodbye cgo\n"); fflush(stdout); } + +-- m/overlay/f.go -- +package main + +import "m/dir2" + +func main() { + dir2.PrintMessage() +} +-- m/call_asm/main.go -- +package main + +func foo() // There will be a "missing function body" error if the assembly file isn't found. + +func main() { + foo() +} +-- m/overlay/dir_g.go -- +package dir + +import "fmt" + +func PrintMessage() { + fmt.Println("hello") +} +-- m/overlay/printpath.go -- +package main + +import ( + "fmt" + "path/filepath" + "runtime" +) + +func main() { + _, file, _, _ := runtime.Caller(0) + + // Since https://golang.org/cl/214286, the runtime's debug paths are + // slash-separated regardless of platform, so normalize them to system file + // paths. + fmt.Println(filepath.FromSlash(file)) +} +-- m/overlay2/printpath2.go -- +package main + +import ( + "fmt" + "path/filepath" + "runtime" +) + +func init() { + _, file, _, _ := runtime.Caller(0) + fmt.Println(filepath.FromSlash(file)) +} +-- m/overlay/dir2_i.go -- +package dir2 + +import "m/dir" + +func printMessage() { + dir.PrintMessage() +} +-- m/overlay/cgo_hello_quote.go -- +package main + +// #include "cgo_header.h" +import "C" + +func main() { + C.say_hello() +} +-- m/overlay/cgo_hello_angle.go -- +package main + +// #include +import "C" + +func main() { + C.say_hello() +} +-- m/overlay/cgo_head.h -- +void say_hello(); +-- m/overlay/hello.c -- +#include + +void say_hello() { puts("hello cgo\n"); fflush(stdout); } +-- m/overlay/asm_gc.s -- +// +build gc + +TEXT ·foo(SB),0,$0 + RET + +-- m/overlay/asm_gccgo.s -- +// +build gccgo + +.globl main.foo +.text +main.foo: + ret + +-- m/cgo_hello_quote/hello.c -- +#include + +void say_hello() { puts("hello cgo\n"); fflush(stdout); } +-- m/cgo_hello_angle/hello.c -- +#include + +void say_hello() { puts("hello cgo\n"); fflush(stdout); } From 4d1000c44e2e0221477b91bbcc980b3659476dd0 Mon Sep 17 00:00:00 2001 From: Michael Matloob Date: Fri, 3 Jul 2026 17:04:08 -0400 Subject: [PATCH 2/4] cmd/go: split test_vet script test for improved parallelism For #78152 Change-Id: I0e0a0a4bcec2c3785619162bd837fbe76a6a6964 Reviewed-on: https://go-review.googlesource.com/c/go/+/798361 LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com Reviewed-by: Dmitri Shuralyov Reviewed-by: Dmitri Shuralyov Reviewed-by: David Chase --- src/cmd/go/testdata/script/test_vet.txt | 31 ---------------- .../go/testdata/script/test_vet_vetall.txt | 37 +++++++++++++++++++ 2 files changed, 37 insertions(+), 31 deletions(-) create mode 100644 src/cmd/go/testdata/script/test_vet_vetall.txt diff --git a/src/cmd/go/testdata/script/test_vet.txt b/src/cmd/go/testdata/script/test_vet.txt index 6151f912ae0db1..5af26b54f9141b 100644 --- a/src/cmd/go/testdata/script/test_vet.txt +++ b/src/cmd/go/testdata/script/test_vet.txt @@ -16,22 +16,6 @@ go test -vet=off p1.go ! stderr '[\\/]vet.*-shift' stdout '\[no test files\]' -# ensure all runs non-default vet -! go test -vet=all ./vetall/... -stderr 'using resp before checking for errors' - -# Test issue #47309 -! go test -vet=bools,xyz ./vetall/... -stderr '-vet argument must be a supported analyzer' - -# Test with a single analyzer -! go test -vet=httpresponse ./vetall/... -stderr 'using resp before checking for errors' - -# Test with a list of analyzers -go test -vet=atomic,bools,nilfunc ./vetall/... -stdout 'm/vetall.*\[no tests to run\]' - # Test issue #22890 go test m/vetcycle stdout 'm/vetcycle.*\[no test files\]' @@ -67,21 +51,6 @@ import "fmt" func F() { fmt.Printf("%d") // oops } --- vetall/p.go -- -package p - -import "net/http" - -func F() { - resp, err := http.Head("example.com") - defer resp.Body.Close() - if err != nil { - panic(err) - } - // (defer statement belongs here) -} --- vetall/p_test.go -- -package p -- vetcycle/p.go -- package p diff --git a/src/cmd/go/testdata/script/test_vet_vetall.txt b/src/cmd/go/testdata/script/test_vet_vetall.txt new file mode 100644 index 00000000000000..6f7b6657337968 --- /dev/null +++ b/src/cmd/go/testdata/script/test_vet_vetall.txt @@ -0,0 +1,37 @@ +[short] skip + +# ensure all runs non-default vet +! go test -vet=all ./vetall/... +stderr 'using resp before checking for errors' + +# Test issue #47309 +! go test -vet=bools,xyz ./vetall/... +stderr '-vet argument must be a supported analyzer' + +# Test with a single analyzer +! go test -vet=httpresponse ./vetall/... +stderr 'using resp before checking for errors' + +# Test with a list of analyzers +go test -vet=atomic,bools,nilfunc ./vetall/... +stdout 'm/vetall.*\[no tests to run\]' + +-- go.mod -- +module m + +go 1.16 +-- vetall/p.go -- +package p + +import "net/http" + +func F() { + resp, err := http.Head("example.com") + defer resp.Body.Close() + if err != nil { + panic(err) + } + // (defer statement belongs here) +} +-- vetall/p_test.go -- +package p From 0a9b01c5e1e5dd78cc40e15b795e51a356d0879d Mon Sep 17 00:00:00 2001 From: Daniel McCarney Date: Mon, 22 Jun 2026 10:38:38 -0400 Subject: [PATCH 3/4] crypto/mlkem: improved semi-expanded wycheproof tests Takes an upstream update to the Wycheproof test vectors. This includes an update to the ML-KEM semi-expanded form decapsulation test schema that adds the expected K. We use that to tighten up TestMLKEMSemiExpandedDecapsWycheproof to take advantage. Change-Id: I67abcc9c1c6728ab154742f9a466e18be22eef89 Reviewed-on: https://go-review.googlesource.com/c/go/+/792940 Reviewed-by: David Chase Reviewed-by: Dmitri Shuralyov Reviewed-by: Filippo Valsorda Auto-Submit: Daniel McCarney LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com --- .../cryptotest/wycheproof/_schema/go.mod | 2 +- .../cryptotest/wycheproof/_schema/go.sum | 4 +-- .../internal/cryptotest/wycheproof/schema.go | 10 ++++++ .../cryptotest/wycheproof/schemaversion.go | 2 +- src/crypto/mlkem/mlkem_wycheproof_test.go | 32 ++++++++----------- 5 files changed, 28 insertions(+), 22 deletions(-) diff --git a/src/crypto/internal/cryptotest/wycheproof/_schema/go.mod b/src/crypto/internal/cryptotest/wycheproof/_schema/go.mod index 1253c1c5a94eb1..d7c20ce6f6d307 100644 --- a/src/crypto/internal/cryptotest/wycheproof/_schema/go.mod +++ b/src/crypto/internal/cryptotest/wycheproof/_schema/go.mod @@ -4,7 +4,7 @@ go 1.26.4 require ( github.com/atombender/go-jsonschema v0.23.1 - github.com/c2sp/wycheproof v0.0.0-20260606153636-6d7cccd0fcb1 + github.com/c2sp/wycheproof v0.0.0-20260625212325-ee7b4f7e6119 ) require ( diff --git a/src/crypto/internal/cryptotest/wycheproof/_schema/go.sum b/src/crypto/internal/cryptotest/wycheproof/_schema/go.sum index bc5fe4eb9e0b96..5ad2f74b721e16 100644 --- a/src/crypto/internal/cryptotest/wycheproof/_schema/go.sum +++ b/src/crypto/internal/cryptotest/wycheproof/_schema/go.sum @@ -1,7 +1,7 @@ dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8= dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA= -github.com/c2sp/wycheproof v0.0.0-20260606153636-6d7cccd0fcb1 h1:veaGluF2y7kZnV/owZzY3FuOZWZQdzqnIcJsbJpFV7A= -github.com/c2sp/wycheproof v0.0.0-20260606153636-6d7cccd0fcb1/go.mod h1:/5JsOpi3fKmnnig5BQ2mz49TNtnrD308VfTVHcbr5x4= +github.com/c2sp/wycheproof v0.0.0-20260625212325-ee7b4f7e6119 h1:jOCu6erj86P93+eFn8Qxp6XLwftn1nW0C9RUx7xZwZg= +github.com/c2sp/wycheproof v0.0.0-20260625212325-ee7b4f7e6119/go.mod h1:/5JsOpi3fKmnnig5BQ2mz49TNtnrD308VfTVHcbr5x4= github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/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= diff --git a/src/crypto/internal/cryptotest/wycheproof/schema.go b/src/crypto/internal/cryptotest/wycheproof/schema.go index 50c655f6fe032e..06939c82bb63c8 100644 --- a/src/crypto/internal/cryptotest/wycheproof/schema.go +++ b/src/crypto/internal/cryptotest/wycheproof/schema.go @@ -4980,6 +4980,10 @@ func (j *MLKEMDecapsTestGroupParameterSet) UnmarshalJSON(value []byte) error { } type MLKEMDecapsTestGroupTestsElem struct { + // If present, the shared key the implementation MUST return on a successful + // Decapsulate call. + K *string `json:"K,omitempty,omitzero"` + // An input ciphertext C string `json:"c"` @@ -4989,6 +4993,9 @@ type MLKEMDecapsTestGroupTestsElem struct { // The full decapsulation key Dk string `json:"dk"` + // The encapsulation key bytes of dk. + Ek string `json:"ek"` + // A list of flags Flags []string `json:"flags"` @@ -5011,6 +5018,9 @@ func (j *MLKEMDecapsTestGroupTestsElem) UnmarshalJSON(value []byte) error { if _, ok := raw["dk"]; raw != nil && !ok { return fmt.Errorf("field dk in MLKEMDecapsTestGroupTestsElem: required") } + if _, ok := raw["ek"]; raw != nil && !ok { + return fmt.Errorf("field ek in MLKEMDecapsTestGroupTestsElem: required") + } if _, ok := raw["flags"]; raw != nil && !ok { return fmt.Errorf("field flags in MLKEMDecapsTestGroupTestsElem: required") } diff --git a/src/crypto/internal/cryptotest/wycheproof/schemaversion.go b/src/crypto/internal/cryptotest/wycheproof/schemaversion.go index 642266db1f454f..9a837a27f6dbdc 100644 --- a/src/crypto/internal/cryptotest/wycheproof/schemaversion.go +++ b/src/crypto/internal/cryptotest/wycheproof/schemaversion.go @@ -8,4 +8,4 @@ package wycheproof // wycheproofVersion is the github.com/c2sp/wycheproof module version that // schema.go was generated against. -const wycheproofVersion = "v0.0.0-20260606153636-6d7cccd0fcb1" +const wycheproofVersion = "v0.0.0-20260625212325-ee7b4f7e6119" diff --git a/src/crypto/mlkem/mlkem_wycheproof_test.go b/src/crypto/mlkem/mlkem_wycheproof_test.go index 1188437ce78fbd..c5162525b37c77 100644 --- a/src/crypto/mlkem/mlkem_wycheproof_test.go +++ b/src/crypto/mlkem/mlkem_wycheproof_test.go @@ -356,6 +356,9 @@ func runSemiExpandedDecapsTest(t *testing.T, paramSet wycheproof.MLKEMDecapsTest if !bytes.Equal(mlkem.TestingOnlyExpandedBytes768(dk), dkBytes) { t.Errorf("expanded decapsulation key roundtrip mismatch") } + if want := wycheproof.MustDecodeHex(tv.Ek); !bytes.Equal(dk.EncapsulationKey().Bytes(), want) { + t.Errorf("encapsulation key mismatch:\n got: %x\nwant: %x", dk.EncapsulationKey().Bytes(), want) + } k, err := dk.Decapsulate(ciphertext) if err != nil { if shouldPass { @@ -367,16 +370,11 @@ func runSemiExpandedDecapsTest(t *testing.T, paramSet wycheproof.MLKEMDecapsTest t.Errorf("Decapsulate unexpectedly succeeded") return } - if len(k) != SharedKeySize { - t.Errorf("shared key has wrong length: got %d, want %d", len(k), SharedKeySize) - } - kFresh, cFresh := dk.EncapsulationKey().Encapsulate() - kRT, err := dk.Decapsulate(cFresh) - if err != nil { - t.Fatalf("Decapsulate of fresh ciphertext: %v", err) + if tv.K == nil { + t.Fatalf("Decapsulate succeeded but test vector has no expected K") } - if !bytes.Equal(kFresh, kRT) { - t.Errorf("encaps/decaps roundtrip key mismatch") + if want := wycheproof.MustDecodeHex(*tv.K); !bytes.Equal(k, want) { + t.Errorf("shared key mismatch:\n got: %x\nwant: %x", k, want) } case wycheproof.MLKEMDecapsTestGroupParameterSetMLKEM1024: @@ -390,6 +388,9 @@ func runSemiExpandedDecapsTest(t *testing.T, paramSet wycheproof.MLKEMDecapsTest if !bytes.Equal(mlkem.TestingOnlyExpandedBytes1024(dk), dkBytes) { t.Errorf("expanded decapsulation key roundtrip mismatch") } + if want := wycheproof.MustDecodeHex(tv.Ek); !bytes.Equal(dk.EncapsulationKey().Bytes(), want) { + t.Errorf("encapsulation key mismatch:\n got: %x\nwant: %x", dk.EncapsulationKey().Bytes(), want) + } k, err := dk.Decapsulate(ciphertext) if err != nil { if shouldPass { @@ -401,16 +402,11 @@ func runSemiExpandedDecapsTest(t *testing.T, paramSet wycheproof.MLKEMDecapsTest t.Errorf("Decapsulate unexpectedly succeeded") return } - if len(k) != SharedKeySize { - t.Errorf("shared key has wrong length: got %d, want %d", len(k), SharedKeySize) - } - kFresh, cFresh := dk.EncapsulationKey().Encapsulate() - kRT, err := dk.Decapsulate(cFresh) - if err != nil { - t.Fatalf("Decapsulate of fresh ciphertext: %v", err) + if tv.K == nil { + t.Fatalf("Decapsulate succeeded but test vector has no expected K") } - if !bytes.Equal(kFresh, kRT) { - t.Errorf("encaps/decaps roundtrip key mismatch") + if want := wycheproof.MustDecodeHex(*tv.K); !bytes.Equal(k, want) { + t.Errorf("shared key mismatch:\n got: %x\nwant: %x", k, want) } default: From f20c97b756352d6529d286b97c489a3cb9afcffd Mon Sep 17 00:00:00 2001 From: Kyle Shannon Date: Wed, 8 Jul 2026 13:02:18 -0600 Subject: [PATCH 4/4] lib/time: update to 2026c/2026c Commit generated by update.bash. For #22487. Change-Id: If8e3d4a0a2584897926b75bd0aa41756e4457c37 Reviewed-on: https://go-review.googlesource.com/c/go/+/798480 Reviewed-by: Dmitri Shuralyov Reviewed-by: Dmitri Shuralyov Reviewed-by: David Chase Auto-Submit: Dmitri Shuralyov Reviewed-by: Tobias Klauser LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com --- lib/time/update.bash | 4 ++-- lib/time/zoneinfo.zip | Bin 409690 -> 408467 bytes 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/time/update.bash b/lib/time/update.bash index 5e2c0873cd3600..768c244cf0f374 100755 --- a/lib/time/update.bash +++ b/lib/time/update.bash @@ -24,8 +24,8 @@ # in the CL match the update.bash in the CL. # Versions to use. -CODE=2026b -DATA=2026b +CODE=2026c +DATA=2026c set -e diff --git a/lib/time/zoneinfo.zip b/lib/time/zoneinfo.zip index 2d8488cee0223aa9183f6e0e69abaee9fc4b36e4..46c90a2b806a92fcd3291449fe448ce8db4d1753 100644 GIT binary patch delta 5757 zcmcgw2Uk_s*1h)}&Y?(EKtQTu0qI>tie2nI*cBDAMGesy8yXWe<{8bEOrz0g)YxK2 z5p38|L9v0Nhz%Qx(gZ=^o11*&CHVu7F*4?!Yt2>mI(u&Yw9&KEt+qASN;*e7FWD#D=Wsu}ma5UJ zhs_GpC5R81^D-o)Z`Ow3tNq%Oo#Nt!OEcbN?P`G&y7f$Kz_+s- zcwB4G1|FC7Sp$#PH*4VWdqW%eC&Gd~NIiv%j0r zXqsp=nE6_%Kx^FnqzWG%`v?Xwf{H{s5z?i zm5Qv;D@6&By4m2n6eU!$u*F%yvu*JyMTwNQ+9CXy(q0=ZiBW0P?P`q; zY19pEgB-#2-O%JXJ1KNS@8e1b3GVpeIO96D#f9V4)wlim1kL9?5OIQZmM6Xz=34+yW@+(0Ybeg(t!B``3U^Vh~w#uOX-U0 zbk>dQhLAJ#yLH!D^lyUYXB2m7XS8nSI7?)lQG%qMy&Kk+XBB^Gd%uSD$g|9|V_?I2 z&soJ+`h7^ly7a8#Ev<;*+8z<-m}k|92K%CO)T|h-n>ooDH-&x0INi)CwrF~u>lqWc zw$@Fbu3|K~_DdW*r&!^)^NOGJ^^}JA7v~wjYjKwHW@79G&ZP4!{Ca_V*gqS2 z0#D9?%|-ThU>*isr2pH6_|HY9qx9us+_*@8>Jpe;qJ8>OL|@{J_AkeGmw1@=tw6>l z&Sd3E=x5MA`3H2$pl<$ZEX<&PmJaC|N|a=SpEg^=_A=X+HlWL8O1p2w;>#SL|0bNe z%oMG*pjPnLTM&AM{yo2A_7(C&yKwjl{cHb3=@q6*+OJ!1tSNe3Wv-D2@YPjn`W(iQ ztNgSRlTmS%+83z^$P}?@n3>63OHX01;N4H_d@`(m&SGf0Gw{d~9bdqtEOy#01G@$P zHWSaYC=JX;i)%`A`+q(==KsAKVo{ilvDY}8fE@fL(E2X&ukkum-i70J^7#)j;yU@@ zXV`e1&8>Tm{OfFP&r8^66Qkc?cs47Ay~jGi@d3HnO1Nxat%1!AB~-r3#o!xC2YEq_ z21z%VGVv2E^t4Uz{D$IgHm+8qiJCTHR($MO?`~ht#hRB&6ZAAy?c`2%8uY!%%~a`O zrNG68xO9^(95#afEv37pF+u-ZN~G*=p~VRstquOX#gY8n1b1&KU8T9!aK5c{kOBU+Igi6N zAB@p?oZ$PR*qBHE<6+1X_U)r!d!OBn9;-#kB#t)zKD)aYi=_LkY8Ho_`;3Z>hvfrC zP52!BA22Fr7FIuC_5rhz{eb?!1u)Ggf3X04^4W!U3BJ##y?!||@X@R)vGGJbljM96)P zGW$ubC0;&ecApejKH-OSJ%J%lm@W1UAoz*%xc7urGB3jFDRK5?^nc1tUCqRgPnm7w zHC%tn&8)hih4VeF6`DU|wx+r0^Ngy8ckzS3ArEoo8GE=`0Fy$V<-Jd}h$y0ZTp`sd zFR-eRs>&i{7Ao!JhwrqQQOUtLKBxEWdqh8{w`&!a6Xg$8T3mY0lBplHP+rh7xmt_P zFPPT5MvF6&WR3MNIKG>oD15=YbfH!YgO^H(oKmkvrLcQT7id} zAoLYK?PNR5eZ}2&Ylb7QsGskIidXF6m@E8WD=z4#3eORyq@iiXv7h2|?f+a)cq_4SCNFNPfeKt%*YA8^(9; zh`_f*^G^8UEp@Lt;m}*wx!)CKZeqoR{8atgm3*;H}815P7%5sH9GtipK&Eq@r0B?F-T{w2E;(j^ihR z^G+eFivGo?q5qNf*Pca}kNjTe&SB|C+C4Ae)JOJr{{kvMGQZtrcvll+G7(oz|E%lS zQq4TWv+LSf9^Jx*Dzm3E-uwD|BE~*pSZ8Ge1r*H`3PTp;@syy z#(_`l@3$v-BXG%6w5esCj?XZrmihCaV?!t9m6^POFxZTBsrNz)w=rC^cAq zRVO8_Q-h>%DJffRCv8yCNUH`*qx8{PtAX*i#RN$|};A6<@@(4^bB)1=fJ%-FvGY-!Ush=?(t&G$Nd2pPJ)zf54%r|0n z(<#_#MAez;cxuGxyPw0k5ixisMmAC-rSE6qH^KYO#)C#`n5=#+BPx+kotH7AT^3@P zF>~KrjP=Icaqu_DF=mwYGT4}Kf{&M@zX^LO`yM|EetQ)%1pcxbT2s|qGE9P>sp>Bo z{E9eJRyp}QwwW?d)f5$9M}iobUv{Sg5{I@(W~Is6NuZx2O~Lj>YhAtOiPVi!oW?jCa`5m`Bp+ zJ?;tI_8t~Zh~XvZ(S-h-5+n+oUWycfY8i?JZYo1dOJYztMhLuC4xPY>6}Td>t^!&s z;@S@g5$IWo&#jm@qY^s=##W&~U|kiOS`&Zyh`s^?s+;o_!P#Ma3$wBh0t7m+rqzrmV%jw&J68?|n#E$VDkV{Eoj zO{KOP9H3u1twEu{fm+zv@|3;RVz8|mAT5!w(w66f%kY z(2n-omPoVXS1zzdrLbSMgi-7ryLJ1=at zr#{yQPwW|=7X$|f>NDG8xC8zCg}6@OfX=w%z|(Oi8di?voBCpaBlVU;@E=FoGh>kD z$aC9b1XL%UDv!~KbRz#|Eao~7Hn(5y0^CDX$$V-;SM;vGT)=!7~x9$jD6VPO5NN8$Z=)f zvO_R$$-Iq^pifKc9;e{@mh?|b!-bZN?{ykdEBa@hMPw`Ttn*mVig9-?BBd4e$yZR; ziu##Z@M=vSm5s@*sULF-J6qGLqP_ zhFWrcZIPa)Tkk=*?xxz~J2%zTV9j5awz%e|I{am7@uorK`Ijk`D(T1@Tz2C%?D`fp zZfcDHrcTp(QUbzigGM(%T4d8z*%9B`G8tsH?Bl`4-P-A5(yq0&Y~(D^bni>h<6?w zhFLY*da9vHdNnI0ZBd=D!c#SsP3!cq-ji>~cnMja9Kr(`l9%eMcUw=<;A9{#Qa>-Y zlcQiN&C*VN{N}~C(#9Cs0^LlY^=8-@3j}$yT%k1*yjkv?Ee;4Qx5pcA&a|})?0u+9 za7BL~)lYwS8%5J^Kqu7Y@>%=Chf^Emj-x`c%o{~M++cTKwDe`h6@iHLVoC|^p|zP zC4c(2b%kC42RytRx&%=7v^y3BP*>aoCk1|tMoj?o-{^_pK;F9jy)Y+`JgYYj2Qp7? zACwB7-xpp%SBQ@3dd zEJ9ds!cg=Lp>EP=_#uQkyBK7IaNo~kVAPKKJ;TwXof_K6VE{Z}PdK8PK;UqU!m5?8EqdvSz>|Obs+DpQ&gDeK~8>iT;l)@+ zr+&t4MKie5ApDq4`7t5?Yz{Igm-@{^eHaUMT!fGgeDjATVurvG%doQpxBKe~6bim} zH5|gJU$+K>!rA!gBr m+w$C=j^JFkVO5i`+3hfX8t?>|IX|4aoyMVdwsY2x$oz#5-V+Q&9_V2ThGL& zeOl-|LycyhVdCL>6SO(|U9CDw^J2zcankS;lk_G<-~|6RPAbN3P;pY7hbe+j3Ncps zI8TD`Hig;dVf^&lprB_&m+b_f1s8 zH{J_WoRxPjMZ?c*rKO5-{?xy zf2e$A2YsXe{G*<#UsX3iwXe?1)Z-Iim0!Fd#Gx_ zNPVYkwGUEg)~pTIce<`{x$0l9=o{Uzy;9{H?&=%eID2CX<(iGVPO0{kex3EWK;P&V zr~NA5GDzR(*2=F^H2iF9KF>+i*K9w1Hbupc`c8jYKgmh(U#{vq-5Fm$Mev;|`bK|i zyHMr7P184;THoDC_)|OfR_(t(zpCOMdwrv6S#4FG_DbLAzEw}0H2mz#t}{<{qz~(_ z8q$;WogVb7R_zC4^_?E7vsLvU3f4E8S!Aj5EK7Z(hxcTt`onkcsP>~vhU+n1-)MHf ziz?4vp>Onr+Z0uQV$i&wRL9B6V%2cUTi@yFyk)9AN7i?GX1llQKU1J@G&g>O%5!(> z8$I8xqpCkYeVl5)==e;Jz4VP>w$ zdqHxrYQG+KM31rhMsJ$Bs{CdLeWQgBuBiGV%eSiiR^|*nKG8RNXUQX#-#OONNz#7) zmpI2J6eB!!-Nk=?iJ3ND20me)KKn~;nky!&3eJpeVW`oxFif;_h|y;4U+nN)`@c8F z|K1q?dt+$+U%fH3I_W?E@byi}Br&{a6V&+0fhZ4?!%==!S0`~_;~@RJqpY#A&t#UN z;hpn3jpn>A@za%96mQfT$g)PGvCeRDm2xH2y2!?;+N_H(sI5&(!QN-u{tMgR$Y_5< zJF4$rg0ZKiH0i&JURvoXWmJ0VUe5n(c=_+TnExsqSIV`fOT*K38R6*$rJw%t(-Qpl z$-SjM_E@}64w6zGkiAb1k)}67wcr7b;lE!Fmy8`TeZL&qCeu-)X*VW*{HQ4Jj*}9i zVxuB@XeG}5pU>x)szzh+AFEi5b;3)gkg{Chkxq1X#dv|HZrG772TNIQC`p&wN;}=r z=OAOv z{ZMm|+6#UN&XC(ktNbw|gFGw%`vukp;Dx}{K)4u_Y17aq`q$(T+U=($1s>@$zf7{SfX=)6{51(LvmaEkVWm}aGV$D z*bat=nd3uybU4g@A9ci>!?dsJf-J!o_Q0FN%(bvLe2=iUZv^6w(Em09zaOD}YQMx2 z5!Q)?-A!S3l=-I)Ah$uUqjGC0ZZOwPuua&f4CT5$9v_vxrHR8u4BU@#9XV26Pd-Nd zSJ7gfcxFCVX+4w!E#FdzxD79mqP(J*?e<%G1p8dM5&M$PezqlpOk}|Asw+ z&)tXTIrNV>keIf+0otEouBbzad-pWJVzGA3#NIR1*&o4+GkngikHYIL_4`j^!dVf2 z3cJoSU&L8F7Th`)O>^0Yd>+xcqUStpCbzK4=e3y-t-m+X6S4WOY=yL7#S|9jWOJ#{ zbvT}5xV8vG&&f?3KEGWw8q2?3qP;~}caEF3^DYVnuDFl-=Xq&ji!ty#`Kw1r68!wL z#JGpnC_T?1%wC}W1vc$ej!1#o6KT~ISEiXF7J z=x~LN=eEG4E6ic$ioI7@;vXI;yTZm_c*8B9IMD}V^LZkA_+d*v{cVD9FJJB=MYMs- zRbpg2OukCpH=U4rmAwt=jIyiL`E-G60Z-+$t{7Dyx2pgNn88Di z;ka>~{sALlb%S>MG3a}Pao5IS?_^fiNsqByO@egw-|Od4JNmF5|-`NqSY>~HHO?~sO14H zz0Km)2XOYb9ICU;(Bk+WZ38&mp?5(hy58Yd1!Q5x9Udp6BU+@TGqzZGPaTEnT@Jea z7<%57!*y#Toz1!~6TbPS0v`Rh~QSTndYL|yz0-s&M@_QUF{2Frav2wi|FuKqF zbVcZNpZf3bVd;JP`xPTc;Dtxf6|;xXC+J+v?Q8N3i;JoAc!{&c^v6~}F5!vkSBdZv z>H^*~ZRzlbV8t!v3=K-(6Hc7(K2W-5Hft36Q#|x1qwEII2 z(s>w4m`#gR&m2eoU~|b4?@AB#$%@Or`u z7Hu){3HgEcNELj12b4YG*n7I5)t`(X*%cE7dUeC@KdCe9j%R17TK5o;(zK~MBY`Jo!}$f{9?Zdz7u3C)i^LaJ{Gl$FZt{ zabr*5g21(>p}e7gQx3x4u>QVW%zeY>Q*sVRg}uiGRK8(^}@s7t?zUPPmjg_5S-l<`rpY^2y?`#afQD!GLd@0j}W-Q-GEl1mU) z$qDN|M1sJbkFmRwJHGA-o>sEcqkp3Ldt%B{M7?Ll5v5rBo|USfTCdly%6jX6R5O7=L7FrYSmpWQo~knDddP!_ATLk^VLocqwo|J-B>g z%8phT`-vl-w!!vK9I1mX9(-clD_b9h<_Wmb#YB z(4m%jB3!Vrmi90=9Ia)Zhu-*5OMN}Rq#z|!Y7~%^ptO}f1tc9L`y(i+LJ5&_L*T7d z!lcYLn50#{kUDfgs^FvfjigoDOAcM&BaxSML7YT?vmV$ZDZ$dsUMLmzl)iA&DPg)- z{d6ersjH6#I>k-OABa?1rSFEIOvk7#!{Kf~%o>651}yG85<3JB8H0xg%w{(pjxzNt z|AFB$dz>->DFQv>P$JWRe<~al#=T3xV1bd-k*p};(yud6DEP$LurU~o{%zyh=+%;w%o8Mt)qB#BSh4}a1CEleY(u5IZhw!5bCzyI11tyGiJqwFEtg*r`#gppB*uu&Y~ZmO6|Id>3h%4SyGN36ik#rWA& z@ih*8qSJI5J9F|>ylkL2)HnFs3whRaI>*OHBixL6imaF?;WYxyIE--xV$BqPX;THZ z3JiRMTV_gtl>Y|x%!x5?(OsbY4&R#7|MNR!3iPi;xxh=6aIqjpzsE3vpWY)$U{Vz> z63sk6u=LbX-d%e3cMlfz-HdYnWkP;4#Rid=k_^?uRIL zSQWw_i04{!Gt(8Uv{wA2ZiYB*%@eev4kQ~s-+^Wbvmqa1iP<(hv8}9-A?)kzP+`OK zu%jVb)u;W(#)zrU=f1`nyXwy2J^zgoM;NGp+(wO!`J8-u#>#o}c2S-k`eK!U>GT$$IkmN{v;C@_lq%QmbES#7( zD+Aq}n71esOP!Pu^Iwnf=_SNZnjG!je|$XR4)K?oX;}uArl0SMcQ$IAnA++zLY)~J zd=@jE$=962L1(7iZ~^7cEII2kJesgn&{d3WLT+>&TboetQiu{^FS`wgro?x5F|a9H z;}3kvf=_yY{HBVpBL88a>Czsx_PmZQnknXWMn4q>&(D{12(41?OT;weB_C9d4b2oE zsk9uIi3YP@8E7!qN^!!7GM?2DW{Qbq_8NZ8c_p^KMoe?YY_7nD<~);m?{Kv_&u~H| z3|sJB)A>ERwqPs9Ran@9Egz}Ei546!{sXFo-KiP@F0>a^W2y^xf5Atjx^N3Re?qCS zyVRg%OOAY_2BQTotwl;prIpEbN!E0m5+4;Ei<&F41Kzdd0PcoRTv>dp5kg%#zRadUydI+GYaO$Jb{x;QRvE^?_0vyjaXh6A#MzFsgFr+thu`(Qr%cDQy1!r8fjhDjS%MZ;wIGaTPhIuegLbdUEEKZ85-;c_TXFN5S(u;gTmG+wRUV^`b7m3%YqRPs?st=*2vDy5WQu z{aM|Uy_Ha1Ob;0+I?LAR>&;=Be2KZ<6z}SZL*5i0=!JIzkN1XOD;D`F0+UsCagRN&SzXcj=fAadz6SDX-2I?<6!b3Nf;1J{qSV` z5X?cAti#1%g&8->n#g|m+Jx`$^q=Lw-v0?(5Eh~Ym~Q<=NWA++O_&sgy&=4%#{+qs zhy04&A?)NCzxhKHf1?FEWz9g(ev#N5KuJKTVy<|n($opBtdvF=OG9JB{j%n(gxG|L V9