internal/stream: reject trailing data (no EOF) after end of stream

This commit is contained in:
Filippo Valsorda
2022-06-19 23:11:14 +02:00
parent 2e090545df
commit 3f56ac13fb
45 changed files with 526 additions and 29 deletions

View File

@@ -8,6 +8,7 @@ package stream
import (
"crypto/cipher"
"errors"
"fmt"
"io"
"golang.org/x/crypto/chacha20poly1305"
@@ -66,7 +67,17 @@ func (r *Reader) Read(p []byte) (int, error) {
r.unread = r.unread[n:]
if last {
r.err = io.EOF
// Ensure there is an EOF after the last chunk as expected. In other
// words, check for trailing data after a full-length final chunk.
// Hopefully, the underlying reader supports returning EOF even if it
// had previously returned an EOF to ReadFull.
if _, err := r.src.Read(make([]byte, 1)); err == nil {
r.err = errors.New("trailing data after end of encrypted file")
} else if err != io.EOF {
r.err = fmt.Errorf("non-EOF error reading after end of encrypted file: %w", err)
} else {
r.err = io.EOF
}
}
return n, nil

View File

@@ -9,6 +9,7 @@ import (
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"encoding/hex"
"fmt"
"io"
"os"
@@ -30,6 +31,16 @@ var _, TestX25519Identity, _ = bech32.Decode(
var TestX25519Recipient, _ = curve25519.X25519(TestX25519Identity, curve25519.Basepoint)
// These are the file key and nonce used to encrypt any full/multiple-chunk
// tests. They were generated by a previous iteration of this test suite.
// Reusing them across files and history makes the repository easier to pack and
// the test suite easier to compress.
var LargeTestFileKey, _ = hex.DecodeString("7aa5bdac0e6afeed3dd0a7eccb42af44")
var LargeTestNonce, _ = hex.DecodeString("c82f71eb82029b77136399e485e879f4")
var LargeTestFirstChunk = bytes.Repeat([]byte{0}, 64*1024)
var LargeTestSecondChunk = bytes.Repeat([]byte{1}, 64*1024)
var LargeTestThirdChunk = bytes.Repeat([]byte{2}, 64*1024)
func NotCanonicalBase64(s string) string {
// Assuming there are spare zero bits at the end of the encoded bitstring,
// the character immediately after in the alphabet compared to the last one
@@ -222,6 +233,14 @@ func (f *TestFile) ExpectHeaderFailure() {
func (f *TestFile) ExpectPayloadFailure() {
f.expect = "payload failure"
f.payload.Reset()
}
func (f *TestFile) ExpectPartialPayload(goodBytes int) {
f.expect = "payload failure"
payload := f.payload.Bytes()
f.payload.Reset()
f.payload.Write(payload[:goodBytes])
}
func (f *TestFile) ExpectHMACFailure() {
@@ -238,7 +257,7 @@ func (f *TestFile) Comment(c string) {
func (f *TestFile) Generate() {
fmt.Printf("expect: %s\n", f.expect)
if f.expect == "success" {
if f.expect == "success" || f.expect == "payload failure" {
fmt.Printf("payload: %x\n", sha256.Sum256(f.payload.Bytes()))
}
fmt.Printf("file key: %x\n", f.fileKey)

10
testdata/testkit/stream_bad_tag vendored Normal file
View File

@@ -0,0 +1,10 @@
expect: payload failure
payload: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1XMWWC06LY3EE5RYTXM9MFLAZ2U56JJJ36S0MYPDRWSVLUL66MV4QX3S7F6
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
EmECAEcKN+n/Vs9SbWiV+Hu0r+E8R77DdWYyd83nw7U
--- Vn+54jqiiUCE+WZcEVY3f1sqHjlu/z1LCQ/T7Xm7qI0
îÏbÇδ3'NhÔòùL·L[þ÷¾ªRÈð¼™,ƒ1ûF

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

10
testdata/testkit/stream_missing_tag vendored Normal file
View File

@@ -0,0 +1,10 @@
expect: payload failure
payload: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1XMWWC06LY3EE5RYTXM9MFLAZ2U56JJJ36S0MYPDRWSVLUL66MV4QX3S7F6
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
EmECAEcKN+n/Vs9SbWiV+Hu0r+E8R77DdWYyd83nw7U
--- Vn+54jqiiUCE+WZcEVY3f1sqHjlu/z1LCQ/T7Xm7qI0
îÏbÇδ3'NhÔòùL·L[

10
testdata/testkit/stream_no_chunks vendored Normal file
View File

@@ -0,0 +1,10 @@
expect: payload failure
payload: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1XMWWC06LY3EE5RYTXM9MFLAZ2U56JJJ36S0MYPDRWSVLUL66MV4QX3S7F6
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
EmECAEcKN+n/Vs9SbWiV+Hu0r+E8R77DdWYyd83nw7U
--- Vn+54jqiiUCE+WZcEVY3f1sqHjlu/z1LCQ/T7Xm7qI0
îÏbÇδ3'NhÔòùL

11
testdata/testkit/stream_no_final vendored Normal file
View File

@@ -0,0 +1,11 @@
expect: payload failure
payload: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1XMWWC06LY3EE5RYTXM9MFLAZ2U56JJJ36S0MYPDRWSVLUL66MV4QX3S7F6
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
EmECAEcKN+n/Vs9SbWiV+Hu0r+E8R77DdWYyd83nw7U
--- Vn+54jqiiUCE+WZcEVY3f1sqHjlu/z1LCQ/T7Xm7qI0
îÏbÇδ3'NhÔòùL<>íS ;àû¬|º9¥¥È
w<EFBFBD>

BIN
testdata/testkit/stream_no_final_full vendored Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

8
testdata/testkit/stream_no_nonce vendored Normal file
View File

@@ -0,0 +1,8 @@
expect: header failure
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1XMWWC06LY3EE5RYTXM9MFLAZ2U56JJJ36S0MYPDRWSVLUL66MV4QX3S7F6
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
EmECAEcKN+n/Vs9SbWiV+Hu0r+E8R77DdWYyd83nw7U
--- Vn+54jqiiUCE+WZcEVY3f1sqHjlu/z1LCQ/T7Xm7qI0

10
testdata/testkit/stream_short_chunk vendored Normal file
View File

@@ -0,0 +1,10 @@
expect: payload failure
payload: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1XMWWC06LY3EE5RYTXM9MFLAZ2U56JJJ36S0MYPDRWSVLUL66MV4QX3S7F6
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
EmECAEcKN+n/Vs9SbWiV+Hu0r+E8R77DdWYyd83nw7U
--- Vn+54jqiiUCE+WZcEVY3f1sqHjlu/z1LCQ/T7Xm7qI0
îÏbÇδ3'NhÔòùL[æè. ½Ó#Èw

9
testdata/testkit/stream_short_nonce vendored Normal file
View File

@@ -0,0 +1,9 @@
expect: header failure
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1XMWWC06LY3EE5RYTXM9MFLAZ2U56JJJ36S0MYPDRWSVLUL66MV4QX3S7F6
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
EmECAEcKN+n/Vs9SbWiV+Hu0r+E8R77DdWYyd83nw7U
--- Vn+54jqiiUCE+WZcEVY3f1sqHjlu/z1LCQ/T7Xm7qI0
îÏbÇδ3'NhÔ

Binary file not shown.

BIN
testdata/testkit/stream_three_chunks vendored Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
testdata/testkit/stream_two_chunks vendored Normal file

Binary file not shown.

BIN
testdata/testkit/stream_two_final_chunks vendored Normal file

Binary file not shown.

View File

@@ -155,6 +155,9 @@ func testVector(t *testing.T, test []byte) {
if err != nil {
if expect == "payload failure" {
t.Log(err)
if payloadHash != nil && sha256.Sum256(out) != *payloadHash {
t.Error("partial payload hash mismatch")
}
return
}
t.Fatalf("expected %s, got: %v", expect, err)

23
tests/stream_bad_tag.go Normal file
View File

@@ -0,0 +1,23 @@
// Copyright 2022 The age 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 ignore
package main
import "filippo.io/age/internal/testkit"
func main() {
f := testkit.NewTestFile()
f.VersionLine("v1")
f.X25519(testkit.TestX25519Recipient)
f.HMAC()
f.Payload("age")
file := f.Buf.Bytes()
f.Buf.Reset()
file[len(file)-1] ^= 0b0010_0000
f.Buf.Write(file)
f.ExpectPayloadFailure()
f.Generate()
}

View File

@@ -0,0 +1,26 @@
// Copyright 2022 The age 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 ignore
package main
import "filippo.io/age/internal/testkit"
func main() {
f := testkit.NewTestFile()
f.FileKey(testkit.LargeTestFileKey)
f.VersionLine("v1")
f.X25519(testkit.TestX25519Identity)
f.HMAC()
f.Nonce(testkit.LargeTestNonce)
f.PayloadChunk(testkit.LargeTestFirstChunk)
f.PayloadChunkFinal([]byte("age"))
file := f.Buf.Bytes()
f.Buf.Reset()
file[len(file)-1] ^= 0b0010_0000
f.Buf.Write(file)
f.ExpectPartialPayload(64 * 1024)
f.Generate()
}

View File

@@ -0,0 +1,26 @@
// Copyright 2022 The age 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 ignore
package main
import "filippo.io/age/internal/testkit"
func main() {
f := testkit.NewTestFile()
f.FileKey(testkit.LargeTestFileKey)
f.VersionLine("v1")
f.X25519(testkit.TestX25519Identity)
f.HMAC()
f.Nonce(testkit.LargeTestNonce)
f.PayloadChunk(testkit.LargeTestFirstChunk)
f.PayloadChunkFinal(testkit.LargeTestSecondChunk)
file := f.Buf.Bytes()
f.Buf.Reset()
file[len(file)-1] ^= 0b0010_0000
f.Buf.Write(file)
f.ExpectPartialPayload(64 * 1024)
f.Generate()
}

View File

@@ -6,27 +6,18 @@
package main
import (
"bytes"
"encoding/hex"
"filippo.io/age/internal/testkit"
)
import "filippo.io/age/internal/testkit"
func main() {
f := testkit.NewTestFile()
// Reuse the file key and nonce from a previous test vector to avoid
// bloating the git history with two versions that can't be compressed.
fileKey, _ := hex.DecodeString("7aa5bdac0e6afeed3dd0a7eccb42af44")
f.FileKey(fileKey)
f.FileKey(testkit.LargeTestFileKey)
f.VersionLine("v1")
f.X25519(testkit.TestX25519Identity)
f.HMAC()
nonce, _ := hex.DecodeString("c82f71eb82029b77136399e485e879f4")
f.Nonce(nonce)
f.PayloadChunk(bytes.Repeat([]byte{0}, 64*1024))
f.Nonce(testkit.LargeTestNonce)
f.PayloadChunk(testkit.LargeTestFirstChunk)
f.PayloadChunkFinal([]byte{})
f.Comment("final STREAM chunk can't be empty unless whole payload is empty")
f.ExpectPayloadFailure()
f.ExpectPartialPayload(64 * 1024)
f.Generate()
}

View File

@@ -6,24 +6,15 @@
package main
import (
"bytes"
"encoding/hex"
"filippo.io/age/internal/testkit"
)
import "filippo.io/age/internal/testkit"
func main() {
f := testkit.NewTestFile()
// Reuse the file key and nonce from a previous test vector to avoid
// bloating the git history with two versions that can't be compressed.
fileKey, _ := hex.DecodeString("5085919e0d59b19d6cbd00330f03861c")
f.FileKey(fileKey)
f.FileKey(testkit.LargeTestFileKey)
f.VersionLine("v1")
f.X25519(testkit.TestX25519Identity)
f.HMAC()
nonce, _ := hex.DecodeString("32521791a6f22e11637fb69ead3f2d5f")
f.Nonce(nonce)
f.PayloadChunkFinal(bytes.Repeat([]byte{0}, 64*1024))
f.Nonce(testkit.LargeTestNonce)
f.PayloadChunkFinal(testkit.LargeTestFirstChunk)
f.Generate()
}

View File

@@ -0,0 +1,21 @@
// Copyright 2022 The age 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 ignore
package main
import "filippo.io/age/internal/testkit"
func main() {
f := testkit.NewTestFile()
f.FileKey(testkit.LargeTestFileKey)
f.VersionLine("v1")
f.X25519(testkit.TestX25519Identity)
f.HMAC()
f.Nonce(testkit.LargeTestNonce)
f.PayloadChunk(testkit.LargeTestFirstChunk)
f.PayloadChunkFinal(testkit.LargeTestSecondChunk)
f.Generate()
}

View File

@@ -0,0 +1,22 @@
// Copyright 2022 The age 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 ignore
package main
import "filippo.io/age/internal/testkit"
func main() {
f := testkit.NewTestFile()
f.VersionLine("v1")
f.X25519(testkit.TestX25519Recipient)
f.HMAC()
f.Payload("age")
file := f.Buf.Bytes()
f.Buf.Reset()
f.Buf.Write(file[:len(file)-16])
f.ExpectPayloadFailure()
f.Generate()
}

19
tests/stream_no_chunks.go Normal file
View File

@@ -0,0 +1,19 @@
// Copyright 2022 The age 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 ignore
package main
import "filippo.io/age/internal/testkit"
func main() {
f := testkit.NewTestFile()
f.VersionLine("v1")
f.X25519(testkit.TestX25519Recipient)
f.HMAC()
f.Nonce(f.Rand(16))
f.ExpectPayloadFailure()
f.Generate()
}

20
tests/stream_no_final.go Normal file
View File

@@ -0,0 +1,20 @@
// Copyright 2022 The age 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 ignore
package main
import "filippo.io/age/internal/testkit"
func main() {
f := testkit.NewTestFile()
f.VersionLine("v1")
f.X25519(testkit.TestX25519Recipient)
f.HMAC()
f.Nonce(f.Rand(16))
f.PayloadChunk([]byte("age"))
f.ExpectPayloadFailure()
f.Generate()
}

View File

@@ -0,0 +1,21 @@
// Copyright 2022 The age 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 ignore
package main
import "filippo.io/age/internal/testkit"
func main() {
f := testkit.NewTestFile()
f.FileKey(testkit.LargeTestFileKey)
f.VersionLine("v1")
f.X25519(testkit.TestX25519Identity)
f.HMAC()
f.Nonce(testkit.LargeTestNonce)
f.PayloadChunk(testkit.LargeTestFirstChunk)
f.ExpectPartialPayload(64 * 1024)
f.Generate()
}

View File

@@ -0,0 +1,22 @@
// Copyright 2022 The age 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 ignore
package main
import "filippo.io/age/internal/testkit"
func main() {
f := testkit.NewTestFile()
f.FileKey(testkit.LargeTestFileKey)
f.VersionLine("v1")
f.X25519(testkit.TestX25519Identity)
f.HMAC()
f.Nonce(testkit.LargeTestNonce)
f.PayloadChunk(testkit.LargeTestFirstChunk)
f.PayloadChunk([]byte("age"))
f.ExpectPartialPayload(64 * 1024)
f.Generate()
}

View File

@@ -0,0 +1,22 @@
// Copyright 2022 The age 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 ignore
package main
import "filippo.io/age/internal/testkit"
func main() {
f := testkit.NewTestFile()
f.FileKey(testkit.LargeTestFileKey)
f.VersionLine("v1")
f.X25519(testkit.TestX25519Identity)
f.HMAC()
f.Nonce(testkit.LargeTestNonce)
f.PayloadChunk(testkit.LargeTestFirstChunk)
f.PayloadChunk(testkit.LargeTestSecondChunk)
f.ExpectPartialPayload(64 * 1024 * 2)
f.Generate()
}

20
tests/stream_no_nonce.go Normal file
View File

@@ -0,0 +1,20 @@
// Copyright 2022 The age 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 ignore
package main
import "filippo.io/age/internal/testkit"
func main() {
f := testkit.NewTestFile()
f.VersionLine("v1")
f.X25519(testkit.TestX25519Recipient)
f.HMAC()
// Marked as header failure because we read the nonce while reading the
// header, before handing off to the STREAM implementation.
f.ExpectHeaderFailure()
f.Generate()
}

View File

@@ -0,0 +1,20 @@
// Copyright 2022 The age 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 ignore
package main
import "filippo.io/age/internal/testkit"
func main() {
f := testkit.NewTestFile()
f.VersionLine("v1")
f.X25519(testkit.TestX25519Recipient)
f.HMAC()
f.Nonce(f.Rand(16))
f.Nonce(f.Rand(12)) // less than the length of a Poly1305 tag
f.ExpectPayloadFailure()
f.Generate()
}

View File

@@ -0,0 +1,21 @@
// Copyright 2022 The age 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 ignore
package main
import "filippo.io/age/internal/testkit"
func main() {
f := testkit.NewTestFile()
f.VersionLine("v1")
f.X25519(testkit.TestX25519Recipient)
f.HMAC()
f.Nonce(f.Rand(12))
// Marked as header failure because we read the nonce while reading the
// header, before handing off to the STREAM implementation.
f.ExpectHeaderFailure()
f.Generate()
}

View File

@@ -0,0 +1,22 @@
// Copyright 2022 The age 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 ignore
package main
import "filippo.io/age/internal/testkit"
func main() {
f := testkit.NewTestFile()
f.FileKey(testkit.LargeTestFileKey)
f.VersionLine("v1")
f.X25519(testkit.TestX25519Identity)
f.HMAC()
f.Nonce(testkit.LargeTestNonce)
f.PayloadChunk(testkit.LargeTestFirstChunk)
f.Nonce(f.Rand(12)) // less than the length of a Poly1305 tag
f.ExpectPartialPayload(64 * 1024)
f.Generate()
}

View File

@@ -0,0 +1,22 @@
// Copyright 2022 The age 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 ignore
package main
import "filippo.io/age/internal/testkit"
func main() {
f := testkit.NewTestFile()
f.FileKey(testkit.LargeTestFileKey)
f.VersionLine("v1")
f.X25519(testkit.TestX25519Identity)
f.HMAC()
f.Nonce(testkit.LargeTestNonce)
f.PayloadChunk(testkit.LargeTestFirstChunk)
f.PayloadChunk(testkit.LargeTestSecondChunk)
f.PayloadChunkFinal(testkit.LargeTestThirdChunk)
f.Generate()
}

View File

@@ -0,0 +1,22 @@
// Copyright 2022 The age 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 ignore
package main
import "filippo.io/age/internal/testkit"
func main() {
f := testkit.NewTestFile()
f.FileKey(testkit.LargeTestFileKey)
f.VersionLine("v1")
f.X25519(testkit.TestX25519Identity)
f.HMAC()
f.Nonce(testkit.LargeTestNonce)
f.PayloadChunkFinal(testkit.LargeTestFirstChunk)
f.Buf.Write(f.Rand(20))
f.ExpectPartialPayload(64 * 1024)
f.Generate()
}

View File

@@ -0,0 +1,22 @@
// Copyright 2022 The age 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 ignore
package main
import "filippo.io/age/internal/testkit"
func main() {
f := testkit.NewTestFile()
f.FileKey(testkit.LargeTestFileKey)
f.VersionLine("v1")
f.X25519(testkit.TestX25519Identity)
f.HMAC()
f.Nonce(testkit.LargeTestNonce)
f.PayloadChunkFinal(testkit.LargeTestFirstChunk)
f.Buf.Write(f.Rand(12))
f.ExpectPartialPayload(64 * 1024)
f.Generate()
}

View File

@@ -0,0 +1,21 @@
// Copyright 2022 The age 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 ignore
package main
import "filippo.io/age/internal/testkit"
func main() {
f := testkit.NewTestFile()
f.FileKey(testkit.LargeTestFileKey)
f.VersionLine("v1")
f.X25519(testkit.TestX25519Identity)
f.HMAC()
f.Nonce(testkit.LargeTestNonce)
f.PayloadChunk(testkit.LargeTestFirstChunk)
f.PayloadChunkFinal(testkit.LargeTestSecondChunk)
f.Generate()
}

View File

@@ -0,0 +1,22 @@
// Copyright 2022 The age 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 ignore
package main
import "filippo.io/age/internal/testkit"
func main() {
f := testkit.NewTestFile()
f.FileKey(testkit.LargeTestFileKey)
f.VersionLine("v1")
f.X25519(testkit.TestX25519Identity)
f.HMAC()
f.Nonce(testkit.LargeTestNonce)
f.PayloadChunkFinal(testkit.LargeTestFirstChunk)
f.PayloadChunkFinal([]byte("age"))
f.ExpectPartialPayload(64 * 1024)
f.Generate()
}