Phase 3, step 5: interoperability with Go at the level of the capsule
scripts/capsule-ts-samples.mjs writes thirteen capsules of format 2 with
encrypt (both policies and padding rules, 0 to 16 credentials, chunk
borders, extensions in the three objects, an instant with nanoseconds),
four mixes of two capsules, the inputs of an encoder differential drawn
from a seed, a corpus of recipient strings and the invalid options that
Go also rejects. scripts/capsule-go-verdicts.go gives the verdicts of the
reference on them:
- capsule.Inspect, and capsule.Open with each credential alone and all
together: every sample opens to its content, with format 2 and the L,
padding rule and P requested;
- SEALED_CONTROL opened layer by layer with the agewrap identities, 16
stanzas in INNER_ACCESS_AGE, and PUBLIC_HEADER, CONTROL_CBOR and the
.dkk encoded again to the same bytes;
- the code and step of each mix;
- EncodeHeader, EncodeControl (format 2) and MarshalBody equal on all 500
encoder inputs;
- the texts of age.ParseX25519Recipient, agewrap.CheckX25519Recipient and
capsule.Encrypt, equal to those of this library.
The capsules are random, so the output is frozen in
src/lib/dkc/testing/capsule-vectors.json, and interop.test.ts checks the
verdicts of Go and that open reaches the same ones on the frozen bytes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
//go:build ignore
// Prints src/lib/dkc/testing/capsule-vectors.json: the verdicts of the Go
// reference on what scripts/capsule-ts-samples.mjs wrote with the writer of
// this repository (plan of phase 3, decision 11 and section 8, point 9):
//
Format 3, step 4: Go opens what encryptFiles writes
capsule-vectors.json is written again with six capsules of format 3
from encryptFiles, next to the thirteen of format 2:
- one file with its mtime; a tree of seven files, one of them over two
STREAM chunks, with paths out of ASCII and the pair U+FFFD and
U+10000, which UTF-8 and UTF-16 order the other way round, a comment
and a declared author; a comment and no file; bloque256; time_and_key
with three recipients and a portable key; and head extensions.
- capsule-go-verdicts.go opens them with capsule.Open into a Sink, with
each credential alone and with all of them, and records the files it
receives with their SHA-256, the head encoded again with
capsule.EncodeHead and the verdicts of the security area. It decodes
the control of each capsule in the format of its prelude, and runs
capsule.Encrypt on the invalid options as a generator of test vectors.
- interop.test.ts requires Go to find the files, the head and the
verdicts written, and open, into a MemorySink, to reach the same
verdicts on the same bytes.
The format 2 samples, the mixes, the encoder differential (500 equal),
the recipients and the 21 option errors are regenerated too, with the
same verdicts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
// - samples: each .dkc, of format 2 or 3, is inspected with capsule.Inspect
// and opened with capsule.Open and the published signature of its round,
// with each credential alone and with all of them, and the verdict, the
// format, L, the padding rule and P are recorded; in format 2 the SHA-256
// of the content, and in format 3 the files that a Sink receives, with
Go opens what the writer of v0.11 writes: capsule-vectors.json again
Fixes T10 of the review of the session of 1 and 2 October: no test checked
that Go opens what encryptFiles writes today, since capsule-vectors.json
came from c3c124a, with an area of 512 bytes and no note.
- capsule-ts-samples.mjs writes format 2 with encryptVectors of
testing/encrypt.ts, as a generator of test vectors, and format 3 with
encryptFiles, as any caller writes it: the six samples of before, now
with the area of 32 KiB, and two more with a public note, one out of
ASCII, and one of 1024 bytes in time_and_key beside another noncritical
extension of the header.
- capsule-go-verdicts.go records the size of the area that capsule.Open
gives, the note that Header.PublicNote reads, the text of capsule.Encrypt
for a public note in format 2, and the text of capsule.EncryptFiles for
nine public notes that break their rules.
- interop.test.ts requires Go to open each of the 21 samples with each
credential, to find the area of 32 KiB in format 3 and to read the note
written, and this library to read the same note; and the texts of the 22
options and of the 9 notes to be those of Go.
Go at spec-v0.11 (ae33434) opens the 21 samples with each credential and
with all of them, encodes their objects again byte for byte, and gives the
texts of this library for the 22 options and the 9 notes; the four mixes,
the 500 inputs of the encoder differential and the 22 recipients give what
they gave. npm run verify passes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
// their SHA-256, the head encoded again with capsule.EncodeHead, the
// verdicts of the security area and the size of the area. Its
// PUBLIC_HEADER, its CONTROL_CBOR, opened layer by layer with the
// identities of agewrap, and its .dkk are encoded again by the reference
// and compared with the bytes written, the public note that
// Header.PublicNote reads in its PUBLIC_HEADER is recorded, null without
// one, and so is the number of stanzas of its INNER_ACCESS_AGE.
Phase 3, step 5: interoperability with Go at the level of the capsule
scripts/capsule-ts-samples.mjs writes thirteen capsules of format 2 with
encrypt (both policies and padding rules, 0 to 16 credentials, chunk
borders, extensions in the three objects, an instant with nanoseconds),
four mixes of two capsules, the inputs of an encoder differential drawn
from a seed, a corpus of recipient strings and the invalid options that
Go also rejects. scripts/capsule-go-verdicts.go gives the verdicts of the
reference on them:
- capsule.Inspect, and capsule.Open with each credential alone and all
together: every sample opens to its content, with format 2 and the L,
padding rule and P requested;
- SEALED_CONTROL opened layer by layer with the agewrap identities, 16
stanzas in INNER_ACCESS_AGE, and PUBLIC_HEADER, CONTROL_CBOR and the
.dkk encoded again to the same bytes;
- the code and step of each mix;
- EncodeHeader, EncodeControl (format 2) and MarshalBody equal on all 500
encoder inputs;
- the texts of age.ParseX25519Recipient, agewrap.CheckX25519Recipient and
capsule.Encrypt, equal to those of this library.
The capsules are random, so the output is frozen in
src/lib/dkc/testing/capsule-vectors.json, and interop.test.ts checks the
verdicts of Go and that open reaches the same ones on the frozen bytes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
// - mixes: the code and the step at which capsule.Open fails.
// - encoders: capsule.EncodeHeader, capsule.EncodeControl (format 2) and
// AccessKey.MarshalBody on every input, compared with the bytes of the
// TypeScript library.
// - recipients: age.ParseX25519Recipient, then agewrap.CheckX25519Recipient,
// on every string.
Format 3, step 4: Go opens what encryptFiles writes
capsule-vectors.json is written again with six capsules of format 3
from encryptFiles, next to the thirteen of format 2:
- one file with its mtime; a tree of seven files, one of them over two
STREAM chunks, with paths out of ASCII and the pair U+FFFD and
U+10000, which UTF-8 and UTF-16 order the other way round, a comment
and a declared author; a comment and no file; bloque256; time_and_key
with three recipients and a portable key; and head extensions.
- capsule-go-verdicts.go opens them with capsule.Open into a Sink, with
each credential alone and with all of them, and records the files it
receives with their SHA-256, the head encoded again with
capsule.EncodeHead and the verdicts of the security area. It decodes
the control of each capsule in the format of its prelude, and runs
capsule.Encrypt on the invalid options as a generator of test vectors.
- interop.test.ts requires Go to find the files, the head and the
verdicts written, and open, into a MemorySink, to reach the same
verdicts on the same bytes.
The format 2 samples, the mixes, the encoder differential (500 equal),
the recipients and the 21 option errors are regenerated too, with the
same verdicts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
// - errors: the text of capsule.Encrypt for each invalid option, as a
// generator of test vectors, the only writer of format 2 (spec §62.1
// rule 1).
Go opens what the writer of v0.11 writes: capsule-vectors.json again
Fixes T10 of the review of the session of 1 and 2 October: no test checked
that Go opens what encryptFiles writes today, since capsule-vectors.json
came from c3c124a, with an area of 512 bytes and no note.
- capsule-ts-samples.mjs writes format 2 with encryptVectors of
testing/encrypt.ts, as a generator of test vectors, and format 3 with
encryptFiles, as any caller writes it: the six samples of before, now
with the area of 32 KiB, and two more with a public note, one out of
ASCII, and one of 1024 bytes in time_and_key beside another noncritical
extension of the header.
- capsule-go-verdicts.go records the size of the area that capsule.Open
gives, the note that Header.PublicNote reads, the text of capsule.Encrypt
for a public note in format 2, and the text of capsule.EncryptFiles for
nine public notes that break their rules.
- interop.test.ts requires Go to open each of the 21 samples with each
credential, to find the area of 32 KiB in format 3 and to read the note
written, and this library to read the same note; and the texts of the 22
options and of the 9 notes to be those of Go.
Go at spec-v0.11 (ae33434) opens the 21 samples with each credential and
with all of them, encodes their objects again byte for byte, and gives the
texts of this library for the 22 options and the 9 notes; the four mixes,
the 500 inputs of the encoder differential and the 22 recipients give what
they gave. npm run verify passes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
// - note_errors: the text of capsule.EncryptFiles for each public note that
// breaks the rules of spec §24.1.
Phase 3, step 5: interoperability with Go at the level of the capsule
scripts/capsule-ts-samples.mjs writes thirteen capsules of format 2 with
encrypt (both policies and padding rules, 0 to 16 credentials, chunk
borders, extensions in the three objects, an instant with nanoseconds),
four mixes of two capsules, the inputs of an encoder differential drawn
from a seed, a corpus of recipient strings and the invalid options that
Go also rejects. scripts/capsule-go-verdicts.go gives the verdicts of the
reference on them:
- capsule.Inspect, and capsule.Open with each credential alone and all
together: every sample opens to its content, with format 2 and the L,
padding rule and P requested;
- SEALED_CONTROL opened layer by layer with the agewrap identities, 16
stanzas in INNER_ACCESS_AGE, and PUBLIC_HEADER, CONTROL_CBOR and the
.dkk encoded again to the same bytes;
- the code and step of each mix;
- EncodeHeader, EncodeControl (format 2) and MarshalBody equal on all 500
encoder inputs;
- the texts of age.ParseX25519Recipient, agewrap.CheckX25519Recipient and
capsule.Encrypt, equal to those of this library.
The capsules are random, so the output is frozen in
src/lib/dkc/testing/capsule-vectors.json, and interop.test.ts checks the
verdicts of Go and that open reaches the same ones on the frozen bytes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
//
// Run it from a scratch module that requires the reference implementation
// (replace g.activething.com/go/DateKeys => ../datekeys-go, GOFLAGS=-mod=mod
// and the go directive of the reference, so that its toolchain is used),
// passing the output of capsule-ts-samples.mjs:
//
// go run capsule-go-verdicts.go ts-samples.json > capsule-vectors.json
package main
import (
"bytes"
"context"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"maps"
"os"
"runtime/debug"
"slices"
"strings"
"time"
"filippo.io/age"
datekeys "g.activething.com/go/DateKeys"
"g.activething.com/go/DateKeys/accesskey"
"g.activething.com/go/DateKeys/agewrap"
"g.activething.com/go/DateKeys/capsule"
"g.activething.com/go/DateKeys/codec/bech32"
"g.activething.com/go/DateKeys/datekey"
"g.activething.com/go/DateKeys/extension"
"g.activething.com/go/DateKeys/profile"
"g.activething.com/go/DateKeys/provider"
)
// The published Quicknet signatures of the rounds of the samples, as in the
// fixtures; provider.Verify checks them in capsule.Open.
var published = map [ uint64 ] string {
1000 : "b44679b9a59af2ec876b1a6b1ad52ea9b1615fc3982b19576350f93447cb1125e342b73a8dd2bacbe47e4b6b63ed5e39" ,
1001 : "b33bf3667cbd5a82de3a24b4e0e9fe5513cc1a0e840368c6e31f5fcfa79bea03f73896b25883abf2853d10337fb8fa41" ,
2000 : "b6cb8f482a0b15d45936a4c4ea08e98a087e71787caee3f4d07a8a9843b1bc5423c6b3c22f446488b3137eaca799c77e" ,
}
type extJSON struct {
ID string ` json:"id" `
Version uint64 ` json:"version" `
Data * string ` json:"data,omitempty" `
}
type sampleIn struct {
Format 3, step 4: Go opens what encryptFiles writes
capsule-vectors.json is written again with six capsules of format 3
from encryptFiles, next to the thirteen of format 2:
- one file with its mtime; a tree of seven files, one of them over two
STREAM chunks, with paths out of ASCII and the pair U+FFFD and
U+10000, which UTF-8 and UTF-16 order the other way round, a comment
and a declared author; a comment and no file; bloque256; time_and_key
with three recipients and a portable key; and head extensions.
- capsule-go-verdicts.go opens them with capsule.Open into a Sink, with
each credential alone and with all of them, and records the files it
receives with their SHA-256, the head encoded again with
capsule.EncodeHead and the verdicts of the security area. It decodes
the control of each capsule in the format of its prelude, and runs
capsule.Encrypt on the invalid options as a generator of test vectors.
- interop.test.ts requires Go to find the files, the head and the
verdicts written, and open, into a MemorySink, to reach the same
verdicts on the same bytes.
The format 2 samples, the mixes, the encoder differential (500 equal),
the recipients and the 21 option errors are regenerated too, with the
same verdicts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
Name string ` json:"name" `
Round uint64 ` json:"round" `
Policy string ` json:"policy" `
Format int ` json:"format" `
Length uint64 ` json:"length" `
Padding int ` json:"padding" `
PaddedLength uint64 ` json:"padded_length" `
// Format 2: the SHA-256 of the content. Format 3: the head written and
// its files.
ContentSHA256 string ` json:"content_sha256,omitempty" `
HeadCBOR string ` json:"head_cbor,omitempty" `
Files [ ] fileJSON ` json:"files,omitempty" `
Identities [ ] string ` json:"identities" `
DKK string ` json:"dkk,omitempty" `
Known [ ] extJSON ` json:"known" `
Go opens what the writer of v0.11 writes: capsule-vectors.json again
Fixes T10 of the review of the session of 1 and 2 October: no test checked
that Go opens what encryptFiles writes today, since capsule-vectors.json
came from c3c124a, with an area of 512 bytes and no note.
- capsule-ts-samples.mjs writes format 2 with encryptVectors of
testing/encrypt.ts, as a generator of test vectors, and format 3 with
encryptFiles, as any caller writes it: the six samples of before, now
with the area of 32 KiB, and two more with a public note, one out of
ASCII, and one of 1024 bytes in time_and_key beside another noncritical
extension of the header.
- capsule-go-verdicts.go records the size of the area that capsule.Open
gives, the note that Header.PublicNote reads, the text of capsule.Encrypt
for a public note in format 2, and the text of capsule.EncryptFiles for
nine public notes that break their rules.
- interop.test.ts requires Go to open each of the 21 samples with each
credential, to find the area of 32 KiB in format 3 and to read the note
written, and this library to read the same note; and the texts of the 22
options and of the 9 notes to be those of Go.
Go at spec-v0.11 (ae33434) opens the 21 samples with each credential and
with all of them, encodes their objects again byte for byte, and gives the
texts of this library for the 22 options and the 9 notes; the four mixes,
the 500 inputs of the encoder differential and the 22 recipients give what
they gave. npm run verify passes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
// PublicNote is the public note that the writer was given, if any.
PublicNote * string ` json:"public_note,omitempty" `
DKC string ` json:"dkc" `
Format 3, step 4: Go opens what encryptFiles writes
capsule-vectors.json is written again with six capsules of format 3
from encryptFiles, next to the thirteen of format 2:
- one file with its mtime; a tree of seven files, one of them over two
STREAM chunks, with paths out of ASCII and the pair U+FFFD and
U+10000, which UTF-8 and UTF-16 order the other way round, a comment
and a declared author; a comment and no file; bloque256; time_and_key
with three recipients and a portable key; and head extensions.
- capsule-go-verdicts.go opens them with capsule.Open into a Sink, with
each credential alone and with all of them, and records the files it
receives with their SHA-256, the head encoded again with
capsule.EncodeHead and the verdicts of the security area. It decodes
the control of each capsule in the format of its prelude, and runs
capsule.Encrypt on the invalid options as a generator of test vectors.
- interop.test.ts requires Go to find the files, the head and the
verdicts written, and open, into a MemorySink, to reach the same
verdicts on the same bytes.
The format 2 samples, the mixes, the encoder differential (500 equal),
the recipients and the 21 option errors are regenerated too, with the
same verdicts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
}
// A file of a format 3 capsule: its path, size, SHA-256 and mtime.
type fileJSON struct {
Path string ` json:"path" `
Size uint64 ` json:"size" `
SHA256 string ` json:"sha256" `
MTime * uint64 ` json:"mtime,omitempty" `
Phase 3, step 5: interoperability with Go at the level of the capsule
scripts/capsule-ts-samples.mjs writes thirteen capsules of format 2 with
encrypt (both policies and padding rules, 0 to 16 credentials, chunk
borders, extensions in the three objects, an instant with nanoseconds),
four mixes of two capsules, the inputs of an encoder differential drawn
from a seed, a corpus of recipient strings and the invalid options that
Go also rejects. scripts/capsule-go-verdicts.go gives the verdicts of the
reference on them:
- capsule.Inspect, and capsule.Open with each credential alone and all
together: every sample opens to its content, with format 2 and the L,
padding rule and P requested;
- SEALED_CONTROL opened layer by layer with the agewrap identities, 16
stanzas in INNER_ACCESS_AGE, and PUBLIC_HEADER, CONTROL_CBOR and the
.dkk encoded again to the same bytes;
- the code and step of each mix;
- EncodeHeader, EncodeControl (format 2) and MarshalBody equal on all 500
encoder inputs;
- the texts of age.ParseX25519Recipient, agewrap.CheckX25519Recipient and
capsule.Encrypt, equal to those of this library.
The capsules are random, so the output is frozen in
src/lib/dkc/testing/capsule-vectors.json, and interop.test.ts checks the
verdicts of Go and that open reaches the same ones on the frozen bytes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
}
type encoderIn struct {
Header struct {
CapsuleID string ` json:"capsule_id" `
Round uint64 ` json:"round" `
Policy int ` json:"policy" `
Critical [ ] extJSON ` json:"critical" `
Noncritical [ ] extJSON ` json:"noncritical" `
} ` json:"header" `
Control struct {
HeaderBinding string ` json:"header_binding" `
PayloadIdentity string ` json:"payload_identity" `
PayloadLength uint64 ` json:"payload_length" `
Padding int ` json:"padding" `
Critical [ ] extJSON ` json:"critical" `
Noncritical [ ] extJSON ` json:"noncritical" `
} ` json:"control" `
DKK struct {
CredentialID string ` json:"credential_id" `
CapsuleID string ` json:"capsule_id" `
Material string ` json:"material" `
CapsuleDigest * string ` json:"capsule_digest,omitempty" `
Critical [ ] extJSON ` json:"critical" `
Noncritical [ ] extJSON ` json:"noncritical" `
} ` json:"dkk" `
HeaderCBOR string ` json:"header_cbor" `
ControlCBOR string ` json:"control_cbor" `
DKKBody string ` json:"dkk_body" `
}
type errorCase struct {
Name string ` json:"name" `
Policy int ` json:"policy" `
Recipients [ ] string ` json:"recipients,omitempty" `
Portable bool ` json:"portable,omitempty" `
UnlockAt string ` json:"unlock_at" `
Now string ` json:"now" `
Length int64 ` json:"length" `
Padding int ` json:"padding,omitempty" `
Critical [ ] extJSON ` json:"critical,omitempty" `
Noncritical [ ] extJSON ` json:"noncritical,omitempty" `
ControlCritical [ ] extJSON ` json:"control_critical,omitempty" `
ControlNoncritical [ ] extJSON ` json:"control_noncritical,omitempty" `
ChainHashFlip bool ` json:"chain_hash_flip,omitempty" `
Go opens what the writer of v0.11 writes: capsule-vectors.json again
Fixes T10 of the review of the session of 1 and 2 October: no test checked
that Go opens what encryptFiles writes today, since capsule-vectors.json
came from c3c124a, with an area of 512 bytes and no note.
- capsule-ts-samples.mjs writes format 2 with encryptVectors of
testing/encrypt.ts, as a generator of test vectors, and format 3 with
encryptFiles, as any caller writes it: the six samples of before, now
with the area of 32 KiB, and two more with a public note, one out of
ASCII, and one of 1024 bytes in time_and_key beside another noncritical
extension of the header.
- capsule-go-verdicts.go records the size of the area that capsule.Open
gives, the note that Header.PublicNote reads, the text of capsule.Encrypt
for a public note in format 2, and the text of capsule.EncryptFiles for
nine public notes that break their rules.
- interop.test.ts requires Go to open each of the 21 samples with each
credential, to find the area of 32 KiB in format 3 and to read the note
written, and this library to read the same note; and the texts of the 22
options and of the 9 notes to be those of Go.
Go at spec-v0.11 (ae33434) opens the 21 samples with each credential and
with all of them, encodes their objects again byte for byte, and gives the
texts of this library for the 22 options and the 9 notes; the four mixes,
the 500 inputs of the encoder differential and the 22 recipients give what
they gave. npm run verify passes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
PublicNote string ` json:"public_note,omitempty" `
Phase 3, step 5: interoperability with Go at the level of the capsule
scripts/capsule-ts-samples.mjs writes thirteen capsules of format 2 with
encrypt (both policies and padding rules, 0 to 16 credentials, chunk
borders, extensions in the three objects, an instant with nanoseconds),
four mixes of two capsules, the inputs of an encoder differential drawn
from a seed, a corpus of recipient strings and the invalid options that
Go also rejects. scripts/capsule-go-verdicts.go gives the verdicts of the
reference on them:
- capsule.Inspect, and capsule.Open with each credential alone and all
together: every sample opens to its content, with format 2 and the L,
padding rule and P requested;
- SEALED_CONTROL opened layer by layer with the agewrap identities, 16
stanzas in INNER_ACCESS_AGE, and PUBLIC_HEADER, CONTROL_CBOR and the
.dkk encoded again to the same bytes;
- the code and step of each mix;
- EncodeHeader, EncodeControl (format 2) and MarshalBody equal on all 500
encoder inputs;
- the texts of age.ParseX25519Recipient, agewrap.CheckX25519Recipient and
capsule.Encrypt, equal to those of this library.
The capsules are random, so the output is frozen in
src/lib/dkc/testing/capsule-vectors.json, and interop.test.ts checks the
verdicts of Go and that open reaches the same ones on the frozen bytes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
TS string ` json:"ts" `
Go string ` json:"go" `
}
Go opens what the writer of v0.11 writes: capsule-vectors.json again
Fixes T10 of the review of the session of 1 and 2 October: no test checked
that Go opens what encryptFiles writes today, since capsule-vectors.json
came from c3c124a, with an area of 512 bytes and no note.
- capsule-ts-samples.mjs writes format 2 with encryptVectors of
testing/encrypt.ts, as a generator of test vectors, and format 3 with
encryptFiles, as any caller writes it: the six samples of before, now
with the area of 32 KiB, and two more with a public note, one out of
ASCII, and one of 1024 bytes in time_and_key beside another noncritical
extension of the header.
- capsule-go-verdicts.go records the size of the area that capsule.Open
gives, the note that Header.PublicNote reads, the text of capsule.Encrypt
for a public note in format 2, and the text of capsule.EncryptFiles for
nine public notes that break their rules.
- interop.test.ts requires Go to open each of the 21 samples with each
credential, to find the area of 32 KiB in format 3 and to read the note
written, and this library to read the same note; and the texts of the 22
options and of the 9 notes to be those of Go.
Go at spec-v0.11 (ae33434) opens the 21 samples with each credential and
with all of them, encodes their objects again byte for byte, and gives the
texts of this library for the 22 options and the 9 notes; the four mixes,
the 500 inputs of the encoder differential and the 22 recipients give what
they gave. npm run verify passes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
// noteError is a public note that breaks the rules of spec §24.1, and the
// texts of capsule.EncryptFiles and of the TypeScript library for it.
type noteError struct {
Name string ` json:"name" `
Note string ` json:"note" `
TS string ` json:"ts" `
Go string ` json:"go" `
}
Phase 3, step 5: interoperability with Go at the level of the capsule
scripts/capsule-ts-samples.mjs writes thirteen capsules of format 2 with
encrypt (both policies and padding rules, 0 to 16 credentials, chunk
borders, extensions in the three objects, an instant with nanoseconds),
four mixes of two capsules, the inputs of an encoder differential drawn
from a seed, a corpus of recipient strings and the invalid options that
Go also rejects. scripts/capsule-go-verdicts.go gives the verdicts of the
reference on them:
- capsule.Inspect, and capsule.Open with each credential alone and all
together: every sample opens to its content, with format 2 and the L,
padding rule and P requested;
- SEALED_CONTROL opened layer by layer with the agewrap identities, 16
stanzas in INNER_ACCESS_AGE, and PUBLIC_HEADER, CONTROL_CBOR and the
.dkk encoded again to the same bytes;
- the code and step of each mix;
- EncodeHeader, EncodeControl (format 2) and MarshalBody equal on all 500
encoder inputs;
- the texts of age.ParseX25519Recipient, agewrap.CheckX25519Recipient and
capsule.Encrypt, equal to those of this library.
The capsules are random, so the output is frozen in
src/lib/dkc/testing/capsule-vectors.json, and interop.test.ts checks the
verdicts of Go and that open reaches the same ones on the frozen bytes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
type input struct {
Generator string ` json:"generator" `
Samples [ ] sampleIn ` json:"samples" `
Mixes [ ] struct {
Name string ` json:"name" `
Round uint64 ` json:"round" `
DKC string ` json:"dkc" `
} ` json:"mixes" `
Encoders struct {
Seed int ` json:"seed" `
Count int ` json:"count" `
SHA256 string ` json:"sha256" `
Cases [ ] encoderIn ` json:"cases" `
} ` json:"encoders" `
Recipients [ ] string ` json:"recipients" `
Errors [ ] errorCase ` json:"errors" `
Go opens what the writer of v0.11 writes: capsule-vectors.json again
Fixes T10 of the review of the session of 1 and 2 October: no test checked
that Go opens what encryptFiles writes today, since capsule-vectors.json
came from c3c124a, with an area of 512 bytes and no note.
- capsule-ts-samples.mjs writes format 2 with encryptVectors of
testing/encrypt.ts, as a generator of test vectors, and format 3 with
encryptFiles, as any caller writes it: the six samples of before, now
with the area of 32 KiB, and two more with a public note, one out of
ASCII, and one of 1024 bytes in time_and_key beside another noncritical
extension of the header.
- capsule-go-verdicts.go records the size of the area that capsule.Open
gives, the note that Header.PublicNote reads, the text of capsule.Encrypt
for a public note in format 2, and the text of capsule.EncryptFiles for
nine public notes that break their rules.
- interop.test.ts requires Go to open each of the 21 samples with each
credential, to find the area of 32 KiB in format 3 and to read the note
written, and this library to read the same note; and the texts of the 22
options and of the 9 notes to be those of Go.
Go at spec-v0.11 (ae33434) opens the 21 samples with each credential and
with all of them, encodes their objects again byte for byte, and gives the
texts of this library for the 22 options and the 9 notes; the four mixes,
the 500 inputs of the encoder differential and the 22 recipients give what
they gave. npm run verify passes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
NoteErrors [ ] noteError ` json:"note_errors" `
Phase 3, step 5: interoperability with Go at the level of the capsule
scripts/capsule-ts-samples.mjs writes thirteen capsules of format 2 with
encrypt (both policies and padding rules, 0 to 16 credentials, chunk
borders, extensions in the three objects, an instant with nanoseconds),
four mixes of two capsules, the inputs of an encoder differential drawn
from a seed, a corpus of recipient strings and the invalid options that
Go also rejects. scripts/capsule-go-verdicts.go gives the verdicts of the
reference on them:
- capsule.Inspect, and capsule.Open with each credential alone and all
together: every sample opens to its content, with format 2 and the L,
padding rule and P requested;
- SEALED_CONTROL opened layer by layer with the agewrap identities, 16
stanzas in INNER_ACCESS_AGE, and PUBLIC_HEADER, CONTROL_CBOR and the
.dkk encoded again to the same bytes;
- the code and step of each mix;
- EncodeHeader, EncodeControl (format 2) and MarshalBody equal on all 500
encoder inputs;
- the texts of age.ParseX25519Recipient, agewrap.CheckX25519Recipient and
capsule.Encrypt, equal to those of this library.
The capsules are random, so the output is frozen in
src/lib/dkc/testing/capsule-vectors.json, and interop.test.ts checks the
verdicts of Go and that open reaches the same ones on the frozen bytes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
}
// The verdict of one opening: "ok" with what was delivered, or the code and
// the step of the failure.
type openVerdict struct {
Credentials string ` json:"credentials" `
Result string ` json:"result" `
Step int ` json:"step,omitempty" `
Opened * openedOut ` json:"opened,omitempty" `
}
type openedOut struct {
Format 3, step 4: Go opens what encryptFiles writes
capsule-vectors.json is written again with six capsules of format 3
from encryptFiles, next to the thirteen of format 2:
- one file with its mtime; a tree of seven files, one of them over two
STREAM chunks, with paths out of ASCII and the pair U+FFFD and
U+10000, which UTF-8 and UTF-16 order the other way round, a comment
and a declared author; a comment and no file; bloque256; time_and_key
with three recipients and a portable key; and head extensions.
- capsule-go-verdicts.go opens them with capsule.Open into a Sink, with
each credential alone and with all of them, and records the files it
receives with their SHA-256, the head encoded again with
capsule.EncodeHead and the verdicts of the security area. It decodes
the control of each capsule in the format of its prelude, and runs
capsule.Encrypt on the invalid options as a generator of test vectors.
- interop.test.ts requires Go to find the files, the head and the
verdicts written, and open, into a MemorySink, to reach the same
verdicts on the same bytes.
The format 2 samples, the mixes, the encoder differential (500 equal),
the recipients and the 21 option errors are regenerated too, with the
same verdicts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
ContentSHA256 string ` json:"content_sha256,omitempty" `
Format int ` json:"format" `
Length uint64 ` json:"length" `
Padding int ` json:"padding" `
PaddedLength uint64 ` json:"padded_length" `
Files [ ] fileJSON ` json:"files,omitempty" `
HeadCBOR string ` json:"head_cbor,omitempty" `
Verdicts [ ] string ` json:"verdicts,omitempty" `
Go opens what the writer of v0.11 writes: capsule-vectors.json again
Fixes T10 of the review of the session of 1 and 2 October: no test checked
that Go opens what encryptFiles writes today, since capsule-vectors.json
came from c3c124a, with an area of 512 bytes and no note.
- capsule-ts-samples.mjs writes format 2 with encryptVectors of
testing/encrypt.ts, as a generator of test vectors, and format 3 with
encryptFiles, as any caller writes it: the six samples of before, now
with the area of 32 KiB, and two more with a public note, one out of
ASCII, and one of 1024 bytes in time_and_key beside another noncritical
extension of the header.
- capsule-go-verdicts.go records the size of the area that capsule.Open
gives, the note that Header.PublicNote reads, the text of capsule.Encrypt
for a public note in format 2, and the text of capsule.EncryptFiles for
nine public notes that break their rules.
- interop.test.ts requires Go to open each of the 21 samples with each
credential, to find the area of 32 KiB in format 3 and to read the note
written, and this library to read the same note; and the texts of the 22
options and of the 9 notes to be those of Go.
Go at spec-v0.11 (ae33434) opens the 21 samples with each credential and
with all of them, encodes their objects again byte for byte, and gives the
texts of this library for the 22 options and the 9 notes; the four mixes,
the 500 inputs of the encoder differential and the 22 recipients give what
they gave. npm run verify passes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
AreaLen uint32 ` json:"area_len,omitempty" `
Format 3, step 4: Go opens what encryptFiles writes
capsule-vectors.json is written again with six capsules of format 3
from encryptFiles, next to the thirteen of format 2:
- one file with its mtime; a tree of seven files, one of them over two
STREAM chunks, with paths out of ASCII and the pair U+FFFD and
U+10000, which UTF-8 and UTF-16 order the other way round, a comment
and a declared author; a comment and no file; bloque256; time_and_key
with three recipients and a portable key; and head extensions.
- capsule-go-verdicts.go opens them with capsule.Open into a Sink, with
each credential alone and with all of them, and records the files it
receives with their SHA-256, the head encoded again with
capsule.EncodeHead and the verdicts of the security area. It decodes
the control of each capsule in the format of its prelude, and runs
capsule.Encrypt on the invalid options as a generator of test vectors.
- interop.test.ts requires Go to find the files, the head and the
verdicts written, and open, into a MemorySink, to reach the same
verdicts on the same bytes.
The format 2 samples, the mixes, the encoder differential (500 equal),
the recipients and the 21 option errors are regenerated too, with the
same verdicts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
}
// sink keeps the files of a format 3 capsule in memory.
type sink struct {
files [ ] * bytes . Buffer
}
type buffer struct { * bytes . Buffer }
func ( buffer ) Close ( ) error { return nil }
func ( s * sink ) Begin ( * capsule . Head ) error { return nil }
func ( s * sink ) Create ( int ) ( io . WriteCloser , error ) {
b := & bytes . Buffer { }
s . files = append ( s . files , b )
return buffer { b } , nil
Phase 3, step 5: interoperability with Go at the level of the capsule
scripts/capsule-ts-samples.mjs writes thirteen capsules of format 2 with
encrypt (both policies and padding rules, 0 to 16 credentials, chunk
borders, extensions in the three objects, an instant with nanoseconds),
four mixes of two capsules, the inputs of an encoder differential drawn
from a seed, a corpus of recipient strings and the invalid options that
Go also rejects. scripts/capsule-go-verdicts.go gives the verdicts of the
reference on them:
- capsule.Inspect, and capsule.Open with each credential alone and all
together: every sample opens to its content, with format 2 and the L,
padding rule and P requested;
- SEALED_CONTROL opened layer by layer with the agewrap identities, 16
stanzas in INNER_ACCESS_AGE, and PUBLIC_HEADER, CONTROL_CBOR and the
.dkk encoded again to the same bytes;
- the code and step of each mix;
- EncodeHeader, EncodeControl (format 2) and MarshalBody equal on all 500
encoder inputs;
- the texts of age.ParseX25519Recipient, agewrap.CheckX25519Recipient and
capsule.Encrypt, equal to those of this library.
The capsules are random, so the output is frozen in
src/lib/dkc/testing/capsule-vectors.json, and interop.test.ts checks the
verdicts of Go and that open reaches the same ones on the frozen bytes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
}
Format 3, step 4: Go opens what encryptFiles writes
capsule-vectors.json is written again with six capsules of format 3
from encryptFiles, next to the thirteen of format 2:
- one file with its mtime; a tree of seven files, one of them over two
STREAM chunks, with paths out of ASCII and the pair U+FFFD and
U+10000, which UTF-8 and UTF-16 order the other way round, a comment
and a declared author; a comment and no file; bloque256; time_and_key
with three recipients and a portable key; and head extensions.
- capsule-go-verdicts.go opens them with capsule.Open into a Sink, with
each credential alone and with all of them, and records the files it
receives with their SHA-256, the head encoded again with
capsule.EncodeHead and the verdicts of the security area. It decodes
the control of each capsule in the format of its prelude, and runs
capsule.Encrypt on the invalid options as a generator of test vectors.
- interop.test.ts requires Go to find the files, the head and the
verdicts written, and open, into a MemorySink, to reach the same
verdicts on the same bytes.
The format 2 samples, the mixes, the encoder differential (500 equal),
the recipients and the 21 option errors are regenerated too, with the
same verdicts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
func ( s * sink ) Commit ( ) error { return nil }
func ( s * sink ) Abort ( ) { s . files = nil }
Phase 3, step 5: interoperability with Go at the level of the capsule
scripts/capsule-ts-samples.mjs writes thirteen capsules of format 2 with
encrypt (both policies and padding rules, 0 to 16 credentials, chunk
borders, extensions in the three objects, an instant with nanoseconds),
four mixes of two capsules, the inputs of an encoder differential drawn
from a seed, a corpus of recipient strings and the invalid options that
Go also rejects. scripts/capsule-go-verdicts.go gives the verdicts of the
reference on them:
- capsule.Inspect, and capsule.Open with each credential alone and all
together: every sample opens to its content, with format 2 and the L,
padding rule and P requested;
- SEALED_CONTROL opened layer by layer with the agewrap identities, 16
stanzas in INNER_ACCESS_AGE, and PUBLIC_HEADER, CONTROL_CBOR and the
.dkk encoded again to the same bytes;
- the code and step of each mix;
- EncodeHeader, EncodeControl (format 2) and MarshalBody equal on all 500
encoder inputs;
- the texts of age.ParseX25519Recipient, agewrap.CheckX25519Recipient and
capsule.Encrypt, equal to those of this library.
The capsules are random, so the output is frozen in
src/lib/dkc/testing/capsule-vectors.json, and interop.test.ts checks the
verdicts of Go and that open reaches the same ones on the frozen bytes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
type sampleOut struct {
sampleIn
Go struct {
Inspect string ` json:"inspect" `
Opens [ ] openVerdict ` json:"opens" `
InnerStanzas int ` json:"inner_stanzas" `
Reencoded bool ` json:"reencoded" `
Go opens what the writer of v0.11 writes: capsule-vectors.json again
Fixes T10 of the review of the session of 1 and 2 October: no test checked
that Go opens what encryptFiles writes today, since capsule-vectors.json
came from c3c124a, with an area of 512 bytes and no note.
- capsule-ts-samples.mjs writes format 2 with encryptVectors of
testing/encrypt.ts, as a generator of test vectors, and format 3 with
encryptFiles, as any caller writes it: the six samples of before, now
with the area of 32 KiB, and two more with a public note, one out of
ASCII, and one of 1024 bytes in time_and_key beside another noncritical
extension of the header.
- capsule-go-verdicts.go records the size of the area that capsule.Open
gives, the note that Header.PublicNote reads, the text of capsule.Encrypt
for a public note in format 2, and the text of capsule.EncryptFiles for
nine public notes that break their rules.
- interop.test.ts requires Go to open each of the 21 samples with each
credential, to find the area of 32 KiB in format 3 and to read the note
written, and this library to read the same note; and the texts of the 22
options and of the 9 notes to be those of Go.
Go at spec-v0.11 (ae33434) opens the 21 samples with each credential and
with all of them, encodes their objects again byte for byte, and gives the
texts of this library for the 22 options and the 9 notes; the four mixes,
the 500 inputs of the encoder differential and the 22 recipients give what
they gave. npm run verify passes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
PublicNote * string ` json:"public_note" `
Phase 3, step 5: interoperability with Go at the level of the capsule
scripts/capsule-ts-samples.mjs writes thirteen capsules of format 2 with
encrypt (both policies and padding rules, 0 to 16 credentials, chunk
borders, extensions in the three objects, an instant with nanoseconds),
four mixes of two capsules, the inputs of an encoder differential drawn
from a seed, a corpus of recipient strings and the invalid options that
Go also rejects. scripts/capsule-go-verdicts.go gives the verdicts of the
reference on them:
- capsule.Inspect, and capsule.Open with each credential alone and all
together: every sample opens to its content, with format 2 and the L,
padding rule and P requested;
- SEALED_CONTROL opened layer by layer with the agewrap identities, 16
stanzas in INNER_ACCESS_AGE, and PUBLIC_HEADER, CONTROL_CBOR and the
.dkk encoded again to the same bytes;
- the code and step of each mix;
- EncodeHeader, EncodeControl (format 2) and MarshalBody equal on all 500
encoder inputs;
- the texts of age.ParseX25519Recipient, agewrap.CheckX25519Recipient and
capsule.Encrypt, equal to those of this library.
The capsules are random, so the output is frozen in
src/lib/dkc/testing/capsule-vectors.json, and interop.test.ts checks the
verdicts of Go and that open reaches the same ones on the frozen bytes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
} ` json:"go" `
}
type mixOut struct {
Name string ` json:"name" `
Round uint64 ` json:"round" `
DKC string ` json:"dkc" `
Go struct {
Code string ` json:"code" `
Step int ` json:"step" `
} ` json:"go" `
}
type recipientOut struct {
String string ` json:"string" `
Parse string ` json:"parse" `
Check string ` json:"check,omitempty" `
}
type output struct {
Description string ` json:"description" `
Generator string ` json:"generator" `
SamplesGenerator string ` json:"samples_generator" `
Libraries string ` json:"libraries" `
Releases [ ] releaseOut ` json:"releases" `
Samples [ ] sampleOut ` json:"samples" `
Mixes [ ] mixOut ` json:"mixes" `
Encoders encodersOut ` json:"encoders" `
Recipients [ ] recipientOut ` json:"recipients" `
Errors [ ] errorCase ` json:"errors" `
Go opens what the writer of v0.11 writes: capsule-vectors.json again
Fixes T10 of the review of the session of 1 and 2 October: no test checked
that Go opens what encryptFiles writes today, since capsule-vectors.json
came from c3c124a, with an area of 512 bytes and no note.
- capsule-ts-samples.mjs writes format 2 with encryptVectors of
testing/encrypt.ts, as a generator of test vectors, and format 3 with
encryptFiles, as any caller writes it: the six samples of before, now
with the area of 32 KiB, and two more with a public note, one out of
ASCII, and one of 1024 bytes in time_and_key beside another noncritical
extension of the header.
- capsule-go-verdicts.go records the size of the area that capsule.Open
gives, the note that Header.PublicNote reads, the text of capsule.Encrypt
for a public note in format 2, and the text of capsule.EncryptFiles for
nine public notes that break their rules.
- interop.test.ts requires Go to open each of the 21 samples with each
credential, to find the area of 32 KiB in format 3 and to read the note
written, and this library to read the same note; and the texts of the 22
options and of the 9 notes to be those of Go.
Go at spec-v0.11 (ae33434) opens the 21 samples with each credential and
with all of them, encodes their objects again byte for byte, and gives the
texts of this library for the 22 options and the 9 notes; the four mixes,
the 500 inputs of the encoder differential and the 22 recipients give what
they gave. npm run verify passes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
NoteErrors [ ] noteError ` json:"note_errors" `
Phase 3, step 5: interoperability with Go at the level of the capsule
scripts/capsule-ts-samples.mjs writes thirteen capsules of format 2 with
encrypt (both policies and padding rules, 0 to 16 credentials, chunk
borders, extensions in the three objects, an instant with nanoseconds),
four mixes of two capsules, the inputs of an encoder differential drawn
from a seed, a corpus of recipient strings and the invalid options that
Go also rejects. scripts/capsule-go-verdicts.go gives the verdicts of the
reference on them:
- capsule.Inspect, and capsule.Open with each credential alone and all
together: every sample opens to its content, with format 2 and the L,
padding rule and P requested;
- SEALED_CONTROL opened layer by layer with the agewrap identities, 16
stanzas in INNER_ACCESS_AGE, and PUBLIC_HEADER, CONTROL_CBOR and the
.dkk encoded again to the same bytes;
- the code and step of each mix;
- EncodeHeader, EncodeControl (format 2) and MarshalBody equal on all 500
encoder inputs;
- the texts of age.ParseX25519Recipient, agewrap.CheckX25519Recipient and
capsule.Encrypt, equal to those of this library.
The capsules are random, so the output is frozen in
src/lib/dkc/testing/capsule-vectors.json, and interop.test.ts checks the
verdicts of Go and that open reaches the same ones on the frozen bytes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
}
type releaseOut struct {
Round uint64 ` json:"round" `
Signature string ` json:"signature" `
}
type encodersOut struct {
Seed int ` json:"seed" `
Count int ` json:"count" `
SHA256 string ` json:"sha256" `
Equal int ` json:"equal" `
Differences [ ] string ` json:"differences" `
}
func must [ T any ] ( v T , err error ) T {
if err != nil {
panic ( err )
}
return v
}
func unhex ( s string ) [ ] byte { return must ( hex . DecodeString ( s ) ) }
func exts ( list [ ] extJSON ) [ ] extension . Extension {
var out [ ] extension . Extension
for _ , e := range list {
x := extension . Extension { ID : e . ID , Version : e . Version }
if e . Data != nil {
x . Data = unhex ( * e . Data )
if x . Data == nil {
x . Data = [ ] byte { }
}
}
out = append ( out , x )
}
return out
}
func source ( round uint64 ) provider . ReleaseSource {
return provider . ReleaseSourceFunc ( func ( _ context . Context , _ * profile . Profile , c provider . Condition ) ( provider . Release , error ) {
return provider . Release { Round : c . Round , Signature : unhex ( published [ c . Round ] ) } , nil
} )
}
func opened ( dkc [ ] byte , round uint64 , reg profile . Registry , ex extension . Registry , ids [ ] age . Identity , dkk [ ] byte ) openVerdict {
var out bytes . Buffer
Format 3, step 4: Go opens what encryptFiles writes
capsule-vectors.json is written again with six capsules of format 3
from encryptFiles, next to the thirteen of format 2:
- one file with its mtime; a tree of seven files, one of them over two
STREAM chunks, with paths out of ASCII and the pair U+FFFD and
U+10000, which UTF-8 and UTF-16 order the other way round, a comment
and a declared author; a comment and no file; bloque256; time_and_key
with three recipients and a portable key; and head extensions.
- capsule-go-verdicts.go opens them with capsule.Open into a Sink, with
each credential alone and with all of them, and records the files it
receives with their SHA-256, the head encoded again with
capsule.EncodeHead and the verdicts of the security area. It decodes
the control of each capsule in the format of its prelude, and runs
capsule.Encrypt on the invalid options as a generator of test vectors.
- interop.test.ts requires Go to find the files, the head and the
verdicts written, and open, into a MemorySink, to reach the same
verdicts on the same bytes.
The format 2 samples, the mixes, the encoder differential (500 equal),
the recipients and the 21 option errors are regenerated too, with the
same verdicts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
files := & sink { }
o := capsule . OpenOptions { Registry : reg , Extensions : ex , Source : source ( round ) , Identities : ids , Sink : files , Now : func ( ) time . Time {
Phase 3, step 5: interoperability with Go at the level of the capsule
scripts/capsule-ts-samples.mjs writes thirteen capsules of format 2 with
encrypt (both policies and padding rules, 0 to 16 credentials, chunk
borders, extensions in the three objects, an instant with nanoseconds),
four mixes of two capsules, the inputs of an encoder differential drawn
from a seed, a corpus of recipient strings and the invalid options that
Go also rejects. scripts/capsule-go-verdicts.go gives the verdicts of the
reference on them:
- capsule.Inspect, and capsule.Open with each credential alone and all
together: every sample opens to its content, with format 2 and the L,
padding rule and P requested;
- SEALED_CONTROL opened layer by layer with the agewrap identities, 16
stanzas in INNER_ACCESS_AGE, and PUBLIC_HEADER, CONTROL_CBOR and the
.dkk encoded again to the same bytes;
- the code and step of each mix;
- EncodeHeader, EncodeControl (format 2) and MarshalBody equal on all 500
encoder inputs;
- the texts of age.ParseX25519Recipient, agewrap.CheckX25519Recipient and
capsule.Encrypt, equal to those of this library.
The capsules are random, so the output is frozen in
src/lib/dkc/testing/capsule-vectors.json, and interop.test.ts checks the
verdicts of Go and that open reaches the same ones on the frozen bytes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
return time . Unix ( 1692803367 + int64 ( round - 1 ) * 3 , 0 )
} }
if dkk != nil {
o . AccessKeyFile = bytes . NewReader ( dkk )
}
res , err := capsule . Open ( context . Background ( ) , & out , bytes . NewReader ( dkc ) , o )
v := openVerdict { Result : "ok" }
if err != nil {
v . Result = datekeys . Code ( err )
if v . Result == "" {
v . Result = "error: " + err . Error ( )
}
if res != nil && res . Inspection != nil && len ( res . Inspection . Checks ) > 0 {
v . Step = res . Inspection . Checks [ len ( res . Inspection . Checks ) - 1 ] . Step
}
return v
}
Format 3, step 4: Go opens what encryptFiles writes
capsule-vectors.json is written again with six capsules of format 3
from encryptFiles, next to the thirteen of format 2:
- one file with its mtime; a tree of seven files, one of them over two
STREAM chunks, with paths out of ASCII and the pair U+FFFD and
U+10000, which UTF-8 and UTF-16 order the other way round, a comment
and a declared author; a comment and no file; bloque256; time_and_key
with three recipients and a portable key; and head extensions.
- capsule-go-verdicts.go opens them with capsule.Open into a Sink, with
each credential alone and with all of them, and records the files it
receives with their SHA-256, the head encoded again with
capsule.EncodeHead and the verdicts of the security area. It decodes
the control of each capsule in the format of its prelude, and runs
capsule.Encrypt on the invalid options as a generator of test vectors.
- interop.test.ts requires Go to find the files, the head and the
verdicts written, and open, into a MemorySink, to reach the same
verdicts on the same bytes.
The format 2 samples, the mixes, the encoder differential (500 equal),
the recipients and the 21 option errors are regenerated too, with the
same verdicts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
v . Opened = & openedOut { Format : int ( res . Format ) , Length : res . PayloadLength , Padding : int ( res . Padding ) , PaddedLength : res . PaddedLength }
if res . Format != capsule . Format3 {
sum := sha256 . Sum256 ( out . Bytes ( ) )
v . Opened . ContentSHA256 = hex . EncodeToString ( sum [ : ] )
return v
}
for i , f := range res . Head . Files {
sum := sha256 . Sum256 ( files . files [ i ] . Bytes ( ) )
fj := fileJSON { Path : f . Path , Size : f . Size , SHA256 : hex . EncodeToString ( sum [ : ] ) }
if f . HasMTime {
mtime := f . MTime
fj . MTime = & mtime
}
v . Opened . Files = append ( v . Opened . Files , fj )
}
v . Opened . HeadCBOR = hex . EncodeToString ( must ( capsule . EncodeHead ( res . Head ) ) )
v . Opened . Verdicts = [ ] string { string ( res . Verdicts . Signature ) , string ( res . Verdicts . Seal ) }
Go opens what the writer of v0.11 writes: capsule-vectors.json again
Fixes T10 of the review of the session of 1 and 2 October: no test checked
that Go opens what encryptFiles writes today, since capsule-vectors.json
came from c3c124a, with an area of 512 bytes and no note.
- capsule-ts-samples.mjs writes format 2 with encryptVectors of
testing/encrypt.ts, as a generator of test vectors, and format 3 with
encryptFiles, as any caller writes it: the six samples of before, now
with the area of 32 KiB, and two more with a public note, one out of
ASCII, and one of 1024 bytes in time_and_key beside another noncritical
extension of the header.
- capsule-go-verdicts.go records the size of the area that capsule.Open
gives, the note that Header.PublicNote reads, the text of capsule.Encrypt
for a public note in format 2, and the text of capsule.EncryptFiles for
nine public notes that break their rules.
- interop.test.ts requires Go to open each of the 21 samples with each
credential, to find the area of 32 KiB in format 3 and to read the note
written, and this library to read the same note; and the texts of the 22
options and of the 9 notes to be those of Go.
Go at spec-v0.11 (ae33434) opens the 21 samples with each credential and
with all of them, encodes their objects again byte for byte, and gives the
texts of this library for the 22 options and the 9 notes; the four mixes,
the 500 inputs of the encoder differential and the 22 recipients give what
they gave. npm run verify passes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
v . Opened . AreaLen = res . AreaLen
Phase 3, step 5: interoperability with Go at the level of the capsule
scripts/capsule-ts-samples.mjs writes thirteen capsules of format 2 with
encrypt (both policies and padding rules, 0 to 16 credentials, chunk
borders, extensions in the three objects, an instant with nanoseconds),
four mixes of two capsules, the inputs of an encoder differential drawn
from a seed, a corpus of recipient strings and the invalid options that
Go also rejects. scripts/capsule-go-verdicts.go gives the verdicts of the
reference on them:
- capsule.Inspect, and capsule.Open with each credential alone and all
together: every sample opens to its content, with format 2 and the L,
padding rule and P requested;
- SEALED_CONTROL opened layer by layer with the agewrap identities, 16
stanzas in INNER_ACCESS_AGE, and PUBLIC_HEADER, CONTROL_CBOR and the
.dkk encoded again to the same bytes;
- the code and step of each mix;
- EncodeHeader, EncodeControl (format 2) and MarshalBody equal on all 500
encoder inputs;
- the texts of age.ParseX25519Recipient, agewrap.CheckX25519Recipient and
capsule.Encrypt, equal to those of this library.
The capsules are random, so the output is frozen in
src/lib/dkc/testing/capsule-vectors.json, and interop.test.ts checks the
verdicts of Go and that open reaches the same ones on the frozen bytes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
return v
}
func main ( ) {
var in input
must ( 0 , json . Unmarshal ( must ( os . ReadFile ( os . Args [ 1 ] ) ) , & in ) )
reg := must ( profile . Default ( ) )
p := profile . Quicknet ( )
out := output {
Description : "Verdicts of the Go reference on capsules, mixes, encodings, recipients and invalid options of the TypeScript writer (plan of phase 3, section 8, point 9); see the header of scripts/capsule-go-verdicts.go." ,
Generator : "scripts/capsule-go-verdicts.go" ,
SamplesGenerator : in . Generator ,
Libraries : libraries ( ) ,
}
for _ , r := range slices . Sorted ( maps . Keys ( published ) ) {
out . Releases = append ( out . Releases , releaseOut { r , published [ r ] } )
}
for _ , s := range in . Samples {
dkc := unhex ( s . DKC )
known := extension . Set { }
for _ , k := range s . Known {
known [ k . ID ] = append ( known [ k . ID ] , k . Version )
}
so := sampleOut { sampleIn : s }
if _ , err := capsule . Inspect ( bytes . NewReader ( dkc ) , capsule . InspectOptions { Registry : reg , Extensions : known } ) ; err != nil {
so . Go . Inspect = datekeys . Code ( err )
} else {
so . Go . Inspect = "ok"
}
var ids [ ] age . Identity
for i , raw := range s . Identities {
id := must ( agewrap . X25519IdentityFromRaw ( unhex ( raw ) ) )
ids = append ( ids , id )
v := opened ( dkc , s . Round , reg , known , [ ] age . Identity { id } , nil )
v . Credentials = fmt . Sprintf ( "identity %d" , i )
so . Go . Opens = append ( so . Go . Opens , v )
}
var dkk [ ] byte
if s . DKK != "" {
dkk = unhex ( s . DKK )
v := opened ( dkc , s . Round , reg , known , nil , dkk )
v . Credentials = ".dkk"
so . Go . Opens = append ( so . Go . Opens , v )
}
v := opened ( dkc , s . Round , reg , known , ids , dkk )
v . Credentials = "all"
if ids == nil && dkk == nil {
v . Credentials = "none"
}
so . Go . Opens = append ( so . Go . Opens , v )
Go opens what the writer of v0.11 writes: capsule-vectors.json again
Fixes T10 of the review of the session of 1 and 2 October: no test checked
that Go opens what encryptFiles writes today, since capsule-vectors.json
came from c3c124a, with an area of 512 bytes and no note.
- capsule-ts-samples.mjs writes format 2 with encryptVectors of
testing/encrypt.ts, as a generator of test vectors, and format 3 with
encryptFiles, as any caller writes it: the six samples of before, now
with the area of 32 KiB, and two more with a public note, one out of
ASCII, and one of 1024 bytes in time_and_key beside another noncritical
extension of the header.
- capsule-go-verdicts.go records the size of the area that capsule.Open
gives, the note that Header.PublicNote reads, the text of capsule.Encrypt
for a public note in format 2, and the text of capsule.EncryptFiles for
nine public notes that break their rules.
- interop.test.ts requires Go to open each of the 21 samples with each
credential, to find the area of 32 KiB in format 3 and to read the note
written, and this library to read the same note; and the texts of the 22
options and of the 9 notes to be those of Go.
Go at spec-v0.11 (ae33434) opens the 21 samples with each credential and
with all of them, encodes their objects again byte for byte, and gives the
texts of this library for the 22 options and the 9 notes; the four mixes,
the 500 inputs of the encoder differential and the 22 recipients give what
they gave. npm run verify passes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
so . Go . InnerStanzas , so . Go . Reencoded , so . Go . PublicNote = layers ( dkc , s , p , dkk )
Phase 3, step 5: interoperability with Go at the level of the capsule
scripts/capsule-ts-samples.mjs writes thirteen capsules of format 2 with
encrypt (both policies and padding rules, 0 to 16 credentials, chunk
borders, extensions in the three objects, an instant with nanoseconds),
four mixes of two capsules, the inputs of an encoder differential drawn
from a seed, a corpus of recipient strings and the invalid options that
Go also rejects. scripts/capsule-go-verdicts.go gives the verdicts of the
reference on them:
- capsule.Inspect, and capsule.Open with each credential alone and all
together: every sample opens to its content, with format 2 and the L,
padding rule and P requested;
- SEALED_CONTROL opened layer by layer with the agewrap identities, 16
stanzas in INNER_ACCESS_AGE, and PUBLIC_HEADER, CONTROL_CBOR and the
.dkk encoded again to the same bytes;
- the code and step of each mix;
- EncodeHeader, EncodeControl (format 2) and MarshalBody equal on all 500
encoder inputs;
- the texts of age.ParseX25519Recipient, agewrap.CheckX25519Recipient and
capsule.Encrypt, equal to those of this library.
The capsules are random, so the output is frozen in
src/lib/dkc/testing/capsule-vectors.json, and interop.test.ts checks the
verdicts of Go and that open reaches the same ones on the frozen bytes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
out . Samples = append ( out . Samples , so )
}
for _ , m := range in . Mixes {
v := opened ( unhex ( m . DKC ) , m . Round , reg , extension . Set { } , nil , nil )
mo := mixOut { Name : m . Name , Round : m . Round , DKC : m . DKC }
mo . Go . Code , mo . Go . Step = v . Result , v . Step
out . Mixes = append ( out . Mixes , mo )
}
out . Encoders = encodersOut { Seed : in . Encoders . Seed , Count : in . Encoders . Count , SHA256 : in . Encoders . SHA256 , Differences : [ ] string { } }
for i , c := range in . Encoders . Cases {
if d := encoders ( c ) ; d != "" {
out . Encoders . Differences = append ( out . Encoders . Differences , fmt . Sprintf ( "case %d: %s" , i , d ) )
} else {
out . Encoders . Equal ++
}
}
for _ , s := range in . Recipients {
r := recipientOut { String : s , Parse : "ok" }
x , err := age . ParseX25519Recipient ( s )
if err != nil {
r . Parse = err . Error ( )
} else if err := agewrap . CheckX25519Recipient ( x ) ; err != nil {
r . Check = err . Error ( )
} else {
r . Check = "ok"
}
out . Recipients = append ( out . Recipients , r )
}
for _ , c := range in . Errors {
c . Go = encryptError ( c )
out . Errors = append ( out . Errors , c )
}
Go opens what the writer of v0.11 writes: capsule-vectors.json again
Fixes T10 of the review of the session of 1 and 2 October: no test checked
that Go opens what encryptFiles writes today, since capsule-vectors.json
came from c3c124a, with an area of 512 bytes and no note.
- capsule-ts-samples.mjs writes format 2 with encryptVectors of
testing/encrypt.ts, as a generator of test vectors, and format 3 with
encryptFiles, as any caller writes it: the six samples of before, now
with the area of 32 KiB, and two more with a public note, one out of
ASCII, and one of 1024 bytes in time_and_key beside another noncritical
extension of the header.
- capsule-go-verdicts.go records the size of the area that capsule.Open
gives, the note that Header.PublicNote reads, the text of capsule.Encrypt
for a public note in format 2, and the text of capsule.EncryptFiles for
nine public notes that break their rules.
- interop.test.ts requires Go to open each of the 21 samples with each
credential, to find the area of 32 KiB in format 3 and to read the note
written, and this library to read the same note; and the texts of the 22
options and of the 9 notes to be those of Go.
Go at spec-v0.11 (ae33434) opens the 21 samples with each credential and
with all of them, encodes their objects again byte for byte, and gives the
texts of this library for the 22 options and the 9 notes; the four mixes,
the 500 inputs of the encoder differential and the 22 recipients give what
they gave. npm run verify passes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
for _ , c := range in . NoteErrors {
c . Go = noteText ( c . Note )
out . NoteErrors = append ( out . NoteErrors , c )
}
Phase 3, step 5: interoperability with Go at the level of the capsule
scripts/capsule-ts-samples.mjs writes thirteen capsules of format 2 with
encrypt (both policies and padding rules, 0 to 16 credentials, chunk
borders, extensions in the three objects, an instant with nanoseconds),
four mixes of two capsules, the inputs of an encoder differential drawn
from a seed, a corpus of recipient strings and the invalid options that
Go also rejects. scripts/capsule-go-verdicts.go gives the verdicts of the
reference on them:
- capsule.Inspect, and capsule.Open with each credential alone and all
together: every sample opens to its content, with format 2 and the L,
padding rule and P requested;
- SEALED_CONTROL opened layer by layer with the agewrap identities, 16
stanzas in INNER_ACCESS_AGE, and PUBLIC_HEADER, CONTROL_CBOR and the
.dkk encoded again to the same bytes;
- the code and step of each mix;
- EncodeHeader, EncodeControl (format 2) and MarshalBody equal on all 500
encoder inputs;
- the texts of age.ParseX25519Recipient, agewrap.CheckX25519Recipient and
capsule.Encrypt, equal to those of this library.
The capsules are random, so the output is frozen in
src/lib/dkc/testing/capsule-vectors.json, and interop.test.ts checks the
verdicts of Go and that open reaches the same ones on the frozen bytes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
enc := json . NewEncoder ( os . Stdout )
enc . SetIndent ( "" , " " )
must ( 0 , enc . Encode ( out ) )
}
// layers opens SEALED_CONTROL of a sample with the published release and, in
// time_and_key, with its first credential, and encodes PUBLIC_HEADER,
// CONTROL_CBOR and the .dkk again. It returns the number of stanzas of
Go opens what the writer of v0.11 writes: capsule-vectors.json again
Fixes T10 of the review of the session of 1 and 2 October: no test checked
that Go opens what encryptFiles writes today, since capsule-vectors.json
came from c3c124a, with an area of 512 bytes and no note.
- capsule-ts-samples.mjs writes format 2 with encryptVectors of
testing/encrypt.ts, as a generator of test vectors, and format 3 with
encryptFiles, as any caller writes it: the six samples of before, now
with the area of 32 KiB, and two more with a public note, one out of
ASCII, and one of 1024 bytes in time_and_key beside another noncritical
extension of the header.
- capsule-go-verdicts.go records the size of the area that capsule.Open
gives, the note that Header.PublicNote reads, the text of capsule.Encrypt
for a public note in format 2, and the text of capsule.EncryptFiles for
nine public notes that break their rules.
- interop.test.ts requires Go to open each of the 21 samples with each
credential, to find the area of 32 KiB in format 3 and to read the note
written, and this library to read the same note; and the texts of the 22
options and of the 9 notes to be those of Go.
Go at spec-v0.11 (ae33434) opens the 21 samples with each credential and
with all of them, encodes their objects again byte for byte, and gives the
texts of this library for the 22 options and the 9 notes; the four mixes,
the 500 inputs of the encoder differential and the 22 recipients give what
they gave. npm run verify passes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
// INNER_ACCESS_AGE, whether every encoding equals the bytes written, and the
// public note of PUBLIC_HEADER, nil when there is none that is usable.
func layers ( dkc [ ] byte , s sampleIn , p * profile . Profile , dkk [ ] byte ) ( int , bool , * string ) {
Phase 3, step 5: interoperability with Go at the level of the capsule
scripts/capsule-ts-samples.mjs writes thirteen capsules of format 2 with
encrypt (both policies and padding rules, 0 to 16 credentials, chunk
borders, extensions in the three objects, an instant with nanoseconds),
four mixes of two capsules, the inputs of an encoder differential drawn
from a seed, a corpus of recipient strings and the invalid options that
Go also rejects. scripts/capsule-go-verdicts.go gives the verdicts of the
reference on them:
- capsule.Inspect, and capsule.Open with each credential alone and all
together: every sample opens to its content, with format 2 and the L,
padding rule and P requested;
- SEALED_CONTROL opened layer by layer with the agewrap identities, 16
stanzas in INNER_ACCESS_AGE, and PUBLIC_HEADER, CONTROL_CBOR and the
.dkk encoded again to the same bytes;
- the code and step of each mix;
- EncodeHeader, EncodeControl (format 2) and MarshalBody equal on all 500
encoder inputs;
- the texts of age.ParseX25519Recipient, agewrap.CheckX25519Recipient and
capsule.Encrypt, equal to those of this library.
The capsules are random, so the output is frozen in
src/lib/dkc/testing/capsule-vectors.json, and interop.test.ts checks the
verdicts of Go and that open reaches the same ones on the frozen bytes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
pre := must ( capsule . ParsePrelude ( dkc ) )
header := dkc [ capsule . PreludeSize : capsule . PreludeSize + int ( pre . PublicHeaderLen ) ]
sealed := dkc [ capsule . PreludeSize + int ( pre . PublicHeaderLen ) : capsule . PreludeSize + int ( pre . PublicHeaderLen ) + int ( pre . SealedControlLen ) ]
same := true
h := must ( capsule . DecodeHeader ( header ) )
same = same && bytes . Equal ( must ( capsule . EncodeHeader ( h ) ) , header )
Go opens what the writer of v0.11 writes: capsule-vectors.json again
Fixes T10 of the review of the session of 1 and 2 October: no test checked
that Go opens what encryptFiles writes today, since capsule-vectors.json
came from c3c124a, with an area of 512 bytes and no note.
- capsule-ts-samples.mjs writes format 2 with encryptVectors of
testing/encrypt.ts, as a generator of test vectors, and format 3 with
encryptFiles, as any caller writes it: the six samples of before, now
with the area of 32 KiB, and two more with a public note, one out of
ASCII, and one of 1024 bytes in time_and_key beside another noncritical
extension of the header.
- capsule-go-verdicts.go records the size of the area that capsule.Open
gives, the note that Header.PublicNote reads, the text of capsule.Encrypt
for a public note in format 2, and the text of capsule.EncryptFiles for
nine public notes that break their rules.
- interop.test.ts requires Go to open each of the 21 samples with each
credential, to find the area of 32 KiB in format 3 and to read the note
written, and this library to read the same note; and the texts of the 22
options and of the 9 notes to be those of Go.
Go at spec-v0.11 (ae33434) opens the 21 samples with each credential and
with all of them, encodes their objects again byte for byte, and gives the
texts of this library for the 22 options and the 9 notes; the four mixes,
the 500 inputs of the encoder differential and the 22 recipients give what
they gave. npm run verify passes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
var note * string
if text , ok := h . PublicNote ( ) ; ok {
note = & text
}
Phase 3, step 5: interoperability with Go at the level of the capsule
scripts/capsule-ts-samples.mjs writes thirteen capsules of format 2 with
encrypt (both policies and padding rules, 0 to 16 credentials, chunk
borders, extensions in the three objects, an instant with nanoseconds),
four mixes of two capsules, the inputs of an encoder differential drawn
from a seed, a corpus of recipient strings and the invalid options that
Go also rejects. scripts/capsule-go-verdicts.go gives the verdicts of the
reference on them:
- capsule.Inspect, and capsule.Open with each credential alone and all
together: every sample opens to its content, with format 2 and the L,
padding rule and P requested;
- SEALED_CONTROL opened layer by layer with the agewrap identities, 16
stanzas in INNER_ACCESS_AGE, and PUBLIC_HEADER, CONTROL_CBOR and the
.dkk encoded again to the same bytes;
- the code and step of each mix;
- EncodeHeader, EncodeControl (format 2) and MarshalBody equal on all 500
encoder inputs;
- the texts of age.ParseX25519Recipient, agewrap.CheckX25519Recipient and
capsule.Encrypt, equal to those of this library.
The capsules are random, so the output is frozen in
src/lib/dkc/testing/capsule-vectors.json, and interop.test.ts checks the
verdicts of Go and that open reaches the same ones on the frozen bytes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
tid := must ( agewrap . NewTimeIdentity ( p , s . Round , provider . Release { Round : s . Round , Signature : unhex ( published [ s . Round ] ) } ) )
inner := must ( io . ReadAll ( must ( age . Decrypt ( bytes . NewReader ( sealed ) , tid ) ) ) )
control := inner
stanzas := 0
if s . Policy == "time_and_key" {
st := must ( agewrap . Stanzas ( bytes . NewReader ( inner ) ) )
stanzas = len ( st )
var id age . Identity
if len ( s . Identities ) > 0 {
id = must ( agewrap . X25519IdentityFromRaw ( unhex ( s . Identities [ 0 ] ) ) )
} else {
k := must ( accesskey . Decode ( bytes . NewReader ( dkk ) ) )
id = must ( agewrap . X25519IdentityFromRaw ( k . Material ) )
}
aid := must ( agewrap . NewAccessIdentity ( agewrap . AccessSlots , id ) )
control = must ( io . ReadAll ( must ( age . Decrypt ( bytes . NewReader ( inner ) , aid ) ) ) )
}
Format 3, step 4: Go opens what encryptFiles writes
capsule-vectors.json is written again with six capsules of format 3
from encryptFiles, next to the thirteen of format 2:
- one file with its mtime; a tree of seven files, one of them over two
STREAM chunks, with paths out of ASCII and the pair U+FFFD and
U+10000, which UTF-8 and UTF-16 order the other way round, a comment
and a declared author; a comment and no file; bloque256; time_and_key
with three recipients and a portable key; and head extensions.
- capsule-go-verdicts.go opens them with capsule.Open into a Sink, with
each credential alone and with all of them, and records the files it
receives with their SHA-256, the head encoded again with
capsule.EncodeHead and the verdicts of the security area. It decodes
the control of each capsule in the format of its prelude, and runs
capsule.Encrypt on the invalid options as a generator of test vectors.
- interop.test.ts requires Go to find the files, the head and the
verdicts written, and open, into a MemorySink, to reach the same
verdicts on the same bytes.
The format 2 samples, the mixes, the encoder differential (500 equal),
the recipients and the 21 option errors are regenerated too, with the
same verdicts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
c := must ( capsule . DecodeControl ( control , pre . Format ) )
same = same && bytes . Equal ( must ( capsule . EncodeControl ( c , pre . Format ) ) , control )
Phase 3, step 5: interoperability with Go at the level of the capsule
scripts/capsule-ts-samples.mjs writes thirteen capsules of format 2 with
encrypt (both policies and padding rules, 0 to 16 credentials, chunk
borders, extensions in the three objects, an instant with nanoseconds),
four mixes of two capsules, the inputs of an encoder differential drawn
from a seed, a corpus of recipient strings and the invalid options that
Go also rejects. scripts/capsule-go-verdicts.go gives the verdicts of the
reference on them:
- capsule.Inspect, and capsule.Open with each credential alone and all
together: every sample opens to its content, with format 2 and the L,
padding rule and P requested;
- SEALED_CONTROL opened layer by layer with the agewrap identities, 16
stanzas in INNER_ACCESS_AGE, and PUBLIC_HEADER, CONTROL_CBOR and the
.dkk encoded again to the same bytes;
- the code and step of each mix;
- EncodeHeader, EncodeControl (format 2) and MarshalBody equal on all 500
encoder inputs;
- the texts of age.ParseX25519Recipient, agewrap.CheckX25519Recipient and
capsule.Encrypt, equal to those of this library.
The capsules are random, so the output is frozen in
src/lib/dkc/testing/capsule-vectors.json, and interop.test.ts checks the
verdicts of Go and that open reaches the same ones on the frozen bytes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
if dkk != nil {
k := must ( accesskey . Decode ( bytes . NewReader ( dkk ) ) )
var b bytes . Buffer
must ( 0 , accesskey . Encode ( & b , k ) )
same = same && bytes . Equal ( b . Bytes ( ) , dkk )
}
Go opens what the writer of v0.11 writes: capsule-vectors.json again
Fixes T10 of the review of the session of 1 and 2 October: no test checked
that Go opens what encryptFiles writes today, since capsule-vectors.json
came from c3c124a, with an area of 512 bytes and no note.
- capsule-ts-samples.mjs writes format 2 with encryptVectors of
testing/encrypt.ts, as a generator of test vectors, and format 3 with
encryptFiles, as any caller writes it: the six samples of before, now
with the area of 32 KiB, and two more with a public note, one out of
ASCII, and one of 1024 bytes in time_and_key beside another noncritical
extension of the header.
- capsule-go-verdicts.go records the size of the area that capsule.Open
gives, the note that Header.PublicNote reads, the text of capsule.Encrypt
for a public note in format 2, and the text of capsule.EncryptFiles for
nine public notes that break their rules.
- interop.test.ts requires Go to open each of the 21 samples with each
credential, to find the area of 32 KiB in format 3 and to read the note
written, and this library to read the same note; and the texts of the 22
options and of the 9 notes to be those of Go.
Go at spec-v0.11 (ae33434) opens the 21 samples with each credential and
with all of them, encodes their objects again byte for byte, and gives the
texts of this library for the 22 options and the 9 notes; the four mixes,
the 500 inputs of the encoder differential and the 22 recipients give what
they gave. npm run verify passes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
return stanzas , same , note
Phase 3, step 5: interoperability with Go at the level of the capsule
scripts/capsule-ts-samples.mjs writes thirteen capsules of format 2 with
encrypt (both policies and padding rules, 0 to 16 credentials, chunk
borders, extensions in the three objects, an instant with nanoseconds),
four mixes of two capsules, the inputs of an encoder differential drawn
from a seed, a corpus of recipient strings and the invalid options that
Go also rejects. scripts/capsule-go-verdicts.go gives the verdicts of the
reference on them:
- capsule.Inspect, and capsule.Open with each credential alone and all
together: every sample opens to its content, with format 2 and the L,
padding rule and P requested;
- SEALED_CONTROL opened layer by layer with the agewrap identities, 16
stanzas in INNER_ACCESS_AGE, and PUBLIC_HEADER, CONTROL_CBOR and the
.dkk encoded again to the same bytes;
- the code and step of each mix;
- EncodeHeader, EncodeControl (format 2) and MarshalBody equal on all 500
encoder inputs;
- the texts of age.ParseX25519Recipient, agewrap.CheckX25519Recipient and
capsule.Encrypt, equal to those of this library.
The capsules are random, so the output is frozen in
src/lib/dkc/testing/capsule-vectors.json, and interop.test.ts checks the
verdicts of Go and that open reaches the same ones on the frozen bytes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
}
// encoders encodes one input with the reference and names the first encoding
// that differs from the bytes of the TypeScript library, or returns "".
func encoders ( c encoderIn ) string {
var h capsule . Header
copy ( h . CapsuleID [ : ] , unhex ( c . Header . CapsuleID ) )
h . DateKey = datekey . DateKey { ProfileID : "datekeys:quicknet:v1" , Round : c . Header . Round }
h . Policy = capsule . Policy ( c . Header . Policy )
h . Critical , h . Noncritical = exts ( c . Header . Critical ) , exts ( c . Header . Noncritical )
hb , err := capsule . EncodeHeader ( & h )
if err != nil || hex . EncodeToString ( hb ) != c . HeaderCBOR {
return fmt . Sprintf ( "PUBLIC_HEADER (%v)" , err )
}
var ctrl capsule . Control
copy ( ctrl . HeaderBinding [ : ] , unhex ( c . Control . HeaderBinding ) )
copy ( ctrl . PayloadIdentity [ : ] , unhex ( c . Control . PayloadIdentity ) )
ctrl . PayloadLength , ctrl . Padding = c . Control . PayloadLength , capsule . Padding ( c . Control . Padding )
ctrl . Critical , ctrl . Noncritical = exts ( c . Control . Critical ) , exts ( c . Control . Noncritical )
cb , err := capsule . EncodeControl ( & ctrl , capsule . Format2 )
if err != nil || hex . EncodeToString ( cb ) != c . ControlCBOR {
return fmt . Sprintf ( "CONTROL_CBOR (%v)" , err )
}
k := accesskey . AccessKey { Type : accesskey . TypeX25519 , Material : unhex ( c . DKK . Material ) }
copy ( k . CredentialID [ : ] , unhex ( c . DKK . CredentialID ) )
copy ( k . CapsuleID [ : ] , unhex ( c . DKK . CapsuleID ) )
if c . DKK . CapsuleDigest != nil {
k . Verification = & accesskey . Verification { CapsuleDigest : unhex ( * c . DKK . CapsuleDigest ) }
}
k . Critical , k . Noncritical = exts ( c . DKK . Critical ) , exts ( c . DKK . Noncritical )
kb , err := k . MarshalBody ( )
if err != nil || hex . EncodeToString ( kb ) != c . DKKBody {
return fmt . Sprintf ( ".dkk BODY_CBOR (%v)" , err )
}
return ""
}
// encryptError runs capsule.Encrypt with the options of a case and returns
// its error text, or "ok".
func encryptError ( c errorCase ) string {
p := profile . Quicknet ( )
if c . ChainHashFlip {
p . ChainHash [ 0 ] ^ = 1
}
var recipients [ ] age . Recipient
for _ , raw := range c . Recipients {
s := must ( bech32 . Encode ( "age" , unhex ( raw ) ) )
recipients = append ( recipients , must ( age . ParseX25519Recipient ( s ) ) )
}
opts := capsule . EncryptOptions {
Profile : p ,
UnlockAt : must ( time . Parse ( time . RFC3339Nano , c . UnlockAt ) ) ,
Policy : capsule . Policy ( c . Policy ) ,
Recipients : recipients ,
NewPortableKey : c . Portable ,
Length : c . Length ,
Padding : capsule . Padding ( c . Padding ) ,
Critical : exts ( c . Critical ) ,
Noncritical : exts ( c . Noncritical ) ,
ControlCritical : exts ( c . ControlCritical ) ,
ControlNoncritical : exts ( c . ControlNoncritical ) ,
Go opens what the writer of v0.11 writes: capsule-vectors.json again
Fixes T10 of the review of the session of 1 and 2 October: no test checked
that Go opens what encryptFiles writes today, since capsule-vectors.json
came from c3c124a, with an area of 512 bytes and no note.
- capsule-ts-samples.mjs writes format 2 with encryptVectors of
testing/encrypt.ts, as a generator of test vectors, and format 3 with
encryptFiles, as any caller writes it: the six samples of before, now
with the area of 32 KiB, and two more with a public note, one out of
ASCII, and one of 1024 bytes in time_and_key beside another noncritical
extension of the header.
- capsule-go-verdicts.go records the size of the area that capsule.Open
gives, the note that Header.PublicNote reads, the text of capsule.Encrypt
for a public note in format 2, and the text of capsule.EncryptFiles for
nine public notes that break their rules.
- interop.test.ts requires Go to open each of the 21 samples with each
credential, to find the area of 32 KiB in format 3 and to read the note
written, and this library to read the same note; and the texts of the 22
options and of the 9 notes to be those of Go.
Go at spec-v0.11 (ae33434) opens the 21 samples with each credential and
with all of them, encodes their objects again byte for byte, and gives the
texts of this library for the 22 options and the 9 notes; the four mixes,
the 500 inputs of the encoder differential and the 22 recipients give what
they gave. npm run verify passes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
PublicNote : c . PublicNote ,
Format 3, step 4: Go opens what encryptFiles writes
capsule-vectors.json is written again with six capsules of format 3
from encryptFiles, next to the thirteen of format 2:
- one file with its mtime; a tree of seven files, one of them over two
STREAM chunks, with paths out of ASCII and the pair U+FFFD and
U+10000, which UTF-8 and UTF-16 order the other way round, a comment
and a declared author; a comment and no file; bloque256; time_and_key
with three recipients and a portable key; and head extensions.
- capsule-go-verdicts.go opens them with capsule.Open into a Sink, with
each credential alone and with all of them, and records the files it
receives with their SHA-256, the head encoded again with
capsule.EncodeHead and the verdicts of the security area. It decodes
the control of each capsule in the format of its prelude, and runs
capsule.Encrypt on the invalid options as a generator of test vectors.
- interop.test.ts requires Go to find the files, the head and the
verdicts written, and open, into a MemorySink, to reach the same
verdicts on the same bytes.
The format 2 samples, the mixes, the encoder differential (500 equal),
the recipients and the 21 option errors are regenerated too, with the
same verdicts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
TestVectors : true ,
Phase 3, step 5: interoperability with Go at the level of the capsule
scripts/capsule-ts-samples.mjs writes thirteen capsules of format 2 with
encrypt (both policies and padding rules, 0 to 16 credentials, chunk
borders, extensions in the three objects, an instant with nanoseconds),
four mixes of two capsules, the inputs of an encoder differential drawn
from a seed, a corpus of recipient strings and the invalid options that
Go also rejects. scripts/capsule-go-verdicts.go gives the verdicts of the
reference on them:
- capsule.Inspect, and capsule.Open with each credential alone and all
together: every sample opens to its content, with format 2 and the L,
padding rule and P requested;
- SEALED_CONTROL opened layer by layer with the agewrap identities, 16
stanzas in INNER_ACCESS_AGE, and PUBLIC_HEADER, CONTROL_CBOR and the
.dkk encoded again to the same bytes;
- the code and step of each mix;
- EncodeHeader, EncodeControl (format 2) and MarshalBody equal on all 500
encoder inputs;
- the texts of age.ParseX25519Recipient, agewrap.CheckX25519Recipient and
capsule.Encrypt, equal to those of this library.
The capsules are random, so the output is frozen in
src/lib/dkc/testing/capsule-vectors.json, and interop.test.ts checks the
verdicts of Go and that open reaches the same ones on the frozen bytes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
Now : func ( ) time . Time { return must ( time . Parse ( time . RFC3339Nano , c . Now ) ) } ,
}
src := bytes . NewReader ( make ( [ ] byte , min ( c . Length , 1 ) ) )
if _ , err := capsule . Encrypt ( io . Discard , src , opts ) ; err != nil {
return err . Error ( )
}
return "ok"
}
Go opens what the writer of v0.11 writes: capsule-vectors.json again
Fixes T10 of the review of the session of 1 and 2 October: no test checked
that Go opens what encryptFiles writes today, since capsule-vectors.json
came from c3c124a, with an area of 512 bytes and no note.
- capsule-ts-samples.mjs writes format 2 with encryptVectors of
testing/encrypt.ts, as a generator of test vectors, and format 3 with
encryptFiles, as any caller writes it: the six samples of before, now
with the area of 32 KiB, and two more with a public note, one out of
ASCII, and one of 1024 bytes in time_and_key beside another noncritical
extension of the header.
- capsule-go-verdicts.go records the size of the area that capsule.Open
gives, the note that Header.PublicNote reads, the text of capsule.Encrypt
for a public note in format 2, and the text of capsule.EncryptFiles for
nine public notes that break their rules.
- interop.test.ts requires Go to open each of the 21 samples with each
credential, to find the area of 32 KiB in format 3 and to read the note
written, and this library to read the same note; and the texts of the 22
options and of the 9 notes to be those of Go.
Go at spec-v0.11 (ae33434) opens the 21 samples with each credential and
with all of them, encodes their objects again byte for byte, and gives the
texts of this library for the 22 options and the 9 notes; the four mixes,
the 500 inputs of the encoder differential and the 22 recipients give what
they gave. npm run verify passes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
// noteText runs capsule.EncryptFiles on a file of one byte, for round 1000
// with now at the genesis, with the public note given, and returns its error
// text, or "ok".
func noteText ( note string ) string {
genesis := time . Unix ( 1692803367 , 0 ) . UTC ( )
opts := capsule . EncryptOptions {
Profile : profile . Quicknet ( ) ,
UnlockAt : genesis . Add ( 999 * 3 * time . Second ) ,
Policy : capsule . TimeOnly ,
PublicNote : note ,
Now : func ( ) time . Time { return genesis } ,
}
src := [ ] capsule . Source { { Path : "a.txt" , Size : 1 , Open : func ( ) ( io . ReadCloser , error ) { return io . NopCloser ( strings . NewReader ( "x" ) ) , nil } } }
if _ , err := capsule . EncryptFiles ( io . Discard , src , opts ) ; err != nil {
return err . Error ( )
}
return "ok"
}
Phase 3, step 5: interoperability with Go at the level of the capsule
scripts/capsule-ts-samples.mjs writes thirteen capsules of format 2 with
encrypt (both policies and padding rules, 0 to 16 credentials, chunk
borders, extensions in the three objects, an instant with nanoseconds),
four mixes of two capsules, the inputs of an encoder differential drawn
from a seed, a corpus of recipient strings and the invalid options that
Go also rejects. scripts/capsule-go-verdicts.go gives the verdicts of the
reference on them:
- capsule.Inspect, and capsule.Open with each credential alone and all
together: every sample opens to its content, with format 2 and the L,
padding rule and P requested;
- SEALED_CONTROL opened layer by layer with the agewrap identities, 16
stanzas in INNER_ACCESS_AGE, and PUBLIC_HEADER, CONTROL_CBOR and the
.dkk encoded again to the same bytes;
- the code and step of each mix;
- EncodeHeader, EncodeControl (format 2) and MarshalBody equal on all 500
encoder inputs;
- the texts of age.ParseX25519Recipient, agewrap.CheckX25519Recipient and
capsule.Encrypt, equal to those of this library.
The capsules are random, so the output is frozen in
src/lib/dkc/testing/capsule-vectors.json, and interop.test.ts checks the
verdicts of Go and that open reaches the same ones on the frozen bytes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
func libraries ( ) string {
info , ok := debug . ReadBuildInfo ( )
if ! ok {
return ""
}
var parts [ ] string
for _ , d := range info . Deps {
switch d . Path {
case "filippo.io/age" , "github.com/drand/drand/v2" , "github.com/drand/kyber" , "github.com/drand/kyber-bls12381" , "github.com/drand/tlock" :
parts = append ( parts , d . Path + " " + d . Version )
}
}
return strings . Join ( parts , ", " )
}