Format 3, step 6b: the nine fixtures of format 3
The fixtures of spec 67 for format 3, each with its record, its BODY,
its inspect output and, for time_and_key, its .dkk:
- format3_single, format3_tree (five files in three folders, one over
two STREAM chunks, one without mtime, a comment and a declared
author), format3_comment_only (no files; a TAB in the comment),
format3_bloque256 and format3_time_and_key_portable, written with
EncryptFiles;
- format3_area_1024, format3_security_v2 (verdict X),
format3_signature_unsupported (an author-signature of alg 1 with a
random key of 32 bytes and a random signature of 64: F1) and
format3_seal_unsupported (that and a seal of seal_type 1: F1 and S1),
which only a generator of test vectors writes (62.1 rule 13), built
with testkit.Build.
The record of a format 3 fixture adds the area, SECURITY_CBOR,
HEAD_CBOR, the salt, the comment, the declared author, the head
extensions, the offset of CONTENT in BODY, each file with its layout,
SHA-256 and mtime, and the verdicts with their lines; its plaintext
file is BODY. The generator writes, then recovers every value by
opening layer by layer for the three formats alike, and refreshes the
records of format 3 through a Sink.
Tests: the conformance test checks BODY, the head, security and every
file, and opens through a MemorySink; the .dkk tests take the .dkk of
formats 2 and 3 too (spec 68); the CLI decrypts five of the fixtures
into folders; the control fuzz target decodes with the three schema
versions. The differential corpus gains two bases, format3_single and
format3_time_and_key_portable, one per policy: 5110 cases, the earlier
ones unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"bytes"
|
|
|
|
|
"crypto/rand"
|
|
|
|
|
"crypto/sha256"
|
|
|
|
|
"encoding/hex"
|
|
|
|
|
"errors"
|
|
|
|
|
"fmt"
|
|
|
|
|
"io"
|
|
|
|
|
"reflect"
|
|
|
|
|
"slices"
|
|
|
|
|
"strings"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"g.activething.com/go/DateKeys/capsule"
|
|
|
|
|
"g.activething.com/go/DateKeys/codec"
|
Signature plan, step 6: the fixture format3_signed and the vectors of its signature
format3_signed is written by EncryptFiles with a test key. Its record gives
the seed of the key, control_commit, head_digest, signers_digest,
AUTHOR_MESSAGE with its code, the signature and the content of key 2, and
verdicts carries the dkauthor1 key. The conformance test recomputes all of
it from the control, the head and the security area, and signs again from
the seed. A second test changes the context, a bit of the signature or of
the key, and the key itself, and removes the signature.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
"g.activething.com/go/DateKeys/codec/bech32"
|
Test data for the second implementation: alg 2, the seal and the locator
Fixtures format3_signed_cms (alg 2, two certificates, each sealed, F6) and
format3_sealed (alg 1 and a seal of seal_type 2, F4 and S4), with the
certificates, SIGNERS, the commitments, SEAL_SUBJECT, the token and the
result of each signer in their records. vectors/security_cms.json has 22
frozen areas with their context and verdicts (F1, F2, F5, F6, S1 to S5), and
vectors/locator.json the extension datekeys.capsule with its envelope hidden
in a host, its locator sealed with tlock, the padding at the boundaries and
the rules of the addresses. The README of testdata describes all of it.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
"g.activething.com/go/DateKeys/internal/cms"
|
Format 3, step 6b: the nine fixtures of format 3
The fixtures of spec 67 for format 3, each with its record, its BODY,
its inspect output and, for time_and_key, its .dkk:
- format3_single, format3_tree (five files in three folders, one over
two STREAM chunks, one without mtime, a comment and a declared
author), format3_comment_only (no files; a TAB in the comment),
format3_bloque256 and format3_time_and_key_portable, written with
EncryptFiles;
- format3_area_1024, format3_security_v2 (verdict X),
format3_signature_unsupported (an author-signature of alg 1 with a
random key of 32 bytes and a random signature of 64: F1) and
format3_seal_unsupported (that and a seal of seal_type 1: F1 and S1),
which only a generator of test vectors writes (62.1 rule 13), built
with testkit.Build.
The record of a format 3 fixture adds the area, SECURITY_CBOR,
HEAD_CBOR, the salt, the comment, the declared author, the head
extensions, the offset of CONTENT in BODY, each file with its layout,
SHA-256 and mtime, and the verdicts with their lines; its plaintext
file is BODY. The generator writes, then recovers every value by
opening layer by layer for the three formats alike, and refreshes the
records of format 3 through a Sink.
Tests: the conformance test checks BODY, the head, security and every
file, and opens through a MemorySink; the .dkk tests take the .dkk of
formats 2 and 3 too (spec 68); the CLI decrypts five of the fixtures
into folders; the control fuzz target decodes with the three schema
versions. The differential corpus gains two bases, format3_single and
format3_time_and_key_portable, one per policy: 5110 cases, the earlier
ones unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
"g.activething.com/go/DateKeys/internal/testkit"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// file3 is a file of a format 3 fixture; a zero mtime is none.
|
|
|
|
|
type file3 struct {
|
|
|
|
|
path string
|
|
|
|
|
content []byte
|
|
|
|
|
mtime time.Time
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// sources returns the files as the Sources of capsule.EncryptFiles.
|
|
|
|
|
func sources(files []file3) []capsule.Source {
|
|
|
|
|
var out []capsule.Source
|
|
|
|
|
for _, f := range files {
|
|
|
|
|
content := f.content
|
|
|
|
|
out = append(out, capsule.Source{Path: f.path, Size: int64(len(content)), ModTime: f.mtime,
|
|
|
|
|
Open: func() (io.ReadCloser, error) { return io.NopCloser(bytes.NewReader(content)), nil }})
|
|
|
|
|
}
|
|
|
|
|
return out
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// body3 returns the BODY of a capsule that only a generator of test vectors
|
|
|
|
|
// writes (spec §62.1 rule 13): the files, in the byte order of their paths,
|
|
|
|
|
// with a fresh salt, and security in an area of area bytes. The reader must
|
|
|
|
|
// accept its head.
|
|
|
|
|
func body3(area uint32, security []byte, comment, author string, files []file3) ([]byte, error) {
|
|
|
|
|
files = slices.Clone(files)
|
|
|
|
|
slices.SortFunc(files, func(a, b file3) int { return strings.Compare(a.path, b.path) })
|
|
|
|
|
h := &capsule.Head{Comment: comment, Author: author}
|
|
|
|
|
_, _ = rand.Read(h.Salt[:])
|
|
|
|
|
var contents [][]byte
|
|
|
|
|
var end uint64
|
|
|
|
|
for _, f := range files {
|
|
|
|
|
n := uint64(len(f.content))
|
|
|
|
|
e := capsule.File{Path: f.path, Size: n, Start: end, End: end + n, SHA256: sha256.Sum256(f.content)}
|
|
|
|
|
if !f.mtime.IsZero() {
|
|
|
|
|
e.MTime, e.HasMTime = uint64(f.mtime.Unix()), true
|
|
|
|
|
}
|
|
|
|
|
h.Files = append(h.Files, e)
|
|
|
|
|
contents = append(contents, f.content)
|
|
|
|
|
end += n
|
|
|
|
|
}
|
|
|
|
|
hb, err := capsule.EncodeHead(h)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
if _, err := capsule.DecodeHead(hb, nil); err != nil {
|
|
|
|
|
return nil, fmt.Errorf("the reader rejects the head: %w", err)
|
|
|
|
|
}
|
|
|
|
|
return testkit.Body3(area, security, hb, contents...), nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// securityV2 is SECURITY_CBOR of version 2, {0: "datekeys-security", 1: 2},
|
|
|
|
|
// which a reader of this version cannot read (verdict X).
|
|
|
|
|
func securityV2() ([]byte, error) {
|
|
|
|
|
var e codec.Encoder
|
|
|
|
|
e.Map(2)
|
|
|
|
|
e.Uint(0)
|
|
|
|
|
e.Text(capsule.SecurityTypeTag)
|
|
|
|
|
e.Uint(1)
|
|
|
|
|
e.Uint(2)
|
|
|
|
|
return e.Out()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// randomBytes returns n bytes of a CSPRNG.
|
|
|
|
|
func randomBytes(n int) []byte {
|
|
|
|
|
b := make([]byte, n)
|
|
|
|
|
_, _ = rand.Read(b)
|
|
|
|
|
return b
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// unsupportedSignature is the content of key 2 of security: an
|
|
|
|
|
// author-signature of an alg that no version defines, 4294967295, with a
|
|
|
|
|
// random key of 32 bytes and a random signature of 64 (verdict F1: this
|
|
|
|
|
// reader does not implement that alg; spec v0.11, §29.7).
|
Format 3, step 6b: the nine fixtures of format 3
The fixtures of spec 67 for format 3, each with its record, its BODY,
its inspect output and, for time_and_key, its .dkk:
- format3_single, format3_tree (five files in three folders, one over
two STREAM chunks, one without mtime, a comment and a declared
author), format3_comment_only (no files; a TAB in the comment),
format3_bloque256 and format3_time_and_key_portable, written with
EncryptFiles;
- format3_area_1024, format3_security_v2 (verdict X),
format3_signature_unsupported (an author-signature of alg 1 with a
random key of 32 bytes and a random signature of 64: F1) and
format3_seal_unsupported (that and a seal of seal_type 1: F1 and S1),
which only a generator of test vectors writes (62.1 rule 13), built
with testkit.Build.
The record of a format 3 fixture adds the area, SECURITY_CBOR,
HEAD_CBOR, the salt, the comment, the declared author, the head
extensions, the offset of CONTENT in BODY, each file with its layout,
SHA-256 and mtime, and the verdicts with their lines; its plaintext
file is BODY. The generator writes, then recovers every value by
opening layer by layer for the three formats alike, and refreshes the
records of format 3 through a Sink.
Tests: the conformance test checks BODY, the head, security and every
file, and opens through a MemorySink; the .dkk tests take the .dkk of
formats 2 and 3 too (spec 68); the CLI decrypts five of the fixtures
into folders; the control fuzz target decodes with the three schema
versions. The differential corpus gains two bases, format3_single and
format3_time_and_key_portable, one per policy: 5110 cases, the earlier
ones unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
func unsupportedSignature() ([]byte, error) {
|
|
|
|
|
return capsule.EncodeAuthorSignature(capsule.AlgTest, randomBytes(32), randomBytes(64))
|
Format 3, step 6b: the nine fixtures of format 3
The fixtures of spec 67 for format 3, each with its record, its BODY,
its inspect output and, for time_and_key, its .dkk:
- format3_single, format3_tree (five files in three folders, one over
two STREAM chunks, one without mtime, a comment and a declared
author), format3_comment_only (no files; a TAB in the comment),
format3_bloque256 and format3_time_and_key_portable, written with
EncryptFiles;
- format3_area_1024, format3_security_v2 (verdict X),
format3_signature_unsupported (an author-signature of alg 1 with a
random key of 32 bytes and a random signature of 64: F1) and
format3_seal_unsupported (that and a seal of seal_type 1: F1 and S1),
which only a generator of test vectors writes (62.1 rule 13), built
with testkit.Build.
The record of a format 3 fixture adds the area, SECURITY_CBOR,
HEAD_CBOR, the salt, the comment, the declared author, the head
extensions, the offset of CONTENT in BODY, each file with its layout,
SHA-256 and mtime, and the verdicts with their lines; its plaintext
file is BODY. The generator writes, then recovers every value by
opening layer by layer for the three formats alike, and refreshes the
records of format 3 through a Sink.
Tests: the conformance test checks BODY, the head, security and every
file, and opens through a MemorySink; the .dkk tests take the .dkk of
formats 2 and 3 too (spec 68); the CLI decrypts five of the fixtures
into folders; the control fuzz target decodes with the three schema
versions. The differential corpus gains two bases, format3_single and
format3_time_and_key_portable, one per policy: 5110 cases, the earlier
ones unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// patterned returns n bytes that look like the content of a binary file:
|
|
|
|
|
// SHA-256 in counter mode over seed.
|
|
|
|
|
func patterned(seed string, n int) []byte {
|
|
|
|
|
var out []byte
|
|
|
|
|
for i := 0; len(out) < n; i++ {
|
|
|
|
|
s := sha256.Sum256(fmt.Appendf(nil, "%s %d", seed, i))
|
|
|
|
|
out = append(out, s[:]...)
|
|
|
|
|
}
|
|
|
|
|
return out[:n]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// record3 fills the fields of format 3 of f from BODY, the first L bytes of
|
|
|
|
|
// the plaintext of PAYLOAD_AGE, checking it with the rules of the reader.
|
Signature plan, step 6: the fixture format3_signed and the vectors of its signature
format3_signed is written by EncryptFiles with a test key. Its record gives
the seed of the key, control_commit, head_digest, signers_digest,
AUTHOR_MESSAGE with its code, the signature and the content of key 2, and
verdicts carries the dkauthor1 key. The conformance test recomputes all of
it from the control, the head and the security area, and signs again from
the seed. A second test changes the context, a bit of the signature or of
the key, and the key itself, and removes the signature.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
func record3(f *testkit.DKCFixture, body []byte, verdicts *capsule.Verdicts) error {
|
Format 3, step 6b: the nine fixtures of format 3
The fixtures of spec 67 for format 3, each with its record, its BODY,
its inspect output and, for time_and_key, its .dkk:
- format3_single, format3_tree (five files in three folders, one over
two STREAM chunks, one without mtime, a comment and a declared
author), format3_comment_only (no files; a TAB in the comment),
format3_bloque256 and format3_time_and_key_portable, written with
EncryptFiles;
- format3_area_1024, format3_security_v2 (verdict X),
format3_signature_unsupported (an author-signature of alg 1 with a
random key of 32 bytes and a random signature of 64: F1) and
format3_seal_unsupported (that and a seal of seal_type 1: F1 and S1),
which only a generator of test vectors writes (62.1 rule 13), built
with testkit.Build.
The record of a format 3 fixture adds the area, SECURITY_CBOR,
HEAD_CBOR, the salt, the comment, the declared author, the head
extensions, the offset of CONTENT in BODY, each file with its layout,
SHA-256 and mtime, and the verdicts with their lines; its plaintext
file is BODY. The generator writes, then recovers every value by
opening layer by layer for the three formats alike, and refreshes the
records of format 3 through a Sink.
Tests: the conformance test checks BODY, the head, security and every
file, and opens through a MemorySink; the .dkk tests take the .dkk of
formats 2 and 3 too (spec 68); the CLI decrypts five of the fixtures
into folders; the control fuzz target decodes with the three schema
versions. The differential corpus gains two bases, format3_single and
format3_time_and_key_portable, one per policy: 5110 cases, the earlier
ones unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
l := uint64(len(body))
|
|
|
|
|
if l < capsule.BodyFrameSize {
|
|
|
|
|
return errors.New("BODY shorter than its frame")
|
|
|
|
|
}
|
|
|
|
|
frame, err := capsule.ParseBodyFrame(body[:capsule.BodyFrameSize], l)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
area := body[capsule.BodyFrameSize : capsule.BodyFrameSize+uint64(frame.AreaLen)]
|
|
|
|
|
if err := capsule.CheckArea(area, frame.SecurityLen); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
security := area[:frame.SecurityLen]
|
|
|
|
|
offset := capsule.BodyFrameSize + uint64(frame.AreaLen) + uint64(frame.HeadLen)
|
|
|
|
|
hb := body[capsule.BodyFrameSize+uint64(frame.AreaLen) : offset]
|
|
|
|
|
h, err := capsule.DecodeHead(hb, nil)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
if err := capsule.CheckHeadEnd(h, frame.ContentLength(l)); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
v := capsule.EvaluateSecurity(security)
|
Signature plan, step 6: the fixture format3_signed and the vectors of its signature
format3_signed is written by EncryptFiles with a test key. Its record gives
the seed of the key, control_commit, head_digest, signers_digest,
AUTHOR_MESSAGE with its code, the signature and the content of key 2, and
verdicts carries the dkauthor1 key. The conformance test recomputes all of
it from the control, the head and the security area, and signs again from
the seed. A second test changes the context, a bit of the signature or of
the key, and the key itself, and removes the signature.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
if verdicts != nil {
|
|
|
|
|
v = *verdicts
|
|
|
|
|
}
|
Format 3, step 6b: the nine fixtures of format 3
The fixtures of spec 67 for format 3, each with its record, its BODY,
its inspect output and, for time_and_key, its .dkk:
- format3_single, format3_tree (five files in three folders, one over
two STREAM chunks, one without mtime, a comment and a declared
author), format3_comment_only (no files; a TAB in the comment),
format3_bloque256 and format3_time_and_key_portable, written with
EncryptFiles;
- format3_area_1024, format3_security_v2 (verdict X),
format3_signature_unsupported (an author-signature of alg 1 with a
random key of 32 bytes and a random signature of 64: F1) and
format3_seal_unsupported (that and a seal of seal_type 1: F1 and S1),
which only a generator of test vectors writes (62.1 rule 13), built
with testkit.Build.
The record of a format 3 fixture adds the area, SECURITY_CBOR,
HEAD_CBOR, the salt, the comment, the declared author, the head
extensions, the offset of CONTENT in BODY, each file with its layout,
SHA-256 and mtime, and the verdicts with their lines; its plaintext
file is BODY. The generator writes, then recovers every value by
opening layer by layer for the three formats alike, and refreshes the
records of format 3 through a Sink.
Tests: the conformance test checks BODY, the head, security and every
file, and opens through a MemorySink; the .dkk tests take the .dkk of
formats 2 and 3 too (spec 68); the CLI decrypts five of the fixtures
into folders; the control fuzz target decodes with the three schema
versions. The differential corpus gains two bases, format3_single and
format3_time_and_key_portable, one per policy: 5110 cases, the earlier
ones unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
f.AreaLen = frame.AreaLen
|
|
|
|
|
f.Security = hex.EncodeToString(security)
|
|
|
|
|
f.Head = hex.EncodeToString(hb)
|
|
|
|
|
f.Salt = hex.EncodeToString(h.Salt[:])
|
|
|
|
|
f.Comment, f.Author = h.Comment, h.Author
|
|
|
|
|
f.HeadExtensions = exts(false, h.Noncritical)
|
|
|
|
|
f.ContentOffset = offset
|
|
|
|
|
f.Files = nil
|
|
|
|
|
for _, e := range h.Files {
|
|
|
|
|
content := body[offset+e.Start : offset+e.End]
|
|
|
|
|
if sha256.Sum256(content) != e.SHA256 {
|
|
|
|
|
return fmt.Errorf("file %q: its SHA-256 is not the one of the head", e.Path)
|
|
|
|
|
}
|
|
|
|
|
ff := testkit.FixtureFile{Path: e.Path, Size: e.Size, Start: e.Start, End: e.End, SHA256: hex.EncodeToString(e.SHA256[:])}
|
|
|
|
|
if e.HasMTime {
|
|
|
|
|
m := e.MTime
|
|
|
|
|
ff.MTime = &m
|
|
|
|
|
}
|
|
|
|
|
f.Files = append(f.Files, ff)
|
|
|
|
|
}
|
|
|
|
|
f.Verdicts = &testkit.FixtureVerdicts{Signature: string(v.Signature), Seal: string(v.Seal), Lines: v.Lines()}
|
Signature plan, step 6: the fixture format3_signed and the vectors of its signature
format3_signed is written by EncryptFiles with a test key. Its record gives
the seed of the key, control_commit, head_digest, signers_digest,
AUTHOR_MESSAGE with its code, the signature and the content of key 2, and
verdicts carries the dkauthor1 key. The conformance test recomputes all of
it from the control, the head and the security area, and signs again from
the seed. A second test changes the context, a bit of the signature or of
the key, and the key itself, and removes the signature.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
f.Signature, err = recordSignature(f, security, hb, v)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
if f.Signature != nil {
|
|
|
|
|
f.Verdicts.AuthorKey = f.Signature.AuthorKey
|
|
|
|
|
}
|
Test data for the second implementation: alg 2, the seal and the locator
Fixtures format3_signed_cms (alg 2, two certificates, each sealed, F6) and
format3_sealed (alg 1 and a seal of seal_type 2, F4 and S4), with the
certificates, SIGNERS, the commitments, SEAL_SUBJECT, the token and the
result of each signer in their records. vectors/security_cms.json has 22
frozen areas with their context and verdicts (F1, F2, F5, F6, S1 to S5), and
vectors/locator.json the extension datekeys.capsule with its envelope hidden
in a host, its locator sealed with tlock, the padding at the boundaries and
the rules of the addresses. The README of testdata describes all of it.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
f.Seal, err = recordSeal(f, security, hb, v)
|
|
|
|
|
return err
|
Format 3, step 6b: the nine fixtures of format 3
The fixtures of spec 67 for format 3, each with its record, its BODY,
its inspect output and, for time_and_key, its .dkk:
- format3_single, format3_tree (five files in three folders, one over
two STREAM chunks, one without mtime, a comment and a declared
author), format3_comment_only (no files; a TAB in the comment),
format3_bloque256 and format3_time_and_key_portable, written with
EncryptFiles;
- format3_area_1024, format3_security_v2 (verdict X),
format3_signature_unsupported (an author-signature of alg 1 with a
random key of 32 bytes and a random signature of 64: F1) and
format3_seal_unsupported (that and a seal of seal_type 1: F1 and S1),
which only a generator of test vectors writes (62.1 rule 13), built
with testkit.Build.
The record of a format 3 fixture adds the area, SECURITY_CBOR,
HEAD_CBOR, the salt, the comment, the declared author, the head
extensions, the offset of CONTENT in BODY, each file with its layout,
SHA-256 and mtime, and the verdicts with their lines; its plaintext
file is BODY. The generator writes, then recovers every value by
opening layer by layer for the three formats alike, and refreshes the
records of format 3 through a Sink.
Tests: the conformance test checks BODY, the head, security and every
file, and opens through a MemorySink; the .dkk tests take the .dkk of
formats 2 and 3 too (spec 68); the CLI decrypts five of the fixtures
into folders; the control fuzz target decodes with the three schema
versions. The differential corpus gains two bases, format3_single and
format3_time_and_key_portable, one per policy: 5110 cases, the earlier
ones unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
}
|
|
|
|
|
|
Test data for the second implementation: alg 2, the seal and the locator
Fixtures format3_signed_cms (alg 2, two certificates, each sealed, F6) and
format3_sealed (alg 1 and a seal of seal_type 2, F4 and S4), with the
certificates, SIGNERS, the commitments, SEAL_SUBJECT, the token and the
result of each signer in their records. vectors/security_cms.json has 22
frozen areas with their context and verdicts (F1, F2, F5, F6, S1 to S5), and
vectors/locator.json the extension datekeys.capsule with its envelope hidden
in a host, its locator sealed with tlock, the padding at the boundaries and
the rules of the addresses. The README of testdata describes all of it.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
// commitmentsOf returns control_commit and head_digest of the fixture f, from
|
|
|
|
|
// its control and its head (spec v0.11, §29.8).
|
|
|
|
|
func commitmentsOf(f *testkit.DKCFixture, head []byte) (cc, hd [32]byte, err error) {
|
Signature plan, step 6: the fixture format3_signed and the vectors of its signature
format3_signed is written by EncryptFiles with a test key. Its record gives
the seed of the key, control_commit, head_digest, signers_digest,
AUTHOR_MESSAGE with its code, the signature and the content of key 2, and
verdicts carries the dkauthor1 key. The conformance test recomputes all of
it from the control, the head and the security area, and signs again from
the seed. A second test changes the context, a bit of the signature or of
the key, and the key itself, and removes the signature.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
cb, err := hex.DecodeString(f.ControlCBOR)
|
|
|
|
|
if err != nil {
|
Test data for the second implementation: alg 2, the seal and the locator
Fixtures format3_signed_cms (alg 2, two certificates, each sealed, F6) and
format3_sealed (alg 1 and a seal of seal_type 2, F4 and S4), with the
certificates, SIGNERS, the commitments, SEAL_SUBJECT, the token and the
result of each signer in their records. vectors/security_cms.json has 22
frozen areas with their context and verdicts (F1, F2, F5, F6, S1 to S5), and
vectors/locator.json the extension datekeys.capsule with its envelope hidden
in a host, its locator sealed with tlock, the padding at the boundaries and
the rules of the addresses. The README of testdata describes all of it.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
return cc, hd, err
|
Signature plan, step 6: the fixture format3_signed and the vectors of its signature
format3_signed is written by EncryptFiles with a test key. Its record gives
the seed of the key, control_commit, head_digest, signers_digest,
AUTHOR_MESSAGE with its code, the signature and the content of key 2, and
verdicts carries the dkauthor1 key. The conformance test recomputes all of
it from the control, the head and the security area, and signs again from
the seed. A second test changes the context, a bit of the signature or of
the key, and the key itself, and removes the signature.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
}
|
|
|
|
|
c, err := capsule.DecodeControl(cb, capsule.Format(f.Format))
|
|
|
|
|
if err != nil {
|
Test data for the second implementation: alg 2, the seal and the locator
Fixtures format3_signed_cms (alg 2, two certificates, each sealed, F6) and
format3_sealed (alg 1 and a seal of seal_type 2, F4 and S4), with the
certificates, SIGNERS, the commitments, SEAL_SUBJECT, the token and the
result of each signer in their records. vectors/security_cms.json has 22
frozen areas with their context and verdicts (F1, F2, F5, F6, S1 to S5), and
vectors/locator.json the extension datekeys.capsule with its envelope hidden
in a host, its locator sealed with tlock, the padding at the boundaries and
the rules of the addresses. The README of testdata describes all of it.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
return cc, hd, err
|
Signature plan, step 6: the fixture format3_signed and the vectors of its signature
format3_signed is written by EncryptFiles with a test key. Its record gives
the seed of the key, control_commit, head_digest, signers_digest,
AUTHOR_MESSAGE with its code, the signature and the content of key 2, and
verdicts carries the dkauthor1 key. The conformance test recomputes all of
it from the control, the head and the security area, and signs again from
the seed. A second test changes the context, a bit of the signature or of
the key, and the key itself, and removes the signature.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
}
|
|
|
|
|
defer clear(c.PayloadIdentity[:])
|
Test data for the second implementation: alg 2, the seal and the locator
Fixtures format3_signed_cms (alg 2, two certificates, each sealed, F6) and
format3_sealed (alg 1 and a seal of seal_type 2, F4 and S4), with the
certificates, SIGNERS, the commitments, SEAL_SUBJECT, the token and the
result of each signer in their records. vectors/security_cms.json has 22
frozen areas with their context and verdicts (F1, F2, F5, F6, S1 to S5), and
vectors/locator.json the extension datekeys.capsule with its envelope hidden
in a host, its locator sealed with tlock, the padding at the boundaries and
the rules of the addresses. The README of testdata describes all of it.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
if cc, err = capsule.ControlCommit(c, capsule.Format(f.Format)); err != nil {
|
|
|
|
|
return cc, hd, err
|
|
|
|
|
}
|
|
|
|
|
return cc, capsule.HeadDigest(head), nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func signerResults(lines []capsule.SignerLine) []testkit.FixtureSignerResult {
|
|
|
|
|
var out []testkit.FixtureSignerResult
|
|
|
|
|
for _, l := range lines {
|
|
|
|
|
r := testkit.FixtureSignerResult{Holder: l.Holder, Issuer: l.Issuer, Result: l.Result, Before: l.Before}
|
|
|
|
|
if !l.SealTime.IsZero() {
|
|
|
|
|
r.SealTime = l.SealTime.UTC().Format(time.RFC3339)
|
|
|
|
|
}
|
|
|
|
|
out = append(out, r)
|
|
|
|
|
}
|
|
|
|
|
return out
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// recordSignature returns what the record of a fixture says about its
|
|
|
|
|
// signature: with alg 1, the seed of its test key, which the generator wrote
|
|
|
|
|
// and this keeps, and the commitments and the message, which it computes from
|
|
|
|
|
// the control of the fixture, its head and its security (spec v0.11, §29.8);
|
|
|
|
|
// with alg 2, the same without a seed, and the certificates, SIGNERS and the
|
|
|
|
|
// result of each signer that Open gave. Nil when the fixture has no valid
|
|
|
|
|
// signature of alg 1 and no signature of alg 2 that Open judged.
|
|
|
|
|
func recordSignature(f *testkit.DKCFixture, security, head []byte, v capsule.Verdicts) (*testkit.FixtureSignature, error) {
|
|
|
|
|
content, value, err := capsule.SecurityKey2(security)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, nil // no signature
|
|
|
|
|
}
|
|
|
|
|
alg, key, _, err := capsule.DecodeAuthorSignature(content)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, nil
|
|
|
|
|
}
|
|
|
|
|
switch {
|
|
|
|
|
case alg == capsule.AlgEd25519 && (v.Signature == capsule.VerdictSignedOther || v.Signature == capsule.VerdictSignedSaved):
|
|
|
|
|
if f.Signature == nil {
|
|
|
|
|
return nil, errors.New("the fixture has a valid signature and its record no seed of the key")
|
|
|
|
|
}
|
|
|
|
|
case alg == capsule.AlgCMS && v.Detail != nil:
|
|
|
|
|
default:
|
|
|
|
|
return nil, nil
|
|
|
|
|
}
|
|
|
|
|
cc, hd, err := commitmentsOf(f, head)
|
Signature plan, step 6: the fixture format3_signed and the vectors of its signature
format3_signed is written by EncryptFiles with a test key. Its record gives
the seed of the key, control_commit, head_digest, signers_digest,
AUTHOR_MESSAGE with its code, the signature and the content of key 2, and
verdicts carries the dkauthor1 key. The conformance test recomputes all of
it from the control, the head and the security area, and signs again from
the seed. A second test changes the context, a bit of the signature or of
the key, and the key itself, and removes the signature.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
Test data for the second implementation: alg 2, the seal and the locator
Fixtures format3_signed_cms (alg 2, two certificates, each sealed, F6) and
format3_sealed (alg 1 and a seal of seal_type 2, F4 and S4), with the
certificates, SIGNERS, the commitments, SEAL_SUBJECT, the token and the
result of each signer in their records. vectors/security_cms.json has 22
frozen areas with their context and verdicts (F1, F2, F5, F6, S1 to S5), and
vectors/locator.json the extension datekeys.capsule with its envelope hidden
in a host, its locator sealed with tlock, the padding at the boundaries and
the rules of the addresses. The README of testdata describes all of it.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
var sd [32]byte
|
|
|
|
|
sig := &testkit.FixtureSignature{Alg: int(alg), SignatureValue: hex.EncodeToString(value), SecurityKey2: hex.EncodeToString(content)}
|
|
|
|
|
if alg == capsule.AlgEd25519 {
|
|
|
|
|
sd = capsule.SignersDigest(capsule.AlgEd25519, nil)
|
|
|
|
|
sig.SecretSeed = f.Signature.SecretSeed
|
|
|
|
|
if sig.AuthorKey, err = bech32.Encode("dkauthor", v.AuthorKey[:]); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
sd = capsule.SignersDigest(capsule.AlgCMS, key)
|
|
|
|
|
sig.Signers = hex.EncodeToString(key)
|
|
|
|
|
parsed, err := cms.ParseSignature(value)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
for _, c := range parsed.Certs {
|
|
|
|
|
sig.Certificates = append(sig.Certificates, hex.EncodeToString(c.Raw))
|
|
|
|
|
}
|
|
|
|
|
sig.Results, sig.Foreign = signerResults(v.Detail.Signers), signerResults(v.Detail.Foreign)
|
|
|
|
|
}
|
Signature plan, step 6: the fixture format3_signed and the vectors of its signature
format3_signed is written by EncryptFiles with a test key. Its record gives
the seed of the key, control_commit, head_digest, signers_digest,
AUTHOR_MESSAGE with its code, the signature and the content of key 2, and
verdicts carries the dkauthor1 key. The conformance test recomputes all of
it from the control, the head and the security area, and signs again from
the seed. A second test changes the context, a bit of the signature or of
the key, and the key itself, and removes the signature.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
msg := capsule.AuthorMessage(cc, hd, sd)
|
Test data for the second implementation: alg 2, the seal and the locator
Fixtures format3_signed_cms (alg 2, two certificates, each sealed, F6) and
format3_sealed (alg 1 and a seal of seal_type 2, F4 and S4), with the
certificates, SIGNERS, the commitments, SEAL_SUBJECT, the token and the
result of each signer in their records. vectors/security_cms.json has 22
frozen areas with their context and verdicts (F1, F2, F5, F6, S1 to S5), and
vectors/locator.json the extension datekeys.capsule with its envelope hidden
in a host, its locator sealed with tlock, the padding at the boundaries and
the rules of the addresses. The README of testdata describes all of it.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
sig.ControlCommit, sig.HeadDigest, sig.SignersDigest = hex.EncodeToString(cc[:]), hex.EncodeToString(hd[:]), hex.EncodeToString(sd[:])
|
|
|
|
|
sig.AuthorMessage, sig.AuthorCode = string(msg), capsule.AuthorCode(msg)
|
|
|
|
|
return sig, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// recordSeal returns what the record of a fixture says about its seal of
|
|
|
|
|
// seal_type 2 when Open found it valid (S4 or S5): SEAL_SUBJECT, the token
|
|
|
|
|
// and the authority and the time that the verdict names.
|
|
|
|
|
func recordSeal(f *testkit.DKCFixture, security, head []byte, v capsule.Verdicts) (*testkit.FixtureSeal, error) {
|
|
|
|
|
if (v.Seal != capsule.VerdictSealed && v.Seal != capsule.VerdictSealedLate) || v.Detail == nil {
|
|
|
|
|
return nil, nil
|
|
|
|
|
}
|
|
|
|
|
typ, token, err := capsule.SecurityKey3(security)
|
Signature plan, step 6: the fixture format3_signed and the vectors of its signature
format3_signed is written by EncryptFiles with a test key. Its record gives
the seed of the key, control_commit, head_digest, signers_digest,
AUTHOR_MESSAGE with its code, the signature and the content of key 2, and
verdicts carries the dkauthor1 key. The conformance test recomputes all of
it from the control, the head and the security area, and signs again from
the seed. A second test changes the context, a bit of the signature or of
the key, and the key itself, and removes the signature.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
Test data for the second implementation: alg 2, the seal and the locator
Fixtures format3_signed_cms (alg 2, two certificates, each sealed, F6) and
format3_sealed (alg 1 and a seal of seal_type 2, F4 and S4), with the
certificates, SIGNERS, the commitments, SEAL_SUBJECT, the token and the
result of each signer in their records. vectors/security_cms.json has 22
frozen areas with their context and verdicts (F1, F2, F5, F6, S1 to S5), and
vectors/locator.json the extension datekeys.capsule with its envelope hidden
in a host, its locator sealed with tlock, the padding at the boundaries and
the rules of the addresses. The README of testdata describes all of it.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
cc, hd, err := commitmentsOf(f, head)
|
Signature plan, step 6: the fixture format3_signed and the vectors of its signature
format3_signed is written by EncryptFiles with a test key. Its record gives
the seed of the key, control_commit, head_digest, signers_digest,
AUTHOR_MESSAGE with its code, the signature and the content of key 2, and
verdicts carries the dkauthor1 key. The conformance test recomputes all of
it from the control, the head and the security area, and signs again from
the seed. A second test changes the context, a bit of the signature or of
the key, and the key itself, and removes the signature.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
Test data for the second implementation: alg 2, the seal and the locator
Fixtures format3_signed_cms (alg 2, two certificates, each sealed, F6) and
format3_sealed (alg 1 and a seal of seal_type 2, F4 and S4), with the
certificates, SIGNERS, the commitments, SEAL_SUBJECT, the token and the
result of each signer in their records. vectors/security_cms.json has 22
frozen areas with their context and verdicts (F1, F2, F5, F6, S1 to S5), and
vectors/locator.json the extension datekeys.capsule with its envelope hidden
in a host, its locator sealed with tlock, the padding at the boundaries and
the rules of the addresses. The README of testdata describes all of it.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
var part []byte
|
|
|
|
|
if content, _, err := capsule.SecurityKey2(security); err == nil {
|
|
|
|
|
part = content
|
|
|
|
|
}
|
|
|
|
|
subject := capsule.SealSubject(cc, hd, capsule.SigPart(part))
|
|
|
|
|
return &testkit.FixtureSeal{
|
|
|
|
|
SealType: int(typ), SealSubject: hex.EncodeToString(subject[:]), Token: hex.EncodeToString(token),
|
|
|
|
|
Holder: v.Detail.SealHolder, Time: v.Detail.SealTime.UTC().Format(time.RFC3339),
|
Signature plan, step 6: the fixture format3_signed and the vectors of its signature
format3_signed is written by EncryptFiles with a test key. Its record gives
the seed of the key, control_commit, head_digest, signers_digest,
AUTHOR_MESSAGE with its code, the signature and the content of key 2, and
verdicts carries the dkauthor1 key. The conformance test recomputes all of
it from the control, the head and the security area, and signs again from
the seed. A second test changes the context, a bit of the signature or of
the key, and the key itself, and removes the signature.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
}, nil
|
|
|
|
|
}
|
|
|
|
|
|
Format 3, step 6b: the nine fixtures of format 3
The fixtures of spec 67 for format 3, each with its record, its BODY,
its inspect output and, for time_and_key, its .dkk:
- format3_single, format3_tree (five files in three folders, one over
two STREAM chunks, one without mtime, a comment and a declared
author), format3_comment_only (no files; a TAB in the comment),
format3_bloque256 and format3_time_and_key_portable, written with
EncryptFiles;
- format3_area_1024, format3_security_v2 (verdict X),
format3_signature_unsupported (an author-signature of alg 1 with a
random key of 32 bytes and a random signature of 64: F1) and
format3_seal_unsupported (that and a seal of seal_type 1: F1 and S1),
which only a generator of test vectors writes (62.1 rule 13), built
with testkit.Build.
The record of a format 3 fixture adds the area, SECURITY_CBOR,
HEAD_CBOR, the salt, the comment, the declared author, the head
extensions, the offset of CONTENT in BODY, each file with its layout,
SHA-256 and mtime, and the verdicts with their lines; its plaintext
file is BODY. The generator writes, then recovers every value by
opening layer by layer for the three formats alike, and refreshes the
records of format 3 through a Sink.
Tests: the conformance test checks BODY, the head, security and every
file, and opens through a MemorySink; the .dkk tests take the .dkk of
formats 2 and 3 too (spec 68); the CLI decrypts five of the fixtures
into folders; the control fuzz target decodes with the three schema
versions. The differential corpus gains two bases, format3_single and
format3_time_and_key_portable, one per policy: 5110 cases, the earlier
ones unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
// check3 checks what Open delivered for the format 3 fixture f, whose BODY
|
|
|
|
|
// is body: the files in its sink, the head and the verdicts.
|
|
|
|
|
func check3(f *testkit.DKCFixture, body []byte, opened *capsule.Opened, sink *testkit.MemorySink) error {
|
|
|
|
|
if !sink.Committed || sink.Aborted || opened.Head == nil || len(sink.Files) != len(f.Files) {
|
|
|
|
|
return errors.New("Open did not deliver the files")
|
|
|
|
|
}
|
|
|
|
|
for i, ff := range f.Files {
|
|
|
|
|
want := body[f.ContentOffset+ff.Start : f.ContentOffset+ff.End]
|
|
|
|
|
if !bytes.Equal(sink.Files[i], want) && (len(want) != 0 || sink.Files[i] != nil) {
|
|
|
|
|
return fmt.Errorf("file %q differs", ff.Path)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
want := &testkit.FixtureVerdicts{Signature: string(opened.Verdicts.Signature), Seal: string(opened.Verdicts.Seal), Lines: opened.Verdicts.Lines()}
|
Signature plan, step 6: the fixture format3_signed and the vectors of its signature
format3_signed is written by EncryptFiles with a test key. Its record gives
the seed of the key, control_commit, head_digest, signers_digest,
AUTHOR_MESSAGE with its code, the signature and the content of key 2, and
verdicts carries the dkauthor1 key. The conformance test recomputes all of
it from the control, the head and the security area, and signs again from
the seed. A second test changes the context, a bit of the signature or of
the key, and the key itself, and removes the signature.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
if f.Verdicts != nil && f.Verdicts.AuthorKey != "" {
|
|
|
|
|
want.AuthorKey, _ = bech32.Encode("dkauthor", opened.Verdicts.AuthorKey[:])
|
|
|
|
|
}
|
Format 3, step 6b: the nine fixtures of format 3
The fixtures of spec 67 for format 3, each with its record, its BODY,
its inspect output and, for time_and_key, its .dkk:
- format3_single, format3_tree (five files in three folders, one over
two STREAM chunks, one without mtime, a comment and a declared
author), format3_comment_only (no files; a TAB in the comment),
format3_bloque256 and format3_time_and_key_portable, written with
EncryptFiles;
- format3_area_1024, format3_security_v2 (verdict X),
format3_signature_unsupported (an author-signature of alg 1 with a
random key of 32 bytes and a random signature of 64: F1) and
format3_seal_unsupported (that and a seal of seal_type 1: F1 and S1),
which only a generator of test vectors writes (62.1 rule 13), built
with testkit.Build.
The record of a format 3 fixture adds the area, SECURITY_CBOR,
HEAD_CBOR, the salt, the comment, the declared author, the head
extensions, the offset of CONTENT in BODY, each file with its layout,
SHA-256 and mtime, and the verdicts with their lines; its plaintext
file is BODY. The generator writes, then recovers every value by
opening layer by layer for the three formats alike, and refreshes the
records of format 3 through a Sink.
Tests: the conformance test checks BODY, the head, security and every
file, and opens through a MemorySink; the .dkk tests take the .dkk of
formats 2 and 3 too (spec 68); the CLI decrypts five of the fixtures
into folders; the control fuzz target decodes with the three schema
versions. The differential corpus gains two bases, format3_single and
format3_time_and_key_portable, one per policy: 5110 cases, the earlier
ones unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
if !reflect.DeepEqual(want, f.Verdicts) || opened.AreaLen != f.AreaLen || opened.Head.Comment != f.Comment || opened.Head.Author != f.Author {
|
|
|
|
|
return errors.New("Open reports another head or other verdicts")
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|