SHA-256 with its own compression, and on it HMAC-SHA256 with the inner and
outer states of the key computed once, HKDF-SHA256 and PBKDF2-HMAC-SHA256,
whose iterations are two compressions over words; scrypt with Salsa20/8;
ChaCha20, Poly1305 in 13-bit limbs and ChaCha20-Poly1305 with the tag
compared in constant time; X25519 on the field of TweetNaCl in doubles,
with the all-zero secret refused; the strict Ed25519 verification of
internal/ed25519strict; Go's Base64 with the offsets of its errors, and
age's Bech32.
tool/gen_primitive_vectors.go computes every expected value with Go and
x/crypto, from the inputs of RFC 5869, 7748, 7914, 8032 and 8439, edge
cases and seeded random ones. The tests also run compiled to JavaScript,
from a Dart copy of the JSON, without the cases that would take too long.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
lib/src/der.dart is the port of internal/der/der.go at 601e6d2, the
draft of v0.12, whose DER already differs from spec-v0.11: check, split,
content, setOfSorted and parseTime, with the texts of the reference. It
is internal, as in Go, and keeps the names of the Go package for an
import with a prefix.
parseTime reads UTCTime and GeneralizedTime in their forms of X.690
and refuses a date or a time that does not exist. It returns a DerTime,
exact to the nanosecond as Go's time.Time and unlike Dart's DateTime:
its fields and its seconds since the epoch, below 2^53.
The tests port der_test.go, with the texts that Go prints. The fuzz
target is a property over seeded mutations of its seeds and of the
signatures and tokens of security_cms.json.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
lib/src/cbor.dart is the port of codec/codec.go: CborEncoder,
CborDecoder, unmarshalCbor, peekSchema, checkSchema and walkCbor, with
the same reads, the same checks in the same order and the same error
texts, such as "codec: offset 0: 23 is not in its shortest form
(initial byte 0x18): ERR_NON_CANONICAL_CBOR".
Integers are exact on the VM and on the web, where an int is a double
and the bit operators work on 32 bits. An argument of eight bytes is
read as two halves of 32 bits, and is an int up to 2^53-1 and a BigInt
above, map keys and the numbers of the error texts included. uint
returns an int, since every schema bounds its integers at 2^53-1, and
uint64 a BigInt. The map that peekSchema reads is bounded at 2^63-1,
Go's math.MaxInt, on the web too.
Two kinds of text are of Dart only. CborEncoder.uint refuses an int
outside 0..2^53-1 and uint64 a BigInt outside 0..2^64-1, with the text
of datekeys-ts, where Go's uint64 cannot hold such a value. And the only
invalid text that a Dart String holds is a lone surrogate: the error
quotes it as Go quotes its bytes in generalized UTF-8.
The tests port codec_test.go, internal_test.go and vectors_test.go,
with the texts that Go prints, and cbor.test.ts. The fuzz targets are
properties over seeded inputs, checked against a reference encoder and
decoder written apart, as internal/cbortest. cbor.json runs its 36
accept and 67 reject vectors with the walk limits and the values; its
172 schema vectors are read and wait for the schema decoders of stage 4.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- lib/src/errors.dart, the port of errors.go: ErrorCode, the 19 codes in
the order of section 69, and DateKeysException, which carries one of
them with the message of the reference, the context and then the code.
wrap and withContext are fmt.Errorf("prefix: %w"), errorCode is
datekeys.Code. test/errors_spec_test.dart reads section 69 from
../datekeys-go at the tag spec-v0.11 and compares its ERR_ lines with
the catalogue; it is skipped when that repository is missing.
- lib/src/bytes.dart, as bytes.ts of datekeys-ts: hexadecimal,
comparison and concatenation; strict UTF-8 that keeps a leading
U+FEFF, which the Utf8Decoder of dart:convert drops on the VM and on
the web; Go's utf8.DecodeRune; and Go's %q, with the table of
strconv.IsPrint of Go 1.26 copied from datekeys-ts and the SHA-256 of
the whole rune set pinned. A lone surrogate, which a Dart String may
hold, is written in generalized UTF-8, which is not UTF-8.
- lib/datekeys.dart exports the errors and the byte functions that a
user needs.
- The tests that read files are marked @TestOn('vm'), those of stage 0
included, so that the others also run compiled to JavaScript with
dart test -p node.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A pure Dart package, without Flutter, for the app that the author will
write in Flutter (docs/PLAN_dart.md, stage 0):
- pubspec.yaml: the package datekeys, unpublished, for Dart 3.13; at run
time only package:crypto, and in development only package:test, which
the author approved on 5 October.
- testdata/ vendored from datekeys-go at the tag spec-v0.11 (ae33434),
124 files, with the same testdata/SOURCE.json that datekeys-ts writes for
that commit.
- tool/sync_testdata.dart, the port of scripts/sync-testdata.mjs, and
test/testdata_test.dart, which checks the copy and that every file names
specVersion; test/version_test.dart keeps pubspec.yaml and
lib/src/version.dart in step.
- tool/check.sh, the local gate: format, analysis with every info fatal,
tests, and the copy against ../datekeys-go.
- The licence, Apache-2.0, as the other two implementations.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>