Compare commits

...

17 Commits
v0.11 ... v0.15

Author SHA1 Message Date
dev e2296b02f0 The recovery annex and the state of a profile, as annex.go and profile/status.go
1 day ago
dev 8eed96f449 testdata, wordlists and annex at datekeys-go aefc8f6: the recovery annex, vendored
1 day ago
dev 00f4ad4582 Dice: diceNumber, diceWord, diceWords and diceList, as wordkey's dice.go
1 day ago
dev bf0f3d35d4 The English list of the EFF, pinned; testdata and wordlists at e671032
1 day ago
dev fcc7780cf1 Export the word lists; README and CHANGELOG for them
1 day ago
dev e29f4299b0 testdata and wordlists at datekeys-go 27a75ee: the word lists, vendored
1 day ago
dev a770d4d8b0 wordlist.dart: the random words of a key of words, as wordkey.Generate
1 day ago
dev faa2c4c891 testdata at spec-v0.15: the release objects are releases/<round>.cbor
2 days ago
dev 124b9d5de9 README and CHANGELOG for the specification 0.15
2 days ago
dev ad18c6c63e Specification 0.15: the release object, a release in hand and step 9.c
2 days ago
dev 013b069522 Specification 0.14, approved: one drand scheme and the tlock steps vectors
2 days ago
dev 2cdc1d9d12 Check the chain and the body of the sealed locator, as ParseInfo of Go
2 days ago
dev 63ca2ba82e Specification 0.13, approved: the spec version 0.13 and testdata at spec-v0.13
2 days ago
dev 450b3f8cf3 Refuse a CID that is not canonical and a host of two brackets, as Go
2 days ago
dev 4a0d4f7e61 checkResolvedIp: an IPv4-mapped prefix is not one of NAT64, a test
2 days ago
dev d65e21864d Draft v0.13: checkResolvedIp counts an address of NAT64 by its IPv4
2 days ago
dev 62107d7cd4 Specification 0.12, approved: SPEC_VERSION 0.12 and testdata at spec-v0.12
2 days ago

8
.gitattributes vendored

@ -4,3 +4,11 @@
# Vendored Go fixtures and vectors must keep their exact bytes: their SHA-256 is
# recorded in testdata/SOURCE.json and in the fixtures themselves.
testdata/** -text
# So must the vendored word lists of wordkey.Generate: their SHA-256 is
# recorded in wordlists/SOURCE.json and pinned in lib/src/wordlist.dart.
wordlists/** -text
# So must the vendored recovery annex of datekeys.RecoveryAnnex: its SHA-256 is
# recorded in annex/SOURCE.json and lib/src/recovery_annex.g.dart is its text.
annex/** -text

@ -2,6 +2,104 @@
Cambios notables de la librería Dart. El proyecto usa versionado semántico; mientras sea 0.x, no hay promesa de estabilidad.
## Especificación 0.15, en la rama `v0.15` — sin versión
### Lo que dice el SDK oficial al sellar (07-10-2026)
- `datekeys-go` añade en `aefc8f6`, en la rama `v0.15`, lo que el SDK oficial debe hacer al sellar y su CLI no hacía todavía (§7.6, §62.1 reglas 26 y 27, §71): `encrypt` escribe junto al `.dkc` el anexo de recuperación, `FICHERO.dkc.recuperacion.txt`, el §79 de la especificación bajo un título con su versión y su SHA-256, el mismo para toda cápsula; dice qué hará falta para abrir la cápsula años después; y no escribe ninguna cápsula con un perfil que no esté activo en el registro de perfiles del §71. No cambia ningún formato.
- **El anexo de recuperación.** `lib/src/annex.dart` porta `annex.go`: `recoveryAnnex`, el texto de `datekeys.RecoveryAnnex`, y `recoveryAnnexSuffix`, `.recuperacion.txt`, lo que se añade al nombre del `.dkc` para nombrar el fichero del anexo. Dart no incrusta ficheros como `go:embed`: el texto es la constante de `lib/src/recovery_annex.g.dart`, que escribe `dart run tool/recovery_annex_copy.dart` desde `annex/recovery.md` tras comprobarlo contra su `SOURCE.json`. Va en un string de varias líneas que escapa la barra invertida, el dólar, la comilla y, como escape Unicode, cada runa salvo el salto de línea que `strconv.IsPrint` de Go rechaza, para que ningún carácter sea invisible en el código y los finales de línea de una copia de trabajo no lleguen al texto; el anexo de hoy no tiene nada que escapar. El programa escribe también el SHA-256 de sus bytes, `recoveryAnnexSha256`, interno, para las pruebas compiladas a JavaScript.
- **El estado de un perfil (§71).** `lib/src/profile.dart` porta `status.go` de `profile`: `ProfileStatus`, `active`, `readOnly` o `compromised`, con el nombre de `Status.String` de Go en `label` y en `toString`; y `profileStatusOf`, el estado del perfil de un `profile_hash` y si esta versión de la librería lo conoce, como `StatusOf`. Quicknet está activo. DateKeys no publica todavía el registro firmado del §71, así que un cambio de estado llega con una versión nueva de la librería. El escritor no lo consulta: lo aplica la app, como lo aplica la CLI de Go.
`lib/datekeys.dart` exporta `recoveryAnnex`, `recoveryAnnexSuffix`, `ProfileStatus` y `profileStatusOf`.
- **`annex/`.** `tool/sync_testdata.dart` copia también `annex` del mismo commit de Go en `annex/`, con un `SOURCE.json` del formato del de `testdata/`, y `check` escribe una tercera línea, la de `annex`. `testdata` y `wordlists` pasan a `aefc8f6`: solo cambia el commit de sus `SOURCE.json`. `.gitattributes` guarda los bytes exactos de `annex/`, como los de `testdata/` y `wordlists/`.
- **Pruebas.** 7 nuevas en la VM y 4 en Node.js: `test/annex_test.dart`, también compilado a JavaScript, con lo que `TestRecoveryAnnex` de Go comprueba del texto (el título del §79, su apartado 79.8, la versión `0.15`, que acaba en «conforme.» y un salto de línea y que no tiene ningún CR), su primera línea, el SHA-256 de sus bytes UTF-8 y el sufijo; `test/annex_vm_test.dart`, que la constante es `annex/recovery.md` byte a byte y que el fichero es el §79 de la especificación bajo el título y el párrafo de `TestRecoveryAnnex`, con la especificación del commit de `annex/SOURCE.json`; `test/testdata_test.dart`, con la línea de `annex`; y `test/formats_objects_test.dart`, con los casos de `TestStatus`. En total, 2250 en la VM y 716 en Node.js.
- **Fallos inyectados**, uno a uno y revertidos: un carácter cambiado en la constante lo detectan la prueba de los bytes y la del SHA-256, también en Node.js; Quicknet `readOnly` en la tabla, también en Node.js, y otro nombre para `readOnly`, los casos de `TestStatus`. El escape del programa se probó aparte sobre un texto con todo lo que escapa (una primera línea de espacios, la barra invertida, el dólar, las comillas, CR, tabulador, U+00A0, U+00AD, U+2028, U+202E, U+FEFF, U+0000, U+007F, U+0085, un emoji y una comilla y una barra al final): el string compilado da sus bytes, byte a byte.
- **Diferencias con Go.** `profileStatusOf` devuelve un registro, `(status, known)`, y toma los bytes del hash, donde Go toma un `[32]byte`: uno de otra longitud es un perfil que no conoce. Un perfil que no conoce está `active`, el `Status` cero de Go, con `known` a falso. El `unknown` de `Status.String`, el de un `Status` fuera de rango, no tiene equivalente en un enum.
### Los dados de la llave de palabras (07-10-2026)
- `datekeys-go` añade en `92e7154`, en la rama `v0.15`, los dados que decidió el autor, para quien no se fía de los números al azar de un ordenador: cinco dados por palabra, leídos en un orden fijo, dan un número de 11111 a 66666, la posición de la palabra en una lista de 7776, el primer dado el más significativo. Son `wordkey.DiceNumber`, `DiceWord`, `DiceWords` y `DiceList`, con `encrypt -dice` y `datekeys wordlist` en la CLI. No cambia ningún formato ni ninguna derivación.
- **`lib/src/wordlist.dart`** porta `dice.go`, con las mismas comprobaciones en el mismo orden y los mismos textos de error, en una `WordKeyException`:
- `diceNumber` da los dados de una posición, y `diceListSize` es 7776;
- `diceWord` da la palabra de cinco dados, después de comprobar el tamaño de la lista: cinco bytes, cada uno una cifra del 1 al 6;
- `diceWords` da las palabras de varios números separados por espacios, y rechaza, por este orden, una lista de otro tamaño; menos de 6 números; y, número a número, uno que no es de cinco dados o que da una palabra que ya salió, y hay que volver a tirar. Separa los números como `strings.Fields` de Go, en los espacios de `unicode.IsSpace`, que son los del §38.1 en los que `normalizeWords` separa las palabras, y no cambia nada más: una cifra de ancho completo o una marca combinante no es un dado;
- `diceList` escribe la lista numerada para los dados, una línea por palabra con sus dados y un tabulador, como publica la EFF la suya: para `en`, sus bytes UTF-8 son el fichero de la EFF, byte a byte (SHA-256 `addd3553…`), y para `es` tienen el SHA-256 `611f779a…`, los dos de `wordlists/README.md`.
`lib/datekeys.dart` los exporta. `diceWordUtf8` y `diceWordsUtf8`, sobre los bytes de un string de Go, son internas, para las pruebas. Los espacios son los de `goIsSpace` de `go_unicode.dart`, el `unicode.IsSpace` de Go.
- **`testdata` y `wordlists`** pasan a `92e7154`: solo cambian `wordlists/README.md`, con el SHA-256 de cada lista numerada para los dados, y el commit de los dos `SOURCE.json`.
- **Vectores de Go:** `tool/wordlist_go_vectors.go` escribe también los dados, en una exportación de `datekeys-go` en `92e7154`: `DiceNumber` en 24 posiciones; `DiceWord` en 63 casos y `DiceWords` en 78, sobre las listas de Go y sobre listas de índices, con los casos de `TestDiceWord` y `TestDiceWords`, cada espacio de `unicode.IsSpace` entre los números y puntos de código y bytes que no lo son, el orden de las comprobaciones, listas con una palabra más de una vez, también con caracteres que `%q` escapa, y listas de otro tamaño; el SHA-256 de `DiceList` de cada lista; y `DiceWords` con cada punto de código de los planos 0, 1 y 14 entre los dos primeros números, como el SHA-256 de sus resultados. El resto de los vectores sale igual: cambian solo su campo `source` y su descripción.
- **Pruebas.** 12 nuevas en la VM y 7 en Node.js: `test/wordlist_test.dart`, también compilado a JavaScript, con los casos de `TestDiceNumber` de Go, los de `TestDiceWord` y `TestDiceList` que no necesitan una lista de Go, sobre una lista de índices, los vectores sobre los bytes de Go y sobre Strings, y los espacios del plano 0; y `test/wordlist_vm_test.dart`, con los casos de `TestDiceWord`, `TestDiceWords` y `TestDiceList` sobre las dos listas de `wordlists/`, los vectores sobre ellas y los espacios de los planos 0, 1 y 14, que son los de `normalizeWords`. En total, 2243 en la VM y 712 en Node.js.
- **Fallos inyectados** en los dados, uno a uno y revertidos: los 17, en las cifras y su orden, los límites, el orden de las comprobaciones, los espacios, los bytes que no son UTF-8 válido, la palabra que sale dos veces, la lista numerada y los textos, los detectan pruebas que corren también en Node.js. Uno se escapaba al principio, la palabra repetida sin el `%q` de Go, porque las palabras de una lista no tienen nada que escapar, y los vectores tienen ahora una lista con caracteres que `%q` escapa.
- **Diferencias con Go:** ninguna. `diceWord` y `diceWords` toman un String como sus bytes UTF-8, como el resto de `wordlist.dart`, y los bytes UTF-8 del String de `diceList` son el string de Go.
### Las palabras al azar de la llave de palabras (07-10-2026)
- `datekeys-go` saca al azar, en la rama `v0.15` después del tag `spec-v0.15` (`c49c67c` y `27a75ee`), las palabras de una llave de palabras, el SHOULD del §38.1 de ofrecer palabras al azar de una lista pública: `wordkey.Generate`, `List`, `CheckList`, `Bits` y la lista española `wordkey/lists/es.txt`, de 7776 palabras, un borrador sin revisar. No cambia ningún formato ni ninguna derivación.
- **`lib/src/wordlist.dart`** lo porta de `27a75ee`, con las mismas comprobaciones en el mismo orden y los mismos textos de error, en una `WordKeyException`:
- `readWordList` toma el fichero de una lista, que la app descarga o empaqueta, solo con el SHA-256 de `wordListSha256` («the list "es" has the SHA-256 …, not …», el texto de `datekeys-ts`), y lo lee como `List` lee su texto;
- `checkWordList` rechaza una lista de menos de 2048 palabras, una palabra que no es una de 3 letras o más una vez normalizada, una runa que rechaza `checkWords`, un carácter que no es del alfabeto de su idioma, que da el código (para `es`, de la `a` a la `z`, `á`, `é`, `í`, `ó`, `ú`, `ü` y `ñ`, en minúscula y NFC), y dos palabras que son una una vez normalizadas;
- `generateWords` saca 7 palabras por defecto, cada índice con `randomIndex`, como `crypto/rand.Int`, y otra vez un índice que ya salió, así que los mismos bytes dan las mismas palabras que Go;
- `wordBits` suma el `math.Log2` de Go, portado con su `Frexp` y su `Log`: el mismo double que Go, en la VM y en la web.
`lib/datekeys.dart` los exporta, con `wordListLanguages`, `defaultWordCount` y `minListSize`. `wordkey.dart` comparte con `wordlist.dart` la comprobación de cada runa, `checkWordRune`, sin cambiar nada de lo suyo.
- **`wordlists/`.** `tool/sync_testdata.dart` copia también `wordkey/lists` del mismo commit de Go en `wordlists/`, con un `SOURCE.json` del formato del de `testdata/`; `check` comprueba los dos árboles con las mismas reglas y escribe una línea por árbol, y un árbol que falta en el commit es un error. `testdata` y `wordlists` se sincronizan con `datekeys-go` en `27a75ee`: los 142 ficheros de `testdata` son los del tag `spec-v0.15`, byte a byte, y solo cambia el commit de `testdata/SOURCE.json`. `.gitattributes` guarda los bytes exactos de `wordlists/`, como los de `testdata/`.
- **La licencia de las listas.** `es.txt` es una adaptación de FrequencyWords de Hermit Dave y tiene licencia CC BY-SA 4.0, no Apache-2.0 como el código. `wordlists/README.md`, copiado de Go, recoge su fuente, su método y su licencia.
- **Vectores de Go:** `test/vectors/wordlist_vectors.json`, de `tool/wordlist_go_vectors.go` en una exportación de `datekeys-go` en `27a75ee`, con su copia en Dart para Node.js: el cuerpo de `List` sobre 19 textos; `CheckList` sobre 83 listas, y con cada punto de código de los planos 0, 1 y 14 en una lista; `Generate` en 51 casos, sobre la lista española y listas de 12 a 2^20 + 1 palabras, con el keystream de `SeededRandomSource`, bloques de SHA-256 y bytes que se acaban, entre ellos la semilla de `TestGenerate`, que solo saca dos índices y se queda sin bytes; y `Bits`, bit a bit, en 221 casos y cuatro resúmenes.
- **Pruebas.** 19 nuevas en la VM y 11 en Node.js: `test/wordlist_test.dart`, también compilado a JavaScript, con los vectores y los casos de `TestCheckList`, `TestGenerate` y `TestBits` de Go; `test/wordlist_vm_test.dart`, con cada punto de código y, sobre la lista española de `wordlists/`, los casos de `TestBuiltInLists`, `TestGenerate` y `TestGenerateUniform`; y `test/testdata_test.dart`, con la línea de `wordlists/`. En total, 2230 en la VM y 705 en Node.js.
- **Fallos inyectados** en `wordlist.dart`, uno a uno y revertidos: los 30 que cambian algún resultado, en el alfabeto, el orden de las comprobaciones, la cuenta de letras, los números de línea, el corte de las líneas, el SHA-256, el sorteo y los bits, los detectan pruebas que corren también en Node.js. Otros dos dan lo mismo con cualquier entero: quitar el atajo de las potencias de dos de `Log2`, porque `Log` da ahí lo mismo, y el borde de √2/2 en `Log`, al que no llega ningún entero.
- **La lista inglesa.** `datekeys-go` añade en `e671032` la lista grande de la EFF, `wordkey/lists/en.txt`, de 7776 palabras, CC BY 4.0, en su orden y sin los números de los dados, y `-dic` la toma por defecto. `testdata` y `wordlists` pasan a `e671032`, con el mismo `testdata`; `wordListSha256` fija la nueva lista, y el alfabeto de `en` es de la `a` a la `z` y el guion de sus cuatro palabras compuestas, como `t-shirt`. Los vectores se regeneran con Go en `e671032`: solo cambian su campo `source` y la lista de listas.
- **Diferencias con Go.** Una `RandomSource` no se acaba: lo que lance la fuente sale de `generateWords`, donde Go da `wordkey: EOF`. El fichero de una lista se lee como lee Go un string, como bytes, y sus palabras se decodifican después de la comprobación, que rechaza con el texto de Go un byte que no es UTF-8 válido.
### La recuperación a largo plazo: el objeto release y el release en la mano (07-10-2026)
- El autor aprobó el 7 de octubre de 2026 el borrador v0.15, la recuperación a largo plazo. `specVersion` pasa a `0.15`, y `testdata` se sincroniza con la rama `v0.15` de `datekeys-go` en `fe50885`: cambia el campo `spec` de cada fichero, `mutations.json` gana el campo `source` y cuatro casos, y llegan `vectors/release.json` y `releases/`, 142 ficheros.
- **El objeto release (§47.1).** `encodeRelease` y `decodeRelease`, como `provider.EncodeRelease` y `DecodeRelease` de Go en `2eeca40`, con el perfil de CBOR de la librería: el tamaño, de 1 a 1024 bytes, antes de nada; el tipo y la versión; el schema. `Release` lleva `chainHash`, y `verifyRelease` compara la cadena que nombra con la del perfil pinneado antes que la ronda y la firma, con `ERR_PROFILE_MISMATCH` (§63 paso 10).
- **El JSON de drand como entrada.** `parseRelease` lee un JSON de drand si el primer byte que no es un espacio de JSON es `{`, y si no, un objeto release. Sigue las reglas de `encoding/json` de Go para sus tres campos con un lector propio: `jsonDecode` no guarda cómo se escribe un número, y en la web lee 1000.0 como el entero 1000.
- **El release en la mano (§49, §63 paso 9.c).** `OpenOptions.release`, un `ReleaseSupplier` (`EncodedRelease` o `ReleaseArchive`), es la alternativa a `OpenOptions.source`, que deja de ser obligatoria: uno de los dos y solo uno. No se compara con el reloj; `Opened.clockBehind` dice que el reloj va por detrás de la ronda, con el detalle del paso 9 de Go. Lo que lance el proveedor es `ERR_RELEASE_UNAVAILABLE` en el paso 9 (`supplyRelease`), y el paso 10 empieza por las capas del objeto. Una fuente de red sigue sin pedirse antes de la hora de la ronda. `Opened.release` lleva la cadena del perfil pinneado.
- **El archivo de releases local (§50, informativo).** `ReleaseArchive` busca una ronda en un archivo que lee por tramos de una `ByteSource`, como `provider.Archive`: lo que no puede entregar es `ERR_RELEASE_UNAVAILABLE` en el paso 9, con los textos de Go, que fija `test/vectors/release_archive_texts.json` (de `tool/release_archive_go_texts.go`).
- **Vectores.** `mutation_texts.json` se regenera con `tool/mutation_go_texts.go`, que abre ahora cada caso con su `source`, como `testkit`: 149 casos cambian solo el detalle del paso 9, «release supplied by the caller»; «round not reached yet» se abre, con el reloj por detrás; y llegan los cuatro casos nuevos. `release_vectors.json`, los de la apertura, los formatos, el localizador, la seguridad y el sellado salen iguales en `fe50885` salvo el campo `spec`, el único que cambia. `test/release_object_vm_test.dart` recorre `release.json`, `releases/` y los textos del archivo; `test/release_object_test.dart`, su copia `test/vectors/release.g.dart`, de `tool/release_copy.dart`, compilada a JavaScript. El corpus prueba el `source` de cada caso; `open_test.dart`, el orden de los pasos 9 y 10 con un release en la mano.
- **Diferencias con Go.** Una ronda del JSON de drand por encima de 2^53 − 1 es aquí `ERR_RELEASE_INVALID` al leerla; Go la lee y la rechaza en el paso 10 con `ERR_ROUND_MISMATCH`. No se portan `NewReleaseObject`, `EncodeArchiveHeader` ni `IsArchive`.
- `test/errors_spec_test.dart` lee la especificación en el commit de `testdata/SOURCE.json`, y no en su tag.
## Especificación 0.14, en la rama `v0.14` — sin versión
### La especificación 0.14, aprobada (06-10-2026)
- El autor aprobó el 6 de octubre de 2026 el borrador v0.14 con la recomendación de cada una de sus diez decisiones: `datekeys-go` lo cierra con el tag `spec-v0.14` (`39b2033`). `specVersion` pasa a `0.14`, y `testdata` se sincroniza con ese tag: cambia el campo `spec` de cada fichero y llega `vectors/tlock_steps.json`, 136 ficheros.
- **Un solo scheme de drand (decisión 8, §12.1).** `validateProfile` admite solo `bls-unchained-g1-rfc9380`, con la clave pública en G2, como `validateDrand` de Go desde `c041fa3`, en su orden: un nombre que drand no conoce sigue siendo «is not a drand scheme», y cualquier otro scheme de drand, también `pedersen-bls-unchained` y `bls-unchained-on-g1`, da `ERR_UNKNOWN_PROFILE` con el texto de Go, «scheme … is not bls-unchained-g1-rfc9380, the only scheme of V1». Ninguna cápsula válida cambia.
- `test/vectors/formats_profile.json` y su parte de `formats_vectors.g.dart` se regeneran con `tool/formats_go_vectors.go` sobre `39b2033`: cambian solo los trece casos de otro scheme de drand y el campo `spec`. Cinco eran válidos y ahora dan `ERR_UNKNOWN_PROFILE`: cuatro de `bls-unchained-on-g1` con la clave de Quicknet, y el perfil `drand:default:v1` con `pedersen-bls-unchained`. Los otros ocho, de `pedersen-bls-chained` y `bls-bn254-unchained-on-g1`, ya se rechazaban y cambian solo de texto. Los demás vectores de `test/vectors/` cambian solo su campo `spec`.
- **`tlock_steps.json`.** `test/tlock_steps_vm_test.dart` lo recorre valor a valor con el código de la librería (`release.dart`, `ibe.dart`, `tlock.dart`, `bls12381_hash.dart`): M, H(M), la ecuación del emparejamiento, las partes del stanza, e(firma, U), H2, sigma, H4, la file key, cada intento de H3 y r, r·G2 = U, que `decryptOnG2` y `unwrapTlockStanza` dan la file key y que `encryptOnG2WithSigma` escribe el mismo cuerpo, y las comprobaciones negativas del generador de Go: otro DST, la ronda sin SHA-256 y un H3 que borre solo el bit más alto. `test/tlock_steps_test.dart` lo hace compilado a JavaScript, sobre la copia `test/vectors/tlock_steps.g.dart`, que escribe `tool/tlock_steps_copy.dart`.
- El comentario de `h3` de `ibe.dart` decía que se borra el bit más alto; el código desplaza el primer byte un bit a la derecha, como kyber y como dice ahora el §63. Solo cambia el comentario.
## Especificación 0.13, en la rama `v0.13` — sin versión
### El localizador sellado, comprobado antes de la fecha (06-10-2026)
- `parseCapsuleInfo` comprueba el localizador sellado como `ParseInfo` de Go desde `69dbb0c`, a petición del autor: la cadena del stanza tlock en hexadecimal en minúsculas y, si la DateKey es de Quicknet, la de Quicknet; y que el cuerpo tras la cabecera `age` lleve un texto de 4096 bytes o un múltiplo, así que una cabecera sin cuerpo se rechaza. Cada caso es `ERR_EXTENSION_DATA_INVALID` con el texto de Go. `CapsuleInfo.toExtension` rechaza además una DateKey de un perfil que la librería no fija. El límite de 1 MiB al abrir el localizador se queda, por decisión del autor.
- Los vectores de Go del localizador se regeneran sobre ese commit: cambian solo los casos de esas comprobaciones.
### La especificación 0.13, aprobada (06-10-2026)
- El autor aprobó el 6 de octubre de 2026 el borrador v0.13, tal como estaba: `datekeys-go` lo cierra con el tag `spec-v0.13` (`913dd60`). `specVersion` pasa a `0.13`, `testdata` se sincroniza con ese tag, y los vectores de `test/vectors/` cambian solo su campo `spec`.
### Dos direcciones que el §44.1 ya rechazaba (06-10-2026)
- Un CID con un carácter de más cuyos bits son cero y `https://[[2000::]/` se rechazan, como en `datekeys-go` desde `e801e03`. `test/vectors/locator_uris.json` y `locator_vectors.json` se regeneran sobre ese commit: cambian solo las diez direcciones de esas dos formas y los localizadores que las llevan.
### NAT64 (06-10-2026)
- El borrador v0.13 de `datekeys-go` (`a83b44d`, sin aprobar) cuenta una dirección de NAT64 a la que resuelve un nombre, de `64:ff9b::/96` o del prefijo de la red, por la IPv4 que lleva dentro (§44.1, cambio 1 del §76). `checkResolvedIp` lo sigue, con el parámetro `nat64` para el prefijo de la red, y los textos de `locator.CheckResolvedIP` de Go. Una dirección de NAT64 escrita en el localizador se sigue rechazando.
- `testdata` se sincroniza con `a83b44d`, que añade `vectors/resolved_ip.json`: 42 casos, que corre `test/resolved_ip_test.dart`. `specVersion` sigue en `0.12` hasta que el autor apruebe el borrador.
## Especificación 0.12, en la rama `v0.12` — sin versión
### La especificación 0.12, aprobada (06-10-2026)
- El autor aprobó el 6 de octubre de 2026 el borrador v0.12, tal como estaba: `datekeys-go` lo cierra con el tag `spec-v0.12` (`fe405e2`). La librería pasa a la rama `v0.12`, como dice el plan: la rama `v0.11` se queda en `bb66e48`.
- `specVersion` pasa a `0.12`, y `testdata` se sincroniza con el tag: solo cambia el campo `spec` de cada fichero.
- Los vectores de `test/vectors/` que escriben los generadores de Go cambian solo su campo `spec`, en los `.json` y en sus copias `.g.dart`: entre `c531e93` y `fe405e2`, Go solo cambia `SpecVersion` y añade `wordkey.json`, así que el resto sale igual. Dos pruebas que comparaban con `0.11` comparan ahora con `specVersion`.
- La librería ya seguía el borrador: no cambia nada más. `tool/check.sh` pasa con 2 131 pruebas en la VM y 665 en Node.
## Especificación 0.11, en la rama `v0.11` — sin versión
### Los vectores compartidos de la llave de palabras (06-10-2026)

@ -23,9 +23,11 @@ Están hechas las etapas 0 a 5 del plan (`docs/PLAN_dart.md` del espacio de trab
- la parte 6b de la etapa 6, el escritor de cápsulas del formato 3: `time_only` y `time_and_key`, los 16 huecos con señuelos, la `.dkk`, la llave de palabras, la nota pública, el área de seguridad con la firma y el sello, el relleno y las autocomprobaciones del §62.1, con las fuentes leídas en streaming.
- la etapa 7, en dos partes:
- la 7a, el localizador y el sobre de `datekeys.capsule`: los datos de la extensión, la lectura y la apertura del localizador, las reglas de sus direcciones y de la IP a la que resuelve un nombre, y el resto del sobre;
- la 7b, las claves de autor `dkauthor1…`, con su firma Ed25519 y su fichero cifrado con scrypt, y el sellado del localizador y la creación del sobre, sobre el escritor de `age` de la 6a.
- la 7b, las claves de autor `dkauthor1…`, con su firma Ed25519 y su fichero cifrado con scrypt, y el sellado del localizador y la creación del sobre, sobre el escritor de `age` de la 6a;
- fuera del plan, con la v0.15, las palabras al azar de la llave de palabras: las listas de palabras de `datekeys-go`, tomadas solo con su SHA-256 fijado y comprobadas con el alfabeto de su idioma, las palabras sacadas al azar de una y su fuerza en bits, y las de cinco dados cada una, con la lista numerada para los dados.
- fuera del plan, con la v0.15, lo que dice el SDK oficial al sellar: el anexo de recuperación que guarda junto a cada `.dkc` y el estado de un perfil en el registro de perfiles del §71.
La librería ya abre cápsulas reales, de los tres formatos, con todas sus credenciales, y evalúa toda su área de seguridad como Go: la firma de `alg` 1, la de `alg` 2 con certificados, el sello de `seal_type` 2 y todos los veredictos de su forma. Y ya escribe cápsulas del formato 3, con todas sus credenciales, su firma y su sello, byte a byte como Go con los mismos valores aleatorios, y Go las abre. Firma con una clave de autor y sella localizadores.
La librería ya abre cápsulas reales, de los tres formatos, con todas sus credenciales, y evalúa toda su área de seguridad como Go: la firma de `alg` 1, la de `alg` 2 con certificados, el sello de `seal_type` 2 y todos los veredictos de su forma. Y ya escribe cápsulas del formato 3, con todas sus credenciales, su firma y su sello, byte a byte como Go con los mismos valores aleatorios, y Go las abre. Firma con una clave de autor y sella localizadores. Y saca al azar las palabras de una llave de palabras de las listas de `datekeys-go`, que toma solo con su SHA-256 fijado, o las da de unos dados. Y da el anexo de recuperación que el SDK oficial guarda junto a cada `.dkc` y el estado de un perfil fijado.
Las etapas 2 y 3 se hicieron en paralelo, en ramas aparte desde la etapa 1, y se integraron el 5 de octubre de 2026. Las partes 4a y 4b también: la 4a, en la rama `stage4a`, se integró encima de la 4b el mismo día. La 4c se hizo después, en la rama `v0.11`, y la 5b también, en paralelo con la 5a, el lector de CMS, que se hizo en la rama `stage5a` y se integró encima de la 5b el mismo día. La 5c, que necesitaba las dos, se hizo después, en la rama `v0.11`. La 6a se hizo en la rama `v0.11`, en paralelo con la 7a, la lectura del localizador, en la rama `stage7a`. La 7a se integró encima de la 6a el mismo día. La 6b, el escritor de cápsulas, se hizo en la rama `v0.11`, en paralelo con la 7b, las claves de autor y el sellado del localizador, en la rama `stage7b`, desde `b23a0ee`. La 7b se integró encima de la 6b el mismo día.
@ -56,7 +58,7 @@ Notas de la etapa 2:
- **El STREAM** se descifra según llega el texto cifrado (`AgePayloadDecryptor`), como el lector de Go: entrega el texto de cada chunk en cuanto se autentica, y un fallo que revela un byte posterior llega en la llamada siguiente.
- **La identity de `OUTER_TIME_AGE`** se compone en la etapa 4, con el perfil: `checkTimeStanzas` de esta etapa, que recibe la ronda, el chain hash y el id del perfil, y `checkTlockProfile` y `unwrapTlockStanza` de la etapa 3.
La etapa 3 porta BLS12-381 de `kilic/bls12-381` v0.1.0, sobre el que calcula `drand/kyber-bls12381` v0.3.4 para drand y tlock; el IBE de `encrypt/ibe` de `drand/kyber` v1.3.2, el de `tlock` v1.2.0 con Quicknet; y `provider.Verify` y el stanza tlock de `agewrap` de `datekeys-go`, con las mismas comprobaciones en el mismo orden y los mismos textos de error. Como `datekeys-ts`, verifica solo el scheme de Quicknet, `bls-unchained-g1-rfc9380`. Todo es código propio: de `package:crypto` usa solo SHA-256.
La etapa 3 porta BLS12-381 de `kilic/bls12-381` v0.1.0, sobre el que calcula `drand/kyber-bls12381` v0.3.4 para drand y tlock; el IBE de `encrypt/ibe` de `drand/kyber` v1.3.2, el de `tlock` v1.2.0 con Quicknet; y `provider.Verify` y el stanza tlock de `agewrap` de `datekeys-go`, con las mismas comprobaciones en el mismo orden y los mismos textos de error. Como `datekeys-ts`, verifica solo el scheme de Quicknet, `bls-unchained-g1-rfc9380`, el único que admite el §12.1 desde la v0.14. Todo es código propio: de `package:crypto` usa solo SHA-256.
| Módulo | Contenido | En Go |
|---|---|---|
@ -66,7 +68,7 @@ La etapa 3 porta BLS12-381 de `kilic/bls12-381` v0.1.0, sobre el que calcula `dr
| `lib/src/bls12381_pairing.dart` | El emparejamiento ate óptimo: el bucle de Miller con las rectas de kilic y su exponenciación final | `pairing.go` de kilic |
| `lib/src/bls12381_hash.dart` | `expand_message_xmd`, `hash_to_field`, el mapa SWU simplificado, la isogenia de grado 11 y el cofactor: el hash a G1 del RFC 9380 con el DST de Quicknet | `hash_to_field.go`, `swu.go`, `isogeny.go` de kilic |
| `lib/src/ibe.dart` | El IBE-CCA de tlock sobre G2 (§63 paso 11): H2, H3 con su rechazo de candidatos, H4, la identidad de la ronda, el descifrado y el cifrado, este con sigma inyectable | `encrypt/ibe` de kyber |
| `lib/src/release.dart` | `verifyRelease` (§17, §51, §63 paso 10), `Release`, `ReleaseSource`, `suppliedRelease` y `fetchRelease`, la regla del paso 9 | `provider` |
| `lib/src/release.dart` | `verifyRelease` (§17, §51, §63 paso 10), `Release`, `ReleaseSource`, `suppliedRelease` y `fetchRelease`, la regla del paso 9; desde la v0.15, el objeto release (§47.1), el JSON de drand como entrada, el release en la mano y el archivo de releases local (§50) | `provider` |
| `lib/src/tlock.dart` | El stanza tlock de `OUTER_TIME_AGE` (§32, §35, §63 paso 11): abrirlo, como `NewTimeIdentity` y su `Unwrap`, y escribirlo, como `NewTimeRecipient` | `agewrap` |
Notas de la etapa 3:
@ -74,11 +76,54 @@ Notas de la etapa 3:
- **Los veredictos de un punto** son los de `FromCompressed` de kilic: el flag de compresión a 1; el punto en el infinito solo como `0xc0` y ceros; coordenadas menores que p, sin reducir; un punto de la curva; y un punto del subgrupo de orden r. En G1 el subgrupo se comprueba con [r]·P = O; en G2, con ψ(P) = [x]·P (Scott, eprint 2021/1130, como noble), que las pruebas comparan con [r]·P = O en puntos fuera del subgrupo, también con torsión de cada orden pequeño del cofactor.
- **GT** es el valor del emparejamiento de kilic, con su exponenciación final, f^(3·(p⁴ − p² + 1)/r), y se serializa en su orden (§63, «Serialización de GT en H2»).
- **El hash a G1** sigue a kilic, que suma las dos salidas del mapa en E′ antes de la isogenia. kilic se aparta del RFC 9380 solo donde ningún hash llega: dos salidas iguales u opuestas, que suma con la fórmula de E. Este código las suma con la ley de grupo de E′, como el RFC.
- **Las diferencias con Go, a propósito,** son las de `datekeys-ts`: otro scheme que el de Quicknet da `ERR_UNKNOWN_PROFILE` con un texto propio, donde Go verificaría los otros schemes de drand; y el punto en el infinito nunca es una firma válida (§63 paso 10), mientras que Go la acepta si la clave pública también es el punto en el infinito, una clave que ningún perfil pinneado tiene (§12.1). Las pruebas fijan las dos.
- **Las diferencias con Go, a propósito,** son las de `datekeys-ts`: otro scheme que el de Quicknet da `ERR_UNKNOWN_PROFILE` con un texto propio, donde `provider.Verify` de Go verificaría los otros schemes de drand en un perfil que no ha pasado por `Validate` (desde la v0.14, `validateProfile` rechaza esos perfiles, como Go); y el punto en el infinito nunca es una firma válida (§63 paso 10), mientras que Go la acepta si la clave pública también es el punto en el infinito, una clave que ningún perfil pinneado tiene (§12.1). Las pruebas fijan las dos.
- **El stanza tlock.** `unwrapTlockStanza` recibe los argumentos y el cuerpo del único stanza y hace lo que `NewTimeIdentity` y su `Unwrap` en Go: el perfil, los argumentos, otra vez el release y el cuerpo. El número y el tipo de los stanzas los comprueban las reglas de `agewrap` de la etapa 2, que necesitan la cabecera entera. Se guarda el último release verificado: el paso 11 vuelve a verificar el del paso 10, como en Go, sin otro emparejamiento.
- **La fuente de releases.** La librería no trae cliente HTTP: recibe una `ReleaseSource`, como `OpenOptions.Source` en Go. `fetchRelease` aplica la regla del paso 9: lo que lance la fuente es `ERR_RELEASE_UNAVAILABLE`, con su texto y ningún otro código.
- **Lo que se exporta.** `lib/datekeys.dart` exporta la verificación de releases y `checkCompressedPoint`, como `datekeys-ts`. El IBE y el stanza tlock son internos: los usará la apertura de la etapa 4. El cifrado no se exporta todavía: es del escritor, la etapa 6.
### El objeto release y el release en la mano (v0.15)
La especificación 0.15 da forma de dato al release de una ronda y distingue dos clases de fuente (§47.1, §49, §50, §63 pasos 9 y 10). `release.dart` lo porta de `provider` de `datekeys-go` en `2eeca40`, con los mismos textos de error, y `open.dart`, de `capsule.Open`:
- **El objeto release** es Deterministic CBOR, `{0: "datekeys-release", 1: 1, 2: chain_hash, 3: round, 4: signature}`. `encodeRelease` lo escribe y `decodeRelease` lo lee con sus capas: el tamaño, de 1 a 1024 bytes, antes de nada; el tipo y la versión; el perfil de CBOR de la librería y el schema. `Release` lleva ahora `chainHash`, la cadena que nombra, o null si no nombra ninguna, y `verifyRelease` la compara con el perfil pinneado antes que la ronda y la firma, con `ERR_PROFILE_MISMATCH`.
- **El JSON de drand** se acepta como entrada: `parseRelease` lee un JSON si el primer byte que no es un espacio de JSON es `{`, y si no, un objeto release. Lee los tres campos con las reglas de `encoding/json` de Go, con un lector propio, porque `jsonDecode` no guarda cómo se escribe un número y en la web lee 1000.0 como el entero 1000: nombres sin distinguir mayúsculas, el último gana, null y los otros tipos como en Go, y la ronda, un entero sin signo escrito como tal. Cualquier fallo es `ERR_RELEASE_INVALID`, en el paso 10.
- **El release en la mano** es un `ReleaseSupplier`, como `provider.Supplier`: `EncodedRelease`, unos bytes ya leídos, objeto o JSON, o `ReleaseArchive`, un archivo de releases local que se lee por tramos de una `ByteSource`. Va en `OpenOptions.release`, que excluye a `OpenOptions.source`: uno de los dos y solo uno, o un `ArgumentError` antes de empezar. No se compara con el reloj (paso 9.c): si el reloj va por detrás de la ronda, la cápsula se abre igual y `Opened.clockBehind` lo dice, con el detalle del paso 9 de Go. Lo que lance el proveedor es `ERR_RELEASE_UNAVAILABLE` en el paso 9 (`supplyRelease`), y el paso 10 empieza por las capas del objeto. Una fuente de red, `OpenOptions.source`, sigue sin pedirse antes de la hora de la ronda. `Opened.release` lleva la cadena del perfil pinneado, así que `encodeRelease` da su objeto.
- **El archivo de releases** es un formato informativo, sin códigos propios: una ronda que falta o que no cubre, una cabecera que no se lee, otra cadena u otra longitud son `ERR_RELEASE_UNAVAILABLE` en el paso 9, con los textos de `provider.Archive`.
- **Las diferencias con Go.** Una ronda del JSON de drand por encima de 2^53 − 1 no cabe en un `int` en todas las plataformas: Go la lee y la rechaza en el paso 10 con `ERR_ROUND_MISMATCH`; aquí es `ERR_RELEASE_INVALID` al leerla, con un texto propio. Ninguna DateKey tiene esa ronda. Un archivo leído con un perfil de otro scheme da un texto propio, como `verifyRelease`. No se portan `NewReleaseObject`, `EncodeArchiveHeader` ni `IsArchive`.
### Las palabras al azar de la llave de palabras (v0.15)
El §38.1 pide que un escritor ofrezca por defecto palabras al azar de una lista pública: al menos 6 de una lista de 2048 o más. `datekeys-go` las añade en la rama `v0.15`, después del tag `spec-v0.15` (`c49c67c` y `27a75ee`), y los dados en `92e7154`, sin cambiar ningún formato ni ninguna derivación, y `wordlist.dart` las porta de `generate.go` de `wordkey` en `27a75ee` y de `dice.go` en `92e7154`, con las mismas comprobaciones en el mismo orden y los mismos textos de error:
| Módulo | Contenido | En Go |
|---|---|---|
| `lib/src/wordlist.dart` | `readWordList`, las palabras del fichero de una lista; `wordListSha256`, el SHA-256 fijado de cada lista, y `wordListLanguages`; `checkWordList`, las reglas de una lista, con el alfabeto de su idioma; `generateWords`, las palabras sacadas al azar de una lista; `wordBits`, su fuerza en bits; `defaultWordCount` y `minListSize`; y los dados: `diceWords`, las palabras de cinco dados cada una; `diceWord`, la de cinco dados; `diceNumber`, los dados de una posición; `diceList`, la lista numerada para los dados; y `diceListSize` | `List`, `Languages`, `CheckList`, `Generate`, `Bits`, `DefaultCount` y `MinListSize` de `wordkey`; y `DiceWords`, `DiceWord`, `DiceNumber`, `DiceList` y `DiceListSize` |
Notas:
- **Las listas no van en la librería.** Go las lleva dentro del módulo; aquí la app descarga o empaqueta el fichero de una lista, `wordkey/lists/<idioma>.txt` de `datekeys-go`, y se lo da a `readWordList`, que no se fía de él: su SHA-256 debe ser el de `wordListSha256`, con el texto «the list "es" has the SHA-256 …, not …», el mismo de `datekeys-ts`, y sus palabras deben pasar `checkWordList`. Una lista cambia solo con su hash. Hoy hay dos, de 7776 palabras cada una: `en`, la lista grande de la EFF, y `es`, un borrador que todavía no ha revisado un hablante nativo. `wordlists/` tiene la copia de las listas (ver «Datos de prueba»).
- **El alfabeto** de cada idioma lo da el código, nunca la lista: para `es`, de la `a` a la `z`, `á`, `é`, `í`, `ó`, `ú`, `ü` y `ñ`, en minúscula y NFC. Una letra de otra escritura que se parece a una de ellas, como la `а` cirílica (U+0430), se volvería a teclear con la latina, y la cápsula no se abriría. Tampoco pasan una mayúscula, una cifra, el CR de un fichero con líneas CRLF ni dos palabras que son una una vez normalizadas, como «papa» y «papá», que valdrían por una.
- **El sorteo** es el de Go: cada índice como lo saca `crypto/rand.Int`, con `randomIndex` de la parte 6a, y un índice que ya salió se saca otra vez, así que los mismos bytes dan las mismas palabras que Go. Son 7 palabras por defecto: 7 de 7776 son unos 90 bits (`wordBits`), y 6 de 2048, el mínimo, unos 66.
- **`wordBits`** suma el `math.Log2` de Go, portado: `Frexp` y el `Log` de FreeBSD que porta Go, con sus operaciones en su orden, así que el double es el de Go en la VM y en la web, bit a bit. El `log` de la plataforma no es el de Go, y `math.log(x) / math.ln2` no da exacto ni el log2 de 2^29 en la VM: la CLI de Go trunca los bits a un entero.
- **Los dados**, para quien no se fía de los números al azar de un ordenador: cinco dados por palabra, leídos en un orden fijo, dan un número de 11111 a 66666, la posición de la palabra en una lista de 7776 (`diceListSize`), el primer dado la cifra más significativa en base 6. `diceWord` toma cinco bytes, cada uno una cifra del 1 al 6, después de comprobar el tamaño de la lista. `diceWords` toma varios números separados por espacios, al menos 6, y nunca da dos veces la misma palabra: hay que volver a tirar los dados. Los números se separan como los separa `strings.Fields` de Go, en los espacios de `unicode.IsSpace`, que son los del §38.1 en los que `normalizeWords` separa las palabras, y nada más cambia: una cifra de ancho completo o una marca combinante no es un dado. Unos dados justos sacan cada palabra como `generateWords`, así que las palabras son igual de fuertes. `diceList` escribe la lista numerada para los dados, para imprimirla: una línea por palabra, con sus dados, un tabulador y la palabra, como publica la EFF la suya. Para `en`, sus bytes UTF-8 son el fichero de la EFF, byte a byte (SHA-256 `addd3553…`), y para `es` tienen el SHA-256 `611f779a…`, como los recoge `wordlists/README.md`.
- **Las diferencias con Go.** Una `RandomSource` no se acaba: lo que lance la fuente sale de `generateWords` tal cual, donde un `io.Reader` de Go que se acaba da `wordkey: EOF`. `readWordList` comprueba el SHA-256, que Go no necesita para sus listas. El fichero se lee como lee Go un string, como bytes: un byte que no es UTF-8 válido es U+FFFD, que ningún alfabeto tiene, así que la comprobación lo rechaza con el texto de Go, y las palabras que pasan se decodifican en estricto.
- **La licencia.** Las listas no son código: `en.txt` es material original de la EFF, con licencia CC BY 4.0, y `es.txt` es una adaptación de FrequencyWords de Hermit Dave y tiene licencia CC BY-SA 4.0, no Apache-2.0. `wordlists/README.md`, copiado de Go, recoge su fuente, su método y su licencia.
- **Lo que se exporta.** `lib/datekeys.dart` exporta `readWordList`, `checkWordList`, `generateWords`, `wordBits`, `wordListSha256`, `wordListLanguages`, `defaultWordCount` y `minListSize`, y `diceNumber`, `diceWord`, `diceWords`, `diceList` y `diceListSize`, como el paquete público `wordkey` de Go. `checkWordListUtf8`, `diceWordUtf8` y `diceWordsUtf8`, sobre bytes, y `parseWordList`, `readWordList` sin el SHA-256, son internas, para las pruebas. `wordkey.dart` comparte con `wordlist.dart` la comprobación de cada runa, `checkWordRune`, también interna.
### Lo que dice el SDK oficial al sellar (v0.15)
La regla 27 del §62.1 recomienda al SDK oficial guardar junto a cada `.dkc` el anexo de recuperación, el §79, que dice cómo abrir una cápsula sin software de DateKeys, y el §71 da a cada perfil un estado en el registro de perfiles. `datekeys-go` los añade en `aefc8f6`, en la rama `v0.15`, sin cambiar ningún formato, y la librería porta lo que no es de la CLI, con los mismos valores:
| Módulo | Contenido | En Go |
|---|---|---|
| `lib/src/annex.dart` y `lib/src/recovery_annex.g.dart` | `recoveryAnnex`, el texto del anexo, y `recoveryAnnexSuffix`, `.recuperacion.txt`, lo que se añade al nombre del `.dkc` para nombrar el fichero del anexo: `carta.dkc.recuperacion.txt` | `RecoveryAnnex` y `RecoveryAnnexSuffix` (`annex.go`) |
| `lib/src/profile.dart` | `ProfileStatus`, el estado de un perfil: `active`, `readOnly` o `compromised`; y `profileStatusOf`, el estado del perfil de un `profile_hash` y si esta versión de la librería lo conoce | `Status` y `StatusOf` de `profile` (`status.go`) |
Notas:
- **El anexo** es el §79 de la especificación bajo un título y un párrafo que nombran la versión de la especificación y el SHA-256 de su texto. Es el mismo para toda cápsula y no lleva nada de una. Sus bytes UTF-8 son `annex/recovery.md` de `datekeys-go`, que Go incrusta con `go:embed` y comprueba contra el §79 de la especificación de su `SpecVersion`. Está en español, como la especificación.
- **Dart no incrusta ficheros**, así que el texto es una constante generada: `dart run tool/recovery_annex_copy.dart` escribe `lib/src/recovery_annex.g.dart` desde `annex/recovery.md`, la copia que hace `tool/sync_testdata.dart` (ver «Datos de prueba»), después de comprobarla contra su `SOURCE.json`. Va en un string de varias líneas, cada línea del fichero una del código: se escapan la barra invertida, el dólar y la comilla, y, como escape Unicode, cada runa salvo el salto de línea que `strconv.IsPrint` de Go rechaza, como un CR, un tabulador, un espacio de no separación o un control de texto bidireccional, para que ningún carácter del texto sea invisible en el código y los finales de línea de una copia de trabajo no lleguen al texto. El anexo de hoy no tiene nada que escapar. Una constante no cuesta nada al cargar, y la compilación a JavaScript la deja fuera si nadie la usa. Hay que ejecutar el programa tras cada `sync` que cambie `annex/`.
- **El estado de un perfil.** DateKeys no publica todavía el registro firmado del §71, así que la librería fija el estado de los perfiles que conoce, por su `profile_hash`, como Go: Quicknet está activo, y un cambio de estado llega con una versión nueva de la librería. Con un perfil `readOnly` no se escribe ninguna cápsula nueva, y las que hay se siguen abriendo; con uno `compromised` también se abren, y el SDK oficial avisa de que su contenido pudo leerse antes de la fecha. La librería da el estado y el escritor no lo consulta: lo aplica la app, como lo aplica la CLI de Go.
- **Las diferencias con Go.** `profileStatusOf` devuelve un registro, `(status, known)`, donde Go devuelve dos valores, y toma los bytes del hash, donde Go toma un `[32]byte`: un hash de otra longitud es un perfil que no conoce. Un perfil que no conoce está `active`, el `Status` cero de Go, con `known` a falso. `ProfileStatus` es un enum de tres valores, cada uno con el nombre de `Status.String` de Go en `label` y en `toString`; el `unknown` de Go, el de un `Status` fuera de rango, no tiene equivalente.
- **Lo que se exporta.** `lib/datekeys.dart` exporta `recoveryAnnex`, `recoveryAnnexSuffix`, `ProfileStatus` y `profileStatusOf`. `recoveryAnnexSha256`, el SHA-256 de los bytes del anexo que escribe también el programa, es interno, para las pruebas compiladas a JavaScript.
La parte 4a de la etapa 4 porta `internal/pathrule` y `wordkey` de `datekeys-go` en `c531e93`, la cabeza de la rama `v0.12`, que sigue la v0.11 con las correcciones de la revisión del 2 de octubre; los dos paquetes no cambian desde el tag `spec-v0.11`. Tienen las mismas comprobaciones, en el mismo orden y con los mismos textos de error:
| Módulo | Contenido | En Go |
@ -271,10 +316,10 @@ La parte 7a de la etapa 7 porta el paquete `locator` de `datekeys-go` en `c531e9
Notas de la parte 7a:
- **Lo que queda fuera.** La librería no descarga nada. La app pide el resto solo cuando la persona lo pide, después de mostrarle el host o el CID (`LocatorAddress.host`), y solo a una dirección que acepte `checkAddressUri` (`Locator.usable`); no sigue una redirección a una dirección que `checkAddressUri` rechace; comprueba con `checkResolvedIp`, en cada conexión, que la IP a la que resuelve un nombre es pública; lee solo los bytes del resto, y se los da a `Locator.openEnvelope`, que comprueba su SHA-256, descifra el `.dkc` y comprueba el suyo (§44.1).
- **`checkResolvedIp`** no está en Go, cuyo lector no descarga. Recibe los 4 o los 16 bytes de la dirección, los de `InternetAddress.rawAddress`, y la clasifica como `publicIP`: una IPv4 mapeada en IPv6 no es pública, así que la app pasa una IPv4 como sus 4 bytes. En una red móvil solo IPv6, el NAT64 del sistema da a un nombre con solo IPv4 una dirección de `64:ff9b::/96`, que el §44.1 no deja usar.
- **`checkResolvedIp`** es `locator.CheckResolvedIP` de Go, de la v0.13. Recibe los 4 o los 16 bytes de la dirección, los de `InternetAddress.rawAddress`, y la clasifica como `publicIP`: una IPv4 mapeada en IPv6 no es pública, así que la app pasa una IPv4 como sus 4 bytes. En una red móvil solo IPv6, el NAT64 del sistema da a un nombre con solo IPv4 una dirección de `64:ff9b::/96`: cuenta como pública si la IPv4 de dentro lo es. Con `nat64`, el prefijo de NAT64 de la red, que la app descubre con RFC 7050, una dirección de ese prefijo cuenta solo por su IPv4. `test/resolved_ip_test.dart` corre los casos de `resolved_ip.json`.
- **Sellar y crear un sobre.** `Seal` y el cifrado `age` de `NewEnvelope` necesitan el escritor de `age` de la etapa 6: son de la parte 7b. `splitEnvelope` es el resto de `NewEnvelope`: parte el fichero `age` del sobre en su cabecera y su resto, con los textos de `headerEnd`.
- **Las direcciones** se leen como están escritas, sin decodificar nada, sobre sus bytes UTF-8, como lee Go un string: el primer byte que RFC 3986 no admite se cita como lo cita el `%q` de Go, una runa (0xc3 es `'Ã'`). Las IP las lee y las clasifica `ipaddr.dart`, código propio con la aceptación exacta de `netip.ParseAddr`, nunca `InternetAddress` de `dart:io`, que acepta otras notaciones; una IPv6 son 16 bytes, y cada bloque se compara byte a byte.
- **Dos rarezas de Go que se conservan,** porque los vectores son los de Go: el host de una IPv6 es `strings.Trim(host, "[]")`, así que `https://[[2000::]/` vale; e `isCIDv1` mira que los bits sobrantes sean cero, no cuántos son, así que un CID con un carácter más cuyos bits son cero vale también, con otro texto que el canónico. Son de Go, no del texto del §44.1: si Go las corrige, sus vectores lo dirán.
- **Dos rarezas de Go, corregidas** en `datekeys-go` `e801e03` y aquí: `https://[[2000::]/` y un CID con un carácter más cuyos bits son cero se rechazan, porque el §44.1 de la v0.12 ya pedía un literal IPv6 con un solo par de corchetes y el CID en su forma canónica. Los vectores de `tool/locator_go_vectors.go` se regeneraron sobre ese commit.
- **La apertura** lee, como Go con `io.LimitReader`, como mucho 1 MiB del texto del localizador: un chunk de STREAM después de ese MiB no se descifra ni se comprueba, y lo leído no tiene la longitud de un localizador.
- **Los errores no llevan código normativo,** como en Go: un localizador que no se lee o no se abre, o una dirección fuera de las reglas, es inutilizable, y su error es una `LocatorException` con el texto de Go. Los datos de la extensión llevan un código solo, `ERR_EXTENSION_DATA_INVALID`, que la hace inutilizable a ella y nunca a la `.dkk` (§54).
- **`StandardExtensions`** comprueba por defecto la `data` de `datekeys.capsule` con `checkCapsuleData`, como `locator.Standard` de Go: al abrir una `.dkk` con ella, una extensión `datekeys.capsule` que no se lee queda inutilizable, con el texto de Go. Con `validateCapsule: null` solo comprueba que haya `data`, como el `extension.Standard` de Go sin `ValidateCapsule`: es el registro con el que el escritor de la `.dkk` comprueba lo que escribe, como el de Go, porque el codificador de `datekeys.capsule`, `CapsuleInfo.toExtension`, lee lo que escribe.
@ -541,7 +586,7 @@ Manda ECDSA: con el exponente 65 537, una verificación de RSA son 17 multiplica
| Número | Dónde | Hoy |
|---|---|---|
| Librería | `version` de `lib/src/version.dart` y de `pubspec.yaml`, que una prueba mantiene iguales | `0.1.0-dev` |
| Especificación | `specVersion` de `lib/src/version.dart`: la que nombra el campo `spec` de cada fichero de `testdata/` | `0.11` |
| Especificación | `specVersion` de `lib/src/version.dart`: la que nombra el campo `spec` de cada fichero de `testdata/` | `0.15` |
La rama sigue la versión de la especificación: `v0.11`, hasta que `datekeys-go` cierre la v0.12. Desde la etapa 5, `testdata/` es ya el de la rama `v0.12`.
@ -568,25 +613,35 @@ tool/check.sh
- `dart analyze --fatal-infos`;
- `dart test`;
- `dart test -p node`: las pruebas que no leen ficheros corren también compiladas a JavaScript, en Node.js, para comprobar que los enteros son exactos en la web. Las que leen ficheros llevan `@TestOn('vm')`. Por eso el gate necesita Node.js, como `datekeys-ts`; lo decidió el autor el 5 de octubre de 2026;
- la copia de `testdata/` frente al repositorio de Go, que debe estar al lado, en `../datekeys-go`.
- las copias de `testdata/`, `wordlists/` y `annex/` frente al repositorio de Go, que debe estar al lado, en `../datekeys-go`.
## Datos de prueba
`testdata/` es una copia de `datekeys-go/testdata` en un commit fijo. `testdata/SOURCE.json` registra el commit y el SHA-256 de cada fichero, igual que en `datekeys-ts`. La copia actual es la de la rama `v0.12` de `datekeys-go` en `084728d`, la misma que tiene `datekeys-ts`: 134 ficheros, con `wordkey.json`, los vectores compartidos de la llave de palabras, con los veredictos y las líneas del borrador v0.12. Cada fichero dice aún `"spec": "0.11"`, como el `SpecVersion` de Go, hasta que el autor apruebe el borrador.
`testdata/` es una copia de `datekeys-go/testdata` en un commit fijo. `testdata/SOURCE.json` registra el commit y el SHA-256 de cada fichero, igual que en `datekeys-ts`. La copia actual es la de `datekeys-go` en `aefc8f6`, la rama `v0.15` después del tag `spec-v0.15`, cuyo `testdata/` es el del tag, `fe50885`, byte a byte: 142 ficheros, con `release.json` y `releases/`, el objeto release, el JSON de drand y el archivo de releases de la v0.15, con el campo `source` de `mutations.json`, con `tlock_steps.json`, los pasos 10 y 11 de Quicknet valor a valor, con `resolved_ip.json`, con `wordkey.json`, los vectores compartidos de la llave de palabras, y los veredictos y las líneas de la v0.12. Cada fichero dice `"spec": "0.15"`, como el `SpecVersion` de Go.
`wordlists/` es la copia de `wordkey/lists` del mismo commit: las listas de palabras de `wordkey.Generate`, hoy `en.txt`, la de la EFF, y `es.txt`, y su `README.md`, con la fuente, el método y la licencia de cada lista, y el SHA-256 de cada lista numerada para los dados. `wordlists/SOURCE.json` tiene el formato de `testdata/SOURCE.json`, y `.gitattributes` guarda sus bytes exactos, como los de `testdata/`: `lib/src/wordlist.dart` fija el SHA-256 de cada lista.
`annex/` es la copia de `annex` del mismo commit: `recovery.md`, el anexo de recuperación de `datekeys.RecoveryAnnex`, el §79 de la especificación bajo su título. `annex/SOURCE.json` tiene el formato de `testdata/SOURCE.json`, y `.gitattributes` guarda sus bytes exactos: `lib/src/recovery_annex.g.dart` es su texto, que escribe `dart run tool/recovery_annex_copy.dart` tras cada `sync` que lo cambie.
```bash
dart run tool/sync_testdata.dart sync --commit 084728d
dart run tool/sync_testdata.dart sync --commit aefc8f6
```
```bash
dart run tool/sync_testdata.dart check --against ../datekeys-go
```
- `sync` lee los ficheros con git en ese commit, así que nunca entran cambios sin commit del repositorio de Go.
- Los ficheros de `testdata/` no se editan ni se generan aquí.
- En cada `dart test`, `test/testdata_test.dart` comprueba la copia, y que cada fichero nombre `specVersion`.
- `sync` copia los tres árboles del mismo commit y lee los ficheros con git, así que nunca entran cambios sin commit del repositorio de Go. Lo lee todo antes de tocar las copias, y un árbol que falta en el commit es un error.
- `check` comprueba los tres árboles con las mismas reglas, sin ficheros que falten, sobren o cambien, y escribe una línea por árbol: la de `testdata`, la de `wordlists` y la de `annex`.
- Los ficheros de `testdata/`, de `wordlists/` y de `annex/` no se editan ni se generan aquí.
- En cada `dart test`, `test/testdata_test.dart` comprueba las tres copias, y que cada fichero de `testdata/` nombre `specVersion`. `test/wordlist_vm_test.dart` lee las dos listas de `wordlists/` con `readWordList`, y numera las dos para los dados.
- `test/tlock_steps_vm_test.dart` recorre `tlock_steps.json` valor a valor con el código de la librería: M, H(M), la ecuación del emparejamiento, las partes del stanza, e(firma, U), H2, sigma, H4, la file key, cada intento de H3 y r, r·G2 = U, y las comprobaciones negativas del generador de Go (otro DST, la ronda sin SHA-256 y H3 que borra solo el bit más alto). `test/tlock_steps_test.dart` hace lo mismo compilado a JavaScript, sobre `test/vectors/tlock_steps.g.dart`, la copia del fichero que escribe `dart run tool/tlock_steps_copy.dart` tras cada `sync`; la prueba de la VM comprueba que es el fichero byte a byte.
- `test/release_object_vm_test.dart` recorre `release.json` caso a caso, con el resultado y el texto de Go: los objetos, con sus capas y el paso 10, el release que dice cada uno y su codificación otra vez byte a byte; el JSON de drand; y las búsquedas en el archivo. Comprueba además cada fichero de `releases/` y los textos de `provider.Archive` sobre archivos editados (`test/vectors/release_archive_texts.json`). `test/release_object_test.dart` hace lo mismo compilado a JavaScript, sobre `test/vectors/release.g.dart`, que escribe `dart run tool/release_copy.dart` tras cada `sync`.
- `test/open_corpus_test.dart` abre cada caso de `mutations.json` con su `source`: `supplied`, el objeto release de su `release` en `OpenOptions.release`, o `network`, una fuente que verifica el release y lo descarta si no cumple el paso 10, como `testkit` de Go.
- `test/errors_spec_test.dart` lee el §69 de la especificación en el commit de `testdata/SOURCE.json`.
- `test/annex_vm_test.dart` comprueba que `recoveryAnnex` es `annex/recovery.md` byte a byte, y que el fichero es el §79 de la especificación bajo el título y el párrafo de `TestRecoveryAnnex` de Go, que nombran su versión y su SHA-256, con la especificación en el commit de `annex/SOURCE.json`, como `test/errors_spec_test.dart`. `test/annex_test.dart` comprueba, también compilado a JavaScript, lo que comprueba Go del texto del anexo y el SHA-256 de sus bytes UTF-8.
`test/vectors/` tiene los vectores de las primitivas, de la lectura y la escritura de `age`, de BLS12-381, de tlock, de las reglas de rutas y textos, de la llave de palabras, de los formatos, de la apertura, del área de seguridad, de la firma con certificados y el sello, del lector de CMS, del localizador, de las claves de autor y de la firma Ed25519, y del sellado del localizador y del sobre. Los escribe Go, con las librerías de la caché de módulos que usa `datekeys-go` (`x/crypto`, `filippo.io/age`, `kilic/bls12-381`, `drand/kyber`, `kyber-bls12381` y `tlock`) y sus paquetes, como `provider`, `agewrap`, `capsule`, `internal/pathrule`, `internal/testkit` y `wordkey`; ningún valor esperado se escribe a mano. Los generadores van en `tool/`, con `//go:build ignore`, y se ejecutan en el contexto del módulo de `datekeys-go`, sin cambiar nada en él; los de las rutas, de la apertura, del lector de CMS y del escritor de `age`, en una exportación suya, y el último, `tool/cms_go_vectors_test.go`, como una prueba de Go. Los de BLS12-381 y tlock dan la misma salida con el tag `spec-v0.11` y con el borrador v0.12, y leen ficheros congelados de `datekeys-ts`, cuya carpeta en esta máquina se llama todavía `App`:
`test/vectors/` tiene los vectores de las primitivas, de la lectura y la escritura de `age`, de BLS12-381, de tlock, de las reglas de rutas y textos, de la llave de palabras y de sus listas, de los formatos, de la apertura, del área de seguridad, de la firma con certificados y el sello, del lector de CMS, del localizador, de las claves de autor y de la firma Ed25519, y del sellado del localizador y del sobre. Los escribe Go, con las librerías de la caché de módulos que usa `datekeys-go` (`x/crypto`, `filippo.io/age`, `kilic/bls12-381`, `drand/kyber`, `kyber-bls12381` y `tlock`) y sus paquetes, como `provider`, `agewrap`, `capsule`, `internal/pathrule`, `internal/testkit` y `wordkey`; ningún valor esperado se escribe a mano. Los generadores van en `tool/`, con `//go:build ignore`, y se ejecutan en el contexto del módulo de `datekeys-go`, sin cambiar nada en él; los de las rutas, de la apertura, del lector de CMS, del escritor de `age` y de las listas de palabras, en una exportación suya, y el último, `tool/cms_go_vectors_test.go`, como una prueba de Go. Los de BLS12-381 y tlock dan la misma salida con el tag `spec-v0.11` y con el borrador v0.12, y leen ficheros congelados de `datekeys-ts`, cuya carpeta en esta máquina se llama todavía `App`:
```bash
cd ../datekeys-go && go run ../datekeys-dart/tool/gen_primitive_vectors.go -out ../datekeys-dart/test/vectors
@ -624,6 +679,10 @@ cd ../datekeys-go && go run ../datekeys-dart/tool/wordkey_go_vectors.go -out ../
cd ../datekeys-go && go run ../datekeys-dart/tool/mutation_go_texts.go ../datekeys-dart/testdata > ../datekeys-dart/test/vectors/mutation_texts.json
```
```bash
cd ../datekeys-go && go run ../datekeys-dart/tool/release_archive_go_texts.go ../datekeys-dart/testdata/releases/archive_1000_1004.bin ../datekeys-dart/testdata/releases/1000.cbor > ../datekeys-dart/test/vectors/release_archive_texts.json
```
```bash
cd ../datekeys-go && go run ../datekeys-dart/tool/security_go_vectors.go -testdata ../datekeys-dart/testdata -out ../datekeys-dart/test/vectors
```
@ -684,6 +743,18 @@ cp tool/age_writer_go_vectors.go "$tmp"
rm -rf "$tmp"
```
El de las listas de palabras corre en una exportación del commit de `wordlists/SOURCE.json`, para que sus vectores sean los de esas listas: `tool/wordlist_go_vectors.go` lee `wordkey/lists`, da a `Generate`, en lugar de `crypto/rand`, el keystream de `SeededRandomSource`, bloques de SHA-256 o bytes que se acaban, y tira los dados sobre las listas de Go y sobre listas de índices. La salida es la misma en cada ejecución:
```bash
commit=$(git -C ../datekeys-go rev-parse 92e7154)
out=$PWD/test/vectors
tmp=$(mktemp -d)
git -C ../datekeys-go archive "$commit" | tar -x -C "$tmp"
cp tool/wordlist_go_vectors.go "$tmp"
(cd "$tmp" && go run ./wordlist_go_vectors.go -source "$commit" -out "$out")
rm -rf "$tmp"
```
Los de la parte 7b corren en el módulo de `datekeys-go`, porque solo importan paquetes públicos: `authorkey`, `locator`, `profile`, `provider` y `codec/bech32`, cuyo `createChecksum` el primero alcanza con `go:linkname` para escribir cadenas Bech32 con cualquier relleno. Mientras escriben cada caso, `crypto/rand.Reader` lee el keystream de `SeededRandomSource`, como en el generador del escritor de `age`; `authorkey.Generate` lo lee también, gracias al `//go:debug cryptocustomrand=1` del generador, sin el que `ed25519.GenerateKey` de Go 1.26 no mira `crypto/rand.Reader`:
```bash
@ -758,13 +829,17 @@ rm -rf "$tmp"
| `ibe_vectors.json` | GT y H2, H3 con candidatos rechazados, H4, identidades de rondas, el stanza tlock de cada fixture de `testdata/` con sus valores intermedios y su file key, los ciphertexts de kyber y los veredictos de `DecryptCCAonG2` sobre copias editadas del stanza de `time_only` |
| `tlock_vectors.json` | El cifrado de kyber con sigma fijo, reproducido byte a byte, y los ciphertexts que escribió `datekeys-ts` y abrió Go |
| `release_vectors.json` | Los veredictos, códigos y textos de `provider.Verify`, de `NewTimeIdentity` con su `Unwrap` y de `NewTimeRecipient` |
| `release_archive_texts.json` | De `tool/release_archive_go_texts.go`: el texto de `provider.Archive` (v0.15, §50) al buscar rondas en el archivo de `testdata/releases/` y en copias editadas: rondas que faltan o que no cubre, otra cadena, otra longitud, una cabecera que no lo es, de otra versión, de 0 rondas, sin la forma más corta o sin una clave |
| `release.g.dart` | `release.json`, los ficheros de `releases/` y `release_archive_texts.json` como constantes de Dart, para las pruebas compiladas a JavaScript |
| `formats_*.json` | El diferencial de los formatos, de `datekeys-go` en `c531e93`: el resultado, el código y el texto de Go en unos 6 400 casos, válidos y rotos en cada capa del §69.1, con una semilla fija y sobre los fixtures editados. Las tramas, `PUBLIC_HEADER`, `CONTROL_CBOR` de los tres formatos, la `.dkk`, los perfiles, las extensiones con sus registros, `dk1_`, el RFC 3339, las rondas, el relleno hasta L_MAX, la comprobación del relleno de `capsule.Open`, los codificadores, los límites del §57, `BODY` y, para la precedencia del §69.1, cada fallo de una lista, solo y con cada otro |
| `formats_vectors.g.dart` | Uno de cada ocho casos de cada sección de `formats_*.json`, como constantes de Dart para las pruebas compiladas a JavaScript |
| `pathrule_vectors.json` | Las reglas de `internal/pathrule`: los casos de las pruebas de Go y de `datekeys-ts` y los dos lados de los límites de R2, R3 y R6b; 1300 cadenas y 350 árboles de una semilla fija (marcas combinantes, Hangul, ignorables, emoji, sosias best-fit de ASCII, nombres de dispositivo, alias 8.3, textos y bytes que no son UTF-8 válido) con el resultado de `CheckPath`, `CheckComment` y `CheckAuthor`, su NFD y su clave; los casos de R9; y, por plano, el SHA-256 de una línea por punto de código de cada función |
| `pathrule_vectors.g.dart` | El mismo JSON como constante de Dart |
| `wordkey_vectors.json` | La llave de palabras de `wordkey`: 400 textos con sus palabras, 515 listas de palabras con el resultado de `Check`, y cuatro llaves con su contraseña P y su sal S, el PBKDF2 de 1000 iteraciones para Node.js y el recipient; la primera es el vector del §38.1 |
| `wordkey_vectors.g.dart` | El mismo JSON como constante de Dart |
| `mutation_texts.json` | De `tool/mutation_go_texts.go`, port de `scripts/mutation-go-texts.go` de `datekeys-ts` sobre el `testdata/` de este repositorio: el texto del error de `capsule.Open` en cada caso del corpus de mutaciones, `ok` si se abre, y sus comprobaciones con el detalle de cada paso. Si Go y el corpus discreparan en el código o el paso de un caso, lo diría con `go_error` y `go_step`: en ninguno de los 218 casos del corpus del borrador v0.12 lo hacen con Go en `c531e93` |
| `wordlist_vectors.json` | Las listas de palabras de `wordkey` (`generate.go`) y sus dados (`dice.go`), en `92e7154`: el SHA-256, los bytes y las palabras de cada lista de Go; el cuerpo de `List` sobre 19 textos de una lista base, con y sin el LF final, con líneas CRLF, una línea vacía, una marca de orden de bytes y bytes que no son UTF-8 válido; `CheckList` sobre 83 listas editadas, con los casos de `TestCheckList`; `CheckList` con cada punto de código de los planos 0, 1 y 14 en la primera palabra, como el SHA-256 de sus resultados, y uno a uno hasta U+017F; `Generate` en 51 casos, sobre la lista española y listas de 12 a 2^20 + 1 palabras, con el keystream de `SeededRandomSource`, bloques de SHA-256 y bytes que se acaban, entre ellos la semilla de `TestGenerate`, que solo saca dos índices y se queda sin bytes; `Bits`, el double de Go bit a bit, en 221 casos y cuatro resúmenes; y los dados: `DiceNumber` en 24 posiciones; `DiceWord` en 63 casos y `DiceWords` en 78, sobre las listas de Go y sobre listas de índices, con los casos de `TestDiceWord` y `TestDiceWords`, cada espacio de `unicode.IsSpace` entre los números y puntos de código y bytes que no lo son, el orden de las comprobaciones, listas con una palabra más de una vez, también con caracteres que `%q` escapa, y listas de otro tamaño; el SHA-256 de `DiceList` de cada lista, el fichero de la EFF para `en`; y `DiceWords` con cada punto de código de los planos 0, 1 y 14 entre los dos primeros números, como el SHA-256 de sus resultados |
| `wordlist_vectors.g.dart` | El mismo JSON como constante de Dart |
| `mutation_texts.json` | De `tool/mutation_go_texts.go`, port de `scripts/mutation-go-texts.go` de `datekeys-ts` sobre el `testdata/` de este repositorio: el texto del error de `capsule.Open` en cada caso del corpus de mutaciones, `ok` si se abre, y sus comprobaciones con el detalle de cada paso. Si Go y el corpus discreparan en el código o el paso de un caso, lo diría con `go_error` y `go_step`: en ninguno de los 222 casos del corpus de la v0.15 lo hacen con Go en `fe50885`, que abre cada caso con su `source`, como `testkit` |
| `open_cases.json` | `capsule.Open` sobre cada fixture con cada una de sus credenciales, y sobre fixtures editados o con otras opciones en cada paso que el corpus no alcanza: la trama, los campos, las extensiones y los vínculos de una `.dkk` en el paso 9.a, el reloj y los fallos de la fuente del release, las cabeceras `age` de los pasos 11 y 17, un stanza X25519 mal formado en `INNER_ACCESS_AGE`, `CONTROL_CBOR` sellado otra vez, `BODY` del formato 3 sellado otra vez, los sinks y la salida que fallan, el rechazo de `Accept` y las extensiones inutilizables de cada objeto. Cada caso tiene el resultado, el texto, el paso, las comprobaciones con su detalle, las peticiones del release, el estado del sink y el contenido o los ficheros, y los del formato 3 que se abren, sus veredictos con sus líneas, también con la clave de autor guardada |
| `open_heads.json` | `capsule.DecodeHead` de heads de una semilla fija, válidos y rotos en cada capa del §69.1, sin registro y con uno, y `capsule.EncodeHead` |
| `open_notes.json` | `extension.CheckNote` sobre textos y bytes, `extension.Note` y `Header.UnusableNote`, y `extension.Standard` con una nota |
@ -802,7 +877,7 @@ rm -rf "$tmp"
| `seal_interop.g.dart` | El mismo JSON como constante de Dart |
- Los fixtures que leen los generadores son los de `testdata/` de este repositorio, la copia sincronizada.
- `primitives.json`, los cuatro ficheros de BLS12-381 y tlock, `pathrule_vectors.json`, `wordkey_vectors.json`, los de los formatos, `security_vectors.json`, `securitycms_vectors.json`, los del lector de CMS, los del escritor de `age`, los del localizador, los de la parte 7b y `capsule_writer.json` salen iguales en cada ejecución, los del lector de CMS, los del localizador y `capsule_writer.json` con Go 1.26.8. `capsule_interop.json` cambia en cada ejecución en sus seis muestras del CSPRNG, que es lo que comprueban. Lo aleatorio de tlock, los ciphertexts de kyber con su sigma y los de `datekeys-ts`, se lee de los ficheros congelados de `datekeys-ts` en `289fe71`, y Go los descifra otra vez. `age`, en cambio, saca sus claves y nonces de `crypto/rand`, así que `age.json` y `age_fixtures.json` cambian en cada ejecución; las pruebas leen lo que esté en el repositorio. `age.json` no lee `testdata/` y es el congelado de la etapa 2; `age_fixtures.json` se escribió otra vez con el `testdata/` de la v0.12, y fuera de los dos fixtures nuevos y del de `seal_type` 4294967295 sale igual.
- `primitives.json`, los cuatro ficheros de BLS12-381 y tlock, `pathrule_vectors.json`, `wordkey_vectors.json`, `wordlist_vectors.json`, los de los formatos, `security_vectors.json`, `securitycms_vectors.json`, los del lector de CMS, los del escritor de `age`, los del localizador, los de la parte 7b y `capsule_writer.json` salen iguales en cada ejecución, los del lector de CMS, los del localizador y `capsule_writer.json` con Go 1.26.8. `capsule_interop.json` cambia en cada ejecución en sus seis muestras del CSPRNG, que es lo que comprueban. Lo aleatorio de tlock, los ciphertexts de kyber con su sigma y los de `datekeys-ts`, se lee de los ficheros congelados de `datekeys-ts` en `289fe71`, y Go los descifra otra vez. `age`, en cambio, saca sus claves y nonces de `crypto/rand`, así que `age.json` y `age_fixtures.json` cambian en cada ejecución; las pruebas leen lo que esté en el repositorio. `age.json` no lee `testdata/` y es el congelado de la etapa 2; `age_fixtures.json` se escribió otra vez con el `testdata/` de la v0.12, y fuera de los dos fixtures nuevos y del de `seal_type` 4294967295 sale igual.
- Un fichero `age` de más de un chunk se guarda como su cabecera, su nonce y su file key: la prueba cifra otra vez el texto documentado y comprueba el SHA-256 del fichero entero antes de leerlo. Las cabeceras de megabytes se escriben como partes que se repiten.
- `locator_vectors.json` guarda un valor editado como ediciones de una base, con una forma más: `[at, 0, byte, n]` inserta n copias del byte. Una dirección con una racha de 32 bytes iguales o más va como `[antes, byte, n, después]`, y un texto de error, como su índice en `texts`. Los ficheros cuyo texto pasa de 1 MiB van como su cabecera, su nonce, su file key y la lista de sus chunks: la prueba los escribe otra vez y comprueba su SHA-256 antes de abrirlos.
- Los casos de `open_cases.json` que editan un fixture lo sellan otra vez como el `testkit` de la referencia, con las file keys y los nonces del fixture, así que salen iguales en cada ejecución, y se guardan como ediciones del fixture.
@ -811,3 +886,7 @@ rm -rf "$tmp"
## Licencia
Apache-2.0 (`LICENSE`), como `datekeys-go` y `datekeys-ts`. La especificación tiene su propia licencia, CC-BY-4.0.
Las listas de palabras de `wordlists/`, copiadas de `datekeys-go`, no son código y tienen su propia licencia: `es.txt` es una adaptación de FrequencyWords de Hermit Dave, con licencia CC BY-SA 4.0. `wordlists/README.md` recoge la fuente, el método y la licencia de cada lista.
El anexo de `annex/`, copiado de `datekeys-go`, y su texto en `lib/src/recovery_annex.g.dart` son el §79 de la especificación bajo un título: texto de la especificación, no código.

@ -0,0 +1,7 @@
{
"module": "g.activething.com/go/DateKeys",
"commit": "aefc8f6dfe89037d71e22d5338a092ff21159429",
"files": {
"recovery.md": "c8c9b8815708d963ca6a3d688003bdc5046c499ab034a2d8c98a18c9811d3bd3"
}
}

@ -0,0 +1,158 @@
# Cómo abrir una cápsula DateKeys sin software de DateKeys
Este texto acompaña a una cápsula del tiempo de DateKeys, un fichero `.dkc`: dice cómo abrirla, llegada su fecha, sin ningún software de DateKeys, por si ya no existe. Es el anexo informativo §79 de la especificación del protocolo DateKeys v0.15, cuyo texto tiene el SHA-256 45105e693be4187af4dd30f4d254402612587b6427c746f5d29f07a541c1e3f3. Es el mismo para toda cápsula: no lleva ningún dato de esta.
## 79. Anexo informativo: recuperación sin software DateKeys
Este anexo no es normativo. Dice cómo abrir una cápsula de Quicknet sin ningún software de DateKeys, por si dentro de décadas no existe. Repite lo que fijan las secciones que cita, que deciden en caso de duda.
La regla 27 de §62.1 recomienda al SDK oficial guardar este anexo junto al `.dkc`. No contiene ningún dato de una cápsula.
Hace falta:
- el `.dkc`;
- el release de su ronda, de cualquier fuente: un relay de drand, un archivo de releases, un servicio de caché (§50) o cualquier copia. No hace falta confiar en quien lo da: se verifica con la clave pública de 79.1 (79.3);
- en `time_and_key`, una credencial: la `.dkk`, la identity `age` de un recipient o las palabras de una llave de palabras (§38.1);
- una librería de BLS12-381 con pairing y con el hash a G1 de RFC 9380, SHA-256, HMAC-SHA256, HKDF-SHA256 (RFC 5869), ChaCha20-Poly1305 (RFC 8439), un decodificador de CBOR y la herramienta `age` (§77) o una librería compatible.
No sirven las herramientas de drand: `tle` pide el release a la red y no acepta uno dado, y `age` no acepta una file key, que es lo que da el stanza tlock (79.4). Por eso este anexo describe esos dos pasos enteros (79.4 y 79.5).
La implementación de referencia lo sigue en `scripts/recovery`, un programa que no importa ningún paquete de DateKeys, tlock ni drand: solo la librería estándar de Go, `golang.org/x/crypto`, `filippo.io/age` y la librería BLS12-381 `drand/kyber-bls12381`. `scripts/recovery_check.sh` abre con él una cápsula `time_only` y otra `time_and_key` de los fixtures oficiales.
### 79.1 Parámetros de Quicknet
Son los de §12, y pueden no estar ya en ningún otro sitio:
```text
chain_hash 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971
clave pública (G2, 96 bytes)
83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c
8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb
5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a
genesis_time 1692803367 (segundos Unix de la ronda 1)
period 3 segundos
round_time(r) = genesis_time + (r − 1)·3
q 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001
DST BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_NUL_
```
Los puntos se codifican comprimidos, en el formato de ZCash (§12.2): 48 bytes en G1, la firma, y 96 en G2, la clave pública y U, con la coordenada c1 antes que c0.
### 79.2 La cápsula
El `.dkc` empieza por 16 bytes (§22):
```text
0 4 "DKC1"
4 1 VERSION: el formato, 1, 2 o 3
5 1 0
6 2 0
8 4 PUBLIC_HEADER_LEN, entero big-endian
12 4 SEALED_CONTROL_LEN, entero big-endian
```
Le siguen `PUBLIC_HEADER`, de `PUBLIC_HEADER_LEN` bytes; `SEALED_CONTROL`, de `SEALED_CONTROL_LEN` bytes; y `PAYLOAD_AGE`, desde el byte 16 + `PUBLIC_HEADER_LEN` + `SEALED_CONTROL_LEN` hasta el final del fichero.
`PUBLIC_HEADER` es un mapa CBOR (§24). Su clave 2 es `capsule_id`, 16 bytes; su clave 4, la política, 0 para `time_only` y 1 para `time_and_key`; y su clave 3, la DateKey, un texto `dk1_` seguido del Base64URL sin relleno de un JSON (§18):
```json
{"version":1,"network":"datekeys:quicknet:v1","round":1000}
```
`round` es la ronda de la cápsula.
### 79.3 El release
Un objeto release es un mapa CBOR (§47.1): la clave 0 es `"datekeys-release"`; la 2, el `chain_hash`, que ha de ser el de 79.1; la 3, la ronda, que ha de ser la de la DateKey; y la 4, la firma, de 48 bytes. Así lo sirven la Release API y un servicio de caché. En un archivo de releases (§50), la firma de la ronda r son los 48 bytes que empiezan en |cabecera| + (r − primera ronda)·48, y 48 ceros si el archivo no la tiene. Un relay de drand la entrega como JSON, `{"round": …, "signature": "…"}`, con la firma en hexadecimal. Hoy se pide así, aunque las direcciones pueden cambiar:
```text
GET https://api.drand.sh/v2/chains/<chain_hash>/rounds/<ronda>
```
La firma no necesita confianza: se verifica (§63, paso 10). Con M el SHA-256 de la ronda en 8 bytes big-endian, y H el hash a G1 de RFC 9380 con la suite `BLS12381G1_XMD:SHA-256_SSWU_RO_` y el DST de 79.1:
```text
e(H(M), clave_pública) == e(firma, G2)
```
con e el pairing de G1 × G2, el primer argumento en G1 y el segundo en G2, y G2 el generador de G2. La firma y la clave pública se decodifican como puntos comprimidos válidos del subgrupo, distintos del punto en el infinito. Para una ronda solo hay una firma válida: cualquier copia que verifique es el release.
### 79.4 El stanza tlock y FK_TIME
`SEALED_CONTROL` es un fichero `age` (79.5) cuya cabecera tiene un solo stanza:
```text
-> tlock <ronda en decimal> <chain_hash en hexadecimal en minúsculas>
<cuerpo en Base64 estándar sin relleno, en líneas de 64 caracteres>
```
El cuerpo mide 128 bytes, U ‖ V ‖ W: U, de 96 bytes, un punto de G2, y V y W, de 16 bytes. Con la firma del release (§63, paso 11):
```text
sigma = V XOR H2(e(firma, U))
FK_TIME = W XOR H4(sigma)
r = H3(sigma, FK_TIME)
comprobar r·G2 == U
```
- H2(x) son los 16 primeros bytes de SHA-256(`IBE-H2` ‖ x), con x los 576 bytes del elemento de GT en el orden de §63, «Serialización de GT en H2»: c1 antes que c0 en cada nivel de la torre, y c2, c1, c0 en Fp6, cada elemento de Fp en 48 bytes big-endian. Una librería que serializa con c0 primero da otro H2. El vector de `testdata/vectors/tlock_ibe.json` lo comprueba: H2(e(G1, G2)) = `cb87319f24560b5231579a09ad79f12e`, con G1 y G2 los generadores.
- H4(sigma) son los 16 primeros bytes de SHA-256(`IBE-H4` ‖ sigma).
- H3(sigma, FK_TIME): base = SHA-256(`IBE-H3` ‖ sigma ‖ FK_TIME); para i = 1, 2, … hasta 65534, d = SHA-256(uint16_le(i) ‖ base), con el contador en 2 bytes little-endian delante de base; se desplaza un bit a la derecha el primer byte de d, solo ese byte; y si d, como entero big-endian de 32 bytes, es menor que q, r = d.
Las etiquetas son los bytes ASCII, sin longitud ni terminador. FK_TIME, de 16 bytes, es la file key del fichero `age` de `SEALED_CONTROL`. `testdata/vectors/tlock_steps.json` da cada valor intermedio de cinco stanzas.
### 79.5 Abrir un fichero `age` con su file key
Es la especificación `age` v1 de C2SP (§77), resumida. Un fichero `age` es una cabecera de texto y un payload binario:
```text
age-encryption.org/v1
-> <tipo> <argumentos…>
<cuerpo del stanza en Base64 sin relleno, líneas de 64 caracteres, la última más corta>
--- <MAC en Base64 sin relleno, 43 caracteres>
<payload>
```
Con la file key FK, de 16 bytes:
1. La cabecera: clave_mac = HKDF-SHA256(ikm = FK, salt = vacío, info = `header`), 32 bytes. El MAC es HMAC-SHA256(clave_mac, la cabecera desde `age-encryption.org/v1` hasta `---` inclusive, sin el espacio que lo sigue). Si no coincide con el de la línea `---`, la file key o la cabecera son otras.
2. El payload empieza tras el salto de línea del MAC por un nonce de 16 bytes. clave = HKDF-SHA256(ikm = FK, salt = nonce, info = `payload`), 32 bytes.
3. Lo demás son bloques de ChaCha20-Poly1305 de 65 536 bytes de texto, 65 552 cifrados, el último más corto. El nonce de 12 bytes del bloque n, desde 0, es n en 11 bytes big-endian seguido de 0x01 en el último bloque y de 0x00 en los demás. No hay datos asociados. El último bloque solo puede estar vacío si es el único, y nada sigue al último bloque.
### 79.6 Las capas siguientes
El plaintext de `SEALED_CONTROL` es:
- en `time_only`, `CONTROL_CBOR`;
- en `time_and_key`, otro fichero `age`, `INNER_ACCESS_AGE`, con stanzas X25519, uno por credencial y señuelos hasta 16 en los formatos 2 y 3. Se abre con `age -d -i clave.txt`, con la identity de la credencial en `clave.txt`. La de una `.dkk` es su `access_material`. La `.dkk` empieza por 12 bytes, `DKK1`, `01`, `00`, `00 00` y `BODY_LEN` en 4 bytes big-endian (§40), y le sigue un mapa CBOR cuya clave 5 es ese `access_material`, 32 bytes (§41), y cuya clave 3 es el `capsule_id` de su cápsula. Una llave de palabras da la identity con §38.1.
`CONTROL_CBOR` es un mapa CBOR (§31). Su clave 3 es `I_PAYLOAD`, otra identity X25519 de 32 bytes, y en los formatos 2 y 3 su clave 6 es L, una cadena de 8 bytes con un entero big-endian, no un entero CBOR. Con `I_PAYLOAD`, `age -d -i payload.txt` abre `PAYLOAD_AGE`.
Una identity X25519 de 32 bytes se escribe para `age` en Bech32 (BIP 173, §77), no Bech32m: el prefijo `age-secret-key-`, los 32 bytes reagrupados de 8 en 5 bits con ceros al final, que dan 52 caracteres, y la suma de comprobación de BIP 173, calculada con el prefijo en minúsculas. Después, todo en mayúsculas: `AGE-SECRET-KEY-1…`.
### 79.7 El contenido
El plaintext de `PAYLOAD_AGE` es:
- en formato 1, el contenido entero;
- en formato 2, el contenido en sus L primeros bytes, seguido de ceros;
- en formato 3, `BODY` en sus L primeros bytes, seguido de ceros (§29.2).
`BODY` empieza por tres enteros de 4 bytes big-endian: `AREA_LEN`, `SECURITY_LEN` y `HEAD_LEN`. Siguen el área de `security`, de `AREA_LEN` bytes, que se puede saltar: solo da los veredictos de la firma y del sello (§29.7); el head, un mapa CBOR de `HEAD_LEN` bytes que empieza en 12 + `AREA_LEN`; y los ficheros, desde 12 + `AREA_LEN` + `HEAD_LEN`, el origen de sus desplazamientos.
La clave 5 del head es la lista de ficheros (§29.4). Cada uno es un mapa:
```text
0 → ruta, con "/" entre carpetas
1 → tamaño
2 → start
3 → end
4 → SHA-256 de sus bytes
5 → mtime, en segundos Unix, opcional
```
Sus bytes van de start a end, sin incluir end, contados desde el origen. Las claves 3 y 4 del head son el comentario y el autor declarado: textos del creador que no prueban nada (§29.7). Una ruta que saldría de la carpeta de destino no se escribe.
### 79.8 Lo que el anexo no comprueba
Este anexo comprueba lo que decide que el resultado es el correcto: la firma del release, r·G2 == U, los MAC de cada fichero `age` y el SHA-256 de cada fichero. No comprueba, entre otras cosas, la codificación canónica de cada objeto, `header_binding` (§26), los 16 stanzas de `INNER_ACCESS_AGE` (§39), los ceros del relleno (§29.1) ni las reglas de las rutas (§29.5). Una cápsula que el lector de §63 rechazaría puede abrirse siguiendo este anexo; su contenido es el que sellaron las MAC de `age`, pero no tiene la garantía de un lector conforme.

@ -38,6 +38,17 @@
/// [CmsSigner] and [Sealer]; and what its options take: the X25519
/// recipients and the source of the random values.
///
/// And, with the specification 0.15, the random words of a key of words:
/// the word lists of datekeys-go, which [readWordList] takes only with the
/// SHA-256 that [wordListSha256] pins and checks against the alphabet of
/// their language, the words that [generateWords] draws from one, and their
/// strength in bits, [wordBits]; and the words of five dice each,
/// [diceWords], with the list numbered for dice, [diceList]. And what the
/// official SDK says when it seals: the recovery annex of spec §79 that it
/// saves next to each .dkc, [recoveryAnnex], in a file whose name ends with
/// [recoveryAnnexSuffix], and the state of a pinned profile in the registry
/// of spec §71, [profileStatusOf].
///
/// DER, the primitives, the reading and the writing of age, the recipients
/// and the random sources, agewrap, the curve arithmetic, the IBE of tlock
/// and its stanza, the rules of paths and texts on the Unicode tables, the
@ -48,6 +59,7 @@
library;
export 'src/accesskey.dart';
export 'src/annex.dart';
export 'src/author.dart';
export 'src/authorkey.dart' hide parseAuthorPublicUtf8, parseAuthorSecretUtf8;
export 'src/bls12381_curve.dart'
@ -84,12 +96,26 @@ export 'src/random.dart' show RandomSource, secureRandom;
export 'src/recipient.dart' show X25519Recipient, checkX25519Recipient;
export 'src/release.dart'
show
EncodedRelease,
PinnedProfile,
Release,
ReleaseArchive,
ReleaseSource,
ReleaseSupplier,
decodeRelease,
encodeRelease,
fetchRelease,
maxReleaseJsonSize,
maxReleaseObjectSize,
maxReleaseSignatureLength,
parseRelease,
quicknetScheme,
releaseArchiveSchemaVersion,
releaseArchiveTypeTag,
releaseSchemaVersion,
releaseTypeTag,
suppliedRelease,
supplyRelease,
verifyRelease;
export 'src/security.dart';
export 'src/securitycms.dart';
@ -106,3 +132,18 @@ export 'src/wordkey.dart'
normalizeWords,
wordKey,
wordKeyRounds;
export 'src/wordlist.dart'
show
checkWordList,
defaultWordCount,
diceList,
diceListSize,
diceNumber,
diceWord,
diceWords,
generateWords,
minListSize,
readWordList,
wordBits,
wordListLanguages,
wordListSha256;

@ -0,0 +1,15 @@
/// The recovery annex that the official SDK saves next to each .dkc (spec
/// §62.1, rule 27), as annex.go of datekeys-go: [recoveryAnnex], its text,
/// and [recoveryAnnexSuffix], the end of the name of its file.
///
/// Dart has no go:embed: the text is the constant of recovery_annex.g.dart,
/// which tool/recovery_annex_copy.dart writes from annex/recovery.md, the
/// copy of annex/ of datekeys-go that tool/sync_testdata.dart vendors.
library;
export 'recovery_annex.g.dart' show recoveryAnnex;
/// What the official SDK appends to the name of a .dkc to name the file of
/// its recovery annex, `carta.dkc.recuperacion.txt`, as RecoveryAnnexSuffix
/// of Go. The annex is in Spanish, as the specification.
const recoveryAnnexSuffix = '.recuperacion.txt';

@ -142,9 +142,11 @@ Uint8List h4(List<int> sigma, int n) => _hashTo(n, [_h4Tag, sigma]);
/// H3, the scalar r of [sigma] and [msg]: with base = SHA-256("IBE-H3" ||
/// sigma || msg), the first d = SHA-256(uint16le(i) || base), i = 1, 2, …,
/// whose top bit cleared makes it a big-endian integer below the order of
/// the scalar field. [iterations] bounds i, for tests; after it, the proof
/// fails, as in kyber.
/// that is a big-endian integer below the order of the scalar field once
/// its first byte is shifted one bit to the right, as kyber does (spec §63,
/// "H3 y H4"). The shift moves every bit of that byte: clearing only its
/// top bit gives another r (testdata/vectors/tlock_steps.json). [iterations]
/// bounds i, for tests; after it, the proof fails, as in kyber.
BigInt h3(List<int> sigma, List<int> msg, {int iterations = h3Iterations}) {
final base = _hashTo(32, [_h3Tag, sigma, msg]);
try {

@ -128,6 +128,14 @@ final class CapsuleInfo {
if (d == null || d != dateKey) {
throw _fail('Info.DateKey is not a canonical DateKey');
}
// A writer writes the DateKey of a capsule it wrote: of a profile that
// this library pins, whose chain the check of the locator then compares.
if (d.profileId != quicknetId) {
throw _fail(
'Info.DateKey is of the profile ${goQuote(utf8Bytes(d.profileId))}, '
'which this module does not pin',
);
}
final s = sealed;
if (s != null && (s.isEmpty || s.length > _maxSealed)) {
throw _fail(
@ -241,28 +249,65 @@ CapsuleInfo parseCapsuleInfo(Extension x) {
throw _dataInvalid('compact_datekey is not a canonical DateKey');
}
final s = sealed;
if (s != null && !_sealedFor(s, d.round)) {
throw _dataInvalid(
'the locator is not an age file with one tlock stanza for round '
'${d.round}, the one of its DateKey',
);
if (s != null) {
final problem = _sealedProblem(s, d);
if (problem != null) throw _dataInvalid(problem);
}
return CapsuleInfo(note: note, dateKey: d, sealed: s);
}
// Whether sealed is an age file whose header holds one tlock stanza with two
// arguments, the first of them round.
bool _sealedFor(Uint8List sealed, int round) {
final List<AgeStanza> st;
// checkSealed of Go: why the sealed locator does not have the form of spec
// §44.1, as far as it can be checked before the date, or null. An age file
// with one tlock stanza, whose arguments are the round of the DateKey d in
// decimal and a chain hash in lower-case hexadecimal (§28.1), the chain of
// the profile of d when this library pins it, Quicknet; and a body that
// holds a plaintext of 4096 bytes or a multiple, as every locator has.
String? _sealedProblem(Uint8List sealed, DateKey d) {
List<AgeStanza>? st;
try {
st = ageStanzas(sealed);
} on DateKeysException {
return false;
st = null;
}
if (st == null ||
st.length != 1 ||
st[0].type != stanzaTlock ||
st[0].args.length != 2 ||
st[0].args[0] != '${d.round}') {
return 'the locator is not an age file with one tlock stanza for round '
'${d.round}, the one of its DateKey';
}
final chain = st[0].args[1];
if (!RegExp(r'^[0-9a-f]{64}$').hasMatch(chain)) {
return 'the tlock stanza of the locator has no chain hash in lower-case '
'hexadecimal';
}
return st.length == 1 &&
st[0].type == stanzaTlock &&
st[0].args.length == 2 &&
st[0].args[0] == '$round';
if (d.profileId == quicknetId && chain != quicknetChainHash) {
return 'the locator is sealed for the chain $chain, not for the one of '
'the profile ${d.profileId} of its DateKey';
}
// ageStanzas read the header up to its MAC line, so it ends.
final end = _headerEnd(sealed);
if (end == sealed.length) {
return 'the locator is an age header without a body';
}
if (!_sealedBodyLength(sealed.length - end)) {
return 'the body of the locator is ${sealed.length - end} bytes, which no '
'plaintext of 4096 bytes or a multiple gives';
}
return null;
}
// sealedBodyLength of Go: whether n bytes after the age header are the body
// of a plaintext of 4096·k bytes, k from 1: the nonce of 16 bytes and the
// plaintext in chunks of 64 KiB, each with its tag of 16 bytes.
bool _sealedBodyLength(int n) {
for (var p = locatorBlock; p <= _maxSealed; p += locatorBlock) {
if (n == 16 + p + 16 * ((p + 65535) ~/ 65536)) return true;
}
return false;
}
/// The check of the data of datekeys.capsule that a reader that knows the
@ -536,7 +581,9 @@ String _lowerAscii(String s) => String.fromCharCodes([
void _checkHost(String host) {
if (host.isEmpty) throw _fail('an https address without a host');
if (host.startsWith('[')) {
final a = parseIpAddress(_trimBrackets(host));
// One pair of brackets, as checkHost of Go: "[[2000::]" is not an IPv6
// literal. _splitAuthority ends the literal at its first ']'.
final a = parseIpAddress(host.substring(1, host.length - 1));
if (a == null || !a.is6 || a.zone.isNotEmpty || !isPublicIp(a)) {
throw _fail('an https address with an IPv6 literal that is not public');
}
@ -639,8 +686,9 @@ bool _isCidV1(String s) {
acc &= (1 << bits) - 1;
}
}
// The bits of the last character beyond a byte are zero.
if (acc != 0) return false;
// Canonical base32 without padding: the last character carries fewer than
// 5 bits beyond the last byte, all zero.
if (bits >= 5 || acc != 0) return false;
final version = _uvarint(out, 0);
if (version == null || version.$1 != BigInt.one) return false;
final codec = _uvarint(out, version.$2);
@ -677,11 +725,48 @@ bool _isCidV1(String s) {
/// 2002::/16 and 3fff::/20. An IPv6 address that holds an IPv4 one is not,
/// IPv4-mapped included: an IPv4 address is checked as its 4 bytes.
///
/// Throws a [LocatorException] for an address that is not public, and an
/// [ArgumentError] for any other length. Go has no such function: a reader
/// of the reference does not download.
void checkResolvedIp(List<int> ip) {
/// On an IPv6-only network with DNS64 and NAT64, a name that has only IPv4
/// addresses resolves to an IPv6 address that holds one (RFC 6052): one of
/// the well-known prefix 64:ff9b::/96 is public when the IPv4 address in its
/// last 32 bits is (spec v0.13, §44.1). [nat64] is the NAT64 prefix of the
/// network, in the notation of netip.ParsePrefix (`64:ff9b:1::/48`), which
/// the application discovers with RFC 7050 or its system gives, or null for
/// none: an address in it is public only when the IPv4 address it holds, at
/// the positions of RFC 6052, is, even when the prefix is a public one. The
/// prefix must have one of the lengths of RFC 6052 and lie in 64:ff9b::/16
/// or be a public IPv6 prefix.
///
/// Throws a [LocatorException] for an address that is not public or a
/// prefix that cannot be one of NAT64, with the texts of
/// locator.CheckResolvedIP of Go, and an [ArgumentError] for an address of
/// another length or a prefix that does not parse.
void checkResolvedIp(List<int> ip, {String? nat64}) {
final a = IpAddress.fromBytes(ip);
_Nat64Prefix? network;
if (nat64 != null) {
network = _Nat64Prefix.parse(nat64);
network.check();
}
// The prefixes of NAT64 decide first: the prefix of a network may be a
// public one, and an address in it reaches the IPv4 address it holds,
// which may be private.
for (final p in [_nat64WellKnown, ?network]) {
if (!p.contains(a)) continue;
final v4 = p.ipv4(a);
if (v4 == null) {
throw _fail(
'an https address whose name resolves to $a, an address of the NAT64 '
'prefix $p whose bits 64 to 71 are not zero',
);
}
if (!isPublicIp(v4)) {
throw _fail(
'an https address whose name resolves to $a, an address of NAT64 '
'that holds $v4, an IP address that is not public',
);
}
return;
}
if (!isPublicIp(a)) {
throw _fail(
'an https address whose name resolves to $a, an IP address that is '
@ -690,6 +775,91 @@ void checkResolvedIp(List<int> ip) {
}
}
final _nat64WellKnown = _Nat64Prefix.parse('64:ff9b::/96');
final _nat64Block = _Nat64Prefix.parse('64:ff9b::/16');
// A NAT64 prefix (RFC 6052), as the netip.Prefix that CheckResolvedIP of Go
// receives: the address as written and its length, bits after the length
// kept, so that check can refuse them.
final class _Nat64Prefix {
_Nat64Prefix(this.addr, this.bits);
// netip.ParsePrefix: an address without a zone, '/', and a length in
// decimal without a sign or leading zeros, up to the bits of the address.
factory _Nat64Prefix.parse(String s) {
final slash = s.lastIndexOf('/');
final addr = slash < 0 ? null : parseIpAddress(s.substring(0, slash));
final len = slash < 0 ? '' : s.substring(slash + 1);
final bits = RegExp(r'^(0|[1-9][0-9]{0,2})$').hasMatch(len)
? int.parse(len)
: -1;
if (addr == null ||
addr.zone.isNotEmpty ||
bits < 0 ||
bits > addr.bytes.length * 8) {
throw ArgumentError.value(s, 'nat64', 'not an IP prefix');
}
return _Nat64Prefix(addr, bits);
}
final IpAddress addr;
final int bits;
// netip.Prefix.Contains: an address of the same family, without a zone,
// whose first bits are those of the prefix.
bool contains(IpAddress a) {
final p = addr.bytes;
final b = a.bytes;
if (a.zone.isNotEmpty || b.length != p.length) return false;
for (var i = 0; i < bits; i++) {
final m = 0x80 >> (i & 7);
if ((b[i >> 3] & m) != (p[i >> 3] & m)) return false;
}
return true;
}
// checkNAT64Prefix of Go.
void check() {
final p = addr.bytes;
if (!addr.is6 || addr.is4In6) {
throw _fail('the NAT64 prefix $this is not an IPv6 prefix');
}
for (var i = bits; i < 128; i++) {
if (p[i >> 3] & (0x80 >> (i & 7)) != 0) {
throw _fail('the NAT64 prefix $this has bits set after its length');
}
}
if (!const [32, 40, 48, 56, 64, 96].contains(bits)) {
throw _fail(
'the NAT64 prefix $this is not of 32, 40, 48, 56, 64 or 96 bits '
'(RFC 6052)',
);
}
if (!_nat64Block.contains(addr) && !isPublicIp(addr)) {
throw _fail(
'the NAT64 prefix $this is neither in 64:ff9b::/16 nor a public IPv6 '
'prefix',
);
}
}
// nat64IPv4 of Go: the IPv4 address that [a], an address of this prefix,
// holds at the positions of RFC 6052, section 2.2, the 32 bits after the
// prefix without bits 64 to 71, which must be zero; null if they are not.
IpAddress? ipv4(IpAddress a) {
final b = a.bytes;
if (bits < 96 && b[8] != 0) return null;
final v4 = <int>[];
for (var i = bits >> 3; v4.length < 4; i++) {
if (i != 8) v4.add(b[i]);
}
return IpAddress.fromBytes(v4);
}
@override
String toString() => '$addr/$bits';
}
// ---------------------------------------------------------------------------
// The locator

@ -56,10 +56,12 @@ import 'verdicts.dart';
/// The options of [openCapsule] and [openCapsuleSource], as OpenOptions of
/// Go.
final class OpenOptions {
/// The options of an opening with the release [source] and the clock
/// [now].
/// The options of an opening with the clock [now] and exactly one of the
/// release [source], a network source, and the [release] in the caller's
/// hand.
const OpenOptions({
required this.source,
this.source,
this.release,
required this.now,
this.registry,
this.extensions,
@ -78,11 +80,23 @@ final class OpenOptions {
/// the opening reports ERR_RELEASE_UNAVAILABLE at step 9 when none is
/// valid (see [ReleaseSource]). Whatever it throws is reported at step 9
/// with ERR_RELEASE_UNAVAILABLE as the only code, keeping only its text
/// ([fetchRelease]).
final ReleaseSource source;
/// The clock. No release is requested for a round whose time has not
/// come (spec §63 step 9.c).
/// ([fetchRelease]). Exactly one of [source] and [release] is set.
final ReleaseSource? source;
/// A release that the caller has in hand, the alternative to [source]
/// (spec v0.15, §49, §63 step 9.c): a release object or drand's JSON with
/// [EncodedRelease], or a local archive with [ReleaseArchive]. It makes no
/// network request, so the opening asks it for the release without
/// comparing [now] with the round time, and reports a clock behind it in
/// [Opened.clockBehind]. What it throws is reported at step 9 with
/// ERR_RELEASE_UNAVAILABLE as the only code ([supplyRelease]); the release
/// it supplies is read with [parseRelease] and verified at step 10, with
/// the codes of that step.
final ReleaseSupplier? release;
/// The clock. No release is requested from a [source] for a round whose
/// time has not come (spec §63 step 9.c); a [release] in hand is not
/// compared with it.
final Instant Function() now;
/// The pinned profiles; the default registry, Quicknet, when null.
@ -153,6 +167,7 @@ final class Opened {
required this.error,
required this.refusal,
required this.release,
required this.clockBehind,
required this.payloadLength,
required this.padding,
required this.paddedLength,
@ -177,9 +192,16 @@ final class Opened {
/// caller refused to publish the files. Null otherwise.
final Object? refusal;
/// The release, once verified at step 10.
/// The release, once verified at step 10, with the chain hash of the
/// pinned profile: [encodeRelease] gives its release object.
final Release? release;
/// The release was in the caller's hand ([OpenOptions.release]) and the
/// clock was before the round time of the DateKey: the release proves the
/// round was published, so the clock is probably behind, which a reader
/// may say (spec v0.15, §63 step 9.c).
final bool clockBehind;
/// L, once the capsule opened: the bytes of content written to the output
/// in formats 1 and 2, or the length of BODY in format 3.
final int? payloadLength;
@ -421,6 +443,13 @@ final class _Failed implements Exception {
}
Future<Opened> _open(_Input input, OpenOptions o) async {
if ((o.source == null) == (o.release == null)) {
final e = ArgumentError(
'open: set exactly one of OpenOptions.source and OpenOptions.release',
);
await _abortQuietly(o.output, e);
throw e;
}
if (o.accessKey != null && o.accessKeyFile != null) {
final e = ArgumentError(
'open: set OpenOptions.accessKey or accessKeyFile, not both',
@ -475,6 +504,7 @@ final class _Run {
late List<CheckResult> _checks;
late Inspection _inspection;
Release? _release;
bool _clockBehind = false;
int? _payloadLength;
PaddingRule? _padding;
int? _paddedLength;
@ -509,6 +539,7 @@ final class _Run {
error: error,
refusal: _refusal,
release: _release,
clockBehind: _clockBehind,
payloadLength: error == null && _refusal == null ? _payloadLength : null,
padding: _padding,
paddedLength: _paddedLength,
@ -629,37 +660,67 @@ final class _Run {
);
}
// Step 9.c and the release, never before its round time. A network
// source has verified each response with the rules of step 10 and
// discarded the invalid ones; whatever the failure of the source, it is
// Step 9.c and the release. A network source is never asked before the
// round time; a release in hand is not compared with the clock, whose
// being behind it is only reported (spec v0.15). A network source has
// verified each response with the rules of step 10 and discarded the
// invalid ones; whatever the failure of the source, it is
// ERR_RELEASE_UNAVAILABLE here.
final unlock = _inspection.unlockAt!;
final now = o.now();
if (compareInstants(now, unlock) < 0) {
throw _fail(
Release release;
final supplier = o.release;
if (supplier != null) {
final Uint8List encoded;
try {
encoded = await supplyRelease(supplier, p, round);
} on DateKeysException catch (e) {
throw _fail(9, 'release', e);
}
_clockBehind = compareInstants(now, unlock) < 0;
_pass(
9,
'release',
DateKeysException(
ErrorCode.releaseUnavailable,
'capsule: round $round is published at ${formatRfc3339(unlock)}, it '
'is ${formatRfc3339(now)}',
),
_clockBehind
? 'release supplied by the caller; round $round is published at '
'${formatRfc3339(unlock)} and the clock says '
'${formatRfc3339(now)}: it may be behind'
: 'release supplied by the caller',
);
// Step 10 starts with the layers of the release object.
try {
release = parseRelease(encoded);
} on DateKeysException catch (e) {
throw _fail(10, 'release verification', e);
}
} else {
if (compareInstants(now, unlock) < 0) {
throw _fail(
9,
'release',
DateKeysException(
ErrorCode.releaseUnavailable,
'capsule: round $round is published at ${formatRfc3339(unlock)}, '
'it is ${formatRfc3339(now)}',
),
);
}
try {
release = await fetchRelease(o.source!, p, round);
} on DateKeysException catch (e) {
throw _fail(9, 'release', e);
}
_pass(9, 'release', 'round ${release.round} obtained');
}
final Release release;
try {
release = await fetchRelease(o.source, p, round);
} on DateKeysException catch (e) {
throw _fail(9, 'release', e);
}
_pass(9, 'release', 'round ${release.round} obtained');
// Step 10: verify the release locally.
// Step 10: verify the release locally: the chain it names, its round
// and its signature.
try {
verifyRelease(p, round, release);
} on DateKeysException catch (e) {
throw _fail(10, 'release verification', e);
}
release = Release(release.round, release.signature, chainHash: p.chainHash);
_release = release;
_pass(
10,

@ -1,8 +1,9 @@
/// Provider Profiles (spec §10 to §13), as package profile of datekeys-go and
/// profile.ts of datekeys-ts: their Deterministic CBOR, profile_hash, their
/// validation by the rules of spec §12.1 in their order, with the codes and
/// texts of Go, and the registry of pinned profiles that is the root of
/// trust (spec §13).
/// texts of Go, the registry of pinned profiles that is the root of trust
/// (spec §13), and the state of a pinned profile in the registry of profiles
/// of DateKeys (spec §71).
library;
import 'dart:typed_data';
@ -424,9 +425,10 @@ Profile _profileOf(_Wire w) => Profile(
/// that is not 32 bytes;
/// 2. the rules of each field (ERR_UNKNOWN_PROFILE): the alphabets of the
/// names and their lengths, the length of the public key, a genesis time
/// in 1..253402300798, the provider drand, a scheme that tlock supports
/// and a public key that is the canonical encoding of a point of the key
/// group of the scheme other than the point at infinity;
/// in 1..253402300798, the provider drand, the scheme
/// bls-unchained-g1-rfc9380, the only one since spec v0.14, and a public
/// key that is the canonical encoding of a point of G2 other than the
/// point at infinity;
/// 3. the check of the chain hash (ERR_PROFILE_MISMATCH): it is the hash of
/// the drand chain information of the other parameters.
void validateProfile(Profile p) {
@ -476,31 +478,31 @@ void validateProfile(Profile p) {
_validateDrand(p);
}
// The key group of each drand scheme that tlock supports; the other schemes
// that drand knows are refused, and any other name is not a drand scheme,
// as SchemeFromName of drand v2.1.7 and the switch of validateDrand of Go.
const _tlockSchemes = {
'bls-unchained-g1-rfc9380': BlsGroup.g2,
'pedersen-bls-unchained': BlsGroup.g1,
'bls-unchained-on-g1': BlsGroup.g2,
};
const _otherDrandSchemes = {
// The schemes that drand knows, as SchemeFromName of drand v2.1.7: any other
// name is not a drand scheme. Of them, spec §12.1 admits since v0.14 only
// bls-unchained-g1-rfc9380, whose public key is in G2, the one scheme whose
// release and tlock decryption the specification writes byte for byte, as
// validateDrand of Go.
const _drandSchemes = {
'pedersen-bls-chained',
'pedersen-bls-unchained',
'bls-unchained-on-g1',
'bls-unchained-g1-rfc9380',
'bls-bn254-unchained-on-g1',
};
void _validateDrand(Profile p) {
final scheme = goQuote(utf8Bytes(p.scheme));
final group = _tlockSchemes[p.scheme];
if (group == null) {
if (_otherDrandSchemes.contains(p.scheme)) {
throw _unknown(
'profile ${p.id}: scheme $scheme is not supported by tlock',
);
}
if (!_drandSchemes.contains(p.scheme)) {
throw _unknown('profile ${p.id}: $scheme is not a drand scheme');
}
final verdict = checkCompressedPoint(group, p.publicKey);
if (p.scheme != quicknetScheme) {
throw _unknown(
'profile ${p.id}: scheme $scheme is not $quicknetScheme, the only '
'scheme of V1',
);
}
final verdict = checkCompressedPoint(BlsGroup.g2, p.publicKey);
if (verdict == PointVerdict.invalid) {
throw _unknown(
'profile ${p.id}: public key is not the canonical encoding of a point '
@ -683,3 +685,43 @@ ProfileRegistry defaultRegistry() {
}
return _default = newRegistry([Pin(q, fromHex(quicknetProfileHash))]);
}
// ---------------------------------------------------------------------------
// The state of a profile (spec §71)
/// The state of a Provider Profile in the registry of profiles of DateKeys
/// (spec §71), as Status of the profile package of Go.
enum ProfileStatus {
/// Capsules are written and opened with the profile.
active('active'),
/// No new capsule is written with the profile, because its provider
/// announces its end or is suspected; the capsules that exist still open.
readOnly('read-only'),
/// There is proof that the confidentiality of the profile failed. The
/// capsules that exist still open, and the official SDK warns that their
/// content may have been read before their date.
compromised('compromised');
const ProfileStatus(this.label);
/// The name of Go's Status.String: active, read-only or compromised.
final String label;
@override
String toString() => label;
}
// The states of the profiles that this release of the library pins, by
// profile_hash, as statuses of Go: DateKeys does not publish the signed
// registry of spec §71 yet, so a change of state comes with a new release.
const _statuses = {quicknetProfileHash: ProfileStatus.active};
/// The state of the profile whose profile_hash is [hash], and whether this
/// release of the library knows it, as StatusOf of Go. A profile it does not
/// know is [ProfileStatus.active], the zero Status of Go, and not known.
({ProfileStatus status, bool known}) profileStatusOf(List<int> hash) {
final status = _statuses[toHex(hash)];
return (status: status ?? ProfileStatus.active, known: status != null);
}

@ -0,0 +1,180 @@
// Generated by tool/recovery_annex_copy.dart from annex/recovery.md,
// the recovery annex of datekeys-go. Do not edit: sync annex/ and run
// the tool again.
/// The text that the official SDK saves next to each .dkc (spec §62.1,
/// rule 27), as RecoveryAnnex of datekeys-go: the informative annex of
/// the specification on how to open a capsule without DateKeys software
/// (spec §79), in Spanish, under a title that names the version of the
/// specification and the SHA-256 of its text. It is the same for every
/// capsule and holds nothing of one. Its UTF-8 bytes are
/// annex/recovery.md of the Go reference, which checks it against §79 of
/// its specification; the official SDK writes them as they are, to the
/// name of the .dkc followed by recoveryAnnexSuffix.
const recoveryAnnex = '''
# Cómo abrir una cápsula DateKeys sin software de DateKeys
Este texto acompaña a una cápsula del tiempo de DateKeys, un fichero `.dkc`: dice cómo abrirla, llegada su fecha, sin ningún software de DateKeys, por si ya no existe. Es el anexo informativo §79 de la especificación del protocolo DateKeys v0.15, cuyo texto tiene el SHA-256 45105e693be4187af4dd30f4d254402612587b6427c746f5d29f07a541c1e3f3. Es el mismo para toda cápsula: no lleva ningún dato de esta.
## 79. Anexo informativo: recuperación sin software DateKeys
Este anexo no es normativo. Dice cómo abrir una cápsula de Quicknet sin ningún software de DateKeys, por si dentro de décadas no existe. Repite lo que fijan las secciones que cita, que deciden en caso de duda.
La regla 27 de §62.1 recomienda al SDK oficial guardar este anexo junto al `.dkc`. No contiene ningún dato de una cápsula.
Hace falta:
- el `.dkc`;
- el release de su ronda, de cualquier fuente: un relay de drand, un archivo de releases, un servicio de caché (§50) o cualquier copia. No hace falta confiar en quien lo da: se verifica con la clave pública de 79.1 (79.3);
- en `time_and_key`, una credencial: la `.dkk`, la identity `age` de un recipient o las palabras de una llave de palabras (§38.1);
- una librería de BLS12-381 con pairing y con el hash a G1 de RFC 9380, SHA-256, HMAC-SHA256, HKDF-SHA256 (RFC 5869), ChaCha20-Poly1305 (RFC 8439), un decodificador de CBOR y la herramienta `age` (§77) o una librería compatible.
No sirven las herramientas de drand: `tle` pide el release a la red y no acepta uno dado, y `age` no acepta una file key, que es lo que da el stanza tlock (79.4). Por eso este anexo describe esos dos pasos enteros (79.4 y 79.5).
La implementación de referencia lo sigue en `scripts/recovery`, un programa que no importa ningún paquete de DateKeys, tlock ni drand: solo la librería estándar de Go, `golang.org/x/crypto`, `filippo.io/age` y la librería BLS12-381 `drand/kyber-bls12381`. `scripts/recovery_check.sh` abre con él una cápsula `time_only` y otra `time_and_key` de los fixtures oficiales.
### 79.1 Parámetros de Quicknet
Son los de §12, y pueden no estar ya en ningún otro sitio:
```text
chain_hash 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971
clave pública (G2, 96 bytes)
83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c
8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb
5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a
genesis_time 1692803367 (segundos Unix de la ronda 1)
period 3 segundos
round_time(r) = genesis_time + (r − 1)·3
q 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001
DST BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_NUL_
```
Los puntos se codifican comprimidos, en el formato de ZCash (§12.2): 48 bytes en G1, la firma, y 96 en G2, la clave pública y U, con la coordenada c1 antes que c0.
### 79.2 La cápsula
El `.dkc` empieza por 16 bytes (§22):
```text
0 4 "DKC1"
4 1 VERSION: el formato, 1, 2 o 3
5 1 0
6 2 0
8 4 PUBLIC_HEADER_LEN, entero big-endian
12 4 SEALED_CONTROL_LEN, entero big-endian
```
Le siguen `PUBLIC_HEADER`, de `PUBLIC_HEADER_LEN` bytes; `SEALED_CONTROL`, de `SEALED_CONTROL_LEN` bytes; y `PAYLOAD_AGE`, desde el byte 16 + `PUBLIC_HEADER_LEN` + `SEALED_CONTROL_LEN` hasta el final del fichero.
`PUBLIC_HEADER` es un mapa CBOR (§24). Su clave 2 es `capsule_id`, 16 bytes; su clave 4, la política, 0 para `time_only` y 1 para `time_and_key`; y su clave 3, la DateKey, un texto `dk1_` seguido del Base64URL sin relleno de un JSON (§18):
```json
{"version":1,"network":"datekeys:quicknet:v1","round":1000}
```
`round` es la ronda de la cápsula.
### 79.3 El release
Un objeto release es un mapa CBOR (§47.1): la clave 0 es `"datekeys-release"`; la 2, el `chain_hash`, que ha de ser el de 79.1; la 3, la ronda, que ha de ser la de la DateKey; y la 4, la firma, de 48 bytes. Así lo sirven la Release API y un servicio de caché. En un archivo de releases (§50), la firma de la ronda r son los 48 bytes que empiezan en |cabecera| + (r − primera ronda)·48, y 48 ceros si el archivo no la tiene. Un relay de drand la entrega como JSON, `{"round": …, "signature": "…"}`, con la firma en hexadecimal. Hoy se pide así, aunque las direcciones pueden cambiar:
```text
GET https://api.drand.sh/v2/chains/<chain_hash>/rounds/<ronda>
```
La firma no necesita confianza: se verifica (§63, paso 10). Con M el SHA-256 de la ronda en 8 bytes big-endian, y H el hash a G1 de RFC 9380 con la suite `BLS12381G1_XMD:SHA-256_SSWU_RO_` y el DST de 79.1:
```text
e(H(M), clave_pública) == e(firma, G2)
```
con e el pairing de G1 × G2, el primer argumento en G1 y el segundo en G2, y G2 el generador de G2. La firma y la clave pública se decodifican como puntos comprimidos válidos del subgrupo, distintos del punto en el infinito. Para una ronda solo hay una firma válida: cualquier copia que verifique es el release.
### 79.4 El stanza tlock y FK_TIME
`SEALED_CONTROL` es un fichero `age` (79.5) cuya cabecera tiene un solo stanza:
```text
-> tlock <ronda en decimal> <chain_hash en hexadecimal en minúsculas>
<cuerpo en Base64 estándar sin relleno, en líneas de 64 caracteres>
```
El cuerpo mide 128 bytes, U ‖ V ‖ W: U, de 96 bytes, un punto de G2, y V y W, de 16 bytes. Con la firma del release (§63, paso 11):
```text
sigma = V XOR H2(e(firma, U))
FK_TIME = W XOR H4(sigma)
r = H3(sigma, FK_TIME)
comprobar r·G2 == U
```
- H2(x) son los 16 primeros bytes de SHA-256(`IBE-H2` ‖ x), con x los 576 bytes del elemento de GT en el orden de §63, «Serialización de GT en H2»: c1 antes que c0 en cada nivel de la torre, y c2, c1, c0 en Fp6, cada elemento de Fp en 48 bytes big-endian. Una librería que serializa con c0 primero da otro H2. El vector de `testdata/vectors/tlock_ibe.json` lo comprueba: H2(e(G1, G2)) = `cb87319f24560b5231579a09ad79f12e`, con G1 y G2 los generadores.
- H4(sigma) son los 16 primeros bytes de SHA-256(`IBE-H4` ‖ sigma).
- H3(sigma, FK_TIME): base = SHA-256(`IBE-H3` ‖ sigma ‖ FK_TIME); para i = 1, 2, … hasta 65534, d = SHA-256(uint16_le(i) ‖ base), con el contador en 2 bytes little-endian delante de base; se desplaza un bit a la derecha el primer byte de d, solo ese byte; y si d, como entero big-endian de 32 bytes, es menor que q, r = d.
Las etiquetas son los bytes ASCII, sin longitud ni terminador. FK_TIME, de 16 bytes, es la file key del fichero `age` de `SEALED_CONTROL`. `testdata/vectors/tlock_steps.json` da cada valor intermedio de cinco stanzas.
### 79.5 Abrir un fichero `age` con su file key
Es la especificación `age` v1 de C2SP (§77), resumida. Un fichero `age` es una cabecera de texto y un payload binario:
```text
age-encryption.org/v1
-> <tipo> <argumentos…>
<cuerpo del stanza en Base64 sin relleno, líneas de 64 caracteres, la última más corta>
--- <MAC en Base64 sin relleno, 43 caracteres>
<payload>
```
Con la file key FK, de 16 bytes:
1. La cabecera: clave_mac = HKDF-SHA256(ikm = FK, salt = vacío, info = `header`), 32 bytes. El MAC es HMAC-SHA256(clave_mac, la cabecera desde `age-encryption.org/v1` hasta `---` inclusive, sin el espacio que lo sigue). Si no coincide con el de la línea `---`, la file key o la cabecera son otras.
2. El payload empieza tras el salto de línea del MAC por un nonce de 16 bytes. clave = HKDF-SHA256(ikm = FK, salt = nonce, info = `payload`), 32 bytes.
3. Lo demás son bloques de ChaCha20-Poly1305 de 65 536 bytes de texto, 65 552 cifrados, el último más corto. El nonce de 12 bytes del bloque n, desde 0, es n en 11 bytes big-endian seguido de 0x01 en el último bloque y de 0x00 en los demás. No hay datos asociados. El último bloque solo puede estar vacío si es el único, y nada sigue al último bloque.
### 79.6 Las capas siguientes
El plaintext de `SEALED_CONTROL` es:
- en `time_only`, `CONTROL_CBOR`;
- en `time_and_key`, otro fichero `age`, `INNER_ACCESS_AGE`, con stanzas X25519, uno por credencial y señuelos hasta 16 en los formatos 2 y 3. Se abre con `age -d -i clave.txt`, con la identity de la credencial en `clave.txt`. La de una `.dkk` es su `access_material`. La `.dkk` empieza por 12 bytes, `DKK1`, `01`, `00`, `00 00` y `BODY_LEN` en 4 bytes big-endian (§40), y le sigue un mapa CBOR cuya clave 5 es ese `access_material`, 32 bytes (§41), y cuya clave 3 es el `capsule_id` de su cápsula. Una llave de palabras da la identity con §38.1.
`CONTROL_CBOR` es un mapa CBOR (§31). Su clave 3 es `I_PAYLOAD`, otra identity X25519 de 32 bytes, y en los formatos 2 y 3 su clave 6 es L, una cadena de 8 bytes con un entero big-endian, no un entero CBOR. Con `I_PAYLOAD`, `age -d -i payload.txt` abre `PAYLOAD_AGE`.
Una identity X25519 de 32 bytes se escribe para `age` en Bech32 (BIP 173, §77), no Bech32m: el prefijo `age-secret-key-`, los 32 bytes reagrupados de 8 en 5 bits con ceros al final, que dan 52 caracteres, y la suma de comprobación de BIP 173, calculada con el prefijo en minúsculas. Después, todo en mayúsculas: `AGE-SECRET-KEY-1…`.
### 79.7 El contenido
El plaintext de `PAYLOAD_AGE` es:
- en formato 1, el contenido entero;
- en formato 2, el contenido en sus L primeros bytes, seguido de ceros;
- en formato 3, `BODY` en sus L primeros bytes, seguido de ceros (§29.2).
`BODY` empieza por tres enteros de 4 bytes big-endian: `AREA_LEN`, `SECURITY_LEN` y `HEAD_LEN`. Siguen el área de `security`, de `AREA_LEN` bytes, que se puede saltar: solo da los veredictos de la firma y del sello (§29.7); el head, un mapa CBOR de `HEAD_LEN` bytes que empieza en 12 + `AREA_LEN`; y los ficheros, desde 12 + `AREA_LEN` + `HEAD_LEN`, el origen de sus desplazamientos.
La clave 5 del head es la lista de ficheros (§29.4). Cada uno es un mapa:
```text
0 → ruta, con "/" entre carpetas
1 → tamaño
2 → start
3 → end
4 → SHA-256 de sus bytes
5 → mtime, en segundos Unix, opcional
```
Sus bytes van de start a end, sin incluir end, contados desde el origen. Las claves 3 y 4 del head son el comentario y el autor declarado: textos del creador que no prueban nada (§29.7). Una ruta que saldría de la carpeta de destino no se escribe.
### 79.8 Lo que el anexo no comprueba
Este anexo comprueba lo que decide que el resultado es el correcto: la firma del release, r·G2 == U, los MAC de cada fichero `age` y el SHA-256 de cada fichero. No comprueba, entre otras cosas, la codificación canónica de cada objeto, `header_binding` (§26), los 16 stanzas de `INNER_ACCESS_AGE` (§39), los ceros del relleno (§29.1) ni las reglas de las rutas (§29.5). Una cápsula que el lector de §63 rechazaría puede abrirse siguiendo este anexo; su contenido es el que sellaron las MAC de `age`, pero no tiene la garantía de un lector conforme.
''';
/// The SHA-256 of the UTF-8 bytes of [recoveryAnnex], for the tests
/// that run compiled to JavaScript, where no file can be read.
///
/// Internal: lib/datekeys.dart does not export it.
const recoveryAnnexSha256 =
'c8c9b8815708d963ca6a3d688003bdc5046c499ab034a2d8c98a18c9811d3bd3';

@ -1,9 +1,14 @@
/// Releases (spec §45 to §52): their local verification, provider.Verify of
/// the Go reference (spec §17, §51, §63 step 10), and the sources that
/// deliver them (provider.ReleaseSource), as release.ts of datekeys-ts.
/// the Go reference (spec §17, §51, §63 step 10), the sources that deliver
/// them (provider.ReleaseSource), as release.ts of datekeys-ts, and, since
/// spec v0.15, the release object (§47.1), drand's JSON as an input of the
/// caller, a release in the caller's hand (provider.Supplier) and the lookup
/// of a local release archive (§50).
///
/// [verifyRelease] checks, in the order of the reference and with its
/// texts: the round against the range of the profile (ERR_DATEKEY_INVALID);
/// the chain hash that the release names, if any, against the pinned profile
/// (ERR_PROFILE_MISMATCH, spec v0.15);
/// the round of the release against the expected one (ERR_ROUND_MISMATCH),
/// before the signature; the length of the signature; the pinned public key
/// (ERR_UNKNOWN_PROFILE if it is not the canonical encoding of a point); and
@ -22,14 +27,19 @@
/// public, the signature of a round once drand publishes it.
library;
import 'dart:convert';
import 'dart:typed_data';
import 'bls12381_curve.dart';
import 'bls12381_hash.dart';
import 'bls12381_pairing.dart';
import 'bytes.dart';
import 'cbor.dart';
import 'errors.dart';
import 'ibe.dart';
import 'schema.dart';
import 'sha256.dart';
import 'source.dart';
/// The drand scheme of Quicknet, the only one this library verifies.
const quicknetScheme = 'bls-unchained-g1-rfc9380';
@ -59,15 +69,22 @@ abstract interface class PinnedProfile {
/// The material that satisfies a round: for drand, the BLS signature of the
/// round.
final class Release {
/// The release of [round] with [signature], which it copies.
Release(this.round, List<int> signature)
: signature = Uint8List.fromList(signature);
/// The release of [round] with [signature], which it copies, and the
/// chain it names, [chainHash], which it copies too.
Release(this.round, List<int> signature, {List<int>? chainHash})
: signature = Uint8List.fromList(signature),
chainHash = chainHash == null ? null : Uint8List.fromList(chainHash);
/// The round.
final int round;
/// The compressed signature of the round.
final Uint8List signature;
/// The chain the release names, key 2 of a release object (spec v0.15,
/// §47.1), or null when it names none, as the answer of a relay and
/// drand's JSON. [verifyRelease] compares it with the pinned profile.
final Uint8List? chainHash;
}
/// Verifies a release of [round] locally against the pinned profile [p], as
@ -86,6 +103,14 @@ G1Point verifiedSignature(PinnedProfile p, int round, Release r) {
'provider: round $round outside the range of ${p.id}',
);
}
final chain = r.chainHash;
if (chain != null && !equalBytes(chain, p.chainHash)) {
throw DateKeysException(
ErrorCode.profileMismatch,
'provider: release of chain ${toHex(chain)}, the pinned profile '
'${p.id} is chain ${toHex(p.chainHash)}',
);
}
if (r.round != round) {
throw DateKeysException(
ErrorCode.roundMismatch,
@ -194,10 +219,12 @@ abstract interface class ReleaseSource {
Future<Release> fetch(PinnedProfile p, int round);
}
/// The source of a release that the caller supplies directly, as the
/// official vectors do: it hands [release] over for any round, unverified,
/// so that step 10 checks it; without a release, it has none to give
/// (ERR_RELEASE_UNAVAILABLE).
/// A source that hands [release] over for any round, unverified, so that
/// step 10 checks it; without a release, it has none to give
/// (ERR_RELEASE_UNAVAILABLE). It is a [ReleaseSource], so the opening does
/// not ask it before the round time; a release in the caller's hand, which
/// is not compared with the clock (spec v0.15, §63 step 9.c), is a
/// [ReleaseSupplier] such as [EncodedRelease], given as OpenOptions.release.
ReleaseSource suppliedRelease([Release? release]) => _Supplied(release);
final class _Supplied implements ReleaseSource {
@ -228,9 +255,14 @@ Future<Release> fetchRelease(
ReleaseSource source,
PinnedProfile p,
int round,
) async {
) => _step9(() => source.fetch(p, round));
// Whatever [body] throws, as sourceFailure of capsule.Open: a
// DateKeysException of ERR_RELEASE_UNAVAILABLE as it is, anything else as
// text only.
Future<T> _step9<T>(Future<T> Function() body) async {
try {
return await source.fetch(p, round);
return await body();
} on Object catch (e, stack) {
if (e is DateKeysException && e.code == ErrorCode.releaseUnavailable) {
rethrow;
@ -244,3 +276,709 @@ Future<Release> fetchRelease(
);
}
}
// ---------------------------------------------------------------------------
// The release object (spec v0.15, §47.1)
/// The type tag of the release object.
const releaseTypeTag = 'datekeys-release';
/// The schema version of the release object.
const releaseSchemaVersion = 1;
/// The largest release object a reader decodes, in bytes (spec v0.15,
/// §47.1): the object has no frame, so a larger input is rejected before it
/// is decoded, with ERR_NON_CANONICAL_CBOR. No valid encoding comes close.
const maxReleaseObjectSize = 1024;
/// The longest signature of a release object: a compressed point of G2.
/// Quicknet signs with 48 bytes, a point of G1.
const maxReleaseSignatureLength = 96;
/// The largest drand JSON that [parseRelease] reads, in bytes, the bound of
/// a relay response in provider/drand of Go.
const maxReleaseJsonSize = 8 << 10;
// The keys of the release object, all required.
const _releaseKeys = 5;
void _encodeReleaseWire(CborEncoder e, Release r) {
e
..map(_releaseKeys)
..uint(0)
..text(releaseTypeTag)
..uint(1)
..uint(releaseSchemaVersion)
..uint(2)
..bstr(r.chainHash!)
..uint(3)
..uint(r.round)
..uint(4)
..bstr(r.signature);
}
DateKeysException _nonCanonical(String context) =>
DateKeysException(ErrorCode.nonCanonicalCbor, context);
// Reads the map with every CDDL rule of the release object, all of them
// ERR_NON_CANONICAL_CBOR: what each field means against the pinned profile
// and the DateKey is checked by verifyRelease, at step 10.
Release _decodeReleaseWire(CborDecoder d) {
final pairs = d.map(_releaseKeys);
if (pairs != _releaseKeys) {
throw _nonCanonical('$pairs keys, want all $_releaseKeys');
}
late Uint8List chainHash;
late int round;
late Uint8List signature;
for (var want = 0; want < _releaseKeys; want++) {
final k = d.key();
if (k != want) throw _nonCanonical('key $k where key $want was expected');
inKey(k, () {
switch (want) {
case 0:
d.text(releaseTypeTag.length);
case 1:
d.uint(releaseSchemaVersion);
case 2:
chainHash = d.bstr(32, 32);
case 3:
round = d.uint();
if (round == 0) throw _nonCanonical('round 0');
default:
signature = d.bstr(1, maxReleaseSignatureLength);
}
});
}
d.endMap();
return Release(round, signature, chainHash: chainHash);
}
/// The release object of [r], its chain hash, its round and its signature
/// (spec v0.15, §47.1), as EncodeRelease of Go. It does not verify the
/// release: [verifyRelease] does, against the pinned profile. A chain hash
/// other than 32 bytes, a round outside 1..2^53-1 or a signature outside
/// 1..96 bytes is ERR_NON_CANONICAL_CBOR.
Uint8List encodeRelease(Release r) {
final chain = r.chainHash;
if (chain == null || chain.length != 32) {
throw _nonCanonical(
'provider: release object: chain hash of ${chain?.length ?? 0} bytes, '
'want 32',
);
}
if (r.round < 1 || r.round > maxSafeUint) {
throw _nonCanonical(
'provider: release object: round ${r.round} outside 1..$maxSafeUint',
);
}
if (r.signature.isEmpty || r.signature.length > maxReleaseSignatureLength) {
throw _nonCanonical(
'provider: release object: signature of ${r.signature.length} bytes '
'outside 1..$maxReleaseSignatureLength',
);
}
final e = CborEncoder();
_encodeReleaseWire(e, r);
return e.out();
}
/// Decodes a release object (spec v0.15, §47.1) with the layers of spec
/// §69.1 that it has, as DecodeRelease of Go: its size, 1 to
/// [maxReleaseObjectSize] bytes; its type and schema version
/// (ERR_NON_CANONICAL_CBOR, then ERR_UNSUPPORTED_VERSION); its encoding and
/// schema (ERR_NON_CANONICAL_CBOR). The release names its chain, which
/// [verifyRelease] checks against the pinned profile at step 10, before the
/// round and the signature.
Release decodeRelease(List<int> b) {
if (b.isEmpty || b.length > maxReleaseObjectSize) {
throw _nonCanonical(
'provider: release object of ${b.length} bytes, outside '
'1..$maxReleaseObjectSize',
);
}
return withContext('provider: release object', () {
checkSchema(b, releaseTypeTag, releaseSchemaVersion);
late Release r;
unmarshalCbor(
b,
(d) => r = _decodeReleaseWire(d),
(e) => _encodeReleaseWire(e, r),
);
return r;
});
}
/// Reads a release that the caller supplies, as ParseRelease of Go: drand's
/// JSON when its first byte other than a JSON space is `{`, or else a
/// release object, with [decodeRelease].
///
/// drand's JSON is the answer of a relay, `{"round": …, "signature": "…"}`,
/// with an optional `randomness` that must be the SHA-256 of the signature,
/// in hexadecimal; other fields are ignored. It does not name its chain, so
/// the release has no chain hash. Any failure to read it, and an input of
/// more than [maxReleaseJsonSize] bytes, is ERR_RELEASE_INVALID. It is an
/// input, never written.
Release parseRelease(List<int> b) {
for (final c in b) {
if (c == 0x20 || c == 0x09 || c == 0x0d || c == 0x0a) continue;
if (c == 0x7b) return _parseDrandJson(b);
break;
}
return decodeRelease(b);
}
DateKeysException _invalidJson(String context) =>
DateKeysException(ErrorCode.releaseInvalid, 'provider: drand JSON$context');
// The name of a JSON key as encoding/json of Go matches it with the name of
// a field: without case, with the two letters of Unicode that fold to an
// ASCII letter of these names, the long s and the Kelvin sign.
String _foldKey(String k) => k
.replaceAll(String.fromCharCode(0x017f), 's')
.replaceAll(String.fromCharCode(0x212a), 'k')
.toLowerCase();
// Reads the JSON of a drand relay, as parseDrandJSON of Go, with the rules
// of encoding/json for its three fields: keys without case, the last one
// wins, null unsets round and signature and leaves randomness as it is, a
// value of another type is an error, and round is an unsigned integer
// written as such, without a sign, a fraction or an exponent. Its own reader
// ([_GoJson]), because jsonDecode of Dart does not keep how a number is
// written, and on the web reads 1000.0 as the int 1000.
Release _parseDrandJson(List<int> b) {
if (b.length > maxReleaseJsonSize) {
throw _invalidJson(
' of ${b.length} bytes, larger than $maxReleaseJsonSize',
);
}
final malformed = _invalidJson(': malformed, or without round or signature');
final List<(String, _JsonValue)> fields;
try {
fields = _GoJson(b).topObject();
} on FormatException {
throw malformed;
}
String? round;
String? signature;
var randomness = '';
var typeError = false;
for (final (key, value) in fields) {
switch (key) {
case 'round':
if (value.isNull) {
round = null;
} else if (value.number != null &&
RegExp(r'^(0|[1-9][0-9]*)$').hasMatch(value.number!)) {
round = value.number;
} else {
typeError = true;
}
case 'signature':
if (value.isNull) {
signature = null;
} else if (value.string != null) {
signature = value.string;
} else {
typeError = true;
}
case 'randomness':
if (value.string != null) {
randomness = value.string!;
} else if (!value.isNull) {
typeError = true;
}
}
}
if (typeError || round == null || signature == null) throw malformed;
// A round above 2^53-1 does not fit an int on every platform: it is an
// unsigned integer of Go up to 2^64-1, and no DateKey has it (spec §58).
final wide = BigInt.parse(round);
if (wide > maxUint64) throw malformed;
if (wide > BigInt.from(maxSafeUint)) {
throw _invalidJson(
': round $round above $maxSafeUint, the largest round of a DateKey',
);
}
final Uint8List sig;
try {
sig = fromHex(signature);
} on FormatException {
throw _invalidJson(': signature is not hex');
}
if (randomness.isNotEmpty && randomness.toLowerCase() != toHex(sha256(sig))) {
throw _invalidJson(': randomness does not match the signature');
}
return Release(wide.toInt(), sig);
}
// A value of the drand JSON that [_parseDrandJson] reads: null, a string, the
// literal of a number, or anything else (a boolean, an array or an object).
final class _JsonValue {
const _JsonValue({this.isNull = false, this.string, this.number});
final bool isNull;
final String? string;
final String? number;
}
// A reader of JSON with the syntax that encoding/json of Go accepts (RFC
// 8259, with invalid UTF-8 in strings read as U+FFFD): the members of the top
// object whose names fold to round, signature or randomness, in order, each
// one that appears, as Go sets them one after another. It
// throws a FormatException for anything else than one object between JSON
// spaces.
final class _GoJson {
_GoJson(this._b);
final List<int> _b;
int _i = 0;
Never _bad() => throw const FormatException('malformed JSON');
void _space() {
while (_i < _b.length) {
final c = _b[_i];
if (c != 0x20 && c != 0x09 && c != 0x0a && c != 0x0d) return;
_i++;
}
}
int _peek() => _i < _b.length ? _b[_i] : -1;
void _expect(int c) {
if (_peek() != c) _bad();
_i++;
}
List<(String, _JsonValue)> topObject() {
_space();
final out = <(String, _JsonValue)>[];
_object(out);
_space();
if (_i != _b.length) _bad();
return out;
}
// Reads an object; with [out], keeps its members of the three names.
void _object([List<(String, _JsonValue)>? out]) {
_expect(0x7b);
_space();
if (_peek() == 0x7d) {
_i++;
return;
}
for (;;) {
_space();
final name = _string();
_space();
_expect(0x3a);
_space();
final v = _value();
if (out != null) {
final k = _foldKey(name);
if (k == 'round' || k == 'signature' || k == 'randomness') {
// In the order of the input: Go sets each in turn.
out.add((k, v));
}
}
_space();
if (_peek() == 0x2c) {
_i++;
continue;
}
_expect(0x7d);
return;
}
}
void _array() {
_expect(0x5b);
_space();
if (_peek() == 0x5d) {
_i++;
return;
}
for (;;) {
_space();
_value();
_space();
if (_peek() == 0x2c) {
_i++;
continue;
}
_expect(0x5d);
return;
}
}
_JsonValue _value() {
final c = _peek();
switch (c) {
case 0x7b:
_object();
return const _JsonValue();
case 0x5b:
_array();
return const _JsonValue();
case 0x22:
return _JsonValue(string: _string());
case 0x74:
_literal('true');
return const _JsonValue();
case 0x66:
_literal('false');
return const _JsonValue();
case 0x6e:
_literal('null');
return const _JsonValue(isNull: true);
}
if (c == 0x2d || (c >= 0x30 && c <= 0x39)) {
return _JsonValue(number: _number());
}
_bad();
}
void _literal(String word) {
for (final c in word.codeUnits) {
_expect(c);
}
}
bool _digit() {
final c = _peek();
return c >= 0x30 && c <= 0x39;
}
String _number() {
final start = _i;
if (_peek() == 0x2d) _i++;
if (_peek() == 0x30) {
_i++;
} else if (_digit()) {
while (_digit()) {
_i++;
}
} else {
_bad();
}
if (_peek() == 0x2e) {
_i++;
if (!_digit()) _bad();
while (_digit()) {
_i++;
}
}
if (_peek() == 0x65 || _peek() == 0x45) {
_i++;
if (_peek() == 0x2b || _peek() == 0x2d) _i++;
if (!_digit()) _bad();
while (_digit()) {
_i++;
}
}
return String.fromCharCodes(_b.sublist(start, _i));
}
int _hex4() {
if (_i + 4 > _b.length) _bad();
var v = 0;
for (var k = 0; k < 4; k++) {
final c = _b[_i++];
final d = c >= 0x30 && c <= 0x39
? c - 0x30
: (c | 0x20) >= 0x61 && (c | 0x20) <= 0x66
? (c | 0x20) - 0x61 + 10
: -1;
if (d < 0) _bad();
v = v << 4 | d;
}
return v;
}
String _string() {
_expect(0x22);
final out = StringBuffer();
final raw = <int>[];
void flush() {
if (raw.isEmpty) return;
out.write(utf8.decode(raw, allowMalformed: true));
raw.clear();
}
for (;;) {
if (_i >= _b.length) _bad();
final c = _b[_i++];
if (c == 0x22) break;
if (c < 0x20) _bad();
if (c != 0x5c) {
raw.add(c);
continue;
}
flush();
if (_i >= _b.length) _bad();
final e = _b[_i++];
switch (e) {
case 0x22 || 0x5c || 0x2f:
out.writeCharCode(e);
case 0x62:
out.writeCharCode(0x08);
case 0x66:
out.writeCharCode(0x0c);
case 0x6e:
out.writeCharCode(0x0a);
case 0x72:
out.writeCharCode(0x0d);
case 0x74:
out.writeCharCode(0x09);
case 0x75:
var u = _hex4();
if (u >= 0xd800 && u < 0xdc00) {
// A pair of surrogates is one character; a lone one is U+FFFD.
final save = _i;
if (_i + 6 <= _b.length && _b[_i] == 0x5c && _b[_i + 1] == 0x75) {
_i += 2;
final low = _hex4();
if (low >= 0xdc00 && low < 0xe000) {
u = 0x10000 + ((u - 0xd800) << 10) + (low - 0xdc00);
} else {
_i = save;
u = 0xfffd;
}
} else {
u = 0xfffd;
}
} else if (u >= 0xdc00 && u < 0xe000) {
u = 0xfffd;
}
out.writeCharCode(u);
default:
_bad();
}
}
flush();
return out.toString();
}
}
// ---------------------------------------------------------------------------
// A release in the caller's hand (spec v0.15, §49, §63 step 9.c)
/// Hands over a release that the caller has in hand, as provider.Supplier of
/// Go: a release object, drand's JSON that the person saved, or an entry of
/// a local release archive. It makes no network request, so the opening asks
/// it for the release without comparing its clock with the round time: a
/// valid signature proves that the round was published.
///
/// [supply] returns the encoding of the release of [round], as it is: a
/// release object or drand's JSON, which the opening reads with
/// [parseRelease] and verifies at step 10, with the codes of that step.
/// Without a release for the round it throws ERR_RELEASE_UNAVAILABLE, the
/// code of step 9; whatever else it throws is reported at step 9 with that
/// code alone, keeping only its text ([supplyRelease]).
abstract interface class ReleaseSupplier {
/// The encoding of the release of [round] of the profile [p].
Future<Uint8List> supply(PinnedProfile p, int round);
}
/// A release in hand, already read: the bytes of a release object or of
/// drand's JSON, as provider.Encoded of Go. It supplies itself whatever the
/// round; step 10 compares its round with the DateKey.
final class EncodedRelease implements ReleaseSupplier {
/// The release encoded in [bytes], which it copies.
EncodedRelease(List<int> bytes) : _bytes = Uint8List.fromList(bytes);
final Uint8List _bytes;
@override
Future<Uint8List> supply(PinnedProfile p, int round) async =>
Uint8List.fromList(_bytes);
}
/// The encoding of the release of [round] from [supplier], as step 9 of the
/// opening obtains it: whatever the supplier throws becomes
/// ERR_RELEASE_UNAVAILABLE, as [fetchRelease] does for a source.
Future<Uint8List> supplyRelease(
ReleaseSupplier supplier,
PinnedProfile p,
int round,
) => _step9(() => supplier.supply(p, round));
// ---------------------------------------------------------------------------
// The local release archive (spec v0.15, §50, informative)
/// The type tag of the header of a release archive.
const releaseArchiveTypeTag = 'datekeys-release-archive';
/// The schema version of the header of a release archive.
const releaseArchiveSchemaVersion = 1;
// The bound of the header of an archive: its five keys take at most
// 1 + 26 + 2 + 35 + 9 + 9 bytes.
const _maxArchiveHeader = 128;
const _archiveKeys = 5;
// The header of an archive, as archiveHeader of Go.
final class _ArchiveHeader {
Uint8List chainHash = Uint8List(0);
int first = 0;
int count = 0;
void encode(CborEncoder e) {
e
..map(_archiveKeys)
..uint(0)
..text(releaseArchiveTypeTag)
..uint(1)
..uint(releaseArchiveSchemaVersion)
..uint(2)
..bstr(chainHash)
..uint(3)
..uint(first)
..uint(4)
..uint(count);
}
// Throws a DateKeysException of the codec, whose text Go prints with its
// code, or an _ArchiveError, a text of Go without a code.
void decode(CborDecoder d) {
final pairs = d.map(_archiveKeys);
if (pairs != _archiveKeys) {
throw _ArchiveError('$pairs keys, want all $_archiveKeys');
}
for (var want = 0; want < _archiveKeys; want++) {
final k = d.key();
if (k != want) {
throw _ArchiveError('key $k where key $want was expected');
}
inKey(k, () {
switch (want) {
case 0:
d.text(releaseArchiveTypeTag.length);
case 1:
d.uint(releaseArchiveSchemaVersion);
case 2:
chainHash = d.bstr(32, 32);
case 3:
first = d.uint();
default:
count = d.uint();
}
});
}
d.endMap();
}
}
final class _ArchiveError implements Exception {
_ArchiveError(this.text);
final String text;
}
/// A local release archive, the informative format of spec v0.15, §50, as
/// provider.Archive of Go: a header in deterministic CBOR,
/// `{0: "datekeys-release-archive", 1: 1, 2: chain_hash, 3: first round,
/// 4: number of rounds}`, followed by the signatures, so that the one of
/// round r starts at the end of the header plus (r - first)·n, with n the
/// length of a signature of the chain, 48 bytes in Quicknet. A round written
/// as zeros is missing.
///
/// Read locally, it is a release in hand: its entry is the release object of
/// the round, with the chain hash of the header, decoded and verified at
/// step 10 like any other. A round it lacks, a header it cannot read, an
/// archive of another chain or of another length, and a failure to read the
/// [ByteSource], are failures to supply a release: ERR_RELEASE_UNAVAILABLE at
/// step 9, with the texts of Go. The format has no codes of its own.
final class ReleaseArchive implements ReleaseSupplier {
/// The archive that [source] reads by ranges. Nothing is read until
/// [supply].
ReleaseArchive(this.source);
/// The bytes of the archive.
final ByteSource source;
@override
Future<Uint8List> supply(PinnedProfile p, int round) async {
DateKeysException unavailable(String text) => DateKeysException(
ErrorCode.releaseUnavailable,
'provider: release archive: $text',
);
final size = source.length;
final Uint8List head;
try {
head = await readRange(
source,
0,
size < _maxArchiveHeader ? size : _maxArchiveHeader,
);
} on Object catch (e) {
throw unavailable('$e');
}
try {
checkSchema(head, releaseArchiveTypeTag, releaseArchiveSchemaVersion);
} on DateKeysException {
throw unavailable(
'not an archive of version $releaseArchiveSchemaVersion',
);
}
final h = _ArchiveHeader();
try {
h.decode(CborDecoder(head));
} on DateKeysException catch (e) {
throw unavailable('its header does not decode: ${e.message}');
} on _ArchiveError catch (e) {
throw unavailable('its header does not decode: ${e.text}');
}
// The header is the deterministic encoding of what it says: its length
// is that of the encoding, and the signatures follow it.
final e = CborEncoder();
h.encode(e);
final enc = e.out();
final shown = enc.length < head.length ? enc.length : head.length;
if (!equalBytes(enc, Uint8List.sublistView(head, 0, shown))) {
throw unavailable(
'its header is not the deterministic encoding of its value',
);
}
if (!equalBytes(h.chainHash, p.chainHash)) {
throw unavailable(
'archive of chain ${toHex(h.chainHash)}, the pinned profile ${p.id} '
'is chain ${toHex(p.chainHash)}',
);
}
if (h.first == 0 ||
h.count == 0 ||
round < h.first ||
round - h.first >= h.count) {
throw unavailable(
'round $round is not in the archive, which holds ${h.count} rounds '
'from ${h.first}',
);
}
if (p.scheme != quicknetScheme) {
throw unavailable(
'profile ${p.id} uses scheme ${p.scheme}; only $quicknetScheme '
'archives are read here',
);
}
const n = signatureLength;
// count is at most 2^53-1: the product is exact on the VM, and on the
// web it is inexact only above 2^53, which no source measures.
if (size != enc.length + h.count * n) {
throw unavailable(
'$size bytes, its header announces ${h.count} rounds of $n bytes',
);
}
final Uint8List sig;
try {
sig = await readRange(source, enc.length + (round - h.first) * n, n);
} on Object catch (e) {
throw unavailable('$e');
}
if (sig.every((b) => b == 0)) {
throw unavailable('round $round is missing: its entry is zeros');
}
return encodeRelease(Release(round, sig, chainHash: h.chainHash));
}
}

@ -5,4 +5,4 @@ const String version = '0.1.0-dev';
/// The version of the DateKeys Protocol Specification that this library
/// implements, and that the `spec` field of every file of its `testdata/`
/// names.
const String specVersion = '0.11';
const String specVersion = '0.15';

@ -116,24 +116,7 @@ void checkWordsUtf8(List<List<int>> words) {
final b = w[i];
final (r, size) = b < 0x80 ? (b, 1) : decodeRune(w, i);
i += size;
// Go's unicode.IsControl: C0 and C1, nothing above U+00FF.
if (r <= 0x1f || (r >= 0x7f && r <= 0x9f)) {
throw WordKeyException(
'wordkey: the words hold the control character ${codePointName(r)}',
);
}
if (isDefaultIgnorable(r)) {
throw WordKeyException(
'wordkey: the words hold the invisible character '
'${codePointName(r)}',
);
}
if (!isAssigned(r)) {
throw WordKeyException(
'wordkey: the words hold ${codePointName(r)}, unassigned in '
'Unicode $unicodeVersion',
);
}
checkWordRune(r);
}
if (n >= minLetters) counted.add(String.fromCharCodes(w));
}
@ -145,6 +128,30 @@ void checkWordsUtf8(List<List<int>> words) {
}
}
/// Throws the [WordKeyException] of Go's wordkey.checkRunes when the rune
/// [r] of a word is a control, a Default_Ignorable_Code_Point or a code
/// point unassigned in Unicode 18.0.0: the check of each rune of
/// [checkWords], and of each word of a list in wordlist.dart.
void checkWordRune(int r) {
// Go's unicode.IsControl: C0 and C1, nothing above U+00FF.
if (r <= 0x1f || (r >= 0x7f && r <= 0x9f)) {
throw WordKeyException(
'wordkey: the words hold the control character ${codePointName(r)}',
);
}
if (isDefaultIgnorable(r)) {
throw WordKeyException(
'wordkey: the words hold the invisible character ${codePointName(r)}',
);
}
if (!isAssigned(r)) {
throw WordKeyException(
'wordkey: the words hold ${codePointName(r)}, unassigned in Unicode '
'$unicodeVersion',
);
}
}
/// The salt S of spec §38.1: `DateKeys llave de palabras v2|`, the chain
/// hash in lower-case hexadecimal, `|`, the round in decimal, `|` and the
/// capsule_id in lower-case hexadecimal, as Go's wordkey.Key writes it with

@ -0,0 +1,463 @@
/// The random words of a key of words (spec §38.1: at least 6 words of a
/// public list of 2048 or more, which a writer SHOULD offer), as List,
/// CheckList, Generate and Bits of package wordkey of datekeys-go
/// (generate.go): the word lists of datekeys-go, taken only with the
/// SHA-256 pinned here and checked against the alphabet of their language;
/// the words drawn from one, uniformly, with a [RandomSource]; and their
/// strength in bits. And the words of dice, as DiceNumber, DiceWord,
/// DiceWords and DiceList (dice.go), for whoever does not trust the random
/// numbers of a computer: five dice for each word of a list of
/// [diceListSize] words, and the list numbered for dice, to print it.
///
/// Go builds its lists into the module; this library holds none. The app
/// downloads or bundles the file of a list, `wordkey/lists/<lang>.txt` of
/// datekeys-go (vendored in wordlists/ of this package), and gives its
/// bytes to [readWordList], which trusts none: their SHA-256 must be that of
/// [wordListSha256], and the words must pass [checkWordList]. The lists are
/// not normative: a reader does not need them, because the key is derived
/// from the normalized text of the words, whatever list they came from.
/// Each list has a license of its own, which its README records (es.txt is
/// CC BY-SA 4.0, an adaptation of FrequencyWords by Hermit Dave), unlike the
/// code.
///
/// As in wordkey.dart, a Dart String is taken as its UTF-8 bytes
/// ([utf8Bytes]), and the functions ending in `Utf8` take the bytes of a Go
/// string: every input gives the result and the text of Go.
library;
import 'dart:math' as math;
import 'dart:typed_data';
import 'bytes.dart';
import 'go_unicode.dart' show goIsSpace;
import 'pathrule.dart' show codePointName;
import 'random.dart';
import 'sha256.dart';
import 'wordkey.dart';
/// The number of words that [generateWords] draws when the caller does not
/// ask for more: 7 words of a list of 7776 are about 90 bits ([wordBits]).
const defaultWordCount = 7;
/// The fewest words of a list that [checkWordList] accepts (spec §38.1: at
/// least 6 words of a list of 2048 or more).
const minListSize = 2048;
/// The SHA-256 of each word list of datekeys-go, by language, as its
/// wordkey/lists/README.md records it: [readWordList] takes a list only with
/// these bytes, so that a list changes only with its hash here.
const Map<String, String> wordListSha256 = {
'en': '6d557f0693958fb5e650b68b5bee585eb82cf4da32965505c789e924743bc522',
'es': 'ff77b487765c000da97cca58fe94a2cdb947303e7a07460614d7d95d800034fe',
};
// The letters that a word of a list of each language may hold, as the list
// writes it: lower case, in NFC. A word with a letter of another script that
// looks like one of these, such as the Cyrillic U+0430 for the Latin a,
// would be written down and typed again with the letter of the keyboard, and
// the capsule would not open. The alphabet of a list comes from here, never
// from the list: Go's alphabets. The English one has the ASCII hyphen of the
// four compound words of the list of the EFF, such as t-shirt.
const _alphabets = {
'en': 'abcdefghijklmnopqrstuvwxyz-',
'es': 'abcdefghijklmnopqrstuvwxyz\u00e1\u00e9\u00ed\u00f3\u00fa\u00fc\u00f1',
};
String _q(String s) => goQuote(utf8Bytes(s));
/// The languages of the lists of [wordListSha256], sorted: Go's Languages.
List<String> wordListLanguages() => wordListSha256.keys.toList()..sort();
/// The words of [file], the word list of the language [lang], one word per
/// line, as Go's List gives the list built into it: [file] must have the
/// SHA-256 of [wordListSha256], and its words must pass [checkWordList].
/// For a list that the app downloads or bundles, which it trusts no more
/// than any other download. Throws a [WordKeyException] with Go's text:
/// `wordkey: no word list for "xx"; the lists are es` for a language
/// without a list; `wordkey: the list "es" has the SHA-256 …, not …` for any
/// other bytes; and the error of [checkWordList] after `wordkey: the list
/// "es": `.
List<String> readWordList(String lang, List<int> file) {
final want = wordListSha256[lang];
if (want == null) {
throw WordKeyException(
'wordkey: no word list for ${_q(lang)}; the lists are '
'${wordListLanguages().join(', ')}',
);
}
final got = toHex(sha256(file));
if (got != want) {
throw WordKeyException(
'wordkey: the list ${_q(lang)} has the SHA-256 $got, not $want',
);
}
return parseWordList(lang, file);
}
/// [readWordList] without its two first checks, the language and the
/// SHA-256: the lines of [file], split as Go's List splits its text,
/// `strings.Split(strings.TrimSuffix(text, "\n"), "\n")`, and checked with
/// [checkWordListUtf8]. The bytes are taken as Go takes a string: a byte
/// that is not valid UTF-8 is U+FFFD, which no alphabet holds, so the check
/// refuses it with Go's text, and the words that pass are decoded strictly.
/// For the tests: the app reads a list with [readWordList].
List<String> parseWordList(String lang, List<int> file) {
final lines = _lines(file);
try {
checkWordListUtf8(lang, lines);
} on WordKeyException catch (e) {
throw WordKeyException('wordkey: the list ${_q(lang)}: ${e.message}');
}
return [for (final l in lines) decodeUtf8(l)!];
}
// The lines of [file], as Go's strings.Split(strings.TrimSuffix(text,
// "\n"), "\n"): one final LF goes, and the text is split at every LF, so
// that an empty text is one empty line. A byte 0x0A is never part of a
// longer UTF-8 sequence.
List<Uint8List> _lines(List<int> file) {
final b = file is Uint8List ? file : Uint8List.fromList(file);
final end = b.isNotEmpty && b.last == 0x0a ? b.length - 1 : b.length;
final lines = <Uint8List>[];
var start = 0;
for (var i = 0; i < end; i++) {
if (b[i] == 0x0a) {
lines.add(Uint8List.sublistView(b, start, i));
start = i + 1;
}
}
lines.add(Uint8List.sublistView(b, start, end));
return lines;
}
/// Checks that [words] can be a list of the language [lang] for
/// [generateWords], as Go's CheckList: the same checks, in the same order,
/// with Go's text in a [WordKeyException]. It refuses a language without an
/// alphabet here; fewer than [minListSize] words; a word that is not one
/// word of [minLetters] characters or more once normalized
/// ([normalizeWords]), that holds a character that [checkWords] refuses, or
/// one that is not a letter of the alphabet of [lang], as the list writes
/// it; and a word that is the same as an earlier one once normalized. Two
/// words such as «papa» and «papá» would be one word with less entropy than
/// the list promises.
void checkWordList(String lang, List<String> words) =>
checkWordListUtf8(lang, [for (final w in words) utf8Bytes(w)]);
/// [checkWordList] of the bytes of [words].
void checkWordListUtf8(String lang, List<List<int>> words) {
final alphabet = _alphabets[lang];
if (alphabet == null) {
throw WordKeyException('no alphabet for the language ${_q(lang)}');
}
if (words.length < minListSize) {
throw WordKeyException('${words.length} words, fewer than $minListSize');
}
final letters = alphabet.runes.toSet();
// The first word of the list that is each normalized word.
final seen = <String, List<int>>{};
for (var i = 0; i < words.length; i++) {
final w = words[i];
final line = i + 1;
final n = normalizeWordsUtf8(w);
// Go also refuses a word with white space at its ends, which a word of
// normalizeWords never has.
if (n.length != 1 || n[0].runes.length < minLetters) {
throw WordKeyException(
'line $line, ${goQuote(w)}, is not one word of $minLetters or more '
'letters',
);
}
try {
for (final r in n[0].runes) {
checkWordRune(r);
}
} on WordKeyException catch (e) {
throw WordKeyException('line $line: ${e.message}');
}
// The runes of the word as the list writes it, as Go's `for range`
// reads them: a byte that is not valid UTF-8 is U+FFFD.
for (var j = 0; j < w.length;) {
final (r, size) = w[j] < 0x80 ? (w[j], 1) : decodeRune(w, j);
if (!letters.contains(r)) {
throw WordKeyException(
'line $line, ${goQuote(w)}, holds ${codePointName(r)}, which is '
'not in the alphabet of ${_q(lang)}',
);
}
j += size;
}
final prev = seen[n[0]];
if (prev != null) {
throw WordKeyException(
'line $line, ${goQuote(w)}, is the same word as ${goQuote(prev)} '
'once normalized',
);
}
seen[n[0]] = w;
}
}
/// [n] different words of [list], drawn uniformly with [random], the CSPRNG
/// of the platform by default, as Go's Generate: each index as
/// crypto/rand.Int draws it ([randomIndex]), and an index already drawn is
/// drawn again, so that the same random bytes draw the same words as Go.
/// Each word adds log2 of the size of the list, a little less for each word
/// already drawn ([wordBits]). The list is taken as it is: it is one that
/// [readWordList] gave.
///
/// Throws a [WordKeyException] with Go's text when [n] is less than
/// [minWords] or more than half the list, before drawing anything. What
/// [random] throws goes through: a [RandomSource] does not run out, where
/// Go's io.Reader can, and Go's Generate then fails with `wordkey: EOF`.
List<String> generateWords(
List<String> list, [
int n = defaultWordCount,
RandomSource random = secureRandom,
]) {
if (n < minWords) {
throw WordKeyException(
'wordkey: a key of words needs at least $minWords words, not $n',
);
}
if (n > list.length ~/ 2) {
throw WordKeyException('wordkey: $n words of a list of ${list.length}');
}
final drawn = <int>{};
final words = <String>[];
while (words.length < n) {
final i = randomIndex(random, list.length);
if (drawn.add(i)) words.add(list[i]);
}
return words;
}
/// The strength of [count] words that [generateWords] draws from a list of
/// [size] words, as Go's Bits: log2 of the number of draws in order,
/// size·(size − 1)·…, which whoever knows the list must search, before the
/// rounds of PBKDF2. It is the sum of the log2 of size − i for each i below
/// [count], each by the math.Log2 of Go, so that the double is Go's, on the
/// VM and on the web: 7 words of 7776 are a little under 90.5 bits.
double wordBits(int size, int count) {
var b = 0.0;
for (var i = 0; i < count; i++) {
b += _log2((size - i).toDouble());
}
return b;
}
// Go's math.Log2 of [x], the one of every platform but s390x: x is
// frac·2^exp with frac in [0.5, 1), as math.Frexp splits it; a power of two
// gives exp − 1, exactly, and any other x Log(frac)·(1/Ln2) + exp. 0 gives
// −Infinity and a negative x NaN, as in Go.
double _log2(double x) {
if (x == 0) return double.negativeInfinity;
if (x < 0 || x.isNaN) return double.nan;
if (x.isInfinite) return x;
final (frac, exp) = _frexp(x);
if (frac == 0.5) return (exp - 1).toDouble();
// dart:math's log2e is Go's 1/Ln2 as a float64, 0x3ff71547652b82fe.
return _log(frac) * math.log2e + exp;
}
final _float = ByteData(8);
// Go's math.Frexp of [x], positive and normal: frac in [0.5, 1) and exp,
// with x = frac·2^exp, from the bits of x. Only the high 32 bits change, so
// that the bit operators are exact on the web too.
(double, int) _frexp(double x) {
_float.setFloat64(0, x);
final high = _float.getUint32(0);
_float.setUint32(0, (high & 0x000fffff) | 0x3fe00000);
return (_float.getFloat64(0), (high >> 20) - 1022);
}
// Go's math.Log of [x], positive and normal: its port of FreeBSD's
// e_log.c, with the operations of its code, and of its assembly for amd64,
// in their order, so that each double is Go's.
double _log(double x) {
const ln2Hi = 6.93147180369123816490e-01; // 3fe62e42 fee00000
const ln2Lo = 1.90821492927058770002e-10; // 3dea39ef 35793c76
const l1 = 6.666666666666735130e-01; // 3fe55555 55555593
const l2 = 3.999999999940941908e-01; // 3fd99999 9997fa04
const l3 = 2.857142874366239149e-01; // 3fd24924 94229359
const l4 = 2.222219843214978396e-01; // 3fcc71c5 1d8e78af
const l5 = 1.818357216161805012e-01; // 3fc74664 96cb03de
const l6 = 1.531383769920937332e-01; // 3fc39a09 d078c69f
const l7 = 1.479819860511658591e-01; // 3fc2f112 df3e5244
var (f1, ki) = _frexp(x);
if (f1 < math.sqrt2 / 2) {
f1 *= 2;
ki--;
}
final f = f1 - 1;
final k = ki.toDouble();
final s = f / (2 + f);
final s2 = s * s;
final s4 = s2 * s2;
final t1 = s2 * (l1 + s4 * (l3 + s4 * (l5 + s4 * l7)));
final t2 = s4 * (l2 + s4 * (l4 + s4 * l6));
final r = t1 + t2;
final hfsq = 0.5 * f * f;
return k * ln2Hi - ((hfsq - (s * (hfsq + r) + k * ln2Lo)) - f);
}
/// The size of a list that dice draw from, Go's DiceListSize: five dice,
/// each from 1 to 6, give 6^5 positions. Whoever does not trust the random
/// numbers of a computer rolls them, and looks the words up in the list
/// numbered for dice ([diceList]).
const diceListSize = 7776;
/// The dice of the word at position [i] of a list of [diceListSize] words,
/// as Go's DiceNumber: five digits from 1 to 6, each one more than a digit
/// of [i] in base 6, the first the most significant, so that 11111 is the
/// first word and 66666 the last, as in the list of the EFF. Throws a
/// [WordKeyException] with Go's text, `wordkey: no dice give position 7776
/// of a list of 7776 words`, for a position outside the list.
String diceNumber(int i) {
if (i < 0 || i >= diceListSize) {
throw WordKeyException(
'wordkey: no dice give position $i of a list of $diceListSize words',
);
}
final dice = Uint8List(5);
var n = i;
for (var k = dice.length - 1; k >= 0; k--) {
dice[k] = 0x31 + n % 6;
n ~/= 6;
}
return String.fromCharCodes(dice);
}
/// The word of [list] that [dice] give, as Go's DiceWord: five digits from
/// 1 to 6, as [diceNumber] numbers the words. The list must have
/// [diceListSize] words, and is taken as it is: one that [readWordList]
/// gave. [dice] is taken as its UTF-8 bytes, as Go takes a string: five
/// bytes, each a digit from 1 to 6, and nothing else, so that white space
/// around them or a full-width digit is refused. Throws a
/// [WordKeyException] with Go's text: `wordkey: dice draw from a list of
/// 7776 words, not 2048` for a list of another size, first; then
/// `wordkey: "1116" is not five dice: five digits from 1 to 6`.
String diceWord(List<String> list, String dice) =>
diceWordUtf8(list, utf8Bytes(dice));
/// [diceWord] of the bytes of a Go string, [dice].
String diceWordUtf8(List<String> list, List<int> dice) {
_checkDiceList(list);
return list[_diceIndex(dice)];
}
/// The words that [dice] give, in their order, as Go's DiceWords: one
/// number of five dice for each word, as [diceWord] reads it, separated by
/// white space, at least [minWords] of them, and never the same word twice,
/// which whoever rolls rolls again. Fair dice draw each word as
/// [generateWords] does, so the words are as strong ([wordBits]).
///
/// [dice] is split as Go's strings.Fields splits its UTF-8 bytes: at the
/// white space of Go's unicode.IsSpace, the set of spec §38.1 at which
/// [normalizeWords] splits (the space, the tab, the line feed, U+00A0,
/// U+3000 and the others), and nothing else changes: the numbers are not
/// normalized, and a combining mark stays in its number. Throws a
/// [WordKeyException] with Go's text for the first failure, in this order:
/// the size of [list], as [diceWord]; fewer than [minWords] numbers,
/// `wordkey: a key of words needs at least 6 words, not 5`; then, number by
/// number, one that is not five dice, with the text of [diceWord], or one
/// that gives a word already given, `wordkey: the dice 11111 give "abacus"
/// a second time; roll them again`.
List<String> diceWords(List<String> list, String dice) =>
diceWordsUtf8(list, utf8Bytes(dice));
/// [diceWords] of the bytes of a Go string, [dice].
List<String> diceWordsUtf8(List<String> list, List<int> dice) {
_checkDiceList(list);
final numbers = _fields(dice);
if (numbers.length < minWords) {
throw WordKeyException(
'wordkey: a key of words needs at least $minWords words, not '
'${numbers.length}',
);
}
// The words given so far: Go compares the words, not their dice, and a
// list that holds a word twice gives it twice from two numbers.
final seen = <String>{};
final words = <String>[];
for (final n in numbers) {
final w = list[_diceIndex(n)];
if (!seen.add(w)) {
// Five digits from 1 to 6, as Go's %s writes their bytes.
throw WordKeyException(
'wordkey: the dice ${String.fromCharCodes(n)} give ${_q(w)} a '
'second time; roll them again',
);
}
words.add(w);
}
return words;
}
/// [list] numbered for dice, to print it, as Go's DiceList: a line for each
/// word, its dice ([diceNumber]), a tab, the word and a line feed, as the
/// EFF publishes its list. For the English list, its UTF-8 bytes are the
/// file of the EFF, byte for byte. Throws a [WordKeyException] with Go's
/// text for a list of another size, as [diceWord].
String diceList(List<String> list) {
_checkDiceList(list);
final out = StringBuffer();
for (var i = 0; i < list.length; i++) {
out
..write(diceNumber(i))
..write('\t')
..write(list[i])
..write('\n');
}
return out.toString();
}
// The first check of DiceWord, DiceWords and DiceList of Go: the size of
// the list.
void _checkDiceList(List<String> list) {
if (list.length != diceListSize) {
throw WordKeyException(
'wordkey: dice draw from a list of $diceListSize words, not '
'${list.length}',
);
}
}
// The position that [dice], the bytes of a Go string, give in a list of
// diceListSize words, as Go's DiceWord reads them: five bytes, then each a
// digit from 1 to 6, the first the most significant digit in base 6.
int _diceIndex(List<int> dice) {
if (dice.length != 5) throw _notDice(dice);
var i = 0;
for (final c in dice) {
if (c < 0x31 || c > 0x36) throw _notDice(dice);
i = i * 6 + c - 0x31;
}
return i;
}
WordKeyException _notDice(List<int> dice) => WordKeyException(
'wordkey: ${goQuote(dice)} is not five dice: five digits from 1 to 6',
);
// The fields of [text], the bytes of a Go string, as Go's strings.Fields
// cuts them: the runs between the runes of Go's unicode.IsSpace, read as
// Go's `for range` reads them, so that a byte that is not valid UTF-8 is
// U+FFFD, which is not white space and stays in its field.
List<Uint8List> _fields(List<int> text) {
final b = text is Uint8List ? text : Uint8List.fromList(text);
final fields = <Uint8List>[];
var start = -1;
for (var i = 0; i < b.length;) {
final (r, size) = b[i] < 0x80 ? (b[i], 1) : decodeRune(b, i);
if (goIsSpace(r)) {
if (start >= 0) fields.add(Uint8List.sublistView(b, start, i));
start = -1;
} else if (start < 0) {
start = i;
}
i += size;
}
if (start >= 0) fields.add(Uint8List.sublistView(b, start));
return fields;
}

@ -0,0 +1,44 @@
// The recovery annex of lib/src/annex.dart, as TestRecoveryAnnex of
// datekeys-go: recoveryAnnex holds §79 of the specification of specVersion,
// from its title to its subsection 79.8, names the version, and ends as the
// specification does, without a CR; and its UTF-8 bytes have the SHA-256 that
// tool/recovery_annex_copy.dart took from annex/recovery.md, so that the
// constant compiled to JavaScript is the file too. It reads no file: it runs
// on the VM and compiled to JavaScript. test/annex_vm_test.dart compares the
// constant with the file and the file with §79 of the specification.
library;
import 'dart:convert';
import 'package:datekeys/datekeys.dart';
import 'package:datekeys/src/recovery_annex.g.dart' show recoveryAnnexSha256;
import 'package:datekeys/src/sha256.dart';
import 'package:test/test.dart';
void main() {
test('the annex is §79 of the specification $specVersion', () {
for (final s in [
'## 79. Anexo informativo: recuperación sin software DateKeys',
'### 79.8 Lo que el anexo no comprueba',
'DateKeys v$specVersion,',
]) {
expect(recoveryAnnex, contains(s));
}
expect(recoveryAnnex, endsWith('conforme.\n'));
expect(recoveryAnnex, isNot(contains('\r')));
expect(
recoveryAnnex,
startsWith(
'# Cómo abrir una cápsula DateKeys sin software de DateKeys\n\n',
),
);
});
test('its UTF-8 bytes are annex/recovery.md, by their SHA-256', () {
expect(toHex(sha256(utf8.encode(recoveryAnnex))), recoveryAnnexSha256);
});
test('its file is the name of the .dkc and .recuperacion.txt', () {
expect(recoveryAnnexSuffix, '.recuperacion.txt');
});
}

@ -0,0 +1,77 @@
// recoveryAnnex is annex/recovery.md byte for byte, the copy that
// tool/recovery_annex_copy.dart writes after each sync of annex/. And
// annex/recovery.md is §79 of the specification of specVersion under the
// title and the paragraph of TestRecoveryAnnex of datekeys-go, which names the
// version and the SHA-256 of the specification: the specification is read
// from the Go repository next to this one, at the commit that annex/SOURCE.json
// pins, as test/errors_spec_test.dart reads it.
@TestOn('vm')
library;
import 'dart:convert';
import 'dart:io';
import 'package:datekeys/datekeys.dart';
import 'package:datekeys/src/recovery_annex.g.dart' show recoveryAnnexSha256;
import 'package:datekeys/src/sha256.dart';
import 'package:test/test.dart';
import '../tool/sync_testdata.dart' as vendored;
void main() {
final root = Directory.current;
final repo = Directory('../datekeys-go');
test('recoveryAnnex is annex/recovery.md byte for byte', () {
final file = File('${root.path}/annex/recovery.md').readAsBytesSync();
expect(utf8.encode(recoveryAnnex), file);
expect(toHex(sha256(file)), recoveryAnnexSha256);
});
test(
'annex/recovery.md is §79 of the specification, as TestRecoveryAnnex',
() {
final commit = vendored.check(root, tree: vendored.annexTree).commit;
final path =
'$commit:spec/DateKeys_Protocol_Specification_v$specVersion.md';
final r = Process.runSync(
'git',
['-C', repo.path, 'show', path],
stdoutEncoding: null,
stderrEncoding: utf8,
);
expect(r.exitCode, 0, reason: '${r.stderr}');
final spec = r.stdout as List<int>;
expect(
File('${root.path}/annex/recovery.md').readAsStringSync(),
annexOf(spec),
);
},
skip: repo.existsSync()
? false
: '../datekeys-go is missing: the spec is read from it',
);
}
// The text of RecoveryAnnex for the specification spec, as recoveryAnnex of
// annex_test.go of Go: its §79, from its title to the end of the document,
// under a title of its own and a paragraph that names the version and the
// SHA-256 of spec.
String annexOf(List<int> spec) {
final text = utf8.decode(spec);
final i = text.indexOf('\n## 79. ');
if (i < 0) throw StateError('the specification $specVersion has no §79');
// strings.TrimRight(text[i+1:], " \n")
var end = text.length;
while (end > i + 1 && (text[end - 1] == ' ' || text[end - 1] == '\n')) {
end--;
}
return '# Cómo abrir una cápsula DateKeys sin software de DateKeys\n\n'
'Este texto acompaña a una cápsula del tiempo de DateKeys, un fichero '
'`.dkc`: dice cómo abrirla, llegada su fecha, sin ningún software de '
'DateKeys, por si ya no existe. Es el anexo informativo §79 de la '
'especificación del protocolo DateKeys v$specVersion, cuyo texto tiene '
'el SHA-256 ${toHex(sha256(spec))}. Es el mismo para toda cápsula: no '
'lleva ningún dato de esta.\n\n'
'${text.substring(i + 1, end)}\n';
}

@ -1,7 +1,8 @@
// The catalogue matches spec §69 exactly, in order, as TestCatalogueMatchesSpec
// of datekeys-go. The spec is read from the Go repository next to this one, at
// the tag of the version of the spec that this package implements, so that
// uncommitted changes there never count.
// the commit that testdata/SOURCE.json pins, the one testdata/ was synced
// from, so that uncommitted changes there never count and a version not yet
// tagged can be read.
@TestOn('vm')
library;
@ -11,13 +12,16 @@ import 'dart:io';
import 'package:datekeys/datekeys.dart';
import 'package:test/test.dart';
import '../tool/sync_testdata.dart' as testdata;
void main() {
final repo = Directory('../datekeys-go');
test(
'the catalogue is the list of ERR_ lines of spec §69, in order',
() {
final commit = testdata.check(Directory.current).commit;
final path =
'spec-v$specVersion:spec/DateKeys_Protocol_Specification_v$specVersion.md';
'$commit:spec/DateKeys_Protocol_Specification_v$specVersion.md';
final r = Process.runSync(
'git',
['-C', repo.path, 'show', path],

@ -9,6 +9,7 @@ library;
import 'dart:convert';
import 'dart:io';
import 'package:datekeys/src/version.dart';
import 'package:test/test.dart';
import 'formats_differential.dart';
@ -37,7 +38,7 @@ void main() {
test('every file is of this specification and of its generator', () {
for (final f in files.values) {
expect(f['spec'], '0.11');
expect(f['spec'], specVersion);
expect(f['generator'], 'tool/formats_go_vectors.go');
}
});

@ -3,7 +3,8 @@
// header.test.ts, control.test.ts, accesskey.test.ts and profile.test.ts of
// datekeys-ts: values of a fixed seed that encode and decode back to
// themselves, the copies of the secrets and their wiping, the texts that
// hide them, and the pinned registry. The values and texts of Go are in the
// hide them, and the pinned registry, with the state of its profiles of spec
// §71, as TestStatus of Go. The values and texts of Go are in the
// differential (formats_header.json, formats_control.json,
// formats_framing.json, formats_profile.json and formats_encode.json). It
// reads no file: it runs on the VM and compiled to JavaScript.
@ -256,6 +257,32 @@ void main() {
expect(quicknet(), isNot(copy));
});
test('Quicknet is active in the registry of §71, as TestStatus of Go', () {
expect(profileStatusOf(profileHash(q)), (
status: ProfileStatus.active,
known: true,
));
// A profile that this release does not know: the zero Status of Go.
for (final h in [Uint8List(32)..[0] = 1, Uint8List(0)]) {
expect(profileStatusOf(h), (
status: ProfileStatus.active,
known: false,
));
}
expect(
{for (final s in ProfileStatus.values) s: '$s'},
{
ProfileStatus.active: 'active',
ProfileStatus.readOnly: 'read-only',
ProfileStatus.compromised: 'compromised',
},
);
expect(
[for (final s in ProfileStatus.values) s.label],
['active', 'read-only', 'compromised'],
);
});
test('a network "default", or none, is left out of the chain hash', () {
final d = q.copyWith(network: 'default');
expect(chainInfoHash(d), chainInfoHash(q.copyWith(network: '')));

@ -17,6 +17,7 @@ import 'package:datekeys/src/framing.dart';
import 'package:datekeys/src/header.dart';
import 'package:datekeys/src/padding.dart';
import 'package:datekeys/src/profile.dart';
import 'package:datekeys/src/version.dart';
import 'package:test/test.dart';
typedef Json = Map<String, Object?>;
@ -42,7 +43,7 @@ void main() {
final vectors = section(file, 'vectors');
test('is of this specification and holds valid and invalid strings', () {
expect(file['spec'], '0.11');
expect(file['spec'], specVersion);
expect(vectors.where((v) => v.containsKey('dk1')), isNotEmpty);
expect(vectors.where((v) => v.containsKey('input')), isNotEmpty);
});

@ -65,17 +65,16 @@ void main() {
}
});
test('Go accepts a doubled opening bracket, and a CID with one more '
'character whose bits are zero', () {
// The host of Go is strings.Trim(host, "[]"), and isCIDv1 checks only
// that the bits left over are zero, not their count: Dart does the
// same, as the vectors of Go say.
test('a doubled opening bracket and a CID with one more character whose '
'bits are zero are refused, as by Go since the draft v0.13', () {
// checkHost of Go takes one pair of brackets, and isCIDv1 refuses 5 or
// more bits left over: neither is the form that spec §44.1 asks for.
for (final uri in [
'https://[[2000::]/',
'ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia',
]) {
final c = rows(v, 'uris').firstWhere((c) => c[0] == uri);
expect(c[1], 0, reason: uri);
expect(c[1], isNot(0), reason: uri);
expectUri(c);
}
});
@ -100,25 +99,34 @@ void main() {
}
});
test('checkResolvedIp checks the bytes of an address as publicIP', () {
for (final c in rows(v, 'public')) {
final b = fromHex(c[0]! as String);
if (c[1] == null) {
expect(() => checkResolvedIp(b), throwsArgumentError);
continue;
test(
'checkResolvedIp checks the bytes of an address as publicIP, but NAT64',
() {
for (final c in rows(v, 'public')) {
final b = fromHex(c[0]! as String);
if (c[1] == null) {
expect(() => checkResolvedIp(b), throwsArgumentError);
continue;
}
final a = IpAddress.fromBytes(b);
expect('$a', c[2]);
expect(isPublicIp(a), c[1], reason: '$a');
// An address of NAT64 counts by the IPv4 address it holds (spec
// v0.13): resolved_ip_test.dart runs those.
if (b.length == 16 &&
toHex(b.sublist(0, 12)) == '0064ff9b0000000000000000') {
continue;
}
expect(
errorText(() => checkResolvedIp(b)),
c[1] == true
? ''
: 'locator: an https address whose name resolves to ${c[2]}, '
'an IP address that is not public',
);
}
final a = IpAddress.fromBytes(b);
expect('$a', c[2]);
expect(isPublicIp(a), c[1], reason: '$a');
expect(
errorText(() => checkResolvedIp(b)),
c[1] == true
? ''
: 'locator: an https address whose name resolves to ${c[2]}, '
'an IP address that is not public',
);
}
});
},
);
test('an IPv4 address mapped in IPv6 is not public', () {
expect(

@ -3,9 +3,12 @@
// and the step of the corpus, and the text and the checks that capsule.Open
// of Go gives on each case (test/vectors/mutation_texts.json, which
// tool/mutation_go_texts.go writes), in memory and from a source read in
// pieces; the verdicts and their lines of each case that opens; no release
// request for a case that fails without the network; and every case whose
// step is 1 to 8 through the inspection too.
// pieces, with the source of each case (spec v0.15, §63 step 9): a release
// in hand, given as a release object (OpenOptions.release), or a network
// source that discards a release breaking a rule of step 10; the verdicts
// and their lines of each case that opens, and the clock behind a release in
// hand; no release request for a case that fails without the network; and
// every case whose step is 1 to 8 through the inspection too.
@TestOn('vm')
library;
@ -37,15 +40,30 @@ void main() {
expect(corpus['spec'], specVersion);
expect(texts['spec'], specVersion);
expect(texts['generator'], 'tool/mutation_go_texts.go');
expect(cases, hasLength(218));
expect(cases, hasLength(222));
expect(
[for (final c in goCases) c['name']],
[for (final c in cases) c['name']],
);
// Go at c531e93 and the corpus of the draft v0.12 agree on every case.
// Go at fe50885 and the corpus of v0.15 agree on every case.
expect(goCases.where((c) => c.containsKey('go_error')), isEmpty);
expect(cases.where((c) => c['spec'] == true), hasLength(178));
expect(cases.where((c) => c['error'] == 'ok'), hasLength(11));
expect(cases.where((c) => c['error'] == 'ok'), hasLength(12));
// Spec v0.15: every case says its source, all of them a release in hand
// but three, and two releases name another chain.
expect(
cases.where((c) => c['source'] != 'supplied').map((c) => c['name']),
[
'round not reached yet, from a network source',
'release of another round, from a network source',
],
);
expect(
cases.where(
(c) => (c['release'] as Json?)?.containsKey('chain_hash') ?? false,
),
hasLength(2),
);
expect(
cases.where((c) => c['error'] != 'ok' && (c['step']! as int) <= 8),
hasLength(57),
@ -64,7 +82,22 @@ void main() {
expect(o.text, go['text'], reason: where);
expect(canonical(o.checks), canonical(go['checks']), reason: where);
final last = o.opened.checks.last;
if (c['error'] == 'ok') {
// Spec v0.15, §63 step 9.c: a release in hand opens with a clock
// behind the round time, which the opening reports.
expect(
o.opened.clockBehind,
o.opened.checks.any(
(k) => k.step == 9 && k.detail.endsWith('it may be behind'),
),
reason: where,
);
if (c['error'] == 'ok' && c['verdicts'] == null) {
// A capsule of format 1 that opens: a release in hand and a clock
// behind its round time.
expect([last.step, last.ok], [18, true], reason: where);
expect(o.opened.clockBehind, isTrue, reason: where);
expect(o.output.closed, isTrue, reason: where);
} else if (c['error'] == 'ok') {
// The cases of security that open, with the verdicts of the
// corpus and their lines; none needs the reader of CMS.
expect([last.step, last.ok], [18, true], reason: where);

@ -21,16 +21,24 @@ export 'security_support.dart';
export 'source_support.dart';
/// A source that answers every request with the release of a case, or
/// fails as its source_error says, and counts the requests.
final class CaseSource implements ReleaseSource {
CaseSource(this.release, this.error);
/// fails as its source_error says, and counts the requests, as the sources
/// of tool/open_go_vectors.go and testkit's singleSource of Go.
///
/// As a [ReleaseSource], it hands its release over unverified, as the cases
/// of open_cases.json expect, or, when [network], verifies it and discards
/// it when it breaks a rule of step 10, as a network source of the mutation
/// corpus (spec v0.15, §63 step 9). As a [ReleaseSupplier], a release in the
/// caller's hand, it hands over the release object of its release, with the
/// chain of the pinned profile unless the release names another.
final class CaseSource implements ReleaseSource, ReleaseSupplier {
CaseSource(this.release, this.error, {this.network = false});
final Release? release;
final Object? error;
final bool network;
int calls = 0;
@override
Future<Release> fetch(PinnedProfile p, int round) async {
Release _release() {
calls++;
final e = error;
if (e != null) throw e;
@ -43,6 +51,30 @@ final class CaseSource implements ReleaseSource {
}
return r;
}
@override
Future<Release> fetch(PinnedProfile p, int round) async {
final r = _release();
if (network) {
try {
verifyRelease(p, round, r);
} on DateKeysException catch (e) {
throw DateKeysException(
ErrorCode.releaseUnavailable,
'testkit: the release is discarded: ${e.message}',
);
}
}
return r;
}
@override
Future<Uint8List> supply(PinnedProfile p, int round) async {
final r = _release();
return encodeRelease(
Release(r.round, r.signature, chainHash: r.chainHash ?? p.chainHash),
);
}
}
/// The failure of a source of a case: a DateKeysException of its code, or
@ -205,11 +237,24 @@ Future<Outcome> openCase(
SecurityEvaluator? evaluator,
}) async {
final rel = c['release'] as Json?;
final chain = rel?['chain_hash'] as String?;
// The source of a case of the mutation corpus (spec v0.15): "supplied",
// a release in hand, or "network"; the cases of open_cases.json have
// none and are opened with a source that hands its release over.
final kind = c['source'] as String?;
if (kind != null && kind != 'supplied' && kind != 'network') {
throw ArgumentError('unknown source $kind');
}
final source = CaseSource(
rel == null
? null
: Release(rel['round']! as int, fromHex(str(rel, 'signature'))),
: Release(
rel['round']! as int,
fromHex(str(rel, 'signature')),
chainHash: chain == null ? null : fromHex(chain),
),
sourceError(c),
network: kind == 'network',
);
AccessKey? key;
final dkk = c['dkk'] as String?;
@ -234,7 +279,8 @@ Future<Outcome> openCase(
final securities = <Uint8List>[];
final evaluate = evaluator ?? evaluateSecurityInput;
final options = OpenOptions(
source: source,
source: kind == 'supplied' ? null : source,
release: kind == 'supplied' ? source : null,
now: () => parseRfc3339(str(c, 'now')),
registry: c['registry'] == 'empty' ? newRegistry([]) : null,
extensions: caseExtensions(c),

@ -499,6 +499,169 @@ void main() {
});
});
group('a release in hand (spec v0.15, §63 step 9.c)', () {
final c = caseNamed('time_and_key_portable: the .dkk, still encoded');
final rel = c['release']! as Json;
final round = rel['round']! as int;
final signature = fromHex(str(rel, 'signature'));
final chain = quicknet().chainHash;
final object = encodeRelease(Release(round, signature, chainHash: chain));
final unlock = parseRfc3339(str(c, 'now'));
Future<Opened> open(
ReleaseSupplier supplier,
Instant now, {
bool withKey = true,
}) => openCapsule(
capsuleOf(c, fixture),
OpenOptions(
release: supplier,
now: () => now,
accessKeyFile: withKey ? fromHex(str(c, 'dkk_file')) : null,
output: RecordingOutput(),
),
);
test('is not compared with the clock, which the opening says is '
'behind', () async {
for (final (name, now, behind) in [
('after the round time', unlock, false),
(
'a clock one nanosecond behind',
Instant(unlock.seconds - 1, 999999999),
true,
),
('a clock years behind', Instant(0), true),
]) {
final o = await open(EncodedRelease(object), now);
expect(o.error, isNull, reason: name);
expect(o.clockBehind, behind, reason: name);
// The release that opened it, with the chain of the pinned
// profile, encodes to the same object.
expect(encodeRelease(o.release!), object, reason: name);
final step9 = o.checks.firstWhere(
(k) => k.step == 9 && k.name == 'release',
);
expect(
step9.detail,
behind
? 'release supplied by the caller; round $round is published at '
'${formatRfc3339(unlock)} and the clock says '
'${formatRfc3339(now)}: it may be behind'
: 'release supplied by the caller',
reason: name,
);
}
// drand's JSON, which names no chain, opens it too.
final json = '{"round":$round,"signature":"${toHex(signature)}"}';
final o = await open(EncodedRelease(utf8.encode(json)), Instant(0));
expect([o.error, o.clockBehind], [null, true]);
expect(o.release!.chainHash, chain);
});
test('keeps the order of steps 9 and 10, with their codes', () async {
final other = Uint8List.fromList(chain)..[5] ^= 1;
for (final (name, supply, withKey, code, step, calls) in [
(
'no credential, before any supply',
() async => object,
false,
'ERR_ACCESS_REQUIRED',
9,
0,
),
(
'nothing supplied',
() async =>
throw DateKeysException(ErrorCode.releaseUnavailable, 'none'),
true,
'ERR_RELEASE_UNAVAILABLE',
9,
1,
),
(
'a supplier failing with another code',
() async => throw DateKeysException(ErrorCode.integrity, 'odd'),
true,
'ERR_RELEASE_UNAVAILABLE',
9,
1,
),
(
'an empty object',
() async => Uint8List(0),
true,
'ERR_NON_CANONICAL_CBOR',
10,
1,
),
(
'another chain and another round',
() async =>
encodeRelease(Release(round + 1, signature, chainHash: other)),
true,
'ERR_PROFILE_MISMATCH',
10,
1,
),
(
'another round',
() async =>
encodeRelease(Release(round + 1, signature, chainHash: chain)),
true,
'ERR_ROUND_MISMATCH',
10,
1,
),
(
"drand's JSON of another round",
() async => utf8.encode('{"round":${round + 1},"signature":"00"}'),
true,
'ERR_ROUND_MISMATCH',
10,
1,
),
]) {
final s = _CountingSupplier(supply);
final o = await open(s, Instant(0), withKey: withKey);
expect(
[o.error?.code.code, o.checks.last.step, s.calls],
[code, step, calls],
reason: name,
);
// As Go, the clock behind is reported once the release is in
// hand, even when step 10 then fails.
expect(o.clockBehind, step == 10, reason: name);
expect(o.release, isNull, reason: name);
}
});
test('is exclusive with a source, and one of them is required', () async {
for (final o in [
OpenOptions(
source: suppliedRelease(),
release: EncodedRelease(object),
now: () => unlock,
output: RecordingOutput(),
),
OpenOptions(now: () => unlock, output: RecordingOutput()),
]) {
await expectLater(
openCapsule(capsuleOf(c, fixture), o),
throwsA(
isArgumentError.having(
(e) => '${e.message}',
'message',
'open: set exactly one of OpenOptions.source and '
'OpenOptions.release',
),
),
);
expect((o.output! as RecordingOutput).aborted, isArgumentError);
}
});
});
group('the sources', () {
test('BytesSource reads views of its bytes, and readRange keeps '
'reading', () async {
@ -561,3 +724,17 @@ RecordingSink _asRecording(MemoryFileSink m) {
r.files = [for (final f in m.files!) BytesBuilder()..add(f)];
return r;
}
// A supplier that counts the requests and answers with [supply].
final class _CountingSupplier implements ReleaseSupplier {
_CountingSupplier(this.supply_);
final Future<List<int>> Function() supply_;
int calls = 0;
@override
Future<Uint8List> supply(PinnedProfile p, int round) async {
calls++;
return Uint8List.fromList(await supply_());
}
}

@ -0,0 +1,398 @@
// The release object, drand's JSON and the local release archive of spec
// v0.15 (§47.1, §50, §63 step 10) against testdata/vectors/release.json,
// strictly: every case with its result and the text of the reference, the
// release each encoding says, and the object written again byte for byte;
// the files of testdata/releases/; and the texts of provider.Archive of Go
// on edited archives (test/vectors/release_archive_texts.json, written by
// tool/release_archive_go_texts.go). release_object_vm_test.dart reads the
// files; release_object_test.dart reads their copy, release.g.dart, compiled
// to JavaScript.
import 'dart:async';
import 'dart:convert';
import 'dart:typed_data';
import 'package:datekeys/datekeys.dart';
import 'package:test/test.dart';
typedef Json = Map<String, Object?>;
String _s(Json v, String key) => v[key]! as String;
List<Json> _list(Json v, String key) => (v[key]! as List).cast<Json>();
/// The result and the text of [body]: `ok` and null, or the code and the
/// message of the DateKeysException it throws.
Future<(String, String?)> _outcome(FutureOr<void> Function() body) async {
try {
await body();
return ('ok', null);
} on DateKeysException catch (e) {
return (e.code.code, e.message);
}
}
void _expectRelease(Release r, Json want, String name) {
expect(r.round, want['round'], reason: name);
expect(toHex(r.signature), want['signature'], reason: name);
final chain = want['chain_hash'] as String?;
expect(r.chainHash == null ? null : toHex(r.chainHash!), chain, reason: name);
}
/// The tests of release.json, the files of testdata/releases/ and the texts
/// of the archive.
void releaseObjectTests(
Json file,
Map<String, Uint8List> files,
Json archiveTexts,
) {
final p = quicknet();
test('release.json has its lists and the keys of each case', () {
expect(file['spec'], specVersion);
expect(file['profile'], p.id);
expect(file.keys.toSet(), {
'spec',
'description',
'profile',
'objects',
'json',
'archive',
});
final objects = _list(file, 'objects');
final json = _list(file, 'json');
expect(objects, hasLength(36));
expect(json, hasLength(12));
for (final c in [...objects, ...json]) {
final ok = c['result'] == 'ok';
expect(c.containsKey('text'), !ok, reason: _s(c, 'name'));
expect(c['round'], isA<int>(), reason: _s(c, 'name'));
expect(
c.keys.toSet().difference({
'name',
'encoding',
'input',
'round',
'release',
'result',
'text',
}),
isEmpty,
reason: _s(c, 'name'),
);
}
expect(objects.where((c) => c['result'] == 'ok'), hasLength(4));
expect(json.where((c) => c['result'] == 'ok'), hasLength(3));
});
test('objects: the layers of the object, then step 10, with the texts of '
'Go', () async {
for (final c in _list(file, 'objects')) {
final name = _s(c, 'name');
final enc = fromHex(c['encoding'] as String? ?? '');
final want = c['release'] as Json?;
Release? decoded;
final got = await _outcome(() {
// parseRelease reads an object as decodeRelease does.
final r = parseRelease(enc);
decoded = r;
expect(decodeRelease(enc).round, r.round);
verifyRelease(p, c['round']! as int, r);
});
expect(got, (c['result'], c['text']), reason: name);
if (want == null) {
expect(decoded, isNull, reason: '$name: it does not decode');
continue;
}
_expectRelease(decoded!, want, name);
// The object is written again byte for byte.
expect(toHex(encodeRelease(decoded!)), toHex(enc), reason: name);
}
});
test(
'json: drand JSON as the input of the caller, with the texts of Go',
() async {
for (final c in _list(file, 'json')) {
final name = _s(c, 'name');
final want = c['release'] as Json?;
Release? decoded;
final got = await _outcome(() {
final r = parseRelease(utf8.encode(_s(c, 'input')));
decoded = r;
verifyRelease(p, c['round']! as int, r);
});
expect(got, (c['result'], c['text']), reason: name);
if (want == null) {
expect(decoded, isNull, reason: name);
} else {
expect(want.containsKey('chain_hash'), isFalse, reason: name);
_expectRelease(decoded!, want, name);
}
}
},
);
test('json: the matching of encoding/json of Go', () async {
const sig =
'b44679b9a59af2ec876b1a6b1ad52ea9b1615fc3982b19576350f93447cb1125e342b'
'73a8dd2bacbe47e4b6b63ed5e39';
Future<(String, String?)> read(String json) =>
_outcome(() => verifyRelease(p, 1000, parseRelease(utf8.encode(json))));
const malformed =
'provider: drand JSON: malformed, or without round or signature: '
'ERR_RELEASE_INVALID';
for (final ok in [
'{"Round":1000,"SIGNATURE":"$sig"}',
'{"round":1,"round":1000,"signature":"$sig","extra":[1,{"a":null}]}',
'{"round":1000,"signature":"$sig","randomness":null}',
'{"round":1000,"signature":"$sig","randomness":""}',
'\t\r\n {"round":1000,"${String.fromCharCode(0x017f)}ignature":"$sig"}',
// Escapes are read in names and values; other names are ignored,
// whatever they hold.
r'{"\u0072ound":1000,"signature":"\u0062'
'${sig.substring(1)}"}',
'{"round":1000,"signature":"$sig",'
r'"r\u00e9":1,"x":"\ud800"}'
'\n\n',
]) {
expect(await read(ok), ('ok', null), reason: ok);
}
// Invalid UTF-8 in a string, as Go.
expect(
await _outcome(
() => verifyRelease(
p,
1000,
parseRelease([
...utf8.encode('{"round":1000,"signature":"$sig","x":"'),
0xff,
...utf8.encode('"}'),
]),
),
),
('ok', null),
);
for (final bad in [
'{"round":1000.0,"signature":"$sig"}',
'{"round":1e3,"signature":"$sig"}',
'{"round":-1000,"signature":"$sig"}',
'{"round":null,"signature":"$sig"}',
'{"round":1000,"signature":null}',
'{"round":1000,"signature":"$sig","randomness":1}',
'{"round":1000,"signature":["$sig"]}',
'{"round":1000,"signature":"$sig"} {}',
'{"round":1000,"signature":"$sig",}',
// The last key wins, and null unsets the round.
'{"round":1000,"signature":"$sig","round":null}',
'{"round":01000,"signature":"$sig"}',
'{"round":-0,"signature":"$sig"}',
'{"round":18446744073709551616,"signature":"$sig"}',
'{"round":1000,"signature":"$sig","x":"\\q"}',
'{"round":1000,"signature":"$sig","x":tru}',
]) {
expect(await read(bad), ('ERR_RELEASE_INVALID', malformed), reason: bad);
}
expect(await read('{"round":1000,"signature":"${sig.substring(1)}"}'), (
'ERR_RELEASE_INVALID',
'provider: drand JSON: signature is not hex: ERR_RELEASE_INVALID',
));
// null leaves randomness as it was.
expect(
await read(
'{"round":1000,"signature":"$sig","randomness":"x",'
'"randomness":null}',
),
(
'ERR_RELEASE_INVALID',
'provider: drand JSON: randomness does not match the signature: '
'ERR_RELEASE_INVALID',
),
);
// Go reads a round up to 2^64-1 and fails it at step 10 with
// ERR_ROUND_MISMATCH; this library does not hold a round above 2^53-1,
// which no DateKey has, and refuses it as it reads it.
expect(await read('{"round":9007199254740992,"signature":"$sig"}'), (
'ERR_RELEASE_INVALID',
'provider: drand JSON: round 9007199254740992 above 9007199254740991, '
'the largest round of a DateKey: ERR_RELEASE_INVALID',
));
// A signature of no byte reads, and fails at the signature.
expect(await read('{"round":1000,"signature":""}'), (
'ERR_RELEASE_INVALID',
'provider: signature is 0 bytes, bls-unchained-g1-rfc9380 uses 48: '
'ERR_RELEASE_INVALID',
));
// Not JSON: the first byte other than a JSON space is not {.
expect(await read('${String.fromCharCode(0xa0)}{}'), (
'ERR_NON_CANONICAL_CBOR',
'provider: release object: codec: offset 0: a tag (initial byte 0xc2) '
'is outside the CBOR profile: ERR_NON_CANONICAL_CBOR',
));
expect(await read('[]'), (
'ERR_NON_CANONICAL_CBOR',
'provider: release object: codec: offset 0: truncated input: '
'ERR_NON_CANONICAL_CBOR',
));
});
test('encodeRelease refuses what the object cannot hold, as Go', () {
final chain = p.chainHash;
String fails(Release r) {
try {
encodeRelease(r);
} on DateKeysException catch (e) {
return e.message;
}
fail('no error');
}
expect(
fails(Release(1000, Uint8List(48))),
'provider: release object: chain hash of 0 bytes, want 32: '
'ERR_NON_CANONICAL_CBOR',
);
expect(
fails(Release(1000, Uint8List(48), chainHash: Uint8List(31))),
'provider: release object: chain hash of 31 bytes, want 32: '
'ERR_NON_CANONICAL_CBOR',
);
expect(
fails(Release(0, Uint8List(48), chainHash: chain)),
'provider: release object: round 0 outside 1..9007199254740991: '
'ERR_NON_CANONICAL_CBOR',
);
expect(
fails(Release(1000, Uint8List(0), chainHash: chain)),
'provider: release object: signature of 0 bytes outside 1..96: '
'ERR_NON_CANONICAL_CBOR',
);
expect(
fails(Release(1000, Uint8List(97), chainHash: chain)),
'provider: release object: signature of 97 bytes outside 1..96: '
'ERR_NON_CANONICAL_CBOR',
);
});
test('the files of testdata/releases/: the object of each round, which '
'opens step 10', () {
final objects = {
for (final c in _list(file, 'objects'))
if (c['result'] == 'ok') c['round']! as int: _s(c, 'encoding'),
};
final rounds = <int>[];
for (final MapEntry(:key, :value) in files.entries) {
final m = RegExp(r'^(\d+)\.[a-z]+$').firstMatch(key);
if (m == null) continue;
final round = int.parse(m[1]!);
rounds.add(round);
final r = decodeRelease(value);
expect(r.round, round, reason: key);
expect(r.chainHash, p.chainHash, reason: key);
verifyRelease(p, round, r);
expect(toHex(encodeRelease(r)), toHex(value), reason: key);
expect(toHex(value), objects[round], reason: key);
expect(value, hasLength(111), reason: key);
}
expect(rounds..sort(), [1000, 1001, 1004, 2000]);
});
test('archive: the lookups of release.json', () async {
final a = file['archive']! as Json;
final name = _s(a, 'file').split('/').last;
final bin = files[name]!;
expect(toHex(bin).startsWith(_s(a, 'header')), isTrue);
final archive = ReleaseArchive(BytesSource(bin));
final lookups = _list(a, 'lookups');
expect(lookups, hasLength(7));
for (final l in lookups) {
final round = l['round']! as int;
Uint8List? got;
final r = await _outcome(() async {
got = await archive.supply(p, round);
});
expect(r.$1, l['result'], reason: 'round $round');
if (l['result'] == 'ok') {
expect(toHex(got!), l['encoding'], reason: 'round $round');
verifyRelease(p, round, decodeRelease(got!));
}
}
});
test('archive: the texts of provider.Archive of Go', () async {
expect(archiveTexts['generator'], 'tool/release_archive_go_texts.go');
final cases = _list(archiveTexts, 'cases');
expect(cases, hasLength(14));
for (final c in cases) {
final round = c['round']! as int;
final r = await _outcome(
() =>
ReleaseArchive(BytesSource(fromHex(_s(c, 'bytes'))))
.supply(p, round),
);
expect(r.$2 ?? 'ok', c['text'], reason: _s(c, 'name'));
if (r.$2 != null) {
expect(r.$1, 'ERR_RELEASE_UNAVAILABLE', reason: _s(c, 'name'));
}
}
});
test('archive: a source that fails is a release unavailable', () async {
final r = await _outcome(
() => ReleaseArchive(_FailingSource()).supply(p, 1000),
);
expect(r, (
'ERR_RELEASE_UNAVAILABLE',
'provider: release archive: disk gone: ERR_RELEASE_UNAVAILABLE',
));
});
test('a release in hand: supplyRelease keeps only the code of step 9', () async {
final object = files.entries
.firstWhere((e) => e.key.startsWith('1000.'))
.value;
expect(await EncodedRelease(object).supply(p, 7), object);
expect(
await _outcome(() => supplyRelease(_ThrowingSupplier('odd'), p, 1000)),
(
'ERR_RELEASE_UNAVAILABLE',
'capsule: release source: odd: ERR_RELEASE_UNAVAILABLE',
),
);
expect(
await _outcome(
() => supplyRelease(
_ThrowingSupplier(DateKeysException(ErrorCode.integrity, 'odd')),
p,
1000,
),
),
(
'ERR_RELEASE_UNAVAILABLE',
'capsule: release source: odd: ERR_INTEGRITY: ERR_RELEASE_UNAVAILABLE',
),
);
final none = DateKeysException(ErrorCode.releaseUnavailable, 'none');
expect(
await _outcome(() => supplyRelease(_ThrowingSupplier(none), p, 1000)),
('ERR_RELEASE_UNAVAILABLE', 'none: ERR_RELEASE_UNAVAILABLE'),
);
});
}
final class _FailingSource implements ByteSource {
@override
int get length => 311;
@override
Future<Uint8List> read(int offset, int n) async => throw 'disk gone';
}
final class _ThrowingSupplier implements ReleaseSupplier {
_ThrowingSupplier(this.error);
final Object error;
@override
Future<Uint8List> supply(PinnedProfile p, int round) async => throw error;
}

@ -0,0 +1,21 @@
// The release object, drand's JSON and the local release archive of spec
// v0.15 against the copy of testdata/vectors/release.json, testdata/releases/
// and test/vectors/release_archive_texts.json, compiled to JavaScript, where
// no file can be read; release_object_vm_test.dart walks the files on the
// VM.
@TestOn('!vm')
library;
import 'dart:convert';
import 'package:datekeys/datekeys.dart' show fromHex;
import 'package:test/test.dart';
import 'release_object_support.dart';
import 'vectors/release.g.dart';
void main() {
releaseObjectTests(jsonDecode(releaseJson) as Json, {
for (final e in releaseFiles.entries) e.key: fromHex(e.value),
}, jsonDecode(releaseArchiveTextsJson) as Json);
}

@ -0,0 +1,44 @@
// The release object, drand's JSON and the local release archive of spec
// v0.15 against testdata/vectors/release.json, testdata/releases/ and
// test/vectors/release_archive_texts.json, read from the files, and the copy
// of them that release_object_test.dart walks compiled to JavaScript
// (test/vectors/release.g.dart, written by tool/release_copy.dart).
@TestOn('vm')
library;
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:datekeys/datekeys.dart' show toHex;
import 'package:test/test.dart';
import 'release_object_support.dart';
import 'vectors/release.g.dart';
void main() {
final text = File('testdata/vectors/release.json').readAsStringSync();
final archiveTexts = File('test/vectors/release_archive_texts.json')
.readAsStringSync();
final files = <String, Uint8List>{
for (final f in Directory('testdata/releases').listSync().whereType<File>())
f.uri.pathSegments.last: f.readAsBytesSync(),
};
test('release.g.dart holds the files', () {
const reason = 'run dart run tool/release_copy.dart';
expect(releaseJson, text, reason: reason);
expect(releaseArchiveTextsJson, archiveTexts, reason: reason);
expect(
{for (final e in files.entries) e.key: toHex(e.value)},
releaseFiles,
reason: reason,
);
});
releaseObjectTests(
jsonDecode(text) as Json,
files,
jsonDecode(archiveTexts) as Json,
);
}

@ -170,6 +170,10 @@ void main() {
...names,
for (final n in names) 'format 2: $n',
for (final n in names) 'format 3: $n',
// Spec v0.15: two release objects of another chain.
'release object of another chain',
'release object of another chain and another round, with a clock '
'behind',
]..sort(),
);
for (final c in corpus) {
@ -187,7 +191,13 @@ void main() {
() => verifyRelease(
quicknet(),
dateKeyRound(bytes),
Release(rel['round']! as int, fromHex(s(rel, 'signature'))),
Release(
rel['round']! as int,
fromHex(s(rel, 'signature')),
chainHash: rel['chain_hash'] == null
? null
: fromHex(s(rel, 'chain_hash')),
),
),
name,
);

@ -0,0 +1,76 @@
// The IP address that the name of an https address of a locator resolves
// to, against testdata/vectors/resolved_ip.json of the draft v0.13 (spec
// §44.1): a public address, or an address of NAT64 of 64:ff9b::/96 or of
// the prefix of the network whose IPv4 address inside is public, with the
// texts of locator.CheckResolvedIP of Go.
@TestOn('vm')
library;
import 'dart:convert';
import 'dart:io';
import 'package:datekeys/src/ipaddr.dart';
import 'package:datekeys/src/locator.dart';
import 'package:test/test.dart';
typedef Json = Map<String, Object?>;
void main() {
final f = jsonDecode(
File('testdata/vectors/resolved_ip.json').readAsStringSync(),
) as Json;
final cases = (f['cases']! as List).cast<Json>();
test('resolved_ip.json has the cases of README', () {
expect(cases, hasLength(greaterThanOrEqualTo(40)));
expect(cases.where((c) => c['result'] == 'ok'), isNotEmpty);
expect(cases.where((c) => c['result'] == 'error'), isNotEmpty);
});
for (final c in cases) {
test('${c['name']}', () {
final ip = parseIpAddress(c['ip']! as String)!;
final nat64 = c['nat64']! as String;
void check() =>
checkResolvedIp(ip.bytes, nat64: nat64.isEmpty ? null : nat64);
if (c['result'] == 'ok') {
check();
} else {
expect(c['result'], 'error');
expect(
check,
throwsA(
isA<LocatorException>().having(
(e) => e.message,
'message',
c['error'],
),
),
);
}
});
}
test('an IPv4-mapped prefix is not one of NAT64, as in Go', () {
expect(
() => checkResolvedIp([8, 8, 8, 8], nat64: '::ffff:0.0.0.0/96'),
throwsA(
isA<LocatorException>().having(
(e) => e.message,
'message',
'locator: the NAT64 prefix ::ffff:0.0.0.0/96 is not an IPv6 prefix',
),
),
);
});
test('a prefix that does not parse is an ArgumentError', () {
for (final s in ['64:ff9b::', '64:ff9b::/129', '64:ff9b::/-1', 'x/96']) {
expect(
() => checkResolvedIp([8, 8, 8, 8], nat64: s),
throwsArgumentError,
reason: s,
);
}
});
}

@ -3,7 +3,9 @@
// than pass with fewer cases. The check is the one of tool/sync_testdata.dart:
// every file matches the SHA-256 recorded in testdata/SOURCE.json for the
// pinned datekeys-go commit, with none missing and none extra. And every file
// names the specification that this package implements.
// names the specification that this package implements. The same check holds
// for wordlists/, the word lists of wordkey/lists of the same commit, and for
// annex/, the recovery annex of annex/ of the same commit.
@TestOn('vm')
library;
@ -24,8 +26,49 @@ void main() {
expect(r.module, testdata.module);
expect(r.commit, matches(RegExp(r'^[0-9a-f]{40}$')));
expect(r.files, greaterThan(100));
expect(
r.line,
'testdata: ${r.files} files match ${r.module} at ${r.commit}',
);
});
test(
'wordlists/ matches SOURCE.json byte for byte, at the commit of testdata/',
() {
final r = testdata.check(root, tree: testdata.wordlistsTree);
expect(r.errors, isEmpty);
expect(r.module, testdata.module);
expect(r.commit, testdata.check(root).commit);
// The README of the lists, with their source and license, and a list.
expect(r.files, greaterThanOrEqualTo(2));
expect(
r.line,
'wordlists: ${r.files} files match ${r.module} at ${r.commit}',
);
},
);
test(
'annex/ matches SOURCE.json byte for byte, at the commit of testdata/',
() {
final r = testdata.check(root, tree: testdata.annexTree);
expect(r.errors, isEmpty);
expect(r.module, testdata.module);
expect(r.commit, testdata.check(root).commit);
// recovery.md, the text of datekeys.RecoveryAnnex.
expect(r.files, greaterThanOrEqualTo(1));
expect(
r.line,
'annex: ${r.files} files match ${r.module} at ${r.commit}',
);
expect(testdata.trees, [
testdata.testdataTree,
testdata.wordlistsTree,
testdata.annexTree,
]);
},
);
test('every JSON of testdata/ with a spec field names specVersion', () {
var named = 0;
final files = Directory('${root.path}/testdata')

@ -0,0 +1,198 @@
// Steps 10 and 11 of spec §63 for Quicknet, value by value, against
// testdata/vectors/tlock_steps.json (spec v0.14, the paragraphs "Mensaje de
// ronda y hash a G1" and "H3 y H4"): every intermediate value of the file is
// computed again with the code of the library, release.dart, ibe.dart,
// tlock.dart and bls12381_*.dart, and so are the negative checks that the
// generator of Go runs on each vector. tlock_steps_vm_test.dart walks the
// file; tlock_steps_test.dart walks its copy compiled to JavaScript.
import 'dart:convert';
import 'dart:typed_data';
import 'package:datekeys/src/bls12381_curve.dart';
import 'package:datekeys/src/bls12381_fp.dart' show groupOrder;
import 'package:datekeys/src/bls12381_hash.dart';
import 'package:datekeys/src/bls12381_pairing.dart';
import 'package:datekeys/src/bytes.dart';
import 'package:datekeys/src/ibe.dart';
import 'package:datekeys/src/profile.dart';
import 'package:datekeys/src/release.dart';
import 'package:datekeys/src/sha256.dart';
import 'package:datekeys/src/tlock.dart';
import 'package:datekeys/src/version.dart';
import 'package:test/test.dart';
typedef Json = Map<String, Object?>;
// The DST of RFC 9380 for G2, which bls-unchained-on-g1 uses to hash to G1:
// a reader that takes it, or the round itself as the message, fails step 10.
const _g2Dst = 'BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_';
String _s(Json v, String key) => v[key]! as String;
Uint8List _h(Json v, String key) => fromHex(_s(v, key));
Uint8List _xor(List<int> a, List<int> b) {
expect(a, hasLength(b.length));
return Uint8List.fromList([for (var i = 0; i < a.length; i++) a[i] ^ b[i]]);
}
BigInt _big(List<int> b) =>
b.isEmpty ? BigInt.zero : BigInt.parse(toHex(b), radix: 16);
/// The tests of [f], the parsed tlock_steps.json.
void tlockStepsTests(Json f) {
final vectors = (f['vectors']! as List).cast<Json>();
final tags = f['tags']! as Json;
test('names this specification and the pinned profile of Quicknet', () {
expect(f['spec'], specVersion);
final p = quicknet();
validateProfile(p);
expect(f['profile'], p.id);
expect(f['scheme'], quicknetScheme);
expect(f['scheme'], p.scheme);
expect(_s(f, 'chain_hash'), toHex(p.chainHash));
expect(_s(f, 'chain_hash'), toHex(chainInfoHash(p)));
expect(_s(f, 'public_key'), toHex(p.publicKey));
expect(f['dst'], quicknetDst);
expect(tags, {
'h2': toHex(ascii.encode('IBE-H2')),
'h3': toHex(ascii.encode('IBE-H3')),
'h4': toHex(ascii.encode('IBE-H4')),
});
expect(vectors, hasLength(5));
// The last vector is the one whose H3 needs more than one try.
expect((vectors.last['h3_tries']! as List).length, greaterThan(2));
});
final key = G2Point.decode(fromHex(_s(f, 'public_key')))!;
final chainHash = _s(f, 'chain_hash');
final h3Tag = fromHex(tags['h3']! as String);
for (final v in vectors) {
final name = _s(v, 'name');
final round = v['round']! as int;
final signature = _h(v, 'signature');
test('$name: step 10, M, H(M) and the pairing equation', () {
final m = roundIdentity(round);
expect(toHex(m), _s(v, 'message'));
final round8 = Uint8List(8)
..buffer.asByteData().setUint32(0, round ~/ 0x100000000)
..buffer.asByteData().setUint32(4, round % 0x100000000);
expect(m, sha256(round8));
final hm = hashToG1(m, quicknetDst);
expect(toHex(hm.toBytes()), _s(v, 'hash_to_g1'));
final sig = signaturePoint(signature);
// e(H(M), public_key) = e(signature, G2).
expect(pairingCheck([(hm, key), (-sig, G2Point.generator)]), isTrue);
verifyRelease(quicknet(), round, Release(round, signature));
// The usual misreadings do not verify: the DST of G2, and the round
// without SHA-256 as the message.
expect(
pairingCheck([(hashToG1(m, _g2Dst), key), (-sig, G2Point.generator)]),
isFalse,
);
expect(
pairingCheck([
(hashToG1(round8, quicknetDst), key),
(-sig, G2Point.generator),
]),
isFalse,
);
});
test('$name: step 11, H2, sigma, H4, the file key, H3 and r·G2 = U', () {
final body = _h(v, 'body');
final u = _h(v, 'u');
final vv = _h(v, 'v');
final w = _h(v, 'w');
expect(body, hasLength(tlockBodyLength));
expect(body, concatBytes([u, vv, w]));
final ct = ciphertextFromBody(body);
expect([ct.u, ct.v, ct.w], [u, vv, w]);
expect(ciphertextToBody(ct), body);
final sig = signaturePoint(signature);
final uPoint = G2Point.decode(u)!;
expect(uPoint.isInfinity, isFalse);
final gt = pairing(sig, uPoint);
expect(toHex(gtBytes(gt)), _s(v, 'pairing'));
final mask2 = h2(gt, tlockBlockLength);
expect(toHex(mask2), _s(v, 'h2'));
final sigma = _xor(vv, mask2);
expect(toHex(sigma), _s(v, 'sigma'));
final mask4 = h4(sigma, tlockBlockLength);
expect(toHex(mask4), _s(v, 'h4'));
final fileKey = _xor(w, mask4);
expect(toHex(fileKey), _s(v, 'file_key'));
// H3, try by try.
final base = sha256(concatBytes([h3Tag, sigma, fileKey]));
expect(toHex(base), _s(v, 'h3_base'));
final tries = (v['h3_tries']! as List).cast<Json>();
expect(tries, isNotEmpty);
Uint8List? cleared;
for (var k = 0; k < tries.length; k++) {
final t = tries[k];
final i = k + 1;
expect(t['i'], i);
final d = sha256(
concatBytes([
[i & 0xff, i >> 8],
base,
]),
);
expect(toHex(d), _s(t, 'digest'));
final shifted = Uint8List.fromList(d)..[0] = d[0] >> 1;
expect(toHex(shifted), _s(t, 'shifted'));
final accepted = _big(shifted) < groupOrder;
expect(t['accepted'], accepted);
expect(accepted, k == tries.length - 1, reason: 'only the last try');
// Clearing the top bit instead accepts another value.
final c = Uint8List.fromList(d)..[0] = d[0] & 0x7f;
if (cleared == null && _big(c) < groupOrder) cleared = c;
}
final r = _h(v, 'r');
expect(toHex(r), _s(tries.last, 'shifted'));
expect(h3(sigma, fileKey), _big(r));
if (tries.length > 1) {
// The library rejects every try before the last one.
expect(
() => h3(sigma, fileKey, iterations: tries.length - 1),
throwsA(isA<IbeException>()),
);
}
expect(cleared, isNotNull);
expect(toHex(cleared!), isNot(toHex(r)));
// r·G2 = U.
expect(proofHolds(_big(r), uPoint), isTrue);
expect(toHex(G2Point.generator.multiply(_big(r)).toBytes()), toHex(u));
expect(proofHolds(_big(cleared), uPoint), isFalse);
});
test('$name: the library opens the stanza and writes it again', () {
final body = _h(v, 'body');
final fileKey = _s(v, 'file_key');
expect(toHex(decryptOnG2(signature, ciphertextFromBody(body))), fileKey);
expect(
toHex(
unwrapTlockStanza(quicknet(), round, Release(round, signature), [
'$round',
chainHash,
], body),
),
fileKey,
);
final ct = encryptOnG2WithSigma(
fromHex(_s(f, 'public_key')),
fromHex(_s(v, 'message')),
fromHex(fileKey),
_h(v, 'sigma'),
);
expect(toHex(ciphertextToBody(ct)), toHex(body));
});
}
}

@ -0,0 +1,16 @@
// Steps 10 and 11 of spec §63 against the copy of
// testdata/vectors/tlock_steps.json, compiled to JavaScript, where no file
// can be read; tlock_steps_vm_test.dart walks the file itself on the VM.
@TestOn('!vm')
library;
import 'dart:convert';
import 'package:test/test.dart';
import 'tlock_steps_support.dart';
import 'vectors/tlock_steps.g.dart';
void main() {
tlockStepsTests(jsonDecode(tlockStepsJson) as Json);
}

@ -0,0 +1,28 @@
// Steps 10 and 11 of spec §63 against testdata/vectors/tlock_steps.json, read
// from the file, and the copy of the file that tlock_steps_test.dart walks
// compiled to JavaScript (test/vectors/tlock_steps.g.dart, written by
// tool/tlock_steps_copy.dart).
@TestOn('vm')
library;
import 'dart:convert';
import 'dart:io';
import 'package:test/test.dart';
import 'tlock_steps_support.dart';
import 'vectors/tlock_steps.g.dart';
void main() {
final text = File('testdata/vectors/tlock_steps.json').readAsStringSync();
test('tlock_steps.g.dart holds testdata/vectors/tlock_steps.json', () {
expect(
tlockStepsJson,
text,
reason: 'run dart run tool/tlock_steps_copy.dart',
);
});
tlockStepsTests(jsonDecode(text) as Json);
}

@ -1,5 +1,5 @@
{
"spec": "0.11",
"spec": "0.15",
"generator": "tool/formats_go_vectors.go",
"description": "The frame of BODY (capsule.ParseBodyFrame) against L, and the zeros of the security area (capsule.CheckArea).",
"frame": [

@ -1,5 +1,5 @@
{
"spec": "0.11",
"spec": "0.15",
"generator": "tool/formats_go_vectors.go",
"description": "CONTROL_CBOR of the three formats (capsule.DecodeControl) of the fixtures, in their format and in another, edited, and built field by field.",
"control": [

@ -1,5 +1,5 @@
{
"spec": "0.11",
"spec": "0.15",
"generator": "tool/formats_go_vectors.go",
"description": "dk1_ strings (datekey.Parse).",
"parse": [

@ -1,5 +1,5 @@
{
"spec": "0.11",
"spec": "0.15",
"generator": "tool/formats_go_vectors.go",
"description": "The encoders on values: capsule.EncodeHeader and EncodeControl, accesskey.Encode, profile.NewRegistry, and the canonical JSON and dk1_ string of DateKeys (CanonicalJSON and Compact, empty when not valid); an encoding is in hex, or as its length and SHA-256 when it is large. big is the size of the data of the noncritical extension a of version 1, bytes 0x01, that takes the object to its limit. limits: the decoders on objects at the limits of spec §57 and one byte past them: zeros bytes of zeros, or an extension array 81 a3 00 61 61 01 01 02 5a <len, 4 bytes> and len bytes 0x07 (extension_data), or Canonical of the extension a of version 1 whose data is len zeros (extension_canonical).",
"header": [

@ -1,5 +1,5 @@
{
"spec": "0.11",
"spec": "0.15",
"generator": "tool/formats_go_vectors.go",
"description": "Extension arrays through codec.Unmarshal with extension.DecodeArray and EncodeArray, Canonical, CheckDisjoint, CheckCriticalIn and CheckNoncriticalIn with the registry placed of the generator (or CheckCritical and CheckNoncritical when object is empty, and no registry when registry is none), and CheckWrite with extension.Standard.",
"array": [

@ -1,5 +1,5 @@
{
"spec": "0.11",
"spec": "0.15",
"generator": "tool/formats_go_vectors.go",
"description": "The PRELUDE of a .dkc (capsule.ParsePrelude), the steps 1 to 3 of capsule.Inspect on truncated and edited fixtures (with the step that fails, 0 when steps 1 to 8 pass), and whole .dkk files (accesskey.Decode), with the result, the code and the text of the Go reference.",
"prelude": [

@ -1,5 +1,5 @@
{
"spec": "0.11",
"spec": "0.15",
"generator": "tool/formats_go_vectors.go",
"description": "PUBLIC_HEADER (capsule.DecodeHeader) of the fixtures, edited, and built field by field.",
"header": [

@ -1,5 +1,5 @@
{
"spec": "0.11",
"spec": "0.15",
"generator": "tool/formats_go_vectors.go",
"description": "capsule.PaddedLength with both codes and capsule.PayloadAgeLength, at the boundaries of spec §29.1 up to L_MAX and past it; a code with null was rejected with text. check: the plaintext of PAYLOAD_AGE checked by capsule.Open against L and P (step 17): the content of the fixture (its .plaintext) followed by zeros, cut or extended to length bytes, with the byte at at set to value when given; step 0 when the capsule opens.",
"padded": [

@ -1,5 +1,5 @@
{
"spec": "0.11",
"spec": "0.15",
"generator": "tool/formats_go_vectors.go",
"description": "Provider Profiles: profile.Decode of the Quicknet profile, edited and with fields replaced, and Profile.Validate of values.",
"decode": [
@ -56,7 +56,7 @@
{"hex":"ab007819646174656b6579732d70726f76696465722d70726f66696c6501010274646174656b6579733a717569636b6e65743a763103656472616e640468717569636b6e657405582052db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e97106586083cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d10640d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a0703081a64e62127097818626c732d756e636861696e65642d67312d726663393338","result":"ERR_NON_CANONICAL_CBOR","text":"profile: codec: offset 204: map key 3 after key 6: keys must be strictly ascending: ERR_NON_CANONICAL_CBOR"},
{"hex":"ab007819646174656b6579732d70726f76696465722d70726f66696c6501010274646174656b6579733a717569636b6e65743a763103656472616e640468717569636b6e657405582065dcdc7eff7c0c02ad8bc809f729ec0c11c95c704a9a63fd509a6d9ec6cc1ed106586083cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a0700081a64e62127097818626c732d756e636861696e65642d67312d726663393338300a5820f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","result":"ERR_NON_CANONICAL_CBOR","text":"profile: key 7: period 0: ERR_NON_CANONICAL_CBOR"},
{"hex":"ab007819646174656b6579732d70726f76696465722d70726f66696c6501010274646174656b6579733a717569636b6e65743a763103656472616e640478406161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616105582052db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e97106586083cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a0703081a64e62127097818626c732d756e636861696e65642d67312d726663393338300a58213a29061a4d8c6d3c715eaf8e48da4b183b5b8ad74fbce0e484fbf91bbc80659911","result":"ERR_NON_CANONICAL_CBOR","text":"profile: key 10: codec: offset 299: a byte string of 33 bytes outside 32..32: ERR_NON_CANONICAL_CBOR"},
{"hex":"ab007819646174656b6579732d70726f76696465722d70726f66696c6501010274646174656b6579733a717569636b6e65743a763103656472616e640468717569636b6e657405582052db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e97106586083cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a0703081a64e62127097819626c732d626e3235342d756e636861696e65642d6f6e2d67310a5820f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: scheme \"bls-bn254-unchained-on-g1\" is not supported by tlock: ERR_UNKNOWN_PROFILE"},
{"hex":"ab007819646174656b6579732d70726f76696465722d70726f66696c6501010274646174656b6579733a717569636b6e65743a763103656472616e640468717569636b6e657405582052db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e97106586083cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a0703081a64e62127097819626c732d626e3235342d756e636861696e65642d6f6e2d67310a5820f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: scheme \"bls-bn254-unchained-on-g1\" is not bls-unchained-g1-rfc9380, the only scheme of V1: ERR_UNKNOWN_PROFILE"},
{"hex":"ab007819646174656b6579732d70726f76696465722d70726f66696c6501010274646174656b6579733a717569636b6e65743a763103656472616e640468717569636b6e657405582052db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e97106586083cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a071b001fffffffffffff081a64e62127097818626c732d756e636861696e65642d67312d726663393338300a5820bd802afddcde3b4521da5b7dac9a4998fac55a86bb410a6852381b053a34d559","result":"ERR_NON_CANONICAL_CBOR","text":"profile: period 9007199254740991 s out of range: ERR_NON_CANONICAL_CBOR"},
{"hex":"ab007819646174656b6579732d70726f76696465722d70726f66696c6501010274646174656b6579733a717569636b6e65743a763103656472616e640468717569636b6e657405582052db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e97106586083cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a0703081b0000003afff4417e097818626c732d756e636861696e65642d67312d726663393338300a582018b07fefff6c8fff0ce6088acf49e4de176436d70f941f0ad3fdfc8bd6c677b2","result":"ERR_PROFILE_MISMATCH","text":"profile datekeys:quicknet:v1: parameters hash to chain 2c6bca0320709af44138375ac31e95ba56907b106c702443b1d558b55d4e9621, not the pinned 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971: ERR_PROFILE_MISMATCH"},
{"hex":"ab007819646174656b6579732d70726f76696465722d70726f66696c6501010274646174656b6579733a717569636b6e65743a763103656472616e64047841616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616105582052db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e97106586083cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a071b001fffffffffffff081a64e62127097818626c732d756e636861696e65642d67312d726663393338300a5820f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","result":"ERR_NON_CANONICAL_CBOR","text":"profile: period 9007199254740991 s out of range: ERR_NON_CANONICAL_CBOR"},
@ -164,8 +164,8 @@
{"hex":"ab007819646174656b6579732d70726f76696465722d70726f66696c650101027880616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616103656472616e640468717569636b6e6574055820b1c41498aa9ccc4100b53f00687c6443f67a6a95f089e5a84ed58a3ac6257c380658608000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000703081a64e62127097818626c732d756e636861696e65642d67312d726663393338300a5820f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","result":"ERR_UNKNOWN_PROFILE","text":"profile aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: public key is not the canonical encoding of a point of the key group of bls-unchained-g1-rfc9380: ERR_UNKNOWN_PROFILE"},
{"hex":"ab007819646174656b6579732d70726f76696465722d70726f66696c6501010274646174656b6579733a717569636b6e65743a763103656472616e640468717569636b6e6574055820076449f967c2022a9342e07eff9b1180fa22e6b7c175a3fab631bdb7622f0cce06586083cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a0703081a64e6212709646e6f70650a5820f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: \"nope\" is not a drand scheme: ERR_UNKNOWN_PROFILE"},
{"hex":"ab007819646174656b6579732d70726f76696465722d70726f66696c6501010274646174656b6579733a717569636b6e65743a763103656472616e640468717569636b6e65740558204aa4595edb8fd7fa3e98d503b2d2c8fe20f06f428fb43700686ba2af394eeeae06583097f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0703081a5f18588a097818626c732d756e636861696e65642d67312d726663393338300a5820f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: public key is not the canonical encoding of a point of the key group of bls-unchained-g1-rfc9380: ERR_UNKNOWN_PROFILE"},
{"hex":"ab007819646174656b6579732d70726f76696465722d70726f66696c65010102706472616e643a64656661756c743a763103656472616e64046764656661756c740558208990e7a9aaed2ffed73dbd7092123d6f289930540d7651336225dc172e51b2ce065830868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af3107181e081a5f18588a0976706564657273656e2d626c732d756e636861696e65640a5820176f93498eac9ca337150b46d21dd58673ea4e3581185f869672e59fa4cb390a","profile":{"chain_hash":"8990e7a9aaed2ffed73dbd7092123d6f289930540d7651336225dc172e51b2ce","genesis_seed":"176f93498eac9ca337150b46d21dd58673ea4e3581185f869672e59fa4cb390a","genesis_time":1595431050,"id":"drand:default:v1","max_round":8393562325,"network":"default","period":30,"provider":"drand","public_key":"868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af31","scheme":"pedersen-bls-unchained"},"result":"ok"},
{"hex":"ab007819646174656b6579732d70726f76696465722d70726f66696c65010102706472616e643a64656661756c743a763103656472616e64046764656661756c740558208990e7a9aaed2ffed73dbd7092123d6f289930540d7651336225dc172e51b2ce065830868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af3107181e081a5f18588a0974706564657273656e2d626c732d636861696e65640a5820176f93498eac9ca337150b46d21dd58673ea4e3581185f869672e59fa4cb390a","result":"ERR_UNKNOWN_PROFILE","text":"profile drand:default:v1: scheme \"pedersen-bls-chained\" is not supported by tlock: ERR_UNKNOWN_PROFILE"}
{"hex":"ab007819646174656b6579732d70726f76696465722d70726f66696c65010102706472616e643a64656661756c743a763103656472616e64046764656661756c740558208990e7a9aaed2ffed73dbd7092123d6f289930540d7651336225dc172e51b2ce065830868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af3107181e081a5f18588a0976706564657273656e2d626c732d756e636861696e65640a5820176f93498eac9ca337150b46d21dd58673ea4e3581185f869672e59fa4cb390a","result":"ERR_UNKNOWN_PROFILE","text":"profile drand:default:v1: scheme \"pedersen-bls-unchained\" is not bls-unchained-g1-rfc9380, the only scheme of V1: ERR_UNKNOWN_PROFILE"},
{"hex":"ab007819646174656b6579732d70726f76696465722d70726f66696c65010102706472616e643a64656661756c743a763103656472616e64046764656661756c740558208990e7a9aaed2ffed73dbd7092123d6f289930540d7651336225dc172e51b2ce065830868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af3107181e081a5f18588a0974706564657273656e2d626c732d636861696e65640a5820176f93498eac9ca337150b46d21dd58673ea4e3581185f869672e59fa4cb390a","result":"ERR_UNKNOWN_PROFILE","text":"profile drand:default:v1: scheme \"pedersen-bls-chained\" is not bls-unchained-g1-rfc9380, the only scheme of V1: ERR_UNKNOWN_PROFILE"}
],
"validate": [
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":83903165811,"network":"Q","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-g1-rfc9380"},"result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: invalid provider, network or scheme name: ERR_UNKNOWN_PROFILE"},
@ -178,7 +178,7 @@
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":83903165811,"network":"quicknet","period":3,"provider":"drand","public_key":"","scheme":"bls-unchained-g1-rfc9380"},"result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: invalid public key length 0: ERR_UNKNOWN_PROFILE"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":0,"id":"datekeys:quicknet:v1","max_round":84467433600,"network":"quicknet","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-g1-rfc9380"},"result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: invalid genesis time 0: ERR_UNKNOWN_PROFILE"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":83903165811,"network":"quicknet","period":3,"provider":"x","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-g1-rfc9380"},"result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: unsupported provider \"x\": ERR_UNKNOWN_PROFILE"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":83903165811,"network":"quicknet","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-on-g1"},"result":"ok"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":83903165811,"network":"quicknet","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-on-g1"},"result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: scheme \"bls-unchained-on-g1\" is not bls-unchained-g1-rfc9380, the only scheme of V1: ERR_UNKNOWN_PROFILE"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":83903165811,"network":"quicknet","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-g1-rfc9380"},"result":"ok"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":83903165811,"network":"quicknet","period":3,"provider":"drand","public_key":"cf87a715c185fffc915f9f1727ad3f9636f944d71d857fdeeab012291255a38e03cba65f31c021431341375991575b17ffc58ea27dd56206821da91223e1f72fe51c75fe30c3986ead0d7d9a622824fde5104421e7a461d13b151227ddc30af0bd637a16cb37c162b92ad9d6b5109ac4d1e0cf815c21c5e2a559f6de3d674a1e7318c80c96bdb26544087fc4e289ae7620c7bb8e8adcd28725f72f2d2551a278a2077d6c167919a629f16e672034941ed1927b97bf4356697eaad969a216315e78dabec06e290d05b0b60e3c2a201a6c0ad7f07a2e01cfa9a429e6ec0ff5c3ab81e359612bbf8bacefbf6e3f53370ba5d30184019e73b39f30c9cc8861a8137eabce1132d5bd3d78d9423f4f37befa45d57d018fd9b0fb3b1b61418c8d4233517c30c9b7ee9a2ecd81cdc55cba922160a38ed77a63eb08576706004c5d63ccfe49b15a3212d5987569f424d3110120673b05dad0ad0432fb2a782b74f9c906654dd0355ee3c90f2553d974a85580a3ae05d55d81502f785444b40fe226452ff5298f08a02be10412336a5a390458e6cce9783174f0d65724e08f9e7033db7606eb9e4c23469bbddd23b4212659480903c7c5d123f131cfa9dba39d27537da5f3428361baaa262b7ac53f50f7a985482c4cdace6e5922c7b83daa4b2cc248f16b9989d6cb55cdf886dd6ef9f1dea716d3aa763bc5005f70edfa2849fff315305b9a6bbb857769b85495069320f6eba8a47e1d27ffd6283d399092ae4576c851afde52eeb3cf17b1ba0881e54be59fa56310fdc769af61fdeb3ec9f7700729f5f25547d34de2244bf839b20a69d4237c43e55c43c9b238eda5bd443da05e3594b1c915d9af90d21758374cc68017c7b2563ac3f81df50b2cda448ec4293603587235b843b1ffbef0ea8a2b2e0c10d1ac9c7626e18798bebe2206e98088c8aecd2be8a6278a90e06b20dd36dae022442a798772912aa1239ab896c6174b352c6b355b8cc0862b31c7167c71fd7a252a1043c46a4124308ae3656a50e1c2be30154a00c83faca0bd52d359ae9044f154717e0adcb68450c15fd1c19e16851c4586a742467434fba558684072385a6fdec6707454ffc4731f8f587238d45fa140710ac6bb4a058c07fb028db32b84a79bfe04caa7f1d51760c09d6ff7609d288548a18789364b9dd145e70197df650c027a2c6293f7347f32e9e2873af1eefbc4a070001518bd2603541e4f9a19961a6863da42934dc2e5716a6edf818f7bbe87ef4dd77cd0e096db2439e51b0d5f14ec3dfb5e4ce9733757a0bab7f7ddf47a473bedbe29b6041bab7d40acd8bdd1d961db4cfb1db82f01ea0fb93a3b202c89c361b41a405f75d0cccd871b9706221277f1fe45e664bd9e41b698d0bf934368c4d7cd6f0d80c4d3c0716844911a64523eddb6e8d739aa24c2ef391685cbc2827a621a","scheme":"bls-unchained-g1-rfc9380"},"result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: public key is not the canonical encoding of a point of the key group of bls-unchained-g1-rfc9380: ERR_UNKNOWN_PROFILE"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":83903165811,"network":"quicknet","period":3,"provider":"","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-g1-rfc9380"},"result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: invalid provider, network or scheme name: ERR_UNKNOWN_PROFILE"},
@ -188,11 +188,11 @@
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":83903165811,"network":"quicknet","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"nope"},"result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: \"nope\" is not a drand scheme: ERR_UNKNOWN_PROFILE"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":83903165811,"network":"quicknet","period":3,"provider":"drand","public_key":"cf87a715c185fffc915f9f1727ad3f9636f944d71d857fdeeab012291255a38e03cba65f31c021431341375991575b17ffc58ea27dd56206821da91223e1f72fe51c75fe30c3986ead0d7d9a622824fde5104421e7a461d13b151227ddc30af0bd637a16cb37c162b92ad9d6b5109ac4d1e0cf815c21c5e2a559f6de3d674a1e7318c80c96bdb26544087fc4e289ae7620c7bb8e8adcd28725f72f2d2551a278a2077d6c167919a629f16e672034941ed1927b97bf4356697eaad969a216315e78dabec06e290d05b0b60e3c2a201a6c0ad7f07a2e01cfa9a429e6ec0ff5c3ab81e359612bbf8bacefbf6e3f53370ba5d30184019e73b39f30c9cc8861a8137eabce1132d5bd3d78d9423f4f37befa45d57d018fd9b0fb3b1b61418c8d4233517c30c9b7ee9a2ecd81cdc55cba922160a38ed77a63eb08576706004c5d63ccfe49b15a3212d5987569f424d3110120673b05dad0ad0432fb2a782b74f9c906654dd0355ee3c90f2553d974a85580a3ae05d55d81502f785444b40fe226452ff5298f08a02be10412336a5a390458e6cce9783174f0d65724e08f9e7033db7606eb9e4c23469bbddd23b4212659480903c7c5d123f131cfa9dba39d27537da5f3428361baaa262b7ac53f50f7a985482c4cdace6e5922c7b83daa4b2cc248f16b9989d6cb55cdf886dd6ef9f1dea716d3aa763bc5005f70edfa2849fff315305b9a6bbb857769b85495069320f6eba8a47e1d27ffd6283d399092ae4576c851afde52eeb3cf17b1ba0881e54be59fa56310fdc769af61fdeb3ec9f7700729f5f25547d34de2244bf839b20a69d4237c43e55c43c9b238eda5bd443da05e3594b1c915d9af90d21758374cc68017c7b2563ac3f81df50b2cda448ec4293603587235b843b1ffbef0ea8a2b2e0c10d1ac9c7626e18798bebe2206e98088c8aecd2be8a6278a90e06b20dd36dae022442a798772912aa1239ab896c6174b352c6b355b8cc0862b31c7167c71fd7a252a1043c46a4124308ae3656a50e1c2be30154a00c83faca0bd52d359ae9044f154717e0adcb68450c15fd1c19e16851c4586a742467434fba558684072385a6fdec6707454ffc4731f8f587238d45fa140710ac6bb4a058c07fb028db32b84a79bfe04caa7f1d51760c09d6ff7609d288548a18789364b9dd145e70197df650c027a2c6293f7347f32e9e2873af1eefbc4a070001518bd2603541e4f9a19961a6863da42934dc2e5716a6edf818f7bbe87ef4dd77cd0e096db2439e51b0d5f14ec3dfb5e4ce9733757a0bab7f7ddf47a473bedbe29b6041bab7d40acd8bdd1d961db4cfb1db82f01ea0fb93a3b202c89c361b41a405f75d0cccd871b9706221277f1fe45e664bd9e41b698d0bf934368c4d7cd6f0d80c4d3c0716844911a64523eddb6e8d739aa24c2ef391685cbc2827a621a","scheme":"bls-unchained-g1-rfc9380"},"result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: public key is not the canonical encoding of a point of the key group of bls-unchained-g1-rfc9380: ERR_UNKNOWN_PROFILE"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":253402300798,"id":"datekeys:quicknet:v1","max_round":1,"network":"quicknet","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-g1-rfc9380"},"result":"ERR_PROFILE_MISMATCH","text":"profile datekeys:quicknet:v1: parameters hash to chain 5daeb5ff2fdfcd368828087dd982690008eccb638dc31cb78b7bfa450cbede18, not the pinned 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971: ERR_PROFILE_MISMATCH"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":83903165811,"network":"quicknet","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"pedersen-bls-chained"},"result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: scheme \"pedersen-bls-chained\" is not supported by tlock: ERR_UNKNOWN_PROFILE"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":83903165811,"network":"quicknet","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"pedersen-bls-chained"},"result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: scheme \"pedersen-bls-chained\" is not bls-unchained-g1-rfc9380, the only scheme of V1: ERR_UNKNOWN_PROFILE"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":9007199254740991,"id":"datekeys:quicknet:v1","max_round":0,"network":"quicknet","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-g1-rfc9380"},"result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: invalid genesis time 9007199254740991: ERR_UNKNOWN_PROFILE"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":83903165811,"network":"quicknet","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-on-g1"},"result":"ok"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":83903165811,"network":"quicknet","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-on-g1"},"result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: scheme \"bls-unchained-on-g1\" is not bls-unchained-g1-rfc9380, the only scheme of V1: ERR_UNKNOWN_PROFILE"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1,"id":"datekeys:quicknet:v1","max_round":84467433600,"network":"quicknet","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-g1-rfc9380"},"result":"ERR_PROFILE_MISMATCH","text":"profile datekeys:quicknet:v1: parameters hash to chain 950cfcb27d257316ed5fa4216178445129f54b6b09bb6051ea45b7ab0dff8f0a, not the pinned 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971: ERR_PROFILE_MISMATCH"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":83903165811,"network":"quicknet","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"pedersen-bls-chained"},"result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: scheme \"pedersen-bls-chained\" is not supported by tlock: ERR_UNKNOWN_PROFILE"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":83903165811,"network":"quicknet","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"pedersen-bls-chained"},"result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: scheme \"pedersen-bls-chained\" is not bls-unchained-g1-rfc9380, the only scheme of V1: ERR_UNKNOWN_PROFILE"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":0,"network":"quicknet","period":-1,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-g1-rfc9380"},"result":"ERR_NON_CANONICAL_CBOR","text":"profile \"datekeys:quicknet:v1\": period -1s is not a whole number of seconds in 1..86400: ERR_NON_CANONICAL_CBOR"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":83903165811,"network":"quicknet","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-g1-rfc9380"},"result":"ok"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"","max_round":83903165811,"network":"quicknet","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-g1-rfc9380"},"result":"ERR_UNKNOWN_PROFILE","text":"profile: invalid profile_id \"\": ERR_UNKNOWN_PROFILE"},
@ -204,14 +204,14 @@
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":2913305,"network":"quicknet","period":86400,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-g1-rfc9380"},"result":"ERR_PROFILE_MISMATCH","text":"profile datekeys:quicknet:v1: parameters hash to chain c11da7002fbe7b2ab5db749677c90aed2afdf497830e0b1ffecb743c823b2888, not the pinned 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971: ERR_PROFILE_MISMATCH"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":2913305,"network":"quicknet","period":86400,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-g1-rfc9380"},"result":"ERR_PROFILE_MISMATCH","text":"profile datekeys:quicknet:v1: parameters hash to chain c11da7002fbe7b2ab5db749677c90aed2afdf497830e0b1ffecb743c823b2888, not the pinned 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971: ERR_PROFILE_MISMATCH"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":2796773,"network":"quicknet","period":90000,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-g1-rfc9380"},"result":"ERR_NON_CANONICAL_CBOR","text":"profile \"datekeys:quicknet:v1\": period 25h0m0s is not a whole number of seconds in 1..86400: ERR_NON_CANONICAL_CBOR"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":83903165811,"network":"quicknet","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-on-g1"},"result":"ok"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":83903165811,"network":"quicknet","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-on-g1"},"result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: scheme \"bls-unchained-on-g1\" is not bls-unchained-g1-rfc9380, the only scheme of V1: ERR_UNKNOWN_PROFILE"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":83903165811,"network":"quicknet","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-g1-rfc9380"},"result":"ok"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":83903165811,"network":"quicknet","period":3,"provider":"drand","public_key":"","scheme":"bls-unchained-g1-rfc9380"},"result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: invalid public key length 0: ERR_UNKNOWN_PROFILE"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":-1,"id":"datekeys:quicknet:v1","max_round":84467433601,"network":"quicknet","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-g1-rfc9380"},"result":"ERR_NON_CANONICAL_CBOR","text":"profile \"datekeys:quicknet:v1\": genesis time -1 outside 0..9007199254740991: ERR_NON_CANONICAL_CBOR"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":2913271,"network":"quicknet","period":86401,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-g1-rfc9380"},"result":"ERR_NON_CANONICAL_CBOR","text":"profile \"datekeys:quicknet:v1\": period 24h0m1s is not a whole number of seconds in 1..86400: ERR_NON_CANONICAL_CBOR"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":-1,"id":"datekeys:quicknet:v1","max_round":84467433601,"network":"quicknet","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-g1-rfc9380"},"result":"ERR_NON_CANONICAL_CBOR","text":"profile \"datekeys:quicknet:v1\": genesis time -1 outside 0..9007199254740991: ERR_NON_CANONICAL_CBOR"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"Q","max_round":83903165811,"network":"quicknet","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-g1-rfc9380"},"result":"ERR_UNKNOWN_PROFILE","text":"profile: invalid profile_id \"Q\": ERR_UNKNOWN_PROFILE"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":83903165811,"network":"quicknet","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"pedersen-bls-chained"},"result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: scheme \"pedersen-bls-chained\" is not supported by tlock: ERR_UNKNOWN_PROFILE"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":83903165811,"network":"quicknet","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"pedersen-bls-chained"},"result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: scheme \"pedersen-bls-chained\" is not bls-unchained-g1-rfc9380, the only scheme of V1: ERR_UNKNOWN_PROFILE"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":83903165811,"network":"quicknet","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-g1-rfc9380"},"result":"ok"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":83903165811,"network":"quicknet","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-g1-rfc9380"},"result":"ok"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":83903165811,"network":"quicknet","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"nope"},"result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: \"nope\" is not a drand scheme: ERR_UNKNOWN_PROFILE"},
@ -223,7 +223,7 @@
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":83903165811,"network":"quicknet","period":3,"provider":"drand","public_key":"cf87a715c185fffc915f9f1727ad3f9636f944d71d857fdeeab012291255a38e03cba65f31c021431341375991575b17ffc58ea27dd56206821da91223e1f72fe51c75fe30c3986ead0d7d9a622824fde5104421e7a461d13b151227ddc30af0bd637a16cb37c162b92ad9d6b5109ac4d1e0cf815c21c5e2a559f6de3d674a1e7318c80c96bdb26544087fc4e289ae7620c7bb8e8adcd28725f72f2d2551a278a2077d6c167919a629f16e672034941ed1927b97bf4356697eaad969a216315e78dabec06e290d05b0b60e3c2a201a6c0ad7f07a2e01cfa9a429e6ec0ff5c3ab81e359612bbf8bacefbf6e3f53370ba5d30184019e73b39f30c9cc8861a8137eabce1132d5bd3d78d9423f4f37befa45d57d018fd9b0fb3b1b61418c8d4233517c30c9b7ee9a2ecd81cdc55cba922160a38ed77a63eb08576706004c5d63ccfe49b15a3212d5987569f424d3110120673b05dad0ad0432fb2a782b74f9c906654dd0355ee3c90f2553d974a85580a3ae05d55d81502f785444b40fe226452ff5298f08a02be10412336a5a390458e6cce9783174f0d65724e08f9e7033db7606eb9e4c23469bbddd23b4212659480903c7c5d123f131cfa9dba39d27537da5f3428361baaa262b7ac53f50f7a985482c4cdace6e5922c7b83daa4b2cc248f16b9989d6cb55cdf886dd6ef9f1dea716d3aa763bc5005f70edfa2849fff315305b9a6bbb857769b85495069320f6eba8a47e1d27ffd6283d399092ae4576c851afde52eeb3cf17b1ba0881e54be59fa56310fdc769af61fdeb3ec9f7700729f5f25547d34de2244bf839b20a69d4237c43e55c43c9b238eda5bd443da05e3594b1c915d9af90d21758374cc68017c7b2563ac3f81df50b2cda448ec4293603587235b843b1ffbef0ea8a2b2e0c10d1ac9c7626e18798bebe2206e98088c8aecd2be8a6278a90e06b20dd36dae022442a798772912aa1239ab896c6174b352c6b355b8cc0862b31c7167c71fd7a252a1043c46a4124308ae3656a50e1c2be30154a00c83faca0bd52d359ae9044f154717e0adcb68450c15fd1c19e16851c4586a742467434fba558684072385a6fdec6707454ffc4731f8f587238d45fa140710ac6bb4a058c07fb028db32b84a79bfe04caa7f1d51760c09d6ff7609d288548a18789364b9dd145e70197df650c027a2c6293f7347f32e9e2873af1eefbc4a070001518bd2603541e4f9a19961a6863da42934dc2e5716a6edf818f7bbe87ef4dd77cd0e096db2439e51b0d5f14ec3dfb5e4ce9733757a0bab7f7ddf47a473bedbe29b6041bab7d40acd8bdd1d961db4cfb1db82f01ea0fb93a3b202c89c361b41a405f75d0cccd871b9706221277f1fe45e664bd9e41b698d0bf934368c4d7cd6f0d80c4d3c0716844911a64523eddb6e8d739aa24c2ef391685cbc2827a621a","scheme":"bls-unchained-g1-rfc9380"},"result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: public key is not the canonical encoding of a point of the key group of bls-unchained-g1-rfc9380: ERR_UNKNOWN_PROFILE"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":83903165811,"network":"quicknet","period":3,"provider":"drand","public_key":"9a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab","scheme":"bls-unchained-g1-rfc9380"},"result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: public key is not the canonical encoding of a point of the key group of bls-unchained-g1-rfc9380: ERR_UNKNOWN_PROFILE"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1,"id":"datekeys:quicknet:v1","max_round":84467433600,"network":"quicknet","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-g1-rfc9380"},"result":"ERR_PROFILE_MISMATCH","text":"profile datekeys:quicknet:v1: parameters hash to chain 950cfcb27d257316ed5fa4216178445129f54b6b09bb6051ea45b7ab0dff8f0a, not the pinned 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971: ERR_PROFILE_MISMATCH"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":83903165811,"network":"quicknet","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-on-g1"},"result":"ok"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":83903165811,"network":"quicknet","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-on-g1"},"result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: scheme \"bls-unchained-on-g1\" is not bls-unchained-g1-rfc9380, the only scheme of V1: ERR_UNKNOWN_PROFILE"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":83903165811,"network":"quicknet","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"nope"},"result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: \"nope\" is not a drand scheme: ERR_UNKNOWN_PROFILE"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"","max_round":83903165811,"network":"quicknet","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-g1-rfc9380"},"result":"ERR_UNKNOWN_PROFILE","text":"profile: invalid profile_id \"\": ERR_UNKNOWN_PROFILE"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":253402300799,"id":"datekeys:quicknet:v1","max_round":1,"network":"quicknet","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-g1-rfc9380"},"result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: invalid genesis time 253402300799: ERR_UNKNOWN_PROFILE"},
@ -322,7 +322,7 @@
{"hex":"ab007819646174656b6579732d70726f76696465722d70726f66696c6501010274646174656b6579733a717569636b6e65743a763103656472616e640468717569636b6e6574055820000000000000000000000000000000000000000000000000000000000000000006586083cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a0700081a64e62127097818626c732d756e636861696e65642d67312d726663393338300a5820f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","name":"another chain_hash, and period 0","result":"ERR_NON_CANONICAL_CBOR","text":"profile: key 7: period 0: ERR_NON_CANONICAL_CBOR"},
{"hex":"ab007819646174656b6579732d70726f76696465722d70726f66696c6501010274646174656b6579733a717569636b6e65743a763103656472616e640468717569636b6e6574055820000000000000000000000000000000000000000000000000000000000000000006586083cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a071a00015181081a64e62127097818626c732d756e636861696e65642d67312d726663393338300a5820f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","name":"another chain_hash, and period 86401","result":"ERR_NON_CANONICAL_CBOR","text":"profile: period 86401 s out of range: ERR_NON_CANONICAL_CBOR"},
{"hex":"ab007819646174656b6579732d70726f76696465722d70726f66696c6501010274646174656b6579733a717569636b6e65743a763103656472616e640468717569636b6e6574055820000000000000000000000000000000000000000000000000000000000000000006586083cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a07030800097818626c732d756e636861696e65642d67312d726663393338300a5820f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","name":"another chain_hash, and genesis_time 0","result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: invalid genesis time 0: ERR_UNKNOWN_PROFILE"},
{"hex":"ab007819646174656b6579732d70726f76696465722d70726f66696c6501010274646174656b6579733a717569636b6e65743a763103656472616e640468717569636b6e6574055820000000000000000000000000000000000000000000000000000000000000000006586083cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a0703081a64e621270974706564657273656e2d626c732d636861696e65640a5820f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","name":"another chain_hash, and the scheme pedersen-bls-chained","result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: scheme \"pedersen-bls-chained\" is not supported by tlock: ERR_UNKNOWN_PROFILE"},
{"hex":"ab007819646174656b6579732d70726f76696465722d70726f66696c6501010274646174656b6579733a717569636b6e65743a763103656472616e640468717569636b6e6574055820000000000000000000000000000000000000000000000000000000000000000006586083cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a0703081a64e621270974706564657273656e2d626c732d636861696e65640a5820f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","name":"another chain_hash, and the scheme pedersen-bls-chained","result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: scheme \"pedersen-bls-chained\" is not bls-unchained-g1-rfc9380, the only scheme of V1: ERR_UNKNOWN_PROFILE"},
{"hex":"aa007819646174656b6579732d70726f76696465722d70726f66696c6501010274646174656b6579733a717569636b6e65743a763103656472616e640468717569636b6e6574055820000000000000000000000000000000000000000000000000000000000000000006586083cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a0703081a64e62127097818626c732d756e636861696e65642d67312d72666339333830","name":"another chain_hash, and no key 10","result":"ERR_NON_CANONICAL_CBOR","text":"profile: 10 keys, want all 11: ERR_NON_CANONICAL_CBOR"},
{"hex":"ac007819646174656b6579732d70726f76696465722d70726f66696c6501010274646174656b6579733a717569636b6e65743a763103656472616e640468717569636b6e6574055820000000000000000000000000000000000000000000000000000000000000000006586083cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a0703081a64e62127097818626c732d756e636861696e65642d67312d726663393338300a5820f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e1400","name":"another chain_hash, and an unknown key","result":"ERR_NON_CANONICAL_CBOR","text":"profile: codec: offset 1: map of 12 entries, at most 11: ERR_NON_CANONICAL_CBOR"},
{"hex":"ab007819646174656b6579732d70726f76696465722d70726f66696c6501010274646174656b6579733a717569636b6e65743a763103656472616e640468717569636b6e6574055820000000000000000000000000000000000000000000000000000000000000000006586083cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a0703081a64e62127097818626c732d756e636861696e65642d67312d726663393338300a5820f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e00","name":"another chain_hash, and a trailing byte","result":"ERR_NON_CANONICAL_CBOR","text":"profile: codec: offset 274: 1 trailing bytes: ERR_NON_CANONICAL_CBOR"},
@ -332,7 +332,7 @@
{"hex":"ab007819646174656b6579732d70726f76696465722d70726f66696c6501010274646174656b6579733a717569636b6e65743a763103656472616e640468717569636b6e657405582052db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e97106583097f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0700081a64e62127097818626c732d756e636861696e65642d67312d726663393338300a5820f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","name":"the public key of G1, and period 0","result":"ERR_NON_CANONICAL_CBOR","text":"profile: key 7: period 0: ERR_NON_CANONICAL_CBOR"},
{"hex":"ab007819646174656b6579732d70726f76696465722d70726f66696c6501010274646174656b6579733a717569636b6e65743a763103656472616e640468717569636b6e657405582052db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e97106583097f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb071a00015181081a64e62127097818626c732d756e636861696e65642d67312d726663393338300a5820f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","name":"the public key of G1, and period 86401","result":"ERR_NON_CANONICAL_CBOR","text":"profile: period 86401 s out of range: ERR_NON_CANONICAL_CBOR"},
{"hex":"ab007819646174656b6579732d70726f76696465722d70726f66696c6501010274646174656b6579733a717569636b6e65743a763103656472616e640468717569636b6e657405582052db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e97106583097f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb07030800097818626c732d756e636861696e65642d67312d726663393338300a5820f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","name":"the public key of G1, and genesis_time 0","result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: invalid genesis time 0: ERR_UNKNOWN_PROFILE"},
{"hex":"ab007819646174656b6579732d70726f76696465722d70726f66696c6501010274646174656b6579733a717569636b6e65743a763103656472616e640468717569636b6e657405582052db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e97106583097f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0703081a64e621270974706564657273656e2d626c732d636861696e65640a5820f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","name":"the public key of G1, and the scheme pedersen-bls-chained","result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: scheme \"pedersen-bls-chained\" is not supported by tlock: ERR_UNKNOWN_PROFILE"},
{"hex":"ab007819646174656b6579732d70726f76696465722d70726f66696c6501010274646174656b6579733a717569636b6e65743a763103656472616e640468717569636b6e657405582052db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e97106583097f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0703081a64e621270974706564657273656e2d626c732d636861696e65640a5820f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","name":"the public key of G1, and the scheme pedersen-bls-chained","result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: scheme \"pedersen-bls-chained\" is not bls-unchained-g1-rfc9380, the only scheme of V1: ERR_UNKNOWN_PROFILE"},
{"hex":"aa007819646174656b6579732d70726f76696465722d70726f66696c6501010274646174656b6579733a717569636b6e65743a763103656472616e640468717569636b6e657405582052db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e97106583097f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0703081a64e62127097818626c732d756e636861696e65642d67312d72666339333830","name":"the public key of G1, and no key 10","result":"ERR_NON_CANONICAL_CBOR","text":"profile: 10 keys, want all 11: ERR_NON_CANONICAL_CBOR"},
{"hex":"ac007819646174656b6579732d70726f76696465722d70726f66696c6501010274646174656b6579733a717569636b6e65743a763103656472616e640468717569636b6e657405582052db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e97106583097f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0703081a64e62127097818626c732d756e636861696e65642d67312d726663393338300a5820f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e1400","name":"the public key of G1, and an unknown key","result":"ERR_NON_CANONICAL_CBOR","text":"profile: codec: offset 1: map of 12 entries, at most 11: ERR_NON_CANONICAL_CBOR"},
{"hex":"ab007819646174656b6579732d70726f76696465722d70726f66696c6501010274646174656b6579733a717569636b6e65743a763103656472616e640468717569636b6e657405582052db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e97106583097f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0703081a64e62127097818626c732d756e636861696e65642d67312d726663393338300a5820f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e00","name":"the public key of G1, and a trailing byte","result":"ERR_NON_CANONICAL_CBOR","text":"profile: codec: offset 226: 1 trailing bytes: ERR_NON_CANONICAL_CBOR"},
@ -362,7 +362,7 @@
{"hex":"ab007819646174656b6579732d70726f76696465722d70726f66696c6501010274646174656b6579733a717569636b6e65743a763103656472616e640468717569636b6e657405582052db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e97106586083cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a07030800097818626c732d756e636861696e65642d67312d726663393338300a5820f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e00","name":"genesis_time 0, and a trailing byte","result":"ERR_NON_CANONICAL_CBOR","text":"profile: codec: offset 270: 1 trailing bytes: ERR_NON_CANONICAL_CBOR"},
{"hex":"ac007819646174656b6579732d70726f76696465722d70726f66696c6501010274646174656b6579733a717569636b6e65743a763103656472616e640468717569636b6e657405582052db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e97106586083cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a07030800097818626c732d756e636861696e65642d67312d726663393338300a5820f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","name":"genesis_time 0, and a head of one entry more","result":"ERR_NON_CANONICAL_CBOR","text":"profile: codec: offset 1: map of 12 entries, at most 11: ERR_NON_CANONICAL_CBOR"},
{"hex":"ab007819646174656b6579732d70726f76696465722d70726f66696c650274646174656b6579733a717569636b6e65743a7631010103656472616e640468717569636b6e657405582052db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e97106586083cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a07030800097818626c732d756e636861696e65642d67312d726663393338300a5820f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","name":"genesis_time 0, and keys 1 and 2 swapped","result":"ERR_NON_CANONICAL_CBOR","text":"profile: codec: offset 30: map key 2 where key 1 was expected: ERR_NON_CANONICAL_CBOR"},
{"hex":"ab007819646174656b6579732d70726f76696465722d70726f66696c6501010274646174656b6579733a717569636b6e65743a763103656472616e640468717569636b6e657405582052db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e97106586083cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a0703081a64e621270974706564657273656e2d626c732d636861696e65640a5820f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","name":"the scheme pedersen-bls-chained","result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: scheme \"pedersen-bls-chained\" is not supported by tlock: ERR_UNKNOWN_PROFILE"},
{"hex":"ab007819646174656b6579732d70726f76696465722d70726f66696c6501010274646174656b6579733a717569636b6e65743a763103656472616e640468717569636b6e657405582052db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e97106586083cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a0703081a64e621270974706564657273656e2d626c732d636861696e65640a5820f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","name":"the scheme pedersen-bls-chained","result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: scheme \"pedersen-bls-chained\" is not bls-unchained-g1-rfc9380, the only scheme of V1: ERR_UNKNOWN_PROFILE"},
{"hex":"aa007819646174656b6579732d70726f76696465722d70726f66696c6501010274646174656b6579733a717569636b6e65743a763103656472616e640468717569636b6e657405582052db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e97106586083cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a0703081a64e621270974706564657273656e2d626c732d636861696e6564","name":"the scheme pedersen-bls-chained, and no key 10","result":"ERR_NON_CANONICAL_CBOR","text":"profile: 10 keys, want all 11: ERR_NON_CANONICAL_CBOR"},
{"hex":"ac007819646174656b6579732d70726f76696465722d70726f66696c6501010274646174656b6579733a717569636b6e65743a763103656472616e640468717569636b6e657405582052db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e97106586083cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a0703081a64e621270974706564657273656e2d626c732d636861696e65640a5820f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e1400","name":"the scheme pedersen-bls-chained, and an unknown key","result":"ERR_NON_CANONICAL_CBOR","text":"profile: codec: offset 1: map of 12 entries, at most 11: ERR_NON_CANONICAL_CBOR"},
{"hex":"ab007819646174656b6579732d70726f76696465722d70726f66696c6501010274646174656b6579733a717569636b6e65743a763103656472616e640468717569636b6e657405582052db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e97106586083cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a0703081a64e621270974706564657273656e2d626c732d636861696e65640a5820f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e00","name":"the scheme pedersen-bls-chained, and a trailing byte","result":"ERR_NON_CANONICAL_CBOR","text":"profile: codec: offset 269: 1 trailing bytes: ERR_NON_CANONICAL_CBOR"},

@ -1,5 +1,5 @@
{
"spec": "0.11",
"spec": "0.15",
"generator": "tool/formats_go_vectors.go",
"description": "RFC 3339: time.Parse with time.RFC3339Nano, ok or error, and Format with RFC3339 and RFC3339Nano in UTC; datekey.Resolve, RoundTime and DateKey.Validate, and Profile.MaxRound, on the Quicknet profile with other genesis times and periods.",
"parse": [

@ -5,7 +5,7 @@
/// Part of test/vectors/formats_framing.json.
const formatsFramingJson = r'''
{
"spec": "0.11",
"spec": "0.15",
"generator": "tool/formats_go_vectors.go",
"description": "The PRELUDE of a .dkc (capsule.ParsePrelude), the steps 1 to 3 of capsule.Inspect on truncated and edited fixtures (with the step that fails, 0 when steps 1 to 8 pass), and whole .dkk files (accesskey.Decode), with the result, the code and the text of the Go reference.",
"prelude": [
@ -181,7 +181,7 @@ const formatsFramingJson = r'''
/// Part of test/vectors/formats_header.json.
const formatsHeaderJson = r'''
{
"spec": "0.11",
"spec": "0.15",
"generator": "tool/formats_go_vectors.go",
"description": "PUBLIC_HEADER (capsule.DecodeHeader) of the fixtures, edited, and built field by field.",
"header": [
@ -301,7 +301,7 @@ const formatsHeaderJson = r'''
/// Part of test/vectors/formats_control.json.
const formatsControlJson = r'''
{
"spec": "0.11",
"spec": "0.15",
"generator": "tool/formats_go_vectors.go",
"description": "CONTROL_CBOR of the three formats (capsule.DecodeControl) of the fixtures, in their format and in another, edited, and built field by field.",
"control": [
@ -440,7 +440,7 @@ const formatsControlJson = r'''
/// Part of test/vectors/formats_profile.json.
const formatsProfileJson = r'''
{
"spec": "0.11",
"spec": "0.15",
"generator": "tool/formats_go_vectors.go",
"description": "Provider Profiles: profile.Decode of the Quicknet profile, edited and with fields replaced, and Profile.Validate of values.",
"decode": [
@ -470,7 +470,7 @@ const formatsProfileJson = r'''
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":83903165811,"network":"Q","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-g1-rfc9380"},"result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: invalid provider, network or scheme name: ERR_UNKNOWN_PROFILE"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":0,"id":"datekeys:quicknet:v1","max_round":84467433600,"network":"quicknet","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-g1-rfc9380"},"result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: invalid genesis time 0: ERR_UNKNOWN_PROFILE"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":83903165811,"network":"default","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-g1-rfc9380"},"result":"ERR_PROFILE_MISMATCH","text":"profile datekeys:quicknet:v1: parameters hash to chain bb53bd3c1f404463b224d27e22872c4754f7d4f5549693d349f616c3ac27d4a9, not the pinned 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971: ERR_PROFILE_MISMATCH"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":83903165811,"network":"quicknet","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"pedersen-bls-chained"},"result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: scheme \"pedersen-bls-chained\" is not supported by tlock: ERR_UNKNOWN_PROFILE"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":83903165811,"network":"quicknet","period":3,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"pedersen-bls-chained"},"result":"ERR_UNKNOWN_PROFILE","text":"profile datekeys:quicknet:v1: scheme \"pedersen-bls-chained\" is not bls-unchained-g1-rfc9380, the only scheme of V1: ERR_UNKNOWN_PROFILE"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":2913271,"network":"quicknet","period":86401,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-g1-rfc9380"},"result":"ERR_NON_CANONICAL_CBOR","text":"profile \"datekeys:quicknet:v1\": period 24h0m1s is not a whole number of seconds in 1..86400: ERR_NON_CANONICAL_CBOR"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":2913271,"network":"quicknet","period":86401,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-g1-rfc9380"},"result":"ERR_NON_CANONICAL_CBOR","text":"profile \"datekeys:quicknet:v1\": period 24h0m1s is not a whole number of seconds in 1..86400: ERR_NON_CANONICAL_CBOR"},
{"profile":{"chain_hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","genesis_seed":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","genesis_time":1692803367,"id":"datekeys:quicknet:v1","max_round":2913305,"network":"quicknet","period":86400,"provider":"drand","public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","scheme":"bls-unchained-g1-rfc9380"},"result":"ERR_PROFILE_MISMATCH","text":"profile datekeys:quicknet:v1: parameters hash to chain c11da7002fbe7b2ab5db749677c90aed2afdf497830e0b1ffecb743c823b2888, not the pinned 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971: ERR_PROFILE_MISMATCH"},
@ -504,7 +504,7 @@ const formatsProfileJson = r'''
/// Part of test/vectors/formats_extension.json.
const formatsExtensionJson = r'''
{
"spec": "0.11",
"spec": "0.15",
"generator": "tool/formats_go_vectors.go",
"description": "Extension arrays through codec.Unmarshal with extension.DecodeArray and EncodeArray, Canonical, CheckDisjoint, CheckCriticalIn and CheckNoncriticalIn with the registry placed of the generator (or CheckCritical and CheckNoncritical when object is empty, and no registry when registry is none), and CheckWrite with extension.Standard.",
"array": [
@ -596,7 +596,7 @@ const formatsExtensionJson = r'''
/// Part of test/vectors/formats_datekey.json.
const formatsDatekeyJson = r'''
{
"spec": "0.11",
"spec": "0.15",
"generator": "tool/formats_go_vectors.go",
"description": "dk1_ strings (datekey.Parse).",
"parse": [
@ -666,7 +666,7 @@ const formatsDatekeyJson = r'''
/// Part of test/vectors/formats_time.json.
const formatsTimeJson = r'''
{
"spec": "0.11",
"spec": "0.15",
"generator": "tool/formats_go_vectors.go",
"description": "RFC 3339: time.Parse with time.RFC3339Nano, ok or error, and Format with RFC3339 and RFC3339Nano in UTC; datekey.Resolve, RoundTime and DateKey.Validate, and Profile.MaxRound, on the Quicknet profile with other genesis times and periods.",
"parse": [
@ -817,7 +817,7 @@ const formatsTimeJson = r'''
/// Part of test/vectors/formats_padding.json.
const formatsPaddingJson = r'''
{
"spec": "0.11",
"spec": "0.15",
"generator": "tool/formats_go_vectors.go",
"description": "capsule.PaddedLength with both codes and capsule.PayloadAgeLength, at the boundaries of spec §29.1 up to L_MAX and past it; a code with null was rejected with text. check: the plaintext of PAYLOAD_AGE checked by capsule.Open against L and P (step 17): the content of the fixture (its .plaintext) followed by zeros, cut or extended to length bytes, with the byte at at set to value when given; step 0 when the capsule opens.",
"padded": [
@ -897,7 +897,7 @@ const formatsPaddingJson = r'''
/// Part of test/vectors/formats_encode.json.
const formatsEncodeJson = r'''
{
"spec": "0.11",
"spec": "0.15",
"generator": "tool/formats_go_vectors.go",
"description": "The encoders on values: capsule.EncodeHeader and EncodeControl, accesskey.Encode, profile.NewRegistry, and the canonical JSON and dk1_ string of DateKeys (CanonicalJSON and Compact, empty when not valid); an encoding is in hex, or as its length and SHA-256 when it is large. big is the size of the data of the noncritical extension a of version 1, bytes 0x01, that takes the object to its limit. limits: the decoders on objects at the limits of spec §57 and one byte past them: zeros bytes of zeros, or an extension array 81 a3 00 61 61 01 01 02 5a <len, 4 bytes> and len bytes 0x07 (extension_data), or Canonical of the extension a of version 1 whose data is len zeros (extension_canonical).",
"header": [
@ -932,7 +932,7 @@ const formatsEncodeJson = r'''
/// Part of test/vectors/formats_body.json.
const formatsBodyJson = r'''
{
"spec": "0.11",
"spec": "0.15",
"generator": "tool/formats_go_vectors.go",
"description": "The frame of BODY (capsule.ParseBodyFrame) against L, and the zeros of the security area (capsule.CheckArea).",
"frame": [

@ -1115,7 +1115,7 @@ const locatorUrisJson = r'''
["https://[2000::]:0443/",37,""],
["https://[2000::%25eth0]/",5,""],
["https://[2000::%eth0]/",29,""],
["https://[[2000::]/",0,"2000::"],
["https://[[2000::]/",11,""],
["https://[[2000::]]/",12,""],
["https://[2000::]]/",12,""],
["https://[2000::/",15,""],
@ -1138,7 +1138,7 @@ const locatorUrisJson = r'''
["https://[3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]:0443/",37,""],
["https://[3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff%25eth0]/",5,""],
["https://[3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff%eth0]/",29,""],
["https://[[3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]/",0,"3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"],
["https://[[3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]/",11,""],
["https://[[3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]]/",12,""],
["https://[3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]]/",12,""],
["https://[3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/",15,""],
@ -1886,7 +1886,7 @@ const locatorUrisJson = r'''
["https://[2620:4f:8000::]:0443/",37,""],
["https://[2620:4f:8000::%25eth0]/",5,""],
["https://[2620:4f:8000::%eth0]/",29,""],
["https://[[2620:4f:8000::]/",0,"2620:4f:8000::"],
["https://[[2620:4f:8000::]/",11,""],
["https://[[2620:4f:8000::]]/",12,""],
["https://[2620:4f:8000::]]/",12,""],
["https://[2620:4f:8000::/",15,""],
@ -1910,7 +1910,7 @@ const locatorUrisJson = r'''
["https://[2620:4f:8000:ffff:ffff:ffff:ffff:ffff]:0443/",37,""],
["https://[2620:4f:8000:ffff:ffff:ffff:ffff:ffff%25eth0]/",5,""],
["https://[2620:4f:8000:ffff:ffff:ffff:ffff:ffff%eth0]/",29,""],
["https://[[2620:4f:8000:ffff:ffff:ffff:ffff:ffff]/",0,"2620:4f:8000:ffff:ffff:ffff:ffff:ffff"],
["https://[[2620:4f:8000:ffff:ffff:ffff:ffff:ffff]/",11,""],
["https://[[2620:4f:8000:ffff:ffff:ffff:ffff:ffff]]/",12,""],
["https://[2620:4f:8000:ffff:ffff:ffff:ffff:ffff]]/",12,""],
["https://[2620:4f:8000:ffff:ffff:ffff:ffff:ffff/",15,""],
@ -1934,7 +1934,7 @@ const locatorUrisJson = r'''
["https://[2001:4860::]:0443/",37,""],
["https://[2001:4860::%25eth0]/",5,""],
["https://[2001:4860::%eth0]/",29,""],
["https://[[2001:4860::]/",0,"2001:4860::"],
["https://[[2001:4860::]/",11,""],
["https://[[2001:4860::]]/",12,""],
["https://[2001:4860::]]/",12,""],
["https://[2001:4860::/",15,""],
@ -1957,7 +1957,7 @@ const locatorUrisJson = r'''
["https://[2001:4860:ffff:ffff:ffff:ffff:ffff:ffff]:0443/",37,""],
["https://[2001:4860:ffff:ffff:ffff:ffff:ffff:ffff%25eth0]/",5,""],
["https://[2001:4860:ffff:ffff:ffff:ffff:ffff:ffff%eth0]/",29,""],
["https://[[2001:4860:ffff:ffff:ffff:ffff:ffff:ffff]/",0,"2001:4860:ffff:ffff:ffff:ffff:ffff:ffff"],
["https://[[2001:4860:ffff:ffff:ffff:ffff:ffff:ffff]/",11,""],
["https://[[2001:4860:ffff:ffff:ffff:ffff:ffff:ffff]]/",12,""],
["https://[2001:4860:ffff:ffff:ffff:ffff:ffff:ffff]]/",12,""],
["https://[2001:4860:ffff:ffff:ffff:ffff:ffff:ffff/",15,""],
@ -2389,19 +2389,19 @@ const locatorUrisJson = r'''
["https://ejemplo.org/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",75,""],
["ipfs://bafkreiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgfu",0,"bafkreiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgfu"],
["ipfs://bafkreiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgfu/x",0,"bafkreiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgfu"],
["ipfs://bafkreiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgfua",0,"bafkreiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgfua"],
["ipfs://bafkreiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgfua",7,""],
["ipfs://bafkreiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgfuaa",7,""],
["ipfs://bafkreiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgfuq",7,""],
["ipfs://bafkreiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgf",7,""],
["ipfs://bafybeiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgfu",0,"bafybeiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgfu"],
["ipfs://bafybeiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgfu/x",0,"bafybeiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgfu"],
["ipfs://bafybeiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgfua",0,"bafybeiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgfua"],
["ipfs://bafybeiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgfua",7,""],
["ipfs://bafybeiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgfuaa",7,""],
["ipfs://bafybeiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgfuq",7,""],
["ipfs://bafybeiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgf",7,""],
["ipfs://bafkqaaia",0,"bafkqaaia"],
["ipfs://bafkqaaia/x",0,"bafkqaaia"],
["ipfs://bafkqaaiaa",0,"bafkqaaiaa"],
["ipfs://bafkqaaiaa",7,""],
["ipfs://bafkqaaiaaa",7,""],
["ipfs://bafkqaaiaq",7,""],
["ipfs://bafkqaai",7,""],
@ -2508,7 +2508,7 @@ const locatorUrisJson = r'''
["ipfs://b/x",7,""],
["ipfs://baa",7,""],
["ipfs://bq",7,""],
["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",0,"bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia"],
["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",7,""],
["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdib",7,""],
["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdiaa",7,""],
["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi7",7,""],

@ -1110,7 +1110,7 @@
["https://[2000::]:0443/",37,""],
["https://[2000::%25eth0]/",5,""],
["https://[2000::%eth0]/",29,""],
["https://[[2000::]/",0,"2000::"],
["https://[[2000::]/",11,""],
["https://[[2000::]]/",12,""],
["https://[2000::]]/",12,""],
["https://[2000::/",15,""],
@ -1133,7 +1133,7 @@
["https://[3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]:0443/",37,""],
["https://[3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff%25eth0]/",5,""],
["https://[3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff%eth0]/",29,""],
["https://[[3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]/",0,"3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"],
["https://[[3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]/",11,""],
["https://[[3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]]/",12,""],
["https://[3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]]/",12,""],
["https://[3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/",15,""],
@ -1881,7 +1881,7 @@
["https://[2620:4f:8000::]:0443/",37,""],
["https://[2620:4f:8000::%25eth0]/",5,""],
["https://[2620:4f:8000::%eth0]/",29,""],
["https://[[2620:4f:8000::]/",0,"2620:4f:8000::"],
["https://[[2620:4f:8000::]/",11,""],
["https://[[2620:4f:8000::]]/",12,""],
["https://[2620:4f:8000::]]/",12,""],
["https://[2620:4f:8000::/",15,""],
@ -1905,7 +1905,7 @@
["https://[2620:4f:8000:ffff:ffff:ffff:ffff:ffff]:0443/",37,""],
["https://[2620:4f:8000:ffff:ffff:ffff:ffff:ffff%25eth0]/",5,""],
["https://[2620:4f:8000:ffff:ffff:ffff:ffff:ffff%eth0]/",29,""],
["https://[[2620:4f:8000:ffff:ffff:ffff:ffff:ffff]/",0,"2620:4f:8000:ffff:ffff:ffff:ffff:ffff"],
["https://[[2620:4f:8000:ffff:ffff:ffff:ffff:ffff]/",11,""],
["https://[[2620:4f:8000:ffff:ffff:ffff:ffff:ffff]]/",12,""],
["https://[2620:4f:8000:ffff:ffff:ffff:ffff:ffff]]/",12,""],
["https://[2620:4f:8000:ffff:ffff:ffff:ffff:ffff/",15,""],
@ -1929,7 +1929,7 @@
["https://[2001:4860::]:0443/",37,""],
["https://[2001:4860::%25eth0]/",5,""],
["https://[2001:4860::%eth0]/",29,""],
["https://[[2001:4860::]/",0,"2001:4860::"],
["https://[[2001:4860::]/",11,""],
["https://[[2001:4860::]]/",12,""],
["https://[2001:4860::]]/",12,""],
["https://[2001:4860::/",15,""],
@ -1952,7 +1952,7 @@
["https://[2001:4860:ffff:ffff:ffff:ffff:ffff:ffff]:0443/",37,""],
["https://[2001:4860:ffff:ffff:ffff:ffff:ffff:ffff%25eth0]/",5,""],
["https://[2001:4860:ffff:ffff:ffff:ffff:ffff:ffff%eth0]/",29,""],
["https://[[2001:4860:ffff:ffff:ffff:ffff:ffff:ffff]/",0,"2001:4860:ffff:ffff:ffff:ffff:ffff:ffff"],
["https://[[2001:4860:ffff:ffff:ffff:ffff:ffff:ffff]/",11,""],
["https://[[2001:4860:ffff:ffff:ffff:ffff:ffff:ffff]]/",12,""],
["https://[2001:4860:ffff:ffff:ffff:ffff:ffff:ffff]]/",12,""],
["https://[2001:4860:ffff:ffff:ffff:ffff:ffff:ffff/",15,""],
@ -2384,19 +2384,19 @@
["https://ejemplo.org/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",75,""],
["ipfs://bafkreiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgfu",0,"bafkreiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgfu"],
["ipfs://bafkreiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgfu/x",0,"bafkreiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgfu"],
["ipfs://bafkreiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgfua",0,"bafkreiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgfua"],
["ipfs://bafkreiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgfua",7,""],
["ipfs://bafkreiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgfuaa",7,""],
["ipfs://bafkreiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgfuq",7,""],
["ipfs://bafkreiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgf",7,""],
["ipfs://bafybeiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgfu",0,"bafybeiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgfu"],
["ipfs://bafybeiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgfu/x",0,"bafybeiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgfu"],
["ipfs://bafybeiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgfua",0,"bafybeiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgfua"],
["ipfs://bafybeiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgfua",7,""],
["ipfs://bafybeiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgfuaa",7,""],
["ipfs://bafybeiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgfuq",7,""],
["ipfs://bafybeiftzasotym35727cupoyoi6pikjw364gyvpexwpnj6k4dt7humgf",7,""],
["ipfs://bafkqaaia",0,"bafkqaaia"],
["ipfs://bafkqaaia/x",0,"bafkqaaia"],
["ipfs://bafkqaaiaa",0,"bafkqaaiaa"],
["ipfs://bafkqaaiaa",7,""],
["ipfs://bafkqaaiaaa",7,""],
["ipfs://bafkqaaiaq",7,""],
["ipfs://bafkqaai",7,""],
@ -2503,7 +2503,7 @@
["ipfs://b/x",7,""],
["ipfs://baa",7,""],
["ipfs://bq",7,""],
["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",0,"bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia"],
["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",7,""],
["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdib",7,""],
["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdiaa",7,""],
["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi7",7,""],

@ -261,6 +261,7 @@ const locatorVectorsJson = r'''
"a public note of 1025 bytes, not 1 to 1024: ERR_EXTENSION_DATA_INVALID",
"a public note that breaks the rules of text: text: bidirectional control U+202E: ERR_EXTENSION_DATA_INVALID",
"locator: Info.DateKey is not a canonical DateKey",
"locator: Info.DateKey is of the profile \"datekeys:other:v1\", which this module does not pin",
"locator: the extension has no locator",
"locator: the profile of the DateKey is not pinned",
"locator: not datekeys.capsule version 1 with data: ERR_EXTENSION_DATA_INVALID",
@ -274,7 +275,10 @@ const locatorVectorsJson = r'''
"locator: datekeys.capsule: key 9007199254740992 is not defined: ERR_NON_CANONICAL_CBOR: ERR_EXTENSION_DATA_INVALID",
"locator: datekeys.capsule: key 1: codec: offset 5: a text string of 1025 bytes outside 0..1024: ERR_NON_CANONICAL_CBOR: ERR_EXTENSION_DATA_INVALID",
"locator: datekeys.capsule: key 1: codec: offset 2: a byte string where a text string was expected: ERR_NON_CANONICAL_CBOR: ERR_EXTENSION_DATA_INVALID",
"locator: the locator is an age header without a body: ERR_EXTENSION_DATA_INVALID",
"locator: the locator is sealed for the chain 0000000000000000000000000000000000000000000000000000000000000000, not for the one of the profile datekeys:quicknet:v1 of its DateKey: ERR_EXTENSION_DATA_INVALID",
"locator: datekeys.capsule: key 2: codec: offset 99: truncated input: a byte string of 4451 bytes: ERR_NON_CANONICAL_CBOR: ERR_EXTENSION_DATA_INVALID",
"locator: the tlock stanza of the locator has no chain hash in lower-case hexadecimal: ERR_EXTENSION_DATA_INVALID",
"locator: datekeys.capsule: key 1: codec: offset 12: truncated input: a text string of 83 bytes: ERR_NON_CANONICAL_CBOR: ERR_EXTENSION_DATA_INVALID",
"locator: datekeys.capsule: key 0: codec: offset 2: a negative integer (initial byte 0x26) is outside the CBOR profile: ERR_NON_CANONICAL_CBOR: ERR_EXTENSION_DATA_INVALID",
"locator: datekeys.capsule: key 2: codec: offset 96: an unsigned integer where a byte string was expected: ERR_NON_CANONICAL_CBOR: ERR_EXTENSION_DATA_INVALID",
@ -410,7 +414,7 @@ const locatorVectorsJson = r'''
[1,[[2182,0,"1448"]],73,null],
[2,[[452,0,"28fa"]],18,null],
[2,[[404,3,""]],76,null],
[2,[[294,1,"42"]],0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199254740991,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",true]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","7d79f84b557ede09af7cebbc08ddd80fdd6fdb89675d0e0b88415be78ae8e049","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[2,[[294,1,"42"]],0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199254740991,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"",false]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","7d79f84b557ede09af7cebbc08ddd80fdd6fdb89675d0e0b88415be78ae8e049","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[2,[[59,0,"80099d"]],79,null],
[0,[[82,1,"6a"]],0,[[["https://ejemplo.org/foto.jpg",3000,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26jf3efuylqabf3oclgtqy55fbzdi",0,"bafybeigdyrzt5sfp7udm7hu76uh7y26jf3efuylqabf3oclgtqy55fbzdi",true]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[0,[[337,1,"7e"]],0,[[["https://ejemplo.org/foto.jpg",3000,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi",0,"bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi",true]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b7e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
@ -421,31 +425,31 @@ const locatorVectorsJson = r'''
[2,[[1251,1,"80"]],18,null],
[1,[[3671,425,""]],88,null],
[0,[[238,1,"69"]],0,[[["https://ejemplo.org/foto.jpg",3000,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi",0,"bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi",true]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","e75ba3d623878e7cf1c98919e397ec83651e5961603c4ade361f6c8860f43735","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[2,[[291,1,"b1"]],0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199254740991,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",true]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","112b909835938bd2a404286ca105ab9ce1267ff04bc987b43445da596e401aeb","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[2,[[291,1,"b1"]],0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199254740991,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"",false]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","112b909835938bd2a404286ca105ab9ce1267ff04bc987b43445da596e401aeb","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[1,[[175,0,"288b37bb"]],31,null],
[0,[[375,1,"25"]],0,[[["https://ejemplo.org/foto.jpg",3000,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi",0,"bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi",true]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a3925618f9daf18d4fdd5ab4a069b74"]],
[0,[[118,1,"97"]],0,[[["https://ejemplo.org/foto.jpg",3000,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi",0,"bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi",true]],"d23d7ba6d0f4976cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[2,[[307,0,"55c8ff69"]],69,null],
[0,[[99,2,""]],96,null],
[0,[[204,0,"83ece920"]],93,null],
[2,[[436,1,"2f"]],0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199254740991,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",true]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9d2f18d4fdd5ab4a069b74"]],
[2,[[436,1,"2f"]],0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199254740991,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"",false]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9d2f18d4fdd5ab4a069b74"]],
[1,[[2388,1,"71"]],0,[[[["https://ejemplo0.org/","x",400,""],0,"ejemplo0.org",true],[["https://ejemplo1.org/","x",401,""],1000,"ejemplo1.org",true],[["https://ejemplo2.org/","x",402,""],2000,"ejemplo2.org",true],[["https://ejemplo3.org/","x",403,""],3000,"ejemplo3.org",true],[["https://ejemplo4.org/","x",404,""],4000,"ejemplo4.org",true],[["https://ejemplo5.org/","x",203,"qxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"],5000,"ejemplo5.org",true],[["https://ejemplo6.org/","x",406,""],6000,"ejemplo6.org",true],[["https://ejemplo7.org/","x",407,""],7000,"ejemplo7.org",true]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[2,[[72,1,"64"]],0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejdmplo.org/c",9007199254740991,"ejdmplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",true]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[2,[[72,1,"64"]],0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejdmplo.org/c",9007199254740991,"ejdmplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"",false]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[1,[[112,1,"ca"]],31,null],
[1,[[854,2,""]],100,null],
[2,[[431,1,"31"]],0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199254740991,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",true]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a313d618f9daf18d4fdd5ab4a069b74"]],
[2,[[431,1,"31"]],0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199254740991,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"",false]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a313d618f9daf18d4fdd5ab4a069b74"]],
[1,[[2721,1375,""]],81,null],
[1,[[2152,3,""]],101,null],
[2,[[394,1,"5c"]],0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199254740991,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",true]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5c5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[2,[[394,1,"5c"]],0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199254740991,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"",false]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5c5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[1,[[2847,0,"7f97aaac"]],102,null],
[0,[[360,3736,""]],104,null],
[2,[[11,1,"3f"]],0,[[["http:?/ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199254740991,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",true]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[2,[[11,1,"3f"]],0,[[["http:?/ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199254740991,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"",false]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[1,[[1465,1,"f8"]],65,null],
[0,[[159,3937,""]],60,null],
[1,[[3908,1,"10"]],18,null],
[2,[[362,0,"30"]],106,null],
[2,[[1105,1,"20"]],18,null],
[2,[[416,1,"95"]],0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199254740991,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",true]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2951f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[2,[[416,1,"95"]],0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199254740991,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"",false]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2951f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[1,[[203,1,"79"]],0,[[[["https://ejemplo0.org/","x",174,"yxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"],0,"ejemplo0.org",true],[["https://ejemplo1.org/","x",401,""],1000,"ejemplo1.org",true],[["https://ejemplo2.org/","x",402,""],2000,"ejemplo2.org",true],[["https://ejemplo3.org/","x",403,""],3000,"ejemplo3.org",true],[["https://ejemplo4.org/","x",404,""],4000,"ejemplo4.org",true],[["https://ejemplo5.org/","x",405,""],5000,"ejemplo5.org",true],[["https://ejemplo6.org/","x",406,""],6000,"ejemplo6.org",true],[["https://ejemplo7.org/","x",407,""],7000,"ejemplo7.org",true]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[2,[[2355,0,"666906c4"]],18,null],
[2,[[3117,1,"80"]],18,null],
@ -454,10 +458,10 @@ const locatorVectorsJson = r'''
[0,[[300,3,""]],115,null],
[1,[[3460,3,""]],82,null],
[1,[[2927,1,"f8"]],102,null],
[2,[[425,1,"d9"]],0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199254740991,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",true]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1d98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[2,[[425,1,"d9"]],0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199254740991,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"",false]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1d98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[0,[[365,3731,""]],104,null],
[1,[[519,1,"7c"]],0,[[[["https://ejemplo0.org/","x",400,""],0,"ejemplo0.org",true],[["https://ejemplo1.org/","x",64,"|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"],1000,"",false],[["https://ejemplo2.org/","x",402,""],2000,"ejemplo2.org",true],[["https://ejemplo3.org/","x",403,""],3000,"ejemplo3.org",true],[["https://ejemplo4.org/","x",404,""],4000,"ejemplo4.org",true],[["https://ejemplo5.org/","x",405,""],5000,"ejemplo5.org",true],[["https://ejemplo6.org/","x",406,""],6000,"ejemplo6.org",true],[["https://ejemplo7.org/","x",407,""],7000,"ejemplo7.org",true]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[2,[[108,1,"66"]],0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199254740991,"ejemplo.org",true],["ipfs://bafyfeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"bafyfeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",true]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[2,[[108,1,"66"]],0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199254740991,"ejemplo.org",true],["ipfs://bafyfeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"",false]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[0,[[178,1,"21"]],0,[[["https://ejemplo.org/foto.jpg",3000,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi",0,"bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi",true]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","28157b09d1c8526bcd0a8b62af976d71b11c5f9e692408dfbb7916edca16e66f","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[1,[[178,0,"a7"]],31,null],
[2,[[225,3871,""]],64,null],
@ -476,7 +480,7 @@ const locatorVectorsJson = r'''
[1,[[638,1,"4a"]],0,[[[["https://ejemplo0.org/","x",400,""],0,"ejemplo0.org",true],[["https://ejemplo1.org/","x",183,"Jxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"],1000,"ejemplo1.org",true],[["https://ejemplo2.org/","x",402,""],2000,"ejemplo2.org",true],[["https://ejemplo3.org/","x",403,""],3000,"ejemplo3.org",true],[["https://ejemplo4.org/","x",404,""],4000,"ejemplo4.org",true],[["https://ejemplo5.org/","x",405,""],5000,"ejemplo5.org",true],[["https://ejemplo6.org/","x",406,""],6000,"ejemplo6.org",true],[["https://ejemplo7.org/","x",407,""],7000,"ejemplo7.org",true]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[1,[[2151,4,""]],125,null],
[1,[[3503,1,"09"]],126,null],
[2,[[316,1,"70"]],0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199254740991,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",true]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","8e3cd735cc11cf256dacdc68f2ebfcde48c5ba70d1f5438d13219ea636816960","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[2,[[316,1,"70"]],0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199254740991,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"",false]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","8e3cd735cc11cf256dacdc68f2ebfcde48c5ba70d1f5438d13219ea636816960","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[1,[[3023,3,""]],127,null],
[1,[[1788,1,"e3"]],125,null],
[0,[[362,1,"68"]],0,[[["https://ejemplo.org/foto.jpg",3000,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi",0,"bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi",true]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6892105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
@ -484,23 +488,23 @@ const locatorVectorsJson = r'''
[1,[[798,3298,""]],130,null],
[1,[[3243,0,"b0bc"]],132,null],
[0,[[226,3,""]],115,null],
[2,[[382,1,"8e"]],0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199254740991,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",true]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e8eed926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[2,[[382,1,"8e"]],0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199254740991,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"",false]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e8eed926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[2,[[268,0,"4d"]],106,null],
[2,[[208,1,"67"]],0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199254740991,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",true]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","18f421ae02be52154a2090c0338dd6d6611b781d323d4ebf2d6dfbbed866bedd","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[2,[[208,1,"67"]],0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199254740991,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"",false]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","18f421ae02be52154a2090c0338dd6d6611b781d323d4ebf2d6dfbbed866bedd","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[1,[[2793,0,"48"]],136,null],
[2,[[187,1,"1f"]],0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199254740991,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",true]],"d23d7ba6d0f4956cea30c7ed4437a55c052e1fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[2,[[187,1,"1f"]],0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199254740991,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"",false]],"d23d7ba6d0f4956cea30c7ed4437a55c052e1fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[0,[[4092,4,""]],19,null],
[0,[[396,1,"10"]],18,null],
[1,[[2457,1,"70"]],0,[[[["https://ejemplo0.org/","x",400,""],0,"ejemplo0.org",true],[["https://ejemplo1.org/","x",401,""],1000,"ejemplo1.org",true],[["https://ejemplo2.org/","x",402,""],2000,"ejemplo2.org",true],[["https://ejemplo3.org/","x",403,""],3000,"ejemplo3.org",true],[["https://ejemplo4.org/","x",404,""],4000,"ejemplo4.org",true],[["https://ejemplo5.org/","x",272,"pxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"],5000,"ejemplo5.org",true],[["https://ejemplo6.org/","x",406,""],6000,"ejemplo6.org",true],[["https://ejemplo7.org/","x",407,""],7000,"ejemplo7.org",true]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[2,[[392,1,"d4"]],0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199254740991,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",true]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d47b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[2,[[392,1,"d4"]],0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199254740991,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"",false]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d47b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[1,[[2166,4,""]],99,null],
[1,[[2894,1,"17"]],0,[[[["https://ejemplo0.org/","x",400,""],0,"ejemplo0.org",true],[["https://ejemplo1.org/","x",401,""],1000,"ejemplo1.org",true],[["https://ejemplo2.org/","x",402,""],2000,"ejemplo2.org",true],[["https://ejemplo3.org/","x",403,""],3000,"ejemplo3.org",true],[["https://ejemplo4.org/","x",404,""],4000,"ejemplo4.org",true],[["https://ejemplo5.org/","x",405,""],5000,"ejemplo5.org",true],[["https://ejemplo6.org/","x",274,"\u0017xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"],6000,"",false],[["https://ejemplo7.org/","x",407,""],7000,"ejemplo7.org",true]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[1,[[600,0,"86e251"]],66,null],
[2,[[276,1,""]],78,null],
[2,[[108,1,"66"]],0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199254740991,"ejemplo.org",true],["ipfs://bafyfeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"bafyfeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",true]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[2,[[108,1,"66"]],0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199254740991,"ejemplo.org",true],["ipfs://bafyfeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"",false]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[1,[[3718,2,""]],140,null],
[0,[[119,0,"4c1c951c"]],141,null],
[2,[[90,1,"7f"]],0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199246352383,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",true]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[2,[[90,1,"7f"]],0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199246352383,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"",false]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[1,[[820,1,"88"]],66,null],
[1,[[1119,2977,""]],89,null],
[1,[[780,0,"85c5c60c"]],66,null],
@ -508,11 +512,11 @@ const locatorVectorsJson = r'''
[1,[[2954,1142,""]],81,null],
[0,[[343,0,"081384ac"]],145,null],
[1,[[1720,1,""]],119,null],
[2,[[229,1,"f2"]],0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199254740991,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",true]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","5ef899941c35b5c5c877f95639deb5fcaa640a640a6a710bc6f2a283d0e39986","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[2,[[229,1,"f2"]],0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199254740991,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"",false]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","5ef899941c35b5c5c877f95639deb5fcaa640a640a6a710bc6f2a283d0e39986","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[1,[[3660,436,""]],88,null],
[0,[[4092,4,""]],19,null],
[1,[[2396,1700,""]],70,null],
[2,[[370,1,"4f"]],0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199254740991,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",true]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","4d00c18e3a50f3204639b76e7298aba52c8db6d6bb34b4d7519704fd928afbf5","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[2,[[370,1,"4f"]],0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199254740991,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"",false]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","4d00c18e3a50f3204639b76e7298aba52c8db6d6bb34b4d7519704fd928afbf5","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
[0,[[250,2,""]],147,null],
[2,[[367,3729,""]],64,null],
[1,[[2902,1,"58"]],0,[[[["https://ejemplo0.org/","x",400,""],0,"ejemplo0.org",true],[["https://ejemplo1.org/","x",401,""],1000,"ejemplo1.org",true],[["https://ejemplo2.org/","x",402,""],2000,"ejemplo2.org",true],[["https://ejemplo3.org/","x",403,""],3000,"ejemplo3.org",true],[["https://ejemplo4.org/","x",404,""],4000,"ejemplo4.org",true],[["https://ejemplo5.org/","x",405,""],5000,"ejemplo5.org",true],[["https://ejemplo6.org/","x",282,"Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"],6000,"ejemplo6.org",true],[["https://ejemplo7.org/","x",407,""],7000,"ejemplo7.org",true]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
@ -699,34 +703,34 @@ const locatorVectorsJson = r'''
["","datekeys:quicknet:v1",9007199254740992,null,253,0,""],
["","datekeys:quicknet:v1",9007199254740991,null,0,103,"a7f179ee5f8f33a791434b38c038f444fc9c0a8a20d1f7e1b7119ef6645d9481"],
["","Datekeys:quicknet:v1",1000,null,253,0,""],
["","datekeys:other:v1",1000,null,0,83,"0eacb050625f98eb18a3525356f61e861698511d41d3647af0ed324eb78f2e4f"],
["","datekeys:other:v1",1000,null,254,0,""],
["","",0,null,253,0,""],
["a\tb","",0,"",253,0,""]
],
"open_info": [
["datekeys:quicknet:v1",1000,0,1000,0,[[["https://ejemplo.org/foto.jpg",3000,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi",0,"bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi",true]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
["datekeys:quicknet:v1",1000,null,1000,254,null],
["datekeys:other:v1",1000,0,1000,255,null],
["datekeys:quicknet:v1",1000,null,1000,255,null],
["datekeys:other:v1",1000,0,1000,256,null],
["datekeys:quicknet:v1",1001,1,1001,0,[[["https://ejemplo.org/foto.jpg",3000,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi",0,"bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi",true]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]],
["datekeys:quicknet:v1",1001,1,1000,167,null],
["datekeys:quicknet:v1",1000,1,1000,168,null],
["datekeys:quicknet:v1",2000,2,2000,0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199254740991,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",true]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]]
["datekeys:quicknet:v1",2000,2,2000,0,[[["http://ejemplo.org/a",7,"",false],["https://[64:ff9b::7f00:1]/b",0,"",false],["https://ejemplo.org/c",9007199254740991,"ejemplo.org",true],["ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdia",1,"",false]],"d23d7ba6d0f4956cea30c7ed4437a55c052e3fbe4d7c8fc77290eae4f877eac7","773656573906057e9a0062fe979bdcd837ea58ac565d3e748cc3635ef9765e49","dcc94474a1ac6e0ced926a423d3f091fd4d67b5e5a6125a696edcf17d454a0f8",809,"e1e2351f2b6a92105e27f1c98396daf42a393d618f9daf18d4fdd5ab4a069b74"]]
],
"parse": [
["datekeys.note",1,1,[],256,"","",0,null],
["datekeys.capsule",0,1,[],256,"","",0,null],
["datekeys.capsulE",1,1,[],256,"","",0,null],
["datekeys.note",1,1,[],257,"","",0,null],
["datekeys.capsule",0,1,[],257,"","",0,null],
["datekeys.capsulE",1,1,[],257,"","",0,null],
["datekeys.capsule",1,0,[[0,0,"a1017853646b315f65794a325a584a7a61573975496a6f784c434a755a58523362334a72496a6f695a4746305a57746c65584d3663585670593274755a585136646a45694c434a79623356755a4349364d5441774d4830"]],0,"","dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0",1000,null],
["datekeys.capsule",1,1,[[0,9,"a2"]],0,"","dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0",1000,"9b1872806ff868586a155403560bb4649bee05090c24a735c5b26d9d47d85e6c"],
["datekeys.capsule",1,0,[[0,0,"a100616e"]],3,"","",0,null],
["datekeys.capsule",1,0,[[0,0,"a200790400"],[0,0,"6e",1024],[0,0,"017853646b315f65794a325a584a7a61573975496a6f784c434a755a58523362334a72496a6f695a4746305a57746c65584d3663585670593274755a585136646a45694c434a79623356755a4349364d5441774d4830"]],0,"nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn","dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0",1000,null],
["datekeys.capsule",1,0,[[0,0,"a20063610962017853646b315f65794a325a584a7a61573975496a6f784c434a755a58523362334a72496a6f695a4746305a57746c65584d3663585670593274755a585136646a45694c434a79623356755a4349364d5441774d4830"]],5,"","",0,null],
["datekeys.capsule",1,0,[[0,0,"a20062fffe017853646b315f65794a325a584a7a61573975496a6f784c434a755a58523362334a72496a6f695a4746305a57746c65584d3663585670593274755a585136646a45694c434a79623356755a4349364d5441774d4830"]],260,"","",0,null],
["datekeys.capsule",1,2,[[87,4455,"00616e"]],262,"","",0,null],
["datekeys.capsule",1,0,[[0,0,"a20062fffe017853646b315f65794a325a584a7a61573975496a6f784c434a755a58523362334a72496a6f695a4746305a57746c65584d3663585670593274755a585136646a45694c434a79623356755a4349364d5441774d4830"]],261,"","",0,null],
["datekeys.capsule",1,2,[[87,4455,"00616e"]],263,"","",0,null],
["datekeys.capsule",1,2,[[87,4455,"034100"]],6,"","",0,null],
["datekeys.capsule",1,0,[[0,0,"a10160"]],4,"","",0,null],
["datekeys.capsule",1,0,[[0,0,"a1017854646b315f65794a325a584a7a61573975496a6f784c434a755a58523362334a72496a6f695a4746305a57746c65584d3663585670593274755a585136646a45694c434a79623356755a4349364d5441774d483041"]],4,"","",0,null],
["datekeys.capsule",1,0,[[0,0,"a101790401"],[0,0,"64",1025]],265,"","",0,null],
["datekeys.capsule",1,0,[[0,0,"a101790401"],[0,0,"64",1025]],266,"","",0,null],
["datekeys.capsule",1,0,[[0,0,"a1017853444b315f65794a325a584a7a61573975496a6f784c434a755a58523362334a72496a6f695a4746305a57746c65584d3663585670593274755a585136646a45694c434a79623356755a4349364d5441774d4830"]],4,"","",0,null],
["datekeys.capsule",1,0,[[0,0,"a1017854646b315f65794a325a584a7a61573975496a6f784c434a755a58523362334a72496a6f695a4746305a57746c65584d3663585670593274755a585136646a45694c434a79623356755a4349364d5441774d48303d"]],4,"","",0,null],
["datekeys.capsule",1,2,[[88,4454,"4100"]],1,"","",0,null],
@ -734,59 +738,59 @@ const locatorVectorsJson = r'''
["datekeys.capsule",1,4,[],1,"","",0,null],
["datekeys.capsule",1,2,[[89,4453,"01426167652d656e6372797074696f6e2e6f72672f76310a2d3e20746c6f636b203130303020353264623962613730653063633066366561663738303364643037343437613166353437373733356664336636363137393262613934363030633834653937310a6b4f67676e7651537537465679574f5a5337434f646b6d76795245736d7978412b312b77504e2b6c754775412b69566b38413362784f6a467147456d627631330a456f6d5152766f5a714334767263557744626d4d53574e79354d304e476a4b4f53544d366b2f73347071786c384838643830346b334e74386c435259684653480a364532654661736f34504d68534e3631724c6342534a514979566d6335667a54666a6978734f344a3535490a2d2d2d20764a6d45736d4d69377a49334939527a5a49514f416a3153305961737a6e584e4c77624943516844733538"]],1,"","",0,null],
["datekeys.capsule",1,1,[[0,199,"a2017853646b315f65794a325a584a7a61573975496a6f784c434a755a58523362334a72496a6f695a4746305a57746c65584d3663585670593274755a585136646a45694c434a79623356755a4349364d5441774d4830025911226167652d656e6372797074696f6e2e6f72672f76310a2d3e20746c6f636b2031303030"]],1,"","",0,null],
["datekeys.capsule",1,1,[[0,199,"a2017853646b315f65794a325a584a7a61573975496a6f784c434a755a58523362334a72496a6f695a4746305a57746c65584d3663585670593274755a585136646a45694c434a79623356755a4349364d5441774d4830025911636167652d656e6372797074696f6e2e6f72672f76310a2d3e20746c6f636b203130303020"],[199,0,"30",64]],0,"","dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0",1000,"872ce88bde5be954e9e3a768ee10edf54936f257b5d78f097e23fa809cc625ab"],
["datekeys.capsule",1,1,[[0,199,"a2017853646b315f65794a325a584a7a61573975496a6f784c434a755a58523362334a72496a6f695a4746305a57746c65584d3663585670593274755a585136646a45694c434a79623356755a4349364d5441774d4830025911636167652d656e6372797074696f6e2e6f72672f76310a2d3e20746c6f636b203130303020"],[199,0,"30",64]],269,"","",0,null],
["datekeys.capsule",1,1,[[0,129,"a2017853646b315f65794a325a584a7a61573975496a6f784c434a755a58523362334a72496a6f695a4746305a57746c65584d3663585670593274755a585136646a45694c434a79623356755a4349364d5441774d4830025911646167652d656e6372797074696f6e2e6f72672f76310a2d3e20746c6f636b20"]],1,"","",0,null],
["datekeys.capsule",1,1,[[0,120,"a2017853646b315f65794a325a584a7a61573975496a6f784c434a755a58523362334a72496a6f695a4746305a57746c65584d3663585670593274755a585136646a45694c434a79623356755a4349364d5441774d4830025912606167652d656e6372797074696f6e2e6f72672f76310a2d3e20746c6f636b203130303020353264623962613730653063633066366561663738303364643037343437613166353437373733356664336636363137393262613934363030633834653937310a6b4f67676e7651537537465679574f5a5337434f646b6d76795245736d7978412b312b77504e2b6c754775412b69566b38413362784f6a467147456d627631330a456f6d5152766f5a714334767263557744626d4d53574e79354d304e476a4b4f53544d366b2f73347071786c384838643830346b334e74386c435259684653480a364532654661736f34504d68534e3631724c6342534a514979566d6335667a54666a6978734f344a353549"]],1,"","",0,null],
["datekeys.capsule",1,1,[[344,4206,""]],267,"","",0,null],
["datekeys.capsule",1,1,[[344,4206,""]],270,"","",0,null],
["datekeys.capsule",1,1,[[338,1,"24"]],1,"","",0,null],
["datekeys.capsule",1,1,[[235,1,""]],267,"","",0,null],
["datekeys.capsule",1,1,[[553,3997,""]],267,"","",0,null],
["datekeys.capsule",1,1,[[584,3966,""]],267,"","",0,null],
["datekeys.capsule",1,1,[[235,1,""]],270,"","",0,null],
["datekeys.capsule",1,1,[[553,3997,""]],270,"","",0,null],
["datekeys.capsule",1,1,[[584,3966,""]],270,"","",0,null],
["datekeys.capsule",1,1,[[12,1,"24"]],4,"","",0,null],
["datekeys.capsule",1,1,[[391,1,""]],267,"","",0,null],
["datekeys.capsule",1,1,[[391,1,""]],270,"","",0,null],
["datekeys.capsule",1,1,[[425,1,"ec"]],0,"Cartas","dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0",1000,"b1c7080496ba18f4707589a3f4a145f27970cb4c1b8fabe4ba0576052c42b94a"],
["datekeys.capsule",1,1,[[413,1,""]],267,"","",0,null],
["datekeys.capsule",1,1,[[323,1,""]],267,"","",0,null],
["datekeys.capsule",1,1,[[131,4419,""]],267,"","",0,null],
["datekeys.capsule",1,1,[[96,1,""]],270,"","",0,null],
["datekeys.capsule",1,1,[[413,1,""]],270,"","",0,null],
["datekeys.capsule",1,1,[[323,1,""]],270,"","",0,null],
["datekeys.capsule",1,1,[[131,4419,""]],270,"","",0,null],
["datekeys.capsule",1,1,[[96,1,""]],274,"","",0,null],
["datekeys.capsule",1,1,[[328,1,"68"]],0,"Cartas","dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0",1000,"ba4913a2cb35d6aca1979d009d9d35f428c214a7c89c6d689216fa21381282c1"],
["datekeys.capsule",1,1,[[571,1,""]],267,"","",0,null],
["datekeys.capsule",1,1,[[353,4197,""]],267,"","",0,null],
["datekeys.capsule",1,1,[[571,1,""]],270,"","",0,null],
["datekeys.capsule",1,1,[[353,4197,""]],270,"","",0,null],
["datekeys.capsule",1,1,[[459,1,"1a"]],0,"Cartas","dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0",1000,"c2e247433e36d8c686ef163946b53fa8aa93c8cad85368165cef468a5993bddd"],
["datekeys.capsule",1,1,[[377,4173,""]],267,"","",0,null],
["datekeys.capsule",1,1,[[377,4173,""]],270,"","",0,null],
["datekeys.capsule",1,1,[[438,1,"64"]],0,"Cartas","dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0",1000,"7e9debc80af2e9e9a5e3037eba4d5cbac029640a8cfa210b9c6cc466ea9502d1"],
["datekeys.capsule",1,1,[[433,1,"95"]],0,"Cartas","dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0",1000,"8c29835772295c6c476ab558bf595cc1c1dfc15fb99974c2fc6f8ac3203e4d3a"],
["datekeys.capsule",1,1,[[21,4529,""]],268,"","",0,null],
["datekeys.capsule",1,1,[[347,1,""]],267,"","",0,null],
["datekeys.capsule",1,1,[[21,4529,""]],272,"","",0,null],
["datekeys.capsule",1,1,[[347,1,""]],270,"","",0,null],
["datekeys.capsule",1,1,[[541,1,"38"]],0,"Cartas","dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0",1000,"837c504759e590eb96d11eb6b7924f4bcda6bcc77069842d937712e5438d05a0"],
["datekeys.capsule",1,1,[[309,1,""]],267,"","",0,null],
["datekeys.capsule",1,1,[[309,1,""]],270,"","",0,null],
["datekeys.capsule",1,1,[[229,1,"7b"]],1,"","",0,null],
["datekeys.capsule",1,1,[[313,1,"30"]],0,"Cartas","dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0",1000,"be6a50ae605acf5b3d150ec3886e2c79a77f729bcc08f8a5bc7709d0b53d7114"],
["datekeys.capsule",1,1,[[36,1,"1a"]],4,"","",0,null],
["datekeys.capsule",1,1,[[102,4448,""]],267,"","",0,null],
["datekeys.capsule",1,1,[[102,4448,""]],270,"","",0,null],
["datekeys.capsule",1,1,[[275,1,"24"]],1,"","",0,null],
["datekeys.capsule",1,1,[[431,1,""]],267,"","",0,null],
["datekeys.capsule",1,1,[[22,1,""]],271,"","",0,null],
["datekeys.capsule",1,1,[[471,4079,""]],267,"","",0,null],
["datekeys.capsule",1,1,[[431,1,""]],270,"","",0,null],
["datekeys.capsule",1,1,[[22,1,""]],275,"","",0,null],
["datekeys.capsule",1,1,[[471,4079,""]],270,"","",0,null],
["datekeys.capsule",1,1,[[521,1,"ee"]],0,"Cartas","dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0",1000,"c369944cca2d97d9f3f03c39d0c295b973cbd761a0f5b38b06c30ad98a96f24e"],
["datekeys.capsule",1,1,[[22,1,"0a"]],4,"","",0,null],
["datekeys.capsule",1,1,[[300,1,"76"]],0,"Cartas","dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0",1000,"ec5addd718aac21e927fa4f200f9b991d1691778a425d412799d1fcbee858743"],
["datekeys.capsule",1,1,[[404,1,"69"]],0,"Cartas","dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0",1000,"2c579a396edf2ae61ebce991a3f1cb93de5c19ae3e76763faad88cf2fcca1706"],
["datekeys.capsule",1,1,[[217,1,"33"]],0,"Cartas","dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0",1000,"38f4f96e3136879691ae22a09cb187868737e6d48679dcac741fd6b95ff2ac34"],
["datekeys.capsule",1,1,[[398,1,""]],267,"","",0,null],
["datekeys.capsule",1,1,[[94,1,"b0"]],272,"","",0,null],
["datekeys.capsule",1,1,[[340,1,""]],267,"","",0,null],
["datekeys.capsule",1,1,[[398,1,""]],270,"","",0,null],
["datekeys.capsule",1,1,[[94,1,"b0"]],276,"","",0,null],
["datekeys.capsule",1,1,[[340,1,""]],270,"","",0,null],
["datekeys.capsule",1,1,[[391,1,"79"]],0,"Cartas","dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0",1000,"db7a6bff12e78067943259000919e1e3b3772fd57d029e66b1c54103e4b30bbf"]
],
"registry": [
["datekeys.capsule",1,0,[],273,0,274,0],
["datekeys.capsule",1,1,[],273,0,274,0],
["datekeys.capsule",1,2,[],273,0,274,0],
["datekeys.capsule",1,3,[],273,0,274,0],
["datekeys.capsule",1,4,[275],273,276,274,0],
["datekeys.capsule",1,5,[277],273,278,274,0],
["datekeys.capsule",1,-1,[279],273,280,274,280],
["datekeys.capsule",2,4,[],281,0,0,0]
["datekeys.capsule",1,0,[],277,0,278,0],
["datekeys.capsule",1,1,[],277,0,278,0],
["datekeys.capsule",1,2,[],277,0,278,0],
["datekeys.capsule",1,3,[],277,0,278,0],
["datekeys.capsule",1,4,[279],277,280,278,0],
["datekeys.capsule",1,5,[281],277,282,278,0],
["datekeys.capsule",1,-1,[283],277,284,278,284],
["datekeys.capsule",2,4,[],285,0,0,0]
]
}
''';

File diff suppressed because one or more lines are too long

@ -1,41 +1,41 @@
{
"spec": "0.11",
"spec": "0.15",
"generator": "tool/mutation_go_texts.go",
"description": "The text of the error of capsule.Open for every case of testdata/vectors/mutations.json, or ok for a capsule that opens, and its checks as [step, name, ok, detail, code]; go_error and go_step where Go and the corpus disagree. See the header of tool/mutation_go_texts.go.",
"cases": [
{"name":"PUBLIC_HEADER_A + SEALED_CONTROL_B","text":"capsule: header_binding does not match PRELUDE || PUBLIC_HEADER: ERR_HEADER_BINDING","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",false,"capsule: header_binding does not match PRELUDE || PUBLIC_HEADER: ERR_HEADER_BINDING","ERR_HEADER_BINDING"]]},
{"name":"SEALED_CONTROL_A + PAYLOAD_AGE_B","text":"capsule: PAYLOAD_AGE: agewrap: PAYLOAD_AGE is not encrypted to this control's R_PAYLOAD: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: agewrap: PAYLOAD_AGE is not encrypted to this control's R_PAYLOAD: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"DateKey A + release of round B","text":"provider: release for round 1001, expected 1000: ERR_ROUND_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1001 obtained",""],[10,"release verification",false,"provider: release for round 1001, expected 1000: ERR_ROUND_MISMATCH","ERR_ROUND_MISMATCH"]]},
{"name":"PUBLIC_HEADER_A + SEALED_CONTROL_B","text":"capsule: header_binding does not match PRELUDE || PUBLIC_HEADER: ERR_HEADER_BINDING","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",false,"capsule: header_binding does not match PRELUDE || PUBLIC_HEADER: ERR_HEADER_BINDING","ERR_HEADER_BINDING"]]},
{"name":"SEALED_CONTROL_A + PAYLOAD_AGE_B","text":"capsule: PAYLOAD_AGE: agewrap: PAYLOAD_AGE is not encrypted to this control's R_PAYLOAD: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: agewrap: PAYLOAD_AGE is not encrypted to this control's R_PAYLOAD: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"DateKey A + release of round B","text":"provider: release for round 1001, expected 1000: ERR_ROUND_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",false,"provider: release for round 1001, expected 1000: ERR_ROUND_MISMATCH","ERR_ROUND_MISMATCH"]]},
{"name":"chain hash changed","text":"agewrap: tlock stanza chain hash \"abababababababababababababababababababababababababababababababab\", pinned profile datekeys:quicknet:v1 uses 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971: ERR_PROFILE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",false,"agewrap: tlock stanza chain hash \"abababababababababababababababababababababababababababababababab\", pinned profile datekeys:quicknet:v1 uses 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971: ERR_PROFILE_MISMATCH","ERR_PROFILE_MISMATCH"]]},
{"name":"version changed","text":"capsule: framing version 4: ERR_UNSUPPORTED_VERSION","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",false,"capsule: framing version 4: ERR_UNSUPPORTED_VERSION","ERR_UNSUPPORTED_VERSION"]]},
{"name":"flags != 0","text":"capsule: flags 0x80, reserved 0x0000: ERR_INVALID_FLAGS","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",false,"capsule: flags 0x80, reserved 0x0000: ERR_INVALID_FLAGS","ERR_INVALID_FLAGS"]]},
{"name":"reserved != 0","text":"capsule: flags 0x0, reserved 0x0001: ERR_INVALID_FLAGS","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",false,"capsule: flags 0x0, reserved 0x0001: ERR_INVALID_FLAGS","ERR_INVALID_FLAGS"]]},
{"name":"payload truncated","text":"capsule: PAYLOAD_AGE: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"payload age modified","text":"capsule: PAYLOAD_AGE: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"control modified","text":"capsule: age: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",false,"capsule: age: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"payload truncated","text":"capsule: PAYLOAD_AGE: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"payload age modified","text":"capsule: PAYLOAD_AGE: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"control modified","text":"capsule: age: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",false,"capsule: age: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"non-canonical dk1_ JSON","text":"capsule: PUBLIC_HEADER: datekey: not the canonical encoding dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0: ERR_DATEKEY_NON_CANONICAL","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=124, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"124 bytes",""],[4,"header validation",false,"capsule: PUBLIC_HEADER: datekey: not the canonical encoding dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0: ERR_DATEKEY_NON_CANONICAL","ERR_DATEKEY_NON_CANONICAL"]]},
{"name":"unknown profile","text":"capsule: profile \"datekeys:evmnet:v1\" is not pinned: ERR_UNKNOWN_PROFILE","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=118, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"118 bytes",""],[4,"header validation",false,"capsule: profile \"datekeys:evmnet:v1\" is not pinned: ERR_UNKNOWN_PROFILE","ERR_UNKNOWN_PROFILE"]]},
{"name":"release of another round","text":"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",false,"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","ERR_RELEASE_INVALID"]]},
{"name":"access_policy=time_only with time_and_key structure","text":"capsule: time_only capsule seals an age file: ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=646",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=448e134a13457c319cab7fceaf7ffa1f datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",false,"capsule: time_only capsule seals an age file: ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"access_policy=time_and_key with time_only structure","text":"capsule: time_and_key capsule does not seal an age file: ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",true,"1 identities to try",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",false,"capsule: time_and_key capsule does not seal an age file: ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"release of another round","text":"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",false,"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","ERR_RELEASE_INVALID"]]},
{"name":"access_policy=time_only with time_and_key structure","text":"capsule: time_only capsule seals an age file: ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=646",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=448e134a13457c319cab7fceaf7ffa1f datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",false,"capsule: time_only capsule seals an age file: ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"access_policy=time_and_key with time_only structure","text":"capsule: time_and_key capsule does not seal an age file: ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",true,"1 identities to try",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",false,"capsule: time_and_key capsule does not seal an age file: ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"extra stanza in OUTER_TIME_AGE","text":"capsule: OUTER_TIME_AGE must hold exactly one tlock stanza, found 2: ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=544",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ac64a02dff47ec22aaf1a44b1a89605d datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",false,"capsule: OUTER_TIME_AGE must hold exactly one tlock stanza, found 2: ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"extra stanza in PAYLOAD_AGE","text":"agewrap: PAYLOAD_AGE has 2 stanzas, want exactly one X25519 stanza: ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=3f985af7af37ad62b40ec5ccc3c6b8d1 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",false,"agewrap: PAYLOAD_AGE has 2 stanzas, want exactly one X25519 stanza: ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"non-X25519 stanza in INNER_ACCESS_AGE","text":"agewrap: INNER_ACCESS_AGE stanza 1 has type \"scrypt\", want \"X25519\": ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=726",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c800935c81d094a93d56b9fad957b18b datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",true,"1 identities to try",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",false,"agewrap: INNER_ACCESS_AGE stanza 1 has type \"scrypt\", want \"X25519\": ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"non-X25519 stanza in INNER_ACCESS_AGE","text":"agewrap: INNER_ACCESS_AGE stanza 1 has type \"scrypt\", want \"X25519\": ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=726",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c800935c81d094a93d56b9fad957b18b datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",true,"1 identities to try",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",false,"agewrap: INNER_ACCESS_AGE stanza 1 has type \"scrypt\", want \"X25519\": ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"tlock stanza round differs from DateKey.round","text":"agewrap: tlock stanza round \"1001\", DateKey round 1000: ERR_ROUND_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=08f94a0475441b20180762647ee71902 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",false,"agewrap: tlock stanza round \"1001\", DateKey round 1000: ERR_ROUND_MISMATCH","ERR_ROUND_MISMATCH"]]},
{"name":"tlock stanza chain hash differs from the pinned profile","text":"agewrap: tlock stanza chain hash \"dbd506d6ef76e5f386f41c651dcb808c5bcbd75471cc4eafa3f4df7ad4e4c493\", pinned profile datekeys:quicknet:v1 uses 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971: ERR_PROFILE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=5d6090f141146d36ba274b96b44eb941 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",false,"agewrap: tlock stanza chain hash \"dbd506d6ef76e5f386f41c651dcb808c5bcbd75471cc4eafa3f4df7ad4e4c493\", pinned profile datekeys:quicknet:v1 uses 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971: ERR_PROFILE_MISMATCH","ERR_PROFILE_MISMATCH"]]},
{"name":"extension data of a type other than bstr","text":"capsule: PUBLIC_HEADER: key 6: extension \"org.example.label\": key 2: codec: offset 146: a text string where a byte string was expected: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=159, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"159 bytes",""],[4,"header validation",false,"capsule: PUBLIC_HEADER: key 6: extension \"org.example.label\": key 2: codec: offset 146: a text string where a byte string was expected: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"empty extension data (h'')","text":"capsule: PUBLIC_HEADER: key 6: extension \"org.example.label\": data is present but empty; an extension without data omits key 2: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=147, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"147 bytes",""],[4,"header validation",false,"capsule: PUBLIC_HEADER: key 6: extension \"org.example.label\": data is present but empty; an extension without data omits key 2: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"65 extensions in one array","text":"capsule: PUBLIC_HEADER: key 6: extension: codec: offset 124: array of 65 items, at most 64: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=1424, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"1424 bytes",""],[4,"header validation",false,"capsule: PUBLIC_HEADER: key 6: extension: codec: offset 124: array of 65 items, at most 64: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"tlock stanza U re-encoded with c0 + p","text":"capsule: age: agewrap: U of the tlock stanza is not the canonical encoding of a point of the key group: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",false,"capsule: age: agewrap: U of the tlock stanza is not the canonical encoding of a point of the key group: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"tlock stanza U is the point at infinity","text":"capsule: age: agewrap: U of the tlock stanza is the point at infinity: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",false,"capsule: age: agewrap: U of the tlock stanza is the point at infinity: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"tlock stanza U with the infinity flag and a payload","text":"capsule: age: agewrap: U of the tlock stanza is not the canonical encoding of a point of the key group: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",false,"capsule: age: agewrap: U of the tlock stanza is not the canonical encoding of a point of the key group: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"tlock stanza body of 127 bytes","text":"capsule: age: agewrap: tlock stanza body of 127 bytes, want 128: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=445",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",false,"capsule: age: agewrap: tlock stanza body of 127 bytes, want 128: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"tlock stanza body of 129 bytes","text":"capsule: age: agewrap: tlock stanza body of 129 bytes, want 128: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=447",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",false,"capsule: age: agewrap: tlock stanza body of 129 bytes, want 128: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"release signature re-encoded with x + p","text":"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1004 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=250416bc1e6d8da84f5a69e47a9f66f2 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwNH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1004, unlock at 2023-08-23T15:59:36Z",""],[8,"tlock stanza",true,"round 1004, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1004 obtained",""],[10,"release verification",false,"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1004 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","ERR_RELEASE_INVALID"]]},
{"name":"release signature is the point at infinity","text":"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",false,"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","ERR_RELEASE_INVALID"]]},
{"name":"release signature with the infinity flag and a payload","text":"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",false,"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","ERR_RELEASE_INVALID"]]},
{"name":"release signature negated","text":"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",false,"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","ERR_RELEASE_INVALID"]]},
{"name":"negated release signature and U re-encoded with c0 + p","text":"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",false,"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","ERR_RELEASE_INVALID"]]},
{"name":"tlock stanza U re-encoded with c0 + p","text":"capsule: age: agewrap: U of the tlock stanza is not the canonical encoding of a point of the key group: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",false,"capsule: age: agewrap: U of the tlock stanza is not the canonical encoding of a point of the key group: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"tlock stanza U is the point at infinity","text":"capsule: age: agewrap: U of the tlock stanza is the point at infinity: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",false,"capsule: age: agewrap: U of the tlock stanza is the point at infinity: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"tlock stanza U with the infinity flag and a payload","text":"capsule: age: agewrap: U of the tlock stanza is not the canonical encoding of a point of the key group: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",false,"capsule: age: agewrap: U of the tlock stanza is not the canonical encoding of a point of the key group: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"tlock stanza body of 127 bytes","text":"capsule: age: agewrap: tlock stanza body of 127 bytes, want 128: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=445",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",false,"capsule: age: agewrap: tlock stanza body of 127 bytes, want 128: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"tlock stanza body of 129 bytes","text":"capsule: age: agewrap: tlock stanza body of 129 bytes, want 128: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=447",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",false,"capsule: age: agewrap: tlock stanza body of 129 bytes, want 128: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"release signature re-encoded with x + p","text":"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1004 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=250416bc1e6d8da84f5a69e47a9f66f2 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwNH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1004, unlock at 2023-08-23T15:59:36Z",""],[8,"tlock stanza",true,"round 1004, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",false,"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1004 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","ERR_RELEASE_INVALID"]]},
{"name":"release signature is the point at infinity","text":"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",false,"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","ERR_RELEASE_INVALID"]]},
{"name":"release signature with the infinity flag and a payload","text":"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",false,"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","ERR_RELEASE_INVALID"]]},
{"name":"release signature negated","text":"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",false,"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","ERR_RELEASE_INVALID"]]},
{"name":"negated release signature and U re-encoded with c0 + p","text":"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",false,"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","ERR_RELEASE_INVALID"]]},
{"name":"magic","text":"capsule: ERR_INVALID_MAGIC","checks":[[1,"parse DKC1",false,"capsule: ERR_INVALID_MAGIC","ERR_INVALID_MAGIC"]]},
{"name":"a .dkk offered as a .dkc","text":"capsule: ERR_INVALID_MAGIC","checks":[[1,"parse DKC1",false,"capsule: ERR_INVALID_MAGIC","ERR_INVALID_MAGIC"]]},
{"name":"empty file","text":"capsule: ERR_INVALID_MAGIC","checks":[[1,"parse DKC1",false,"capsule: ERR_INVALID_MAGIC","ERR_INVALID_MAGIC"]]},
@ -49,177 +49,181 @@
{"name":"access_policy 256 with a consistent header_binding","text":"capsule: PUBLIC_HEADER: key 4: access_policy 256 is not defined in V1: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=123, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"123 bytes",""],[4,"header validation",false,"capsule: PUBLIC_HEADER: key 4: access_policy 256 is not defined in V1: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"access_policy 257 with a consistent header_binding","text":"capsule: PUBLIC_HEADER: key 4: access_policy 257 is not defined in V1: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=123, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"123 bytes",""],[4,"header validation",false,"capsule: PUBLIC_HEADER: key 4: access_policy 257 is not defined in V1: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"unknown critical PUBLIC_HEADER extension","text":"capsule: PUBLIC_HEADER: extension org.example.must-understand v1: ERR_EXTENSION_CRITICAL_UNKNOWN","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=156, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"156 bytes",""],[4,"header validation",false,"capsule: PUBLIC_HEADER: extension org.example.must-understand v1: ERR_EXTENSION_CRITICAL_UNKNOWN","ERR_EXTENSION_CRITICAL_UNKNOWN"]]},
{"name":"unknown critical CONTROL_CBOR extension","text":"capsule: CONTROL_CBOR: extension org.example.must-understand v1: ERR_EXTENSION_CRITICAL_UNKNOWN","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=481",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=6946e5bb3f531636f39c35aaa686a627 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",false,"capsule: CONTROL_CBOR: extension org.example.must-understand v1: ERR_EXTENSION_CRITICAL_UNKNOWN","ERR_EXTENSION_CRITICAL_UNKNOWN"]]},
{"name":"unknown critical CONTROL_CBOR extension","text":"capsule: CONTROL_CBOR: extension org.example.must-understand v1: ERR_EXTENSION_CRITICAL_UNKNOWN","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=481",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=6946e5bb3f531636f39c35aaa686a627 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",false,"capsule: CONTROL_CBOR: extension org.example.must-understand v1: ERR_EXTENSION_CRITICAL_UNKNOWN","ERR_EXTENSION_CRITICAL_UNKNOWN"]]},
{"name":"known critical PUBLIC_HEADER extension with invalid data","text":"capsule: PUBLIC_HEADER: extension org.example.must-understand v1: data: data 6b6f is not 6f6b: ERR_EXTENSION_DATA_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=160, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"160 bytes",""],[4,"header validation",false,"capsule: PUBLIC_HEADER: extension org.example.must-understand v1: data: data 6b6f is not 6f6b: ERR_EXTENSION_DATA_INVALID","ERR_EXTENSION_DATA_INVALID"]]},
{"name":"known critical CONTROL_CBOR extension with invalid data","text":"capsule: CONTROL_CBOR: extension org.example.must-understand v1: data: data 6b6f is not 6f6b: ERR_EXTENSION_DATA_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=485",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=150c4bed590fa8b69b37b24fe7449e74 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",false,"capsule: CONTROL_CBOR: extension org.example.must-understand v1: data: data 6b6f is not 6f6b: ERR_EXTENSION_DATA_INVALID","ERR_EXTENSION_DATA_INVALID"]]},
{"name":"known critical CONTROL_CBOR extension with invalid data","text":"capsule: CONTROL_CBOR: extension org.example.must-understand v1: data: data 6b6f is not 6f6b: ERR_EXTENSION_DATA_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=485",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=150c4bed590fa8b69b37b24fe7449e74 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",false,"capsule: CONTROL_CBOR: extension org.example.must-understand v1: data: data 6b6f is not 6f6b: ERR_EXTENSION_DATA_INVALID","ERR_EXTENSION_DATA_INVALID"]]},
{"name":"known critical .dkk extension with invalid data","text":"capsule: .dkk: extension org.example.must-understand v1: data: data 6b6f is not 6f6b: ERR_EXTENSION_DATA_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=646",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=448e134a13457c319cab7fceaf7ffa1f datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",false,"capsule: .dkk: extension org.example.must-understand v1: data: data 6b6f is not 6f6b: ERR_EXTENSION_DATA_INVALID","ERR_EXTENSION_DATA_INVALID"]]},
{"name":"extension_version above 2^32-1","text":"capsule: PUBLIC_HEADER: key 6: extension \"org.example.label\": key 1: codec: offset 153: unsigned integer 4294967296 above 4294967295: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=153, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"153 bytes",""],[4,"header validation",false,"capsule: PUBLIC_HEADER: key 6: extension \"org.example.label\": key 1: codec: offset 153: unsigned integer 4294967296 above 4294967295: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"null extension data","text":"capsule: PUBLIC_HEADER: key 6: extension \"org.example.label\": key 2: codec: offset 146: a float or simple value (initial byte 0xf6) is outside the CBOR profile: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=147, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"147 bytes",""],[4,"header validation",false,"capsule: PUBLIC_HEADER: key 6: extension \"org.example.label\": key 2: codec: offset 146: a float or simple value (initial byte 0xf6) is outside the CBOR profile: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"time_and_key without credentials","text":"capsule: time_and_key capsule and no identity or .dkk supplied: ERR_ACCESS_REQUIRED","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=646",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=448e134a13457c319cab7fceaf7ffa1f datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",false,"capsule: time_and_key capsule and no identity or .dkk supplied: ERR_ACCESS_REQUIRED","ERR_ACCESS_REQUIRED"]]},
{"name":".dkk of another capsule","text":"capsule: the .dkk is for capsule c75dfc8e9c576d1369910664df93693a, this is 448e134a13457c319cab7fceaf7ffa1f: ERR_ACCESS_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=646",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=448e134a13457c319cab7fceaf7ffa1f datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",false,"capsule: the .dkk is for capsule c75dfc8e9c576d1369910664df93693a, this is 448e134a13457c319cab7fceaf7ffa1f: ERR_ACCESS_INVALID","ERR_ACCESS_INVALID"]]},
{"name":"capsule_digest of the .dkk does not match","text":"capsule: the .dkk capsule_digest does not match this .dkc: ERR_ACCESS_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=646",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=448e134a13457c319cab7fceaf7ffa1f datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",false,"capsule: the .dkk capsule_digest does not match this .dkc: ERR_ACCESS_INVALID","ERR_ACCESS_INVALID"]]},
{"name":"identity that is not a recipient","text":"capsule: age: agewrap: no supplied identity is a recipient of INNER_ACCESS_AGE: ERR_ACCESS_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=646",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=448e134a13457c319cab7fceaf7ffa1f datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",true,"1 identities to try",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_and_key: INNER_ACCESS_AGE with 1 X25519 stanzas",""],[13,"open access layer",false,"capsule: age: agewrap: no supplied identity is a recipient of INNER_ACCESS_AGE: ERR_ACCESS_INVALID","ERR_ACCESS_INVALID"]]},
{"name":"round not reached yet","text":"capsule: round 1000 is published at 2023-08-23T15:59:24Z, it is 2023-08-23T15:59:23Z: ERR_RELEASE_UNAVAILABLE","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",false,"capsule: round 1000 is published at 2023-08-23T15:59:24Z, it is 2023-08-23T15:59:23Z: ERR_RELEASE_UNAVAILABLE","ERR_RELEASE_UNAVAILABLE"]]},
{"name":"identity that is not a recipient","text":"capsule: age: agewrap: no supplied identity is a recipient of INNER_ACCESS_AGE: ERR_ACCESS_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=646",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=448e134a13457c319cab7fceaf7ffa1f datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",true,"1 identities to try",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_and_key: INNER_ACCESS_AGE with 1 X25519 stanzas",""],[13,"open access layer",false,"capsule: age: agewrap: no supplied identity is a recipient of INNER_ACCESS_AGE: ERR_ACCESS_INVALID","ERR_ACCESS_INVALID"]]},
{"name":"round not reached yet","text":"ok","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller; round 1000 is published at 2023-08-23T15:59:24Z and the clock says 2023-08-23T15:59:23Z: it may be behind",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered",""],[17,"open payload",true,"payload authenticated",""],[18,"commit",true,"78000 bytes of content",""]]},
{"name":"release source unavailable","text":"testkit: no release: ERR_RELEASE_UNAVAILABLE","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",false,"testkit: no release: ERR_RELEASE_UNAVAILABLE","ERR_RELEASE_UNAVAILABLE"]]},
{"name":"trailing data after PAYLOAD_AGE","text":"capsule: PAYLOAD_AGE: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"payload stanza body modified","text":"capsule: PAYLOAD_AGE: agewrap: PAYLOAD_AGE is not encrypted to this control's R_PAYLOAD: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: agewrap: PAYLOAD_AGE is not encrypted to this control's R_PAYLOAD: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"trailing data after PAYLOAD_AGE","text":"capsule: PAYLOAD_AGE: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"payload stanza body modified","text":"capsule: PAYLOAD_AGE: agewrap: PAYLOAD_AGE is not encrypted to this control's R_PAYLOAD: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: agewrap: PAYLOAD_AGE is not encrypted to this control's R_PAYLOAD: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"tlock round edited by a third party","text":"agewrap: tlock stanza round \"1001\", DateKey round 1000: ERR_ROUND_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",false,"agewrap: tlock stanza round \"1001\", DateKey round 1000: ERR_ROUND_MISMATCH","ERR_ROUND_MISMATCH"]]},
{"name":"empty registry","text":"capsule: profile \"datekeys:quicknet:v1\" is not pinned: ERR_UNKNOWN_PROFILE","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",false,"capsule: profile \"datekeys:quicknet:v1\" is not pinned: ERR_UNKNOWN_PROFILE","ERR_UNKNOWN_PROFILE"]]},
{"name":"time_only declared, time_and_key built by the creator","text":"capsule: time_only capsule seals an age file: ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=646",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=238e2912d6448dce358dec034cc73984 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",false,"capsule: time_only capsule seals an age file: ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"time_and_key declared, time_only built by the creator","text":"capsule: time_and_key capsule does not seal an age file: ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=a44c9b18fda29aea727f5398ecf967ce datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",true,"1 identities to try",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",false,"capsule: time_and_key capsule does not seal an age file: ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"two INNER_ACCESS_AGE stanzas for one recipient","text":"capsule: age: agewrap: one identity opens 2 INNER_ACCESS_AGE stanzas, want one per recipient: ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=744",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=1d983beefec16c1a312696440735330c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",true,"1 identities to try",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_and_key: INNER_ACCESS_AGE with 2 X25519 stanzas",""],[13,"open access layer",false,"capsule: age: agewrap: one identity opens 2 INNER_ACCESS_AGE stanzas, want one per recipient: ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"format 2: PUBLIC_HEADER_A + SEALED_CONTROL_B","text":"capsule: header_binding does not match PRELUDE || PUBLIC_HEADER: ERR_HEADER_BINDING","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",false,"capsule: header_binding does not match PRELUDE || PUBLIC_HEADER: ERR_HEADER_BINDING","ERR_HEADER_BINDING"]]},
{"name":"format 2: SEALED_CONTROL_A + PAYLOAD_AGE_B","text":"capsule: PAYLOAD_AGE: agewrap: PAYLOAD_AGE is not encrypted to this control's R_PAYLOAD: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 78000, padding reforzado, P = 79872",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: agewrap: PAYLOAD_AGE is not encrypted to this control's R_PAYLOAD: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 2: DateKey A + release of round B","text":"provider: release for round 1001, expected 1000: ERR_ROUND_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1001 obtained",""],[10,"release verification",false,"provider: release for round 1001, expected 1000: ERR_ROUND_MISMATCH","ERR_ROUND_MISMATCH"]]},
{"name":"time_only declared, time_and_key built by the creator","text":"capsule: time_only capsule seals an age file: ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=646",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=238e2912d6448dce358dec034cc73984 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",false,"capsule: time_only capsule seals an age file: ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"time_and_key declared, time_only built by the creator","text":"capsule: time_and_key capsule does not seal an age file: ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=a44c9b18fda29aea727f5398ecf967ce datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",true,"1 identities to try",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",false,"capsule: time_and_key capsule does not seal an age file: ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"two INNER_ACCESS_AGE stanzas for one recipient","text":"capsule: age: agewrap: one identity opens 2 INNER_ACCESS_AGE stanzas, want one per recipient: ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=744",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=1d983beefec16c1a312696440735330c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",true,"1 identities to try",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_and_key: INNER_ACCESS_AGE with 2 X25519 stanzas",""],[13,"open access layer",false,"capsule: age: agewrap: one identity opens 2 INNER_ACCESS_AGE stanzas, want one per recipient: ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"format 2: PUBLIC_HEADER_A + SEALED_CONTROL_B","text":"capsule: header_binding does not match PRELUDE || PUBLIC_HEADER: ERR_HEADER_BINDING","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",false,"capsule: header_binding does not match PRELUDE || PUBLIC_HEADER: ERR_HEADER_BINDING","ERR_HEADER_BINDING"]]},
{"name":"format 2: SEALED_CONTROL_A + PAYLOAD_AGE_B","text":"capsule: PAYLOAD_AGE: agewrap: PAYLOAD_AGE is not encrypted to this control's R_PAYLOAD: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 78000, padding reforzado, P = 79872",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: agewrap: PAYLOAD_AGE is not encrypted to this control's R_PAYLOAD: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 2: DateKey A + release of round B","text":"provider: release for round 1001, expected 1000: ERR_ROUND_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",false,"provider: release for round 1001, expected 1000: ERR_ROUND_MISMATCH","ERR_ROUND_MISMATCH"]]},
{"name":"format 2: chain hash changed","text":"agewrap: tlock stanza chain hash \"abababababababababababababababababababababababababababababababab\", pinned profile datekeys:quicknet:v1 uses 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971: ERR_PROFILE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",false,"agewrap: tlock stanza chain hash \"abababababababababababababababababababababababababababababababab\", pinned profile datekeys:quicknet:v1 uses 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971: ERR_PROFILE_MISMATCH","ERR_PROFILE_MISMATCH"]]},
{"name":"format 2: version changed","text":"capsule: framing version 4: ERR_UNSUPPORTED_VERSION","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",false,"capsule: framing version 4: ERR_UNSUPPORTED_VERSION","ERR_UNSUPPORTED_VERSION"]]},
{"name":"format 2: flags != 0","text":"capsule: flags 0x80, reserved 0x0000: ERR_INVALID_FLAGS","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",false,"capsule: flags 0x80, reserved 0x0000: ERR_INVALID_FLAGS","ERR_INVALID_FLAGS"]]},
{"name":"format 2: reserved != 0","text":"capsule: flags 0x0, reserved 0x0001: ERR_INVALID_FLAGS","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",false,"capsule: flags 0x0, reserved 0x0001: ERR_INVALID_FLAGS","ERR_INVALID_FLAGS"]]},
{"name":"format 2: payload truncated","text":"capsule: PAYLOAD_AGE: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 78000, padding reforzado, P = 79872",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 2: payload age modified","text":"capsule: PAYLOAD_AGE: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 78000, padding reforzado, P = 79872",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 2: control modified","text":"capsule: age: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",false,"capsule: age: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 2: payload truncated","text":"capsule: PAYLOAD_AGE: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 78000, padding reforzado, P = 79872",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 2: payload age modified","text":"capsule: PAYLOAD_AGE: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 78000, padding reforzado, P = 79872",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 2: control modified","text":"capsule: age: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",false,"capsule: age: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 2: non-canonical dk1_ JSON","text":"capsule: PUBLIC_HEADER: datekey: not the canonical encoding dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0: ERR_DATEKEY_NON_CANONICAL","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=124, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"124 bytes",""],[4,"header validation",false,"capsule: PUBLIC_HEADER: datekey: not the canonical encoding dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0: ERR_DATEKEY_NON_CANONICAL","ERR_DATEKEY_NON_CANONICAL"]]},
{"name":"format 2: unknown profile","text":"capsule: profile \"datekeys:evmnet:v1\" is not pinned: ERR_UNKNOWN_PROFILE","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=118, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"118 bytes",""],[4,"header validation",false,"capsule: profile \"datekeys:evmnet:v1\" is not pinned: ERR_UNKNOWN_PROFILE","ERR_UNKNOWN_PROFILE"]]},
{"name":"format 2: release of another round","text":"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",false,"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","ERR_RELEASE_INVALID"]]},
{"name":"format 2: access_policy=time_only with time_and_key structure","text":"capsule: time_only capsule seals an age file: ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=2128",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=fe68d3b3bb59db0c14b7ef57d8d6cb5e datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",false,"capsule: time_only capsule seals an age file: ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"format 2: access_policy=time_and_key with time_only structure","text":"capsule: time_and_key capsule does not seal an age file: ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",true,"1 identities to try",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",false,"capsule: time_and_key capsule does not seal an age file: ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"format 2: release of another round","text":"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",false,"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","ERR_RELEASE_INVALID"]]},
{"name":"format 2: access_policy=time_only with time_and_key structure","text":"capsule: time_only capsule seals an age file: ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=2128",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=fe68d3b3bb59db0c14b7ef57d8d6cb5e datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",false,"capsule: time_only capsule seals an age file: ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"format 2: access_policy=time_and_key with time_only structure","text":"capsule: time_and_key capsule does not seal an age file: ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",true,"1 identities to try",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",false,"capsule: time_and_key capsule does not seal an age file: ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"format 2: extra stanza in OUTER_TIME_AGE","text":"capsule: OUTER_TIME_AGE must hold exactly one tlock stanza, found 2: ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=556",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=9667d509fc51ccede898d232ce74d47f datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",false,"capsule: OUTER_TIME_AGE must hold exactly one tlock stanza, found 2: ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"format 2: extra stanza in PAYLOAD_AGE","text":"agewrap: PAYLOAD_AGE has 2 stanzas, want exactly one X25519 stanza: ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=4938a3c96f0d6e9a5e0d81dc533705c2 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",false,"agewrap: PAYLOAD_AGE has 2 stanzas, want exactly one X25519 stanza: ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"format 2: non-X25519 stanza in INNER_ACCESS_AGE","text":"agewrap: INNER_ACCESS_AGE stanza 15 has type \"scrypt\", want \"X25519\": ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=2110",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=4100a310fc7101779e8af7d1c91669c6 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",true,"1 identities to try",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",false,"agewrap: INNER_ACCESS_AGE stanza 15 has type \"scrypt\", want \"X25519\": ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"format 2: non-X25519 stanza in INNER_ACCESS_AGE","text":"agewrap: INNER_ACCESS_AGE stanza 15 has type \"scrypt\", want \"X25519\": ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=2110",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=4100a310fc7101779e8af7d1c91669c6 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",true,"1 identities to try",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",false,"agewrap: INNER_ACCESS_AGE stanza 15 has type \"scrypt\", want \"X25519\": ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"format 2: tlock stanza round differs from DateKey.round","text":"agewrap: tlock stanza round \"1001\", DateKey round 1000: ERR_ROUND_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=218abdaca3c0fec6e495e75ebd783d80 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",false,"agewrap: tlock stanza round \"1001\", DateKey round 1000: ERR_ROUND_MISMATCH","ERR_ROUND_MISMATCH"]]},
{"name":"format 2: tlock stanza chain hash differs from the pinned profile","text":"agewrap: tlock stanza chain hash \"dbd506d6ef76e5f386f41c651dcb808c5bcbd75471cc4eafa3f4df7ad4e4c493\", pinned profile datekeys:quicknet:v1 uses 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971: ERR_PROFILE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=1a9e26924b25a9b70ecd24fa769672d8 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",false,"agewrap: tlock stanza chain hash \"dbd506d6ef76e5f386f41c651dcb808c5bcbd75471cc4eafa3f4df7ad4e4c493\", pinned profile datekeys:quicknet:v1 uses 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971: ERR_PROFILE_MISMATCH","ERR_PROFILE_MISMATCH"]]},
{"name":"format 2: extension data of a type other than bstr","text":"capsule: PUBLIC_HEADER: key 6: extension \"org.example.label\": key 2: codec: offset 146: a text string where a byte string was expected: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=159, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"159 bytes",""],[4,"header validation",false,"capsule: PUBLIC_HEADER: key 6: extension \"org.example.label\": key 2: codec: offset 146: a text string where a byte string was expected: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"format 2: empty extension data (h'')","text":"capsule: PUBLIC_HEADER: key 6: extension \"org.example.label\": data is present but empty; an extension without data omits key 2: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=147, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"147 bytes",""],[4,"header validation",false,"capsule: PUBLIC_HEADER: key 6: extension \"org.example.label\": data is present but empty; an extension without data omits key 2: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"format 2: 65 extensions in one array","text":"capsule: PUBLIC_HEADER: key 6: extension: codec: offset 124: array of 65 items, at most 64: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=1424, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"1424 bytes",""],[4,"header validation",false,"capsule: PUBLIC_HEADER: key 6: extension: codec: offset 124: array of 65 items, at most 64: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"format 2: tlock stanza U re-encoded with c0 + p","text":"capsule: age: agewrap: U of the tlock stanza is not the canonical encoding of a point of the key group: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",false,"capsule: age: agewrap: U of the tlock stanza is not the canonical encoding of a point of the key group: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 2: tlock stanza U is the point at infinity","text":"capsule: age: agewrap: U of the tlock stanza is the point at infinity: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",false,"capsule: age: agewrap: U of the tlock stanza is the point at infinity: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 2: tlock stanza U with the infinity flag and a payload","text":"capsule: age: agewrap: U of the tlock stanza is not the canonical encoding of a point of the key group: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",false,"capsule: age: agewrap: U of the tlock stanza is not the canonical encoding of a point of the key group: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 2: tlock stanza body of 127 bytes","text":"capsule: age: agewrap: tlock stanza body of 127 bytes, want 128: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=457",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",false,"capsule: age: agewrap: tlock stanza body of 127 bytes, want 128: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 2: tlock stanza body of 129 bytes","text":"capsule: age: agewrap: tlock stanza body of 129 bytes, want 128: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=459",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",false,"capsule: age: agewrap: tlock stanza body of 129 bytes, want 128: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 2: release signature re-encoded with x + p","text":"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1004 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=dbb9bc102bb15061d58e9c17d302e06f datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwNH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1004, unlock at 2023-08-23T15:59:36Z",""],[8,"tlock stanza",true,"round 1004, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1004 obtained",""],[10,"release verification",false,"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1004 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","ERR_RELEASE_INVALID"]]},
{"name":"format 2: release signature is the point at infinity","text":"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",false,"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","ERR_RELEASE_INVALID"]]},
{"name":"format 2: release signature with the infinity flag and a payload","text":"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",false,"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","ERR_RELEASE_INVALID"]]},
{"name":"format 2: release signature negated","text":"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",false,"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","ERR_RELEASE_INVALID"]]},
{"name":"format 2: negated release signature and U re-encoded with c0 + p","text":"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",false,"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","ERR_RELEASE_INVALID"]]},
{"name":"format 2 time_only relabeled format 3","text":"capsule: CONTROL_CBOR: codec: datekeys-control schema version 2, want 3: ERR_UNSUPPORTED_VERSION","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",false,"capsule: CONTROL_CBOR: codec: datekeys-control schema version 2, want 3: ERR_UNSUPPORTED_VERSION","ERR_UNSUPPORTED_VERSION"]]},
{"name":"format 1 time_only relabeled format 2","text":"capsule: CONTROL_CBOR: codec: datekeys-control schema version 1, want 2: ERR_UNSUPPORTED_VERSION","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",false,"capsule: CONTROL_CBOR: codec: datekeys-control schema version 1, want 2: ERR_UNSUPPORTED_VERSION","ERR_UNSUPPORTED_VERSION"]]},
{"name":"format 1 time_and_key with one stanza relabeled format 2, with the identity","text":"agewrap: INNER_ACCESS_AGE has 1 stanzas, want exactly 16: ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=646",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=448e134a13457c319cab7fceaf7ffa1f datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",true,"1 identities to try",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",false,"agewrap: INNER_ACCESS_AGE has 1 stanzas, want exactly 16: ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"format 2 time_only relabeled format 1","text":"capsule: CONTROL_CBOR: codec: datekeys-control schema version 2, want 1: ERR_UNSUPPORTED_VERSION","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",false,"capsule: CONTROL_CBOR: codec: datekeys-control schema version 2, want 1: ERR_UNSUPPORTED_VERSION","ERR_UNSUPPORTED_VERSION"]]},
{"name":"format 2 time_and_key relabeled format 1, with the identity","text":"capsule: CONTROL_CBOR: codec: datekeys-control schema version 2, want 1: ERR_UNSUPPORTED_VERSION","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=2128",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=fe68d3b3bb59db0c14b7ef57d8d6cb5e datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",true,"1 identities to try",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_and_key: INNER_ACCESS_AGE with 16 X25519 stanzas",""],[13,"open access layer",true,"identity matched exactly one stanza",""],[14,"control",false,"capsule: CONTROL_CBOR: codec: datekeys-control schema version 2, want 1: ERR_UNSUPPORTED_VERSION","ERR_UNSUPPORTED_VERSION"]]},
{"name":"INNER_ACCESS_AGE with 15 stanzas","text":"agewrap: INNER_ACCESS_AGE has 15 stanzas, want exactly 16: ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=2030",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=fe68d3b3bb59db0c14b7ef57d8d6cb5e datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",true,"1 identities to try",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",false,"agewrap: INNER_ACCESS_AGE has 15 stanzas, want exactly 16: ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"INNER_ACCESS_AGE with 17 stanzas","text":"agewrap: INNER_ACCESS_AGE has 17 stanzas, want exactly 16: ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=2226",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=fe68d3b3bb59db0c14b7ef57d8d6cb5e datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",true,"1 identities to try",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",false,"agewrap: INNER_ACCESS_AGE has 17 stanzas, want exactly 16: ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"16 stanzas, two for one recipient, and the identity of that recipient","text":"capsule: age: agewrap: one identity opens 2 INNER_ACCESS_AGE stanzas, want one per recipient: ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=2128",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=fe68d3b3bb59db0c14b7ef57d8d6cb5e datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",true,"1 identities to try",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_and_key: INNER_ACCESS_AGE with 16 X25519 stanzas",""],[13,"open access layer",false,"capsule: age: agewrap: one identity opens 2 INNER_ACCESS_AGE stanzas, want one per recipient: ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"identity that is not a recipient of any of the 16","text":"capsule: age: agewrap: no supplied identity is a recipient of INNER_ACCESS_AGE: ERR_ACCESS_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=2128",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=fe68d3b3bb59db0c14b7ef57d8d6cb5e datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",true,"1 identities to try",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_and_key: INNER_ACCESS_AGE with 16 X25519 stanzas",""],[13,"open access layer",false,"capsule: age: agewrap: no supplied identity is a recipient of INNER_ACCESS_AGE: ERR_ACCESS_INVALID","ERR_ACCESS_INVALID"]]},
{"name":"control of schema version 2 without key 6","text":"capsule: CONTROL_CBOR: key 6 is missing: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=448",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",false,"capsule: CONTROL_CBOR: key 6 is missing: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"control of schema version 2 without key 7","text":"capsule: CONTROL_CBOR: key 7 is missing: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=456",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",false,"capsule: CONTROL_CBOR: key 7 is missing: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"padding code 0","text":"capsule: CONTROL_CBOR: key 7: padding code 0 is not defined: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",false,"capsule: CONTROL_CBOR: key 7: padding code 0 is not defined: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"padding code 3","text":"capsule: CONTROL_CBOR: key 7: padding code 3 is not defined: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",false,"capsule: CONTROL_CBOR: key 7: padding code 3 is not defined: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"payload_length L_MAX + 1","text":"capsule: CONTROL_CBOR: key 6: payload_length 8936830510563329 exceeds L_MAX = 8936830510563328: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",false,"capsule: CONTROL_CBOR: key 6: payload_length 8936830510563329 exceeds L_MAX = 8936830510563328: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"payload_length of 7 bytes","text":"capsule: CONTROL_CBOR: key 6: codec: offset 93: a byte string of 7 bytes outside 8..8: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=457",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",false,"capsule: CONTROL_CBOR: key 6: codec: offset 93: a byte string of 7 bytes outside 8..8: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"payload_length of 9 bytes","text":"capsule: CONTROL_CBOR: key 6: codec: offset 93: a byte string of 9 bytes outside 8..8: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=459",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",false,"capsule: CONTROL_CBOR: key 6: codec: offset 93: a byte string of 9 bytes outside 8..8: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"payload_length as an unsigned integer","text":"capsule: CONTROL_CBOR: key 6: codec: offset 92: an unsigned integer where a byte string was expected: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=454",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",false,"capsule: CONTROL_CBOR: key 6: codec: offset 92: an unsigned integer where a byte string was expected: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"last padding byte not zero","text":"capsule: PAYLOAD_AGE: byte 255 of the plaintext is padding and is not zero: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=159, SEALED_CONTROL_LEN=494",""],[3,"public header",true,"159 bytes",""],[4,"header validation",true,"capsule_id=3ab2c06d482609a9c7ae92f672599883 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MjAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 2000, unlock at 2023-08-23T16:49:24Z",""],[8,"tlock stanza",true,"round 2000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 2000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 34, padding reforzado, P = 256",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: byte 255 of the plaintext is padding and is not zero: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"payload plaintext of P - 1 bytes","text":"capsule: PAYLOAD_AGE: the plaintext is 255 bytes, shorter than P = 256: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=159, SEALED_CONTROL_LEN=494",""],[3,"public header",true,"159 bytes",""],[4,"header validation",true,"capsule_id=3ab2c06d482609a9c7ae92f672599883 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MjAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 2000, unlock at 2023-08-23T16:49:24Z",""],[8,"tlock stanza",true,"round 2000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 2000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 34, padding reforzado, P = 256",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: the plaintext is 255 bytes, shorter than P = 256: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"payload plaintext of P + 256 bytes","text":"capsule: PAYLOAD_AGE: the plaintext is longer than P = 256: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=159, SEALED_CONTROL_LEN=494",""],[3,"public header",true,"159 bytes",""],[4,"header validation",true,"capsule_id=3ab2c06d482609a9c7ae92f672599883 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MjAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 2000, unlock at 2023-08-23T16:49:24Z",""],[8,"tlock stanza",true,"round 2000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 2000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 34, padding reforzado, P = 256",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: the plaintext is longer than P = 256: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"payload plaintext without padding, of L bytes","text":"capsule: PAYLOAD_AGE: the plaintext is 34 bytes, shorter than P = 256: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=159, SEALED_CONTROL_LEN=494",""],[3,"public header",true,"159 bytes",""],[4,"header validation",true,"capsule_id=3ab2c06d482609a9c7ae92f672599883 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MjAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 2000, unlock at 2023-08-23T16:49:24Z",""],[8,"tlock stanza",true,"round 2000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 2000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 34, padding reforzado, P = 256",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: the plaintext is 34 bytes, shorter than P = 256: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"padding code 2 changed to 1, with L = 78000","text":"capsule: PAYLOAD_AGE: the plaintext is longer than P = 78080: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 78000, padding bloque256, P = 78080",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: the plaintext is longer than P = 78080: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"payload_length L - 1, the last byte of the content not zero","text":"capsule: PAYLOAD_AGE: byte 77999 of the plaintext is padding and is not zero: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 77999, padding reforzado, P = 79872",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: byte 77999 of the plaintext is padding and is not zero: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 2: tlock stanza U re-encoded with c0 + p","text":"capsule: age: agewrap: U of the tlock stanza is not the canonical encoding of a point of the key group: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",false,"capsule: age: agewrap: U of the tlock stanza is not the canonical encoding of a point of the key group: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 2: tlock stanza U is the point at infinity","text":"capsule: age: agewrap: U of the tlock stanza is the point at infinity: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",false,"capsule: age: agewrap: U of the tlock stanza is the point at infinity: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 2: tlock stanza U with the infinity flag and a payload","text":"capsule: age: agewrap: U of the tlock stanza is not the canonical encoding of a point of the key group: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",false,"capsule: age: agewrap: U of the tlock stanza is not the canonical encoding of a point of the key group: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 2: tlock stanza body of 127 bytes","text":"capsule: age: agewrap: tlock stanza body of 127 bytes, want 128: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=457",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",false,"capsule: age: agewrap: tlock stanza body of 127 bytes, want 128: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 2: tlock stanza body of 129 bytes","text":"capsule: age: agewrap: tlock stanza body of 129 bytes, want 128: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=459",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",false,"capsule: age: agewrap: tlock stanza body of 129 bytes, want 128: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 2: release signature re-encoded with x + p","text":"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1004 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=dbb9bc102bb15061d58e9c17d302e06f datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwNH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1004, unlock at 2023-08-23T15:59:36Z",""],[8,"tlock stanza",true,"round 1004, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",false,"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1004 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","ERR_RELEASE_INVALID"]]},
{"name":"format 2: release signature is the point at infinity","text":"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",false,"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","ERR_RELEASE_INVALID"]]},
{"name":"format 2: release signature with the infinity flag and a payload","text":"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",false,"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","ERR_RELEASE_INVALID"]]},
{"name":"format 2: release signature negated","text":"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",false,"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","ERR_RELEASE_INVALID"]]},
{"name":"format 2: negated release signature and U re-encoded with c0 + p","text":"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",false,"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","ERR_RELEASE_INVALID"]]},
{"name":"format 2 time_only relabeled format 3","text":"capsule: CONTROL_CBOR: codec: datekeys-control schema version 2, want 3: ERR_UNSUPPORTED_VERSION","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",false,"capsule: CONTROL_CBOR: codec: datekeys-control schema version 2, want 3: ERR_UNSUPPORTED_VERSION","ERR_UNSUPPORTED_VERSION"]]},
{"name":"format 1 time_only relabeled format 2","text":"capsule: CONTROL_CBOR: codec: datekeys-control schema version 1, want 2: ERR_UNSUPPORTED_VERSION","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",false,"capsule: CONTROL_CBOR: codec: datekeys-control schema version 1, want 2: ERR_UNSUPPORTED_VERSION","ERR_UNSUPPORTED_VERSION"]]},
{"name":"format 1 time_and_key with one stanza relabeled format 2, with the identity","text":"agewrap: INNER_ACCESS_AGE has 1 stanzas, want exactly 16: ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=646",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=448e134a13457c319cab7fceaf7ffa1f datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",true,"1 identities to try",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",false,"agewrap: INNER_ACCESS_AGE has 1 stanzas, want exactly 16: ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"format 2 time_only relabeled format 1","text":"capsule: CONTROL_CBOR: codec: datekeys-control schema version 2, want 1: ERR_UNSUPPORTED_VERSION","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",false,"capsule: CONTROL_CBOR: codec: datekeys-control schema version 2, want 1: ERR_UNSUPPORTED_VERSION","ERR_UNSUPPORTED_VERSION"]]},
{"name":"format 2 time_and_key relabeled format 1, with the identity","text":"capsule: CONTROL_CBOR: codec: datekeys-control schema version 2, want 1: ERR_UNSUPPORTED_VERSION","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=2128",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=fe68d3b3bb59db0c14b7ef57d8d6cb5e datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",true,"1 identities to try",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_and_key: INNER_ACCESS_AGE with 16 X25519 stanzas",""],[13,"open access layer",true,"identity matched exactly one stanza",""],[14,"control",false,"capsule: CONTROL_CBOR: codec: datekeys-control schema version 2, want 1: ERR_UNSUPPORTED_VERSION","ERR_UNSUPPORTED_VERSION"]]},
{"name":"INNER_ACCESS_AGE with 15 stanzas","text":"agewrap: INNER_ACCESS_AGE has 15 stanzas, want exactly 16: ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=2030",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=fe68d3b3bb59db0c14b7ef57d8d6cb5e datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",true,"1 identities to try",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",false,"agewrap: INNER_ACCESS_AGE has 15 stanzas, want exactly 16: ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"INNER_ACCESS_AGE with 17 stanzas","text":"agewrap: INNER_ACCESS_AGE has 17 stanzas, want exactly 16: ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=2226",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=fe68d3b3bb59db0c14b7ef57d8d6cb5e datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",true,"1 identities to try",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",false,"agewrap: INNER_ACCESS_AGE has 17 stanzas, want exactly 16: ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"16 stanzas, two for one recipient, and the identity of that recipient","text":"capsule: age: agewrap: one identity opens 2 INNER_ACCESS_AGE stanzas, want one per recipient: ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=2128",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=fe68d3b3bb59db0c14b7ef57d8d6cb5e datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",true,"1 identities to try",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_and_key: INNER_ACCESS_AGE with 16 X25519 stanzas",""],[13,"open access layer",false,"capsule: age: agewrap: one identity opens 2 INNER_ACCESS_AGE stanzas, want one per recipient: ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"identity that is not a recipient of any of the 16","text":"capsule: age: agewrap: no supplied identity is a recipient of INNER_ACCESS_AGE: ERR_ACCESS_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=2128",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=fe68d3b3bb59db0c14b7ef57d8d6cb5e datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",true,"1 identities to try",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_and_key: INNER_ACCESS_AGE with 16 X25519 stanzas",""],[13,"open access layer",false,"capsule: age: agewrap: no supplied identity is a recipient of INNER_ACCESS_AGE: ERR_ACCESS_INVALID","ERR_ACCESS_INVALID"]]},
{"name":"control of schema version 2 without key 6","text":"capsule: CONTROL_CBOR: key 6 is missing: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=448",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",false,"capsule: CONTROL_CBOR: key 6 is missing: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"control of schema version 2 without key 7","text":"capsule: CONTROL_CBOR: key 7 is missing: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=456",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",false,"capsule: CONTROL_CBOR: key 7 is missing: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"padding code 0","text":"capsule: CONTROL_CBOR: key 7: padding code 0 is not defined: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",false,"capsule: CONTROL_CBOR: key 7: padding code 0 is not defined: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"padding code 3","text":"capsule: CONTROL_CBOR: key 7: padding code 3 is not defined: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",false,"capsule: CONTROL_CBOR: key 7: padding code 3 is not defined: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"payload_length L_MAX + 1","text":"capsule: CONTROL_CBOR: key 6: payload_length 8936830510563329 exceeds L_MAX = 8936830510563328: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",false,"capsule: CONTROL_CBOR: key 6: payload_length 8936830510563329 exceeds L_MAX = 8936830510563328: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"payload_length of 7 bytes","text":"capsule: CONTROL_CBOR: key 6: codec: offset 93: a byte string of 7 bytes outside 8..8: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=457",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",false,"capsule: CONTROL_CBOR: key 6: codec: offset 93: a byte string of 7 bytes outside 8..8: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"payload_length of 9 bytes","text":"capsule: CONTROL_CBOR: key 6: codec: offset 93: a byte string of 9 bytes outside 8..8: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=459",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",false,"capsule: CONTROL_CBOR: key 6: codec: offset 93: a byte string of 9 bytes outside 8..8: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"payload_length as an unsigned integer","text":"capsule: CONTROL_CBOR: key 6: codec: offset 92: an unsigned integer where a byte string was expected: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=454",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",false,"capsule: CONTROL_CBOR: key 6: codec: offset 92: an unsigned integer where a byte string was expected: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"last padding byte not zero","text":"capsule: PAYLOAD_AGE: byte 255 of the plaintext is padding and is not zero: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=159, SEALED_CONTROL_LEN=494",""],[3,"public header",true,"159 bytes",""],[4,"header validation",true,"capsule_id=3ab2c06d482609a9c7ae92f672599883 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MjAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 2000, unlock at 2023-08-23T16:49:24Z",""],[8,"tlock stanza",true,"round 2000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 34, padding reforzado, P = 256",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: byte 255 of the plaintext is padding and is not zero: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"payload plaintext of P - 1 bytes","text":"capsule: PAYLOAD_AGE: the plaintext is 255 bytes, shorter than P = 256: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=159, SEALED_CONTROL_LEN=494",""],[3,"public header",true,"159 bytes",""],[4,"header validation",true,"capsule_id=3ab2c06d482609a9c7ae92f672599883 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MjAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 2000, unlock at 2023-08-23T16:49:24Z",""],[8,"tlock stanza",true,"round 2000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 34, padding reforzado, P = 256",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: the plaintext is 255 bytes, shorter than P = 256: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"payload plaintext of P + 256 bytes","text":"capsule: PAYLOAD_AGE: the plaintext is longer than P = 256: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=159, SEALED_CONTROL_LEN=494",""],[3,"public header",true,"159 bytes",""],[4,"header validation",true,"capsule_id=3ab2c06d482609a9c7ae92f672599883 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MjAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 2000, unlock at 2023-08-23T16:49:24Z",""],[8,"tlock stanza",true,"round 2000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 34, padding reforzado, P = 256",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: the plaintext is longer than P = 256: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"payload plaintext without padding, of L bytes","text":"capsule: PAYLOAD_AGE: the plaintext is 34 bytes, shorter than P = 256: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=159, SEALED_CONTROL_LEN=494",""],[3,"public header",true,"159 bytes",""],[4,"header validation",true,"capsule_id=3ab2c06d482609a9c7ae92f672599883 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MjAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 2000, unlock at 2023-08-23T16:49:24Z",""],[8,"tlock stanza",true,"round 2000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 34, padding reforzado, P = 256",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: the plaintext is 34 bytes, shorter than P = 256: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"padding code 2 changed to 1, with L = 78000","text":"capsule: PAYLOAD_AGE: the plaintext is longer than P = 78080: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 78000, padding bloque256, P = 78080",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: the plaintext is longer than P = 78080: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"payload_length L - 1, the last byte of the content not zero","text":"capsule: PAYLOAD_AGE: byte 77999 of the plaintext is padding and is not zero: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=c8cfc53d45c879da916edddf71f3bddd datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 77999, padding reforzado, P = 79872",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: byte 77999 of the plaintext is padding and is not zero: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 1 time_and_key with one stanza relabeled format 2, with the .dkk","text":"capsule: the .dkk capsule_digest does not match this .dkc: ERR_ACCESS_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=646",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=448e134a13457c319cab7fceaf7ffa1f datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",false,"capsule: the .dkk capsule_digest does not match this .dkc: ERR_ACCESS_INVALID","ERR_ACCESS_INVALID"]]},
{"name":"format 2 time_and_key relabeled format 1, with the .dkk","text":"capsule: the .dkk capsule_digest does not match this .dkc: ERR_ACCESS_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=2128",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=fe68d3b3bb59db0c14b7ef57d8d6cb5e datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",false,"capsule: the .dkk capsule_digest does not match this .dkc: ERR_ACCESS_INVALID","ERR_ACCESS_INVALID"]]},
{"name":"INNER_ACCESS_AGE with 15 stanzas, with the .dkk","text":"capsule: the .dkk capsule_digest does not match this .dkc: ERR_ACCESS_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=2030",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=fe68d3b3bb59db0c14b7ef57d8d6cb5e datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",false,"capsule: the .dkk capsule_digest does not match this .dkc: ERR_ACCESS_INVALID","ERR_ACCESS_INVALID"]]},
{"name":"INNER_ACCESS_AGE with 17 stanzas, with the .dkk","text":"capsule: the .dkk capsule_digest does not match this .dkc: ERR_ACCESS_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=2226",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=fe68d3b3bb59db0c14b7ef57d8d6cb5e datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",false,"capsule: the .dkk capsule_digest does not match this .dkc: ERR_ACCESS_INVALID","ERR_ACCESS_INVALID"]]},
{"name":"16 stanzas, two for one recipient, with the .dkk","text":"capsule: the .dkk capsule_digest does not match this .dkc: ERR_ACCESS_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=2128",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=fe68d3b3bb59db0c14b7ef57d8d6cb5e datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",false,"capsule: the .dkk capsule_digest does not match this .dkc: ERR_ACCESS_INVALID","ERR_ACCESS_INVALID"]]},
{"name":"format 3: PUBLIC_HEADER_A + SEALED_CONTROL_B","text":"capsule: header_binding does not match PRELUDE || PUBLIC_HEADER: ERR_HEADER_BINDING","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",false,"capsule: header_binding does not match PRELUDE || PUBLIC_HEADER: ERR_HEADER_BINDING","ERR_HEADER_BINDING"]]},
{"name":"format 3: SEALED_CONTROL_A + PAYLOAD_AGE_B","text":"capsule: PAYLOAD_AGE: agewrap: PAYLOAD_AGE is not encrypted to this control's R_PAYLOAD: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: agewrap: PAYLOAD_AGE is not encrypted to this control's R_PAYLOAD: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 3: DateKey A + release of round B","text":"provider: release for round 1001, expected 1000: ERR_ROUND_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1001 obtained",""],[10,"release verification",false,"provider: release for round 1001, expected 1000: ERR_ROUND_MISMATCH","ERR_ROUND_MISMATCH"]]},
{"name":"format 3: PUBLIC_HEADER_A + SEALED_CONTROL_B","text":"capsule: header_binding does not match PRELUDE || PUBLIC_HEADER: ERR_HEADER_BINDING","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",false,"capsule: header_binding does not match PRELUDE || PUBLIC_HEADER: ERR_HEADER_BINDING","ERR_HEADER_BINDING"]]},
{"name":"format 3: SEALED_CONTROL_A + PAYLOAD_AGE_B","text":"capsule: PAYLOAD_AGE: agewrap: PAYLOAD_AGE is not encrypted to this control's R_PAYLOAD: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: agewrap: PAYLOAD_AGE is not encrypted to this control's R_PAYLOAD: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 3: DateKey A + release of round B","text":"provider: release for round 1001, expected 1000: ERR_ROUND_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",false,"provider: release for round 1001, expected 1000: ERR_ROUND_MISMATCH","ERR_ROUND_MISMATCH"]]},
{"name":"format 3: chain hash changed","text":"agewrap: tlock stanza chain hash \"abababababababababababababababababababababababababababababababab\", pinned profile datekeys:quicknet:v1 uses 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971: ERR_PROFILE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",false,"agewrap: tlock stanza chain hash \"abababababababababababababababababababababababababababababababab\", pinned profile datekeys:quicknet:v1 uses 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971: ERR_PROFILE_MISMATCH","ERR_PROFILE_MISMATCH"]]},
{"name":"format 3: version changed","text":"capsule: framing version 4: ERR_UNSUPPORTED_VERSION","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",false,"capsule: framing version 4: ERR_UNSUPPORTED_VERSION","ERR_UNSUPPORTED_VERSION"]]},
{"name":"format 3: flags != 0","text":"capsule: flags 0x80, reserved 0x0000: ERR_INVALID_FLAGS","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",false,"capsule: flags 0x80, reserved 0x0000: ERR_INVALID_FLAGS","ERR_INVALID_FLAGS"]]},
{"name":"format 3: reserved != 0","text":"capsule: flags 0x0, reserved 0x0001: ERR_INVALID_FLAGS","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",false,"capsule: flags 0x0, reserved 0x0001: ERR_INVALID_FLAGS","ERR_INVALID_FLAGS"]]},
{"name":"format 3: payload truncated","text":"capsule: PAYLOAD_AGE: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 3: payload age modified","text":"capsule: PAYLOAD_AGE: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 3: control modified","text":"capsule: age: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",false,"capsule: age: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 3: payload truncated","text":"capsule: PAYLOAD_AGE: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 3: payload age modified","text":"capsule: PAYLOAD_AGE: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 3: control modified","text":"capsule: age: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",false,"capsule: age: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 3: non-canonical dk1_ JSON","text":"capsule: PUBLIC_HEADER: datekey: not the canonical encoding dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0: ERR_DATEKEY_NON_CANONICAL","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=124, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"124 bytes",""],[4,"header validation",false,"capsule: PUBLIC_HEADER: datekey: not the canonical encoding dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0: ERR_DATEKEY_NON_CANONICAL","ERR_DATEKEY_NON_CANONICAL"]]},
{"name":"format 3: unknown profile","text":"capsule: profile \"datekeys:evmnet:v1\" is not pinned: ERR_UNKNOWN_PROFILE","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=118, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"118 bytes",""],[4,"header validation",false,"capsule: profile \"datekeys:evmnet:v1\" is not pinned: ERR_UNKNOWN_PROFILE","ERR_UNKNOWN_PROFILE"]]},
{"name":"format 3: release of another round","text":"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",false,"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","ERR_RELEASE_INVALID"]]},
{"name":"format 3: access_policy=time_only with time_and_key structure","text":"capsule: time_only capsule seals an age file: ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=2128",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=29737cb54ad5310734ecf20720c2d317 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",false,"capsule: time_only capsule seals an age file: ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"format 3: access_policy=time_and_key with time_only structure","text":"capsule: time_and_key capsule does not seal an age file: ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",true,"1 identities to try",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",false,"capsule: time_and_key capsule does not seal an age file: ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"format 3: release of another round","text":"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",false,"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","ERR_RELEASE_INVALID"]]},
{"name":"format 3: access_policy=time_only with time_and_key structure","text":"capsule: time_only capsule seals an age file: ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=2128",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=29737cb54ad5310734ecf20720c2d317 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",false,"capsule: time_only capsule seals an age file: ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"format 3: access_policy=time_and_key with time_only structure","text":"capsule: time_and_key capsule does not seal an age file: ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",true,"1 identities to try",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",false,"capsule: time_and_key capsule does not seal an age file: ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"format 3: extra stanza in OUTER_TIME_AGE","text":"capsule: OUTER_TIME_AGE must hold exactly one tlock stanza, found 2: ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=556",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=3da4aa192170d6e6a84caf8d1b89665d datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",false,"capsule: OUTER_TIME_AGE must hold exactly one tlock stanza, found 2: ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"format 3: extra stanza in PAYLOAD_AGE","text":"agewrap: PAYLOAD_AGE has 2 stanzas, want exactly one X25519 stanza: ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=0a1312a462cba3721a98b38f2caebdd8 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",false,"agewrap: PAYLOAD_AGE has 2 stanzas, want exactly one X25519 stanza: ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"format 3: non-X25519 stanza in INNER_ACCESS_AGE","text":"agewrap: INNER_ACCESS_AGE stanza 15 has type \"scrypt\", want \"X25519\": ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=2110",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=d9b19f485bc3d438628e0ad1cdf53ce5 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",true,"1 identities to try",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",false,"agewrap: INNER_ACCESS_AGE stanza 15 has type \"scrypt\", want \"X25519\": ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"format 3: non-X25519 stanza in INNER_ACCESS_AGE","text":"agewrap: INNER_ACCESS_AGE stanza 15 has type \"scrypt\", want \"X25519\": ERR_POLICY_STRUCTURE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=2110",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=d9b19f485bc3d438628e0ad1cdf53ce5 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",true,"1 identities to try",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",false,"agewrap: INNER_ACCESS_AGE stanza 15 has type \"scrypt\", want \"X25519\": ERR_POLICY_STRUCTURE_MISMATCH","ERR_POLICY_STRUCTURE_MISMATCH"]]},
{"name":"format 3: tlock stanza round differs from DateKey.round","text":"agewrap: tlock stanza round \"1001\", DateKey round 1000: ERR_ROUND_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=16def2d8ead91535dac7a89d334e5bee datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",false,"agewrap: tlock stanza round \"1001\", DateKey round 1000: ERR_ROUND_MISMATCH","ERR_ROUND_MISMATCH"]]},
{"name":"format 3: tlock stanza chain hash differs from the pinned profile","text":"agewrap: tlock stanza chain hash \"dbd506d6ef76e5f386f41c651dcb808c5bcbd75471cc4eafa3f4df7ad4e4c493\", pinned profile datekeys:quicknet:v1 uses 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971: ERR_PROFILE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=837d8abe415bf5784ef7d568f2fa71cb datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",false,"agewrap: tlock stanza chain hash \"dbd506d6ef76e5f386f41c651dcb808c5bcbd75471cc4eafa3f4df7ad4e4c493\", pinned profile datekeys:quicknet:v1 uses 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971: ERR_PROFILE_MISMATCH","ERR_PROFILE_MISMATCH"]]},
{"name":"format 3: extension data of a type other than bstr","text":"capsule: PUBLIC_HEADER: key 6: extension \"org.example.label\": key 2: codec: offset 146: a text string where a byte string was expected: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=159, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"159 bytes",""],[4,"header validation",false,"capsule: PUBLIC_HEADER: key 6: extension \"org.example.label\": key 2: codec: offset 146: a text string where a byte string was expected: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"format 3: empty extension data (h'')","text":"capsule: PUBLIC_HEADER: key 6: extension \"org.example.label\": data is present but empty; an extension without data omits key 2: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=147, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"147 bytes",""],[4,"header validation",false,"capsule: PUBLIC_HEADER: key 6: extension \"org.example.label\": data is present but empty; an extension without data omits key 2: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"format 3: 65 extensions in one array","text":"capsule: PUBLIC_HEADER: key 6: extension: codec: offset 124: array of 65 items, at most 64: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=1424, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"1424 bytes",""],[4,"header validation",false,"capsule: PUBLIC_HEADER: key 6: extension: codec: offset 124: array of 65 items, at most 64: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"format 3: tlock stanza U re-encoded with c0 + p","text":"capsule: age: agewrap: U of the tlock stanza is not the canonical encoding of a point of the key group: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",false,"capsule: age: agewrap: U of the tlock stanza is not the canonical encoding of a point of the key group: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 3: tlock stanza U is the point at infinity","text":"capsule: age: agewrap: U of the tlock stanza is the point at infinity: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",false,"capsule: age: agewrap: U of the tlock stanza is the point at infinity: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 3: tlock stanza U with the infinity flag and a payload","text":"capsule: age: agewrap: U of the tlock stanza is not the canonical encoding of a point of the key group: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",false,"capsule: age: agewrap: U of the tlock stanza is not the canonical encoding of a point of the key group: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 3: tlock stanza body of 127 bytes","text":"capsule: age: agewrap: tlock stanza body of 127 bytes, want 128: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=457",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",false,"capsule: age: agewrap: tlock stanza body of 127 bytes, want 128: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 3: tlock stanza body of 129 bytes","text":"capsule: age: agewrap: tlock stanza body of 129 bytes, want 128: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=459",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",false,"capsule: age: agewrap: tlock stanza body of 129 bytes, want 128: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 3: release signature re-encoded with x + p","text":"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1004 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=6134b00a1f901953021415cdee365c49 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwNH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1004, unlock at 2023-08-23T15:59:36Z",""],[8,"tlock stanza",true,"round 1004, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1004 obtained",""],[10,"release verification",false,"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1004 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","ERR_RELEASE_INVALID"]]},
{"name":"format 3: release signature is the point at infinity","text":"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",false,"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","ERR_RELEASE_INVALID"]]},
{"name":"format 3: release signature with the infinity flag and a payload","text":"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",false,"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","ERR_RELEASE_INVALID"]]},
{"name":"format 3: release signature negated","text":"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",false,"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","ERR_RELEASE_INVALID"]]},
{"name":"format 3: negated release signature and U re-encoded with c0 + p","text":"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",false,"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","ERR_RELEASE_INVALID"]]},
{"name":"format 3 time_only relabeled format 2","text":"capsule: CONTROL_CBOR: codec: datekeys-control schema version 3, want 2: ERR_UNSUPPORTED_VERSION","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",false,"capsule: CONTROL_CBOR: codec: datekeys-control schema version 3, want 2: ERR_UNSUPPORTED_VERSION","ERR_UNSUPPORTED_VERSION"]]},
{"name":"AREA_LEN 0","text":"capsule: BODY: AREA_LEN 0 is not a multiple of 512 from 512 to 65536: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: BODY: AREA_LEN 0 is not a multiple of 512 from 512 to 65536: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"AREA_LEN 511","text":"capsule: BODY: AREA_LEN 511 is not a multiple of 512 from 512 to 65536: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: BODY: AREA_LEN 511 is not a multiple of 512 from 512 to 65536: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"AREA_LEN 513","text":"capsule: BODY: AREA_LEN 513 is not a multiple of 512 from 512 to 65536: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: BODY: AREA_LEN 513 is not a multiple of 512 from 512 to 65536: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"AREA_LEN 66048","text":"capsule: BODY: AREA_LEN 66048 is not a multiple of 512 from 512 to 65536: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: BODY: AREA_LEN 66048 is not a multiple of 512 from 512 to 65536: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"SECURITY_LEN 0","text":"capsule: BODY: SECURITY_LEN 0 is not from 1 to AREA_LEN = 512: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: BODY: SECURITY_LEN 0 is not from 1 to AREA_LEN = 512: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"SECURITY_LEN 513, larger than AREA_LEN","text":"capsule: BODY: SECURITY_LEN 513 is not from 1 to AREA_LEN = 512: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: BODY: SECURITY_LEN 513 is not from 1 to AREA_LEN = 512: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"HEAD_LEN 0","text":"capsule: BODY: HEAD_LEN 0 is not from 1 to 16777216: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: BODY: HEAD_LEN 0 is not from 1 to 16777216: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"HEAD_LEN 2^24 + 1","text":"capsule: BODY: HEAD_LEN 16777217 is not from 1 to 16777216: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: BODY: HEAD_LEN 16777217 is not from 1 to 16777216: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"12 + AREA_LEN + HEAD_LEN = L + 1","text":"capsule: BODY: the frame, the area of 512 bytes and the head of 136 bytes exceed L = 659: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: BODY: the frame, the area of 512 bytes and the head of 136 bytes exceed L = 659: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"L < 12: 11","text":"capsule: BODY: L = 11 is shorter than the frame of 12 bytes: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 11, padding reforzado, P = 256",""],[17,"open payload",false,"capsule: BODY: L = 11 is shorter than the frame of 12 bytes: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"a byte of the area not zero","text":"capsule: BODY: byte 511 of the security area is not zero: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: BODY: byte 511 of the security area is not zero: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"head of version 2","text":"capsule: head: codec: datekeys-head schema version 2, want 1: ERR_UNSUPPORTED_VERSION","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: codec: datekeys-head schema version 2, want 1: ERR_UNSUPPORTED_VERSION","ERR_UNSUPPORTED_VERSION"]]},
{"name":"head of another type tag","text":"capsule: head: codec: type \"datekeys-heaD\", want \"datekeys-head\": ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: codec: type \"datekeys-heaD\", want \"datekeys-head\": ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"head with a byte more within HEAD_LEN","text":"capsule: head: codec: offset 113: 1 trailing bytes: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 660, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: codec: offset 113: 1 trailing bytes: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"paths b and a, in that order","text":"capsule: head: key 5: file 2: R8: the path is not after the path of file 1 in byte order: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 691, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: key 5: file 2: R8: the path is not after the path of file 1 in byte order: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"paths b/.. and a, in that order","text":"capsule: head: key 5: file 2: R8: the path is not after the path of file 1 in byte order: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 694, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: key 5: file 2: R8: the path is not after the path of file 1 in byte order: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"path of 1025 bytes","text":"capsule: head: key 5: file 1: key 0: codec: offset 60: a text string of 1025 bytes outside 0..1024: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 1678, padding reforzado, P = 1792",""],[17,"open payload",false,"capsule: head: key 5: file 1: key 0: codec: offset 60: a text string of 1025 bytes outside 0..1024: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"path ..","text":"capsule: head: file 1: R3: segment 1: the segment is two dots: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 653, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: file 1: R3: segment 1: the segment is two dots: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"path /a","text":"capsule: head: file 1: R2: segment 1 is empty: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 653, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: file 1: R2: segment 1 is empty: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"paths A.txt and a.txt","text":"capsule: head: R7: path 2 collides with path 1 in segment 1: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 699, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: R7: path 2 collides with path 1 in segment 1: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"paths ab and a, U+200C, b","text":"capsule: head: R7: path 2 collides with path 1 in segment 1: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 696, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: R7: path 2 collides with path 1 in segment 1: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"path CON.txt","text":"capsule: head: file 1: R6: segment 1: CON is a reserved device name: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 658, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: file 1: R6: segment 1: CON is a reserved device name: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"path CON.txt in full-width forms","text":"capsule: head: file 1: R6c: segment 1: code page 874 maps the segment to one that breaks R6: CON is a reserved device name: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 664, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: file 1: R6c: segment 1: code page 874 maps the segment to one that breaks R6: CON is a reserved device name: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"path ABCDEF~1","text":"capsule: head: file 1: R6b: segment 1: the segment has the form of an 8.3 alias: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: file 1: R6b: segment 1: the segment has the form of an 8.3 alias: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"path with U+202E","text":"capsule: head: file 1: R4: segment 1: invisible U+202E: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 660, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: file 1: R4: segment 1: invisible U+202E: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"path .datekeys-x","text":"capsule: head: file 1: R10: the first segment starts with \".datekeys-\": ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 662, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: file 1: R10: the first segment starts with \".datekeys-\": ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"comment with U+202E","text":"capsule: head: comment: text: bidirectional control U+202E: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 666, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: comment: text: bidirectional control U+202E: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"path a.","text":"capsule: head: file 1: R5: segment 1: the segment ends with '.': ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 653, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: file 1: R5: segment 1: the segment ends with '.': ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"paths A and a/b","text":"capsule: head: R7: path 2 collides with path 1 in segment 1: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 693, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: R7: path 2 collides with path 1 in segment 1: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"65536 implicit folders","text":"capsule: head: R9: 65536 folders, more than 65535: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 235309, padding reforzado, P = 237568",""],[17,"open payload",false,"capsule: head: R9: 65536 folders, more than 65535: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"declared author with LF","text":"capsule: head: declared author: text: control U+000A in the declared author: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 671, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: declared author: text: control U+000A in the declared author: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"start of the first entry not 0","text":"capsule: head: file 1: start 1 is not 0, the end of the file before: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: file 1: start 1 is not 0, the end of the file before: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"end - start not size","text":"capsule: head: file 1: from start 0 to end 21 is not the size 22: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: file 1: from start 0 to end 21 is not the size 22: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"path a followed by VS16","text":"capsule: head: file 1: R4b: segment 1: U+FE0F is not part of an emoji variation sequence: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 655, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: file 1: R4b: segment 1: U+FE0F is not part of an emoji variation sequence: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"path with two ZWJ in a row","text":"capsule: head: file 1: R4b: segment 1: U+200D right after U+200D: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: file 1: R4b: segment 1: U+200D right after U+200D: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"comment with the tag U+E0041","text":"capsule: head: comment: text: invisible U+E0041: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 669, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: comment: text: invisible U+E0041: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"comment with the variation selector VS17","text":"capsule: head: comment: text: invisible U+E0100: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 669, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: comment: text: invisible U+E0100: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"start of an entry not the end of the one before","text":"capsule: head: file 2: start 12 is not 11, the end of the file before: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 691, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: file 2: start 12 is not 11, the end of the file before: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"end of the last file not C","text":"capsule: BODY: the files end at byte 21 of a content of 22 bytes: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: BODY: the files end at byte 21 of a content of 22 bytes: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"a byte of a file changed","text":"capsule: PAYLOAD_AGE: file 1: its SHA-256 is not the one of the head: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: file 1: its SHA-256 is not the one of the head: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"path .. and a padding byte not zero","text":"capsule: head: file 1: R3: segment 1: the segment is two dots: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 653, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: file 1: R3: segment 1: the segment is two dots: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"path .. and the next STREAM chunk corrupt","text":"capsule: PAYLOAD_AGE: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=091119676ec081409c666846153ba7eb datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMX0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1001, unlock at 2023-08-23T15:59:27Z",""],[8,"tlock stanza",true,"round 1001, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1001 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 84078, padding reforzado, P = 86016",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"path .. and a cut right after its chunk","text":"capsule: PAYLOAD_AGE: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=091119676ec081409c666846153ba7eb datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMX0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1001, unlock at 2023-08-23T15:59:27Z",""],[8,"tlock stanza",true,"round 1001, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1001 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 84078, padding reforzado, P = 86016",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"security of version 2 opens with the verdict X","text":"ok","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",true,"payload authenticated; BODY of 659 bytes, 1 files, area of 512 bytes",""],[18,"commit",true,"1 files",""]]},
{"name":"a signature of alg 4294967295 opens with the verdict F1","text":"ok","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",true,"payload authenticated; BODY of 659 bytes, 1 files, area of 512 bytes",""],[18,"commit",true,"1 files",""]]},
{"name":"a signature of alg 1 that does not verify opens with the verdict F2","text":"ok","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",true,"payload authenticated; BODY of 659 bytes, 1 files, area of 512 bytes",""],[18,"commit",true,"1 files",""]]},
{"name":"a seal of seal_type 4294967295 opens with the verdict S1","text":"ok","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",true,"payload authenticated; BODY of 659 bytes, 1 files, area of 512 bytes",""],[18,"commit",true,"1 files",""]]},
{"name":"the signature of alg 1 altered opens with the verdict F2","text":"ok","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=681476c1bfa81dd12fec810ee44fe7f7 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 32915, padding reforzado, P = 34816",""],[17,"open payload",true,"payload authenticated; BODY of 32915 bytes, 1 files, area of 32768 bytes",""],[18,"commit",true,"1 files",""]]},
{"name":"the signature of alg 1 removed opens with the verdict F0","text":"ok","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=681476c1bfa81dd12fec810ee44fe7f7 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 32915, padding reforzado, P = 34816",""],[17,"open payload",true,"payload authenticated; BODY of 32915 bytes, 1 files, area of 32768 bytes",""],[18,"commit",true,"1 files",""]]},
{"name":"the signature of alg 1 made again with another key opens with the verdict F4 of that key","text":"ok","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=681476c1bfa81dd12fec810ee44fe7f7 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 32915, padding reforzado, P = 34816",""],[17,"open payload",true,"payload authenticated; BODY of 32915 bytes, 1 files, area of 32768 bytes",""],[18,"commit",true,"1 files",""]]},
{"name":"the signature of alg 1 transplanted to another capsule opens with the verdict F2","text":"ok","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=0cced8e8b035d6dd70f39923b407a96c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 32915, padding reforzado, P = 34816",""],[17,"open payload",true,"payload authenticated; BODY of 32915 bytes, 1 files, area of 32768 bytes",""],[18,"commit",true,"1 files",""]]},
{"name":"a key of 31 bytes in a signature of alg 1 opens with the verdict F1","text":"ok","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=681476c1bfa81dd12fec810ee44fe7f7 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 32915, padding reforzado, P = 34816",""],[17,"open payload",true,"payload authenticated; BODY of 32915 bytes, 1 files, area of 32768 bytes",""],[18,"commit",true,"1 files",""]]},
{"name":"a signature of 65 bytes of alg 1 opens with the verdict F1","text":"ok","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=681476c1bfa81dd12fec810ee44fe7f7 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 32915, padding reforzado, P = 34816",""],[17,"open payload",true,"payload authenticated; BODY of 32915 bytes, 1 files, area of 32768 bytes",""],[18,"commit",true,"1 files",""]]},
{"name":"the area widened to 64 KiB after signing opens with the verdict F4 and the same AUTHOR_MESSAGE","text":"ok","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=681476c1bfa81dd12fec810ee44fe7f7 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 65683, padding reforzado, P = 67584",""],[17,"open payload",true,"payload authenticated; BODY of 65683 bytes, 1 files, area of 65536 bytes",""],[18,"commit",true,"1 files",""]]},
{"name":"the public note changed in PUBLIC_HEADER","text":"capsule: header_binding does not match PRELUDE || PUBLIC_HEADER: ERR_HEADER_BINDING","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=169, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"169 bytes",""],[4,"header validation",true,"capsule_id=1999a39e1beae60b2fc9b157d11dab5a datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",false,"capsule: header_binding does not match PRELUDE || PUBLIC_HEADER: ERR_HEADER_BINDING","ERR_HEADER_BINDING"]]},
{"name":"format 3 time_only relabeled format 1","text":"capsule: CONTROL_CBOR: codec: datekeys-control schema version 3, want 1: ERR_UNSUPPORTED_VERSION","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",false,"capsule: CONTROL_CBOR: codec: datekeys-control schema version 3, want 1: ERR_UNSUPPORTED_VERSION","ERR_UNSUPPORTED_VERSION"]]},
{"name":"format 3 time_and_key relabeled format 2, with the identity","text":"capsule: CONTROL_CBOR: codec: datekeys-control schema version 3, want 2: ERR_UNSUPPORTED_VERSION","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=2128",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=29737cb54ad5310734ecf20720c2d317 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",true,"1 identities to try",""],[9,"release",true,"round 1000 obtained",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_and_key: INNER_ACCESS_AGE with 16 X25519 stanzas",""],[13,"open access layer",true,"identity matched exactly one stanza",""],[14,"control",false,"capsule: CONTROL_CBOR: codec: datekeys-control schema version 3, want 2: ERR_UNSUPPORTED_VERSION","ERR_UNSUPPORTED_VERSION"]]},
{"name":"format 3 time_and_key relabeled format 2, with the .dkk","text":"capsule: the .dkk capsule_digest does not match this .dkc: ERR_ACCESS_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=2128",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=29737cb54ad5310734ecf20720c2d317 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",false,"capsule: the .dkk capsule_digest does not match this .dkc: ERR_ACCESS_INVALID","ERR_ACCESS_INVALID"]]}
{"name":"format 3: tlock stanza U re-encoded with c0 + p","text":"capsule: age: agewrap: U of the tlock stanza is not the canonical encoding of a point of the key group: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",false,"capsule: age: agewrap: U of the tlock stanza is not the canonical encoding of a point of the key group: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 3: tlock stanza U is the point at infinity","text":"capsule: age: agewrap: U of the tlock stanza is the point at infinity: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",false,"capsule: age: agewrap: U of the tlock stanza is the point at infinity: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 3: tlock stanza U with the infinity flag and a payload","text":"capsule: age: agewrap: U of the tlock stanza is not the canonical encoding of a point of the key group: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",false,"capsule: age: agewrap: U of the tlock stanza is not the canonical encoding of a point of the key group: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 3: tlock stanza body of 127 bytes","text":"capsule: age: agewrap: tlock stanza body of 127 bytes, want 128: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=457",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",false,"capsule: age: agewrap: tlock stanza body of 127 bytes, want 128: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 3: tlock stanza body of 129 bytes","text":"capsule: age: agewrap: tlock stanza body of 129 bytes, want 128: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=459",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",false,"capsule: age: agewrap: tlock stanza body of 129 bytes, want 128: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"format 3: release signature re-encoded with x + p","text":"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1004 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=6134b00a1f901953021415cdee365c49 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwNH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1004, unlock at 2023-08-23T15:59:36Z",""],[8,"tlock stanza",true,"round 1004, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",false,"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1004 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","ERR_RELEASE_INVALID"]]},
{"name":"format 3: release signature is the point at infinity","text":"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",false,"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","ERR_RELEASE_INVALID"]]},
{"name":"format 3: release signature with the infinity flag and a payload","text":"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",false,"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","ERR_RELEASE_INVALID"]]},
{"name":"format 3: release signature negated","text":"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",false,"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","ERR_RELEASE_INVALID"]]},
{"name":"format 3: negated release signature and U re-encoded with c0 + p","text":"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",false,"provider: the signature is not a canonical point encoding, or does not verify as the BLS signature of round 1000 under datekeys:quicknet:v1: ERR_RELEASE_INVALID","ERR_RELEASE_INVALID"]]},
{"name":"format 3 time_only relabeled format 2","text":"capsule: CONTROL_CBOR: codec: datekeys-control schema version 3, want 2: ERR_UNSUPPORTED_VERSION","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",false,"capsule: CONTROL_CBOR: codec: datekeys-control schema version 3, want 2: ERR_UNSUPPORTED_VERSION","ERR_UNSUPPORTED_VERSION"]]},
{"name":"AREA_LEN 0","text":"capsule: BODY: AREA_LEN 0 is not a multiple of 512 from 512 to 65536: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: BODY: AREA_LEN 0 is not a multiple of 512 from 512 to 65536: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"AREA_LEN 511","text":"capsule: BODY: AREA_LEN 511 is not a multiple of 512 from 512 to 65536: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: BODY: AREA_LEN 511 is not a multiple of 512 from 512 to 65536: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"AREA_LEN 513","text":"capsule: BODY: AREA_LEN 513 is not a multiple of 512 from 512 to 65536: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: BODY: AREA_LEN 513 is not a multiple of 512 from 512 to 65536: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"AREA_LEN 66048","text":"capsule: BODY: AREA_LEN 66048 is not a multiple of 512 from 512 to 65536: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: BODY: AREA_LEN 66048 is not a multiple of 512 from 512 to 65536: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"SECURITY_LEN 0","text":"capsule: BODY: SECURITY_LEN 0 is not from 1 to AREA_LEN = 512: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: BODY: SECURITY_LEN 0 is not from 1 to AREA_LEN = 512: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"SECURITY_LEN 513, larger than AREA_LEN","text":"capsule: BODY: SECURITY_LEN 513 is not from 1 to AREA_LEN = 512: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: BODY: SECURITY_LEN 513 is not from 1 to AREA_LEN = 512: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"HEAD_LEN 0","text":"capsule: BODY: HEAD_LEN 0 is not from 1 to 16777216: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: BODY: HEAD_LEN 0 is not from 1 to 16777216: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"HEAD_LEN 2^24 + 1","text":"capsule: BODY: HEAD_LEN 16777217 is not from 1 to 16777216: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: BODY: HEAD_LEN 16777217 is not from 1 to 16777216: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"12 + AREA_LEN + HEAD_LEN = L + 1","text":"capsule: BODY: the frame, the area of 512 bytes and the head of 136 bytes exceed L = 659: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: BODY: the frame, the area of 512 bytes and the head of 136 bytes exceed L = 659: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"L < 12: 11","text":"capsule: BODY: L = 11 is shorter than the frame of 12 bytes: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 11, padding reforzado, P = 256",""],[17,"open payload",false,"capsule: BODY: L = 11 is shorter than the frame of 12 bytes: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"a byte of the area not zero","text":"capsule: BODY: byte 511 of the security area is not zero: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: BODY: byte 511 of the security area is not zero: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"head of version 2","text":"capsule: head: codec: datekeys-head schema version 2, want 1: ERR_UNSUPPORTED_VERSION","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: codec: datekeys-head schema version 2, want 1: ERR_UNSUPPORTED_VERSION","ERR_UNSUPPORTED_VERSION"]]},
{"name":"head of another type tag","text":"capsule: head: codec: type \"datekeys-heaD\", want \"datekeys-head\": ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: codec: type \"datekeys-heaD\", want \"datekeys-head\": ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"head with a byte more within HEAD_LEN","text":"capsule: head: codec: offset 113: 1 trailing bytes: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 660, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: codec: offset 113: 1 trailing bytes: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"paths b and a, in that order","text":"capsule: head: key 5: file 2: R8: the path is not after the path of file 1 in byte order: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 691, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: key 5: file 2: R8: the path is not after the path of file 1 in byte order: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"paths b/.. and a, in that order","text":"capsule: head: key 5: file 2: R8: the path is not after the path of file 1 in byte order: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 694, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: key 5: file 2: R8: the path is not after the path of file 1 in byte order: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"path of 1025 bytes","text":"capsule: head: key 5: file 1: key 0: codec: offset 60: a text string of 1025 bytes outside 0..1024: ERR_NON_CANONICAL_CBOR","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 1678, padding reforzado, P = 1792",""],[17,"open payload",false,"capsule: head: key 5: file 1: key 0: codec: offset 60: a text string of 1025 bytes outside 0..1024: ERR_NON_CANONICAL_CBOR","ERR_NON_CANONICAL_CBOR"]]},
{"name":"path ..","text":"capsule: head: file 1: R3: segment 1: the segment is two dots: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 653, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: file 1: R3: segment 1: the segment is two dots: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"path /a","text":"capsule: head: file 1: R2: segment 1 is empty: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 653, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: file 1: R2: segment 1 is empty: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"paths A.txt and a.txt","text":"capsule: head: R7: path 2 collides with path 1 in segment 1: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 699, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: R7: path 2 collides with path 1 in segment 1: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"paths ab and a, U+200C, b","text":"capsule: head: R7: path 2 collides with path 1 in segment 1: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 696, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: R7: path 2 collides with path 1 in segment 1: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"path CON.txt","text":"capsule: head: file 1: R6: segment 1: CON is a reserved device name: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 658, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: file 1: R6: segment 1: CON is a reserved device name: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"path CON.txt in full-width forms","text":"capsule: head: file 1: R6c: segment 1: code page 874 maps the segment to one that breaks R6: CON is a reserved device name: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 664, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: file 1: R6c: segment 1: code page 874 maps the segment to one that breaks R6: CON is a reserved device name: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"path ABCDEF~1","text":"capsule: head: file 1: R6b: segment 1: the segment has the form of an 8.3 alias: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: file 1: R6b: segment 1: the segment has the form of an 8.3 alias: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"path with U+202E","text":"capsule: head: file 1: R4: segment 1: invisible U+202E: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 660, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: file 1: R4: segment 1: invisible U+202E: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"path .datekeys-x","text":"capsule: head: file 1: R10: the first segment starts with \".datekeys-\": ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 662, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: file 1: R10: the first segment starts with \".datekeys-\": ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"comment with U+202E","text":"capsule: head: comment: text: bidirectional control U+202E: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 666, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: comment: text: bidirectional control U+202E: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"path a.","text":"capsule: head: file 1: R5: segment 1: the segment ends with '.': ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 653, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: file 1: R5: segment 1: the segment ends with '.': ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"paths A and a/b","text":"capsule: head: R7: path 2 collides with path 1 in segment 1: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 693, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: R7: path 2 collides with path 1 in segment 1: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"65536 implicit folders","text":"capsule: head: R9: 65536 folders, more than 65535: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 235309, padding reforzado, P = 237568",""],[17,"open payload",false,"capsule: head: R9: 65536 folders, more than 65535: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"declared author with LF","text":"capsule: head: declared author: text: control U+000A in the declared author: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 671, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: declared author: text: control U+000A in the declared author: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"start of the first entry not 0","text":"capsule: head: file 1: start 1 is not 0, the end of the file before: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: file 1: start 1 is not 0, the end of the file before: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"end - start not size","text":"capsule: head: file 1: from start 0 to end 21 is not the size 22: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: file 1: from start 0 to end 21 is not the size 22: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"path a followed by VS16","text":"capsule: head: file 1: R4b: segment 1: U+FE0F is not part of an emoji variation sequence: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 655, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: file 1: R4b: segment 1: U+FE0F is not part of an emoji variation sequence: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"path with two ZWJ in a row","text":"capsule: head: file 1: R4b: segment 1: U+200D right after U+200D: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: file 1: R4b: segment 1: U+200D right after U+200D: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"comment with the tag U+E0041","text":"capsule: head: comment: text: invisible U+E0041: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 669, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: comment: text: invisible U+E0041: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"comment with the variation selector VS17","text":"capsule: head: comment: text: invisible U+E0100: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 669, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: comment: text: invisible U+E0100: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"start of an entry not the end of the one before","text":"capsule: head: file 2: start 12 is not 11, the end of the file before: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 691, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: file 2: start 12 is not 11, the end of the file before: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"end of the last file not C","text":"capsule: BODY: the files end at byte 21 of a content of 22 bytes: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: BODY: the files end at byte 21 of a content of 22 bytes: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"a byte of a file changed","text":"capsule: PAYLOAD_AGE: file 1: its SHA-256 is not the one of the head: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: file 1: its SHA-256 is not the one of the head: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"path .. and a padding byte not zero","text":"capsule: head: file 1: R3: segment 1: the segment is two dots: ERR_HEAD_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 653, padding reforzado, P = 768",""],[17,"open payload",false,"capsule: head: file 1: R3: segment 1: the segment is two dots: ERR_HEAD_INVALID","ERR_HEAD_INVALID"]]},
{"name":"path .. and the next STREAM chunk corrupt","text":"capsule: PAYLOAD_AGE: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=091119676ec081409c666846153ba7eb datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMX0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1001, unlock at 2023-08-23T15:59:27Z",""],[8,"tlock stanza",true,"round 1001, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 84078, padding reforzado, P = 86016",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"path .. and a cut right after its chunk","text":"capsule: PAYLOAD_AGE: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=091119676ec081409c666846153ba7eb datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMX0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1001, unlock at 2023-08-23T15:59:27Z",""],[8,"tlock stanza",true,"round 1001, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 84078, padding reforzado, P = 86016",""],[17,"open payload",false,"capsule: PAYLOAD_AGE: the age payload is truncated, has trailing data or fails STREAM authentication: ERR_INTEGRITY","ERR_INTEGRITY"]]},
{"name":"security of version 2 opens with the verdict X","text":"ok","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",true,"payload authenticated; BODY of 659 bytes, 1 files, area of 512 bytes",""],[18,"commit",true,"1 files",""]]},
{"name":"a signature of alg 4294967295 opens with the verdict F1","text":"ok","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",true,"payload authenticated; BODY of 659 bytes, 1 files, area of 512 bytes",""],[18,"commit",true,"1 files",""]]},
{"name":"a signature of alg 1 that does not verify opens with the verdict F2","text":"ok","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",true,"payload authenticated; BODY of 659 bytes, 1 files, area of 512 bytes",""],[18,"commit",true,"1 files",""]]},
{"name":"a seal of seal_type 4294967295 opens with the verdict S1","text":"ok","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 659, padding reforzado, P = 768",""],[17,"open payload",true,"payload authenticated; BODY of 659 bytes, 1 files, area of 512 bytes",""],[18,"commit",true,"1 files",""]]},
{"name":"the signature of alg 1 altered opens with the verdict F2","text":"ok","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=681476c1bfa81dd12fec810ee44fe7f7 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 32915, padding reforzado, P = 34816",""],[17,"open payload",true,"payload authenticated; BODY of 32915 bytes, 1 files, area of 32768 bytes",""],[18,"commit",true,"1 files",""]]},
{"name":"the signature of alg 1 removed opens with the verdict F0","text":"ok","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=681476c1bfa81dd12fec810ee44fe7f7 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 32915, padding reforzado, P = 34816",""],[17,"open payload",true,"payload authenticated; BODY of 32915 bytes, 1 files, area of 32768 bytes",""],[18,"commit",true,"1 files",""]]},
{"name":"the signature of alg 1 made again with another key opens with the verdict F4 of that key","text":"ok","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=681476c1bfa81dd12fec810ee44fe7f7 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 32915, padding reforzado, P = 34816",""],[17,"open payload",true,"payload authenticated; BODY of 32915 bytes, 1 files, area of 32768 bytes",""],[18,"commit",true,"1 files",""]]},
{"name":"the signature of alg 1 transplanted to another capsule opens with the verdict F2","text":"ok","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=0cced8e8b035d6dd70f39923b407a96c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 32915, padding reforzado, P = 34816",""],[17,"open payload",true,"payload authenticated; BODY of 32915 bytes, 1 files, area of 32768 bytes",""],[18,"commit",true,"1 files",""]]},
{"name":"a key of 31 bytes in a signature of alg 1 opens with the verdict F1","text":"ok","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=681476c1bfa81dd12fec810ee44fe7f7 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 32915, padding reforzado, P = 34816",""],[17,"open payload",true,"payload authenticated; BODY of 32915 bytes, 1 files, area of 32768 bytes",""],[18,"commit",true,"1 files",""]]},
{"name":"a signature of 65 bytes of alg 1 opens with the verdict F1","text":"ok","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=681476c1bfa81dd12fec810ee44fe7f7 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 32915, padding reforzado, P = 34816",""],[17,"open payload",true,"payload authenticated; BODY of 32915 bytes, 1 files, area of 32768 bytes",""],[18,"commit",true,"1 files",""]]},
{"name":"the area widened to 64 KiB after signing opens with the verdict F4 and the same AUTHOR_MESSAGE","text":"ok","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=681476c1bfa81dd12fec810ee44fe7f7 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",true,"matches",""],[16,"payload identity",true,"I_PAYLOAD recovered; L = 65683, padding reforzado, P = 67584",""],[17,"open payload",true,"payload authenticated; BODY of 65683 bytes, 1 files, area of 65536 bytes",""],[18,"commit",true,"1 files",""]]},
{"name":"the public note changed in PUBLIC_HEADER","text":"capsule: header_binding does not match PRELUDE || PUBLIC_HEADER: ERR_HEADER_BINDING","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v3, PUBLIC_HEADER_LEN=169, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"169 bytes",""],[4,"header validation",true,"capsule_id=1999a39e1beae60b2fc9b157d11dab5a datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",true,"canonical CONTROL_CBOR",""],[15,"header binding",false,"capsule: header_binding does not match PRELUDE || PUBLIC_HEADER: ERR_HEADER_BINDING","ERR_HEADER_BINDING"]]},
{"name":"format 3 time_only relabeled format 1","text":"capsule: CONTROL_CBOR: codec: datekeys-control schema version 3, want 1: ERR_UNSUPPORTED_VERSION","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ff23599acbe9b0a742792dcb7cb1bc4c datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_only: CONTROL_CBOR sealed directly",""],[14,"control",false,"capsule: CONTROL_CBOR: codec: datekeys-control schema version 3, want 1: ERR_UNSUPPORTED_VERSION","ERR_UNSUPPORTED_VERSION"]]},
{"name":"format 3 time_and_key relabeled format 2, with the identity","text":"capsule: CONTROL_CBOR: codec: datekeys-control schema version 3, want 2: ERR_UNSUPPORTED_VERSION","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=2128",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=29737cb54ad5310734ecf20720c2d317 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",true,"1 identities to try",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",true,"BLS signature valid under the pinned key",""],[11,"open sealed control",true,"one tlock stanza, header MAC valid",""],[12,"policy structure",true,"time_and_key: INNER_ACCESS_AGE with 16 X25519 stanzas",""],[13,"open access layer",true,"identity matched exactly one stanza",""],[14,"control",false,"capsule: CONTROL_CBOR: codec: datekeys-control schema version 3, want 2: ERR_UNSUPPORTED_VERSION","ERR_UNSUPPORTED_VERSION"]]},
{"name":"format 3 time_and_key relabeled format 2, with the .dkk","text":"capsule: the .dkk capsule_digest does not match this .dkc: ERR_ACCESS_INVALID","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v2, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=2128",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=29737cb54ad5310734ecf20720c2d317 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_and_key profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"access credential",false,"capsule: the .dkk capsule_digest does not match this .dkc: ERR_ACCESS_INVALID","ERR_ACCESS_INVALID"]]},
{"name":"round not reached yet, from a network source","text":"capsule: round 1000 is published at 2023-08-23T15:59:24Z, it is 2023-08-23T15:59:23Z: ERR_RELEASE_UNAVAILABLE","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",false,"capsule: round 1000 is published at 2023-08-23T15:59:24Z, it is 2023-08-23T15:59:23Z: ERR_RELEASE_UNAVAILABLE","ERR_RELEASE_UNAVAILABLE"]]},
{"name":"release of another round, from a network source","text":"testkit: the release is discarded: provider: release for round 1001, expected 1000: ERR_ROUND_MISMATCH: ERR_RELEASE_UNAVAILABLE","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",false,"testkit: the release is discarded: provider: release for round 1001, expected 1000: ERR_ROUND_MISMATCH: ERR_RELEASE_UNAVAILABLE","ERR_RELEASE_UNAVAILABLE"]]},
{"name":"release object of another chain","text":"provider: release of chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e970, the pinned profile datekeys:quicknet:v1 is chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971: ERR_PROFILE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller",""],[10,"release verification",false,"provider: release of chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e970, the pinned profile datekeys:quicknet:v1 is chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971: ERR_PROFILE_MISMATCH","ERR_PROFILE_MISMATCH"]]},
{"name":"release object of another chain and another round, with a clock behind","text":"provider: release of chain d2db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971, the pinned profile datekeys:quicknet:v1 is chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971: ERR_PROFILE_MISMATCH","checks":[[1,"parse DKC1",true,"magic DKC1",""],[2,"prelude",true,"DKC1 v1, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=446",""],[3,"public header",true,"121 bytes",""],[4,"header validation",true,"capsule_id=ad4d676812b134ff8a3de263f77018b4 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1",""],[5,"sealed control structure",true,"one tlock stanza",""],[6,"payload structure",true,"one X25519 stanza",""],[7,"condition",true,"round 1000, unlock at 2023-08-23T15:59:24Z",""],[8,"tlock stanza",true,"round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",""],[9,"release",true,"release supplied by the caller; round 1000 is published at 2023-08-23T15:59:24Z and the clock says 2023-08-23T15:59:23Z: it may be behind",""],[10,"release verification",false,"provider: release of chain d2db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971, the pinned profile datekeys:quicknet:v1 is chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971: ERR_PROFILE_MISMATCH","ERR_PROFILE_MISMATCH"]]}
]
}

@ -1,5 +1,5 @@
{
"spec": "0.11",
"spec": "0.15",
"generator": "tool/open_go_vectors.go",
"source": "c531e936fa8188a4aab01575607cc85d4f5d4fa4",
"description": "capsule.Open of a .dkc, as edits of a fixture, given the release (null: none), or a source that fails with source_error (its text and its code, none for a plain error); the clock now; the registry of profiles, empty when registry is empty; the extensions known at (id, version) with valid data valid_data (testkit.KnownExtensions), or reject_all, a registry that knows every extension and rejects all data with that text; the age identities, the .dkk decoded before (dkk, with its material replaced by dkk_material) or the .dkk still encoded (dkk_file); a sink that fails at sink_fail (begin, create i, write i, close i or commit, with the text no and the call); an output that fails with disk full when output_fail; accept, refuse to refuse every verdict with not trusted; and author_keys, the author keys saved with their labels. The outcome: result (ok, refused, or the code), text, the checks as [step, name, ok, detail, code], the release requests, the state of the sink, the content (length and SHA-256) or the files ([path, size, SHA-256 of what the sink received]) of a capsule that opens, the verdicts of a capsule of format 3 that opens (signature, seal, lines, author_key and author_label of alg 1, sealed_at), and the unusable extensions of each object as [id, version, text].",

@ -1,5 +1,5 @@
{
"spec": "0.11",
"spec": "0.15",
"generator": "tool/open_go_vectors.go",
"source": "c531e936fa8188a4aab01575607cc85d4f5d4fa4",
"description": "HEAD_CBOR of a fixed seed, valid and broken in each layer of spec §69.1, through capsule.DecodeHead with no registry: the result, the code and the text; with_registry when the registry of the extensions a version 1 and org.example version 2 with data 01 (testkit.KnownExtensions) gives another. encode: capsule.EncodeHead of the decoded heads, their extensions reordered, repeated or in both arrays.",

@ -1,5 +1,5 @@
{
"spec": "0.11",
"spec": "0.15",
"generator": "tool/open_go_vectors.go",
"source": "c531e936fa8188a4aab01575607cc85d4f5d4fa4",
"description": "texts: the texts of the errors of capsule.Inspect, and results: for each mutation of testdata/vectors/inspect_differential.json, in its order, the index of its text in texts, -1 when steps 1 to 8 pass. views: the exact output of datekeys inspect -json (internal/inspectview) for time_only_extensions with another PUBLIC_HEADER, with the registry standard (extension.Standard), none, or reject_all, which knows every extension and rejects all data with not today.",

@ -1,5 +1,5 @@
{
"spec": "0.11",
"spec": "0.15",
"generator": "tool/open_go_vectors.go",
"source": "c531e936fa8188a4aab01575607cc85d4f5d4fa4",
"description": "The public note of spec §24.1: extension.CheckNote on the string of the bytes data; extension.Note and Header.UnusableNote of noncritical arrays (usable, text, unusable); and extension.Standard, in the order of check, on a note of version 1 with its bytes, absent data when empty: CheckNoncriticalIn of PUBLIC_HEADER (unusable, as [id, version, text]) and CheckWrite in its noncritical array (result and text).",

@ -15,7 +15,7 @@ const openRecordsJson = r'''
/// Part of test/vectors/open_cases.json: its cases on those fixtures.
const openCasesJson = r'''
{
"spec": "0.11",
"spec": "0.15",
"generator": "tool/open_go_vectors.go",
"source": "c531e936fa8188a4aab01575607cc85d4f5d4fa4",
"description": "Part of open_cases.json.",
@ -97,7 +97,7 @@ const openCasesJson = r'''
/// Part of test/vectors/open_heads.json.
const openHeadsJson = r'''
{
"spec": "0.11",
"spec": "0.15",
"generator": "tool/open_go_vectors.go",
"source": "c531e936fa8188a4aab01575607cc85d4f5d4fa4",
"description": "Part of open_heads.json.",
@ -166,7 +166,7 @@ const openHeadsJson = r'''
/// Part of test/vectors/open_notes.json.
const openNotesJson = r'''
{
"spec": "0.11",
"spec": "0.15",
"generator": "tool/open_go_vectors.go",
"source": "c531e936fa8188a4aab01575607cc85d4f5d4fa4",
"description": "Part of open_notes.json.",
@ -520,7 +520,7 @@ const openNotesJson = r'''
/// The views of test/vectors/open_inspect.json, and every sixth mutation of testdata/vectors/inspect_differential.json of those fixtures, with the text of Go.
const openInspectJson = r'''
{
"spec": "0.11",
"spec": "0.15",
"generator": "tool/open_go_vectors.go",
"source": "c531e936fa8188a4aab01575607cc85d4f5d4fa4",
"description": "Part of open_inspect.json.",

File diff suppressed because one or more lines are too long

@ -0,0 +1,89 @@
{
"cases": [
{
"name": "round 999",
"bytes": "a5007818646174656b6579732d72656c656173652d61726368697665010102582052db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971031903e80405b44679b9a59af2ec876b1a6b1ad52ea9b1615fc3982b19576350f93447cb1125e342b73a8dd2bacbe47e4b6b63ed5e39b33bf3667cbd5a82de3a24b4e0e9fe5513cc1a0e840368c6e31f5fcfa79bea03f73896b25883abf2853d10337fb8fa41000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a40658b820c0f8c10207524179a2031ba9537688a0d04e4851b58026be9a341fee3b96fb48ffad28483d84b40a5864aa",
"round": 999,
"text": "provider: release archive: round 999 is not in the archive, which holds 5 rounds from 1000: ERR_RELEASE_UNAVAILABLE"
},
{
"name": "round 1002",
"bytes": "a5007818646174656b6579732d72656c656173652d61726368697665010102582052db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971031903e80405b44679b9a59af2ec876b1a6b1ad52ea9b1615fc3982b19576350f93447cb1125e342b73a8dd2bacbe47e4b6b63ed5e39b33bf3667cbd5a82de3a24b4e0e9fe5513cc1a0e840368c6e31f5fcfa79bea03f73896b25883abf2853d10337fb8fa41000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a40658b820c0f8c10207524179a2031ba9537688a0d04e4851b58026be9a341fee3b96fb48ffad28483d84b40a5864aa",
"round": 1002,
"text": "provider: release archive: round 1002 is missing: its entry is zeros: ERR_RELEASE_UNAVAILABLE"
},
{
"name": "round 1005",
"bytes": "a5007818646174656b6579732d72656c656173652d61726368697665010102582052db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971031903e80405b44679b9a59af2ec876b1a6b1ad52ea9b1615fc3982b19576350f93447cb1125e342b73a8dd2bacbe47e4b6b63ed5e39b33bf3667cbd5a82de3a24b4e0e9fe5513cc1a0e840368c6e31f5fcfa79bea03f73896b25883abf2853d10337fb8fa41000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a40658b820c0f8c10207524179a2031ba9537688a0d04e4851b58026be9a341fee3b96fb48ffad28483d84b40a5864aa",
"round": 1005,
"text": "provider: release archive: round 1005 is not in the archive, which holds 5 rounds from 1000: ERR_RELEASE_UNAVAILABLE"
},
{
"name": "another chain",
"bytes": "a5007818646174656b6579732d72656c656173652d61726368697665010102582052db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e970031903e80405b44679b9a59af2ec876b1a6b1ad52ea9b1615fc3982b19576350f93447cb1125e342b73a8dd2bacbe47e4b6b63ed5e39b33bf3667cbd5a82de3a24b4e0e9fe5513cc1a0e840368c6e31f5fcfa79bea03f73896b25883abf2853d10337fb8fa41000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a40658b820c0f8c10207524179a2031ba9537688a0d04e4851b58026be9a341fee3b96fb48ffad28483d84b40a5864aa",
"round": 1000,
"text": "provider: release archive: archive of chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e970, the pinned profile datekeys:quicknet:v1 is chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971: ERR_RELEASE_UNAVAILABLE"
},
{
"name": "a byte missing",
"bytes": "a5007818646174656b6579732d72656c656173652d61726368697665010102582052db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971031903e80405b44679b9a59af2ec876b1a6b1ad52ea9b1615fc3982b19576350f93447cb1125e342b73a8dd2bacbe47e4b6b63ed5e39b33bf3667cbd5a82de3a24b4e0e9fe5513cc1a0e840368c6e31f5fcfa79bea03f73896b25883abf2853d10337fb8fa41000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a40658b820c0f8c10207524179a2031ba9537688a0d04e4851b58026be9a341fee3b96fb48ffad28483d84b40a5864",
"round": 1000,
"text": "provider: release archive: 310 bytes, its header announces 5 rounds of 48 bytes: ERR_RELEASE_UNAVAILABLE"
},
{
"name": "a byte more",
"bytes": "a5007818646174656b6579732d72656c656173652d61726368697665010102582052db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971031903e80405b44679b9a59af2ec876b1a6b1ad52ea9b1615fc3982b19576350f93447cb1125e342b73a8dd2bacbe47e4b6b63ed5e39b33bf3667cbd5a82de3a24b4e0e9fe5513cc1a0e840368c6e31f5fcfa79bea03f73896b25883abf2853d10337fb8fa41000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a40658b820c0f8c10207524179a2031ba9537688a0d04e4851b58026be9a341fee3b96fb48ffad28483d84b40a5864aa00",
"round": 1000,
"text": "provider: release archive: 312 bytes, its header announces 5 rounds of 48 bytes: ERR_RELEASE_UNAVAILABLE"
},
{
"name": "empty",
"bytes": "",
"round": 1000,
"text": "provider: release archive: not an archive of version 1: ERR_RELEASE_UNAVAILABLE"
},
{
"name": "a release object",
"bytes": "a50070646174656b6579732d72656c65617365010102582052db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971031903e8045830b44679b9a59af2ec876b1a6b1ad52ea9b1615fc3982b19576350f93447cb1125e342b73a8dd2bacbe47e4b6b63ed5e39",
"round": 1000,
"text": "provider: release archive: not an archive of version 1: ERR_RELEASE_UNAVAILABLE"
},
{
"name": "header version 2",
"bytes": "a5007818646174656b6579732d72656c656173652d61726368697665010202582052db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971031903e80405b44679b9a59af2ec876b1a6b1ad52ea9b1615fc3982b19576350f93447cb1125e342b73a8dd2bacbe47e4b6b63ed5e39b33bf3667cbd5a82de3a24b4e0e9fe5513cc1a0e840368c6e31f5fcfa79bea03f73896b25883abf2853d10337fb8fa41000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a40658b820c0f8c10207524179a2031ba9537688a0d04e4851b58026be9a341fee3b96fb48ffad28483d84b40a5864aa",
"round": 1000,
"text": "provider: release archive: not an archive of version 1: ERR_RELEASE_UNAVAILABLE"
},
{
"name": "count 0",
"bytes": "a5007818646174656b6579732d72656c656173652d61726368697665010102582052db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971031903e80400b44679b9a59af2ec876b1a6b1ad52ea9b1615fc3982b19576350f93447cb1125e342b73a8dd2bacbe47e4b6b63ed5e39b33bf3667cbd5a82de3a24b4e0e9fe5513cc1a0e840368c6e31f5fcfa79bea03f73896b25883abf2853d10337fb8fa41000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a40658b820c0f8c10207524179a2031ba9537688a0d04e4851b58026be9a341fee3b96fb48ffad28483d84b40a5864aa",
"round": 1000,
"text": "provider: release archive: round 1000 is not in the archive, which holds 0 rounds from 1000: ERR_RELEASE_UNAVAILABLE"
},
{
"name": "first round in four bytes",
"bytes": "a5007818646174656b6579732d72656c656173652d61726368697665010102582052db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971031a000003e80405b44679b9a59af2ec876b1a6b1ad52ea9b1615fc3982b19576350f93447cb1125e342b73a8dd2bacbe47e4b6b63ed5e39b33bf3667cbd5a82de3a24b4e0e9fe5513cc1a0e840368c6e31f5fcfa79bea03f73896b25883abf2853d10337fb8fa41000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a40658b820c0f8c10207524179a2031ba9537688a0d04e4851b58026be9a341fee3b96fb48ffad28483d84b40a5864aa",
"round": 1000,
"text": "provider: release archive: its header does not decode: key 3: codec: offset 66: 1000 is not in its shortest form (initial byte 0x1a): ERR_NON_CANONICAL_CBOR: ERR_RELEASE_UNAVAILABLE"
},
{
"name": "four keys",
"bytes": "a4007818646174656b6579732d72656c656173652d61726368697665010102582052db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971b44679b9a59af2ec876b1a6b1ad52ea9b1615fc3982b19576350f93447cb1125e342b73a8dd2bacbe47e4b6b63ed5e39b33bf3667cbd5a82de3a24b4e0e9fe5513cc1a0e840368c6e31f5fcfa79bea03f73896b25883abf2853d10337fb8fa41000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a40658b820c0f8c10207524179a2031ba9537688a0d04e4851b58026be9a341fee3b96fb48ffad28483d84b40a5864aa",
"round": 1000,
"text": "provider: release archive: its header does not decode: 4 keys, want all 5: ERR_RELEASE_UNAVAILABLE"
},
{
"name": "only the header",
"bytes": "a5007818646174656b6579732d72656c656173652d61726368697665010102582052db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971031903e80405",
"round": 1000,
"text": "provider: release archive: 71 bytes, its header announces 5 rounds of 48 bytes: ERR_RELEASE_UNAVAILABLE"
},
{
"name": "count 6 and 6 entries",
"bytes": "a5007818646174656b6579732d72656c656173652d61726368697665010102582052db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971031903e80406b44679b9a59af2ec876b1a6b1ad52ea9b1615fc3982b19576350f93447cb1125e342b73a8dd2bacbe47e4b6b63ed5e39b33bf3667cbd5a82de3a24b4e0e9fe5513cc1a0e840368c6e31f5fcfa79bea03f73896b25883abf2853d10337fb8fa41000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a40658b820c0f8c10207524179a2031ba9537688a0d04e4851b58026be9a341fee3b96fb48ffad28483d84b40a5864aa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"round": 1005,
"text": "provider: release archive: round 1005 is missing: its entry is zeros: ERR_RELEASE_UNAVAILABLE"
}
],
"generator": "tool/release_archive_go_texts.go"
}

@ -5,7 +5,7 @@
/// Part of test/vectors/security_vectors.json.
const securityVectorsJson = r'''
{
"spec": "0.11",
"spec": "0.15",
"generator": "tool/security_go_vectors.go",
"description": "Part of test/vectors/security_vectors.json: every eighth evaluation.",
"contexts": [

@ -1,5 +1,5 @@
{
"spec": "0.11",
"spec": "0.15",
"generator": "tool/security_go_vectors.go",
"description": "The security area of format 3 as package capsule of the Go reference gives it at the draft v0.12: commitments (PayloadCommit, ControlCommit with decode_format and format, or the text of its error, HeadDigest, SignersDigest, AuthorMessage, AuthorCode as Go's string and its bytes, SigPart, SealSubject); encode (EncodeSecurity, EncodeSecurityWith, EncodeAuthorSignature, EncodeSeal); evaluate: EvaluateSecurityIn of SECURITY_CBOR (hex, parts as [hex, repeat], or a base with edits) in the context of the index, EvaluateSecurity when null: the verdicts, author_key and author_label of alg 1, lines as indices into texts, alg and seal_type as read, and cms, the parts that only the reader of CMS evaluates; lines: Verdicts.Lines and SealedAt of verdicts built here; holder: holderText of a name, or of UTF-16 code units, and a hash. See the header of tool/security_go_vectors.go.",
"contexts": [

@ -6,7 +6,7 @@
/// Part of test/vectors/securitycms_vectors.json.
const securityCmsVectorsJson = r'''
{
"spec": "0.11",
"spec": "0.15",
"generator": "tool/security_go_vectors.go",
"description": "Part of test/vectors/securitycms_vectors.json: its contexts and texts, its bases whole, and some of its cases, each built area as its hexadecimal.",
"contexts": [

@ -1,5 +1,5 @@
{
"spec": "0.11",
"spec": "0.15",
"generator": "tool/security_go_vectors.go",
"description": "Signatures of alg 2 and seals of seal_type 2 that this program makes, with keys of labels and the deterministic signatures of Go, as package capsule of the Go reference at the draft v0.12 evaluates them with EvaluateSecurityIn in the context of the index: the verdicts, the lines as indices into texts, alg and seal_type as read, cms, the detail of the signers and of a valid seal as the lines of security_vectors.json write it, sealed_at, and author_key of alg 1. An area is pieces (the hexadecimal of bytes, or the index of a chunk, each chunk itself pieces of the chunks before it), or a base edited in its target (value, the SignedData of key 2; signers, its SIGNERS; token, that of key 3) and written again with the encoders of capsule; sha256 is the first 8 bytes of the SHA-256 of the area. See the header of tool/security_go_vectors.go.",
"contexts": [

@ -0,0 +1,171 @@
// Generated by tool/tlock_steps_copy.dart from
// testdata/vectors/tlock_steps.json, for the tests that also run
// compiled to JavaScript, where no file can be read. Do not edit.
/// The text of testdata/vectors/tlock_steps.json.
const tlockStepsJson = r'''
{
"spec": "0.15",
"description": "Steps 10 and 11 of spec §63 for Quicknet, value by value, over published releases. Step 10: M = SHA-256(uint64_be(round)), H(M) the hash to G1 of RFC 9380 with the suite BLS12381G1_XMD:SHA-256_SSWU_RO_ and the DST dst, and e(H(M), public_key) = e(signature, G2). Step 11: a stanza body U || V || W built with the sigma and the file key of the vector; H2 = SHA-256(\"IBE-H2\" || e(signature, U))[:16], sigma = V XOR H2, H4 = SHA-256(\"IBE-H4\" || sigma)[:16], file_key = W XOR H4, and r = H3(sigma, file_key): h3_base = SHA-256(\"IBE-H3\" || sigma || file_key), then for i = 1, 2, ... d = SHA-256(uint16_le(i) || h3_base), its first byte shifted one bit to the right, until it is below the order of the group; r·G2 = U. Generated by the reference implementation and checked against drand, kyber, tlock and agewrap. See testdata/README.md.",
"profile": "datekeys:quicknet:v1",
"scheme": "bls-unchained-g1-rfc9380",
"chain_hash": "52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",
"public_key": "83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a",
"dst": "BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_NUL_",
"tags": {
"h2": "4942452d4832",
"h3": "4942452d4833",
"h4": "4942452d4834"
},
"vectors": [
{
"name": "round 1000, stanza 0",
"round": 1000,
"signature": "b44679b9a59af2ec876b1a6b1ad52ea9b1615fc3982b19576350f93447cb1125e342b73a8dd2bacbe47e4b6b63ed5e39",
"message": "f652498d092acd949bad74e40683bf3824fb817980504a0c7e6722cfc5a9c0a3",
"hash_to_g1": "8f5a32d53837b00fbc0ee31ce9966435a41c5188a80ce9934d3c80588b6ad6f643ebda1b83ef89e44da9ced6205cdecf",
"body": "a73eb63b9a766ebbd23e06daa313760b001502ab48de4976c98c1697ebd51907c2ab92306e4d04ee9f42bff92775ba6606f08479fbd58a3fb786c94a27bf924c67975f419d5b67b96080b4a3da776eddc762ce07af0a5b5a0965f64a9902f4d3f62867846361583f06a8978ae6876e0eb799ebe3cf0b0bf967921fc5e6eb85d9",
"u": "a73eb63b9a766ebbd23e06daa313760b001502ab48de4976c98c1697ebd51907c2ab92306e4d04ee9f42bff92775ba6606f08479fbd58a3fb786c94a27bf924c67975f419d5b67b96080b4a3da776eddc762ce07af0a5b5a0965f64a9902f4d3",
"v": "f62867846361583f06a8978ae6876e0e",
"w": "b799ebe3cf0b0bf967921fc5e6eb85d9",
"pairing": "13dc0e183d402040f68cb518c39c5fcfc61852058d0d58f962ec5649d3da484f62f8562cb4fa6b576d2882bac78ce474100a3086d82617f2b9ba844f6e2569e5b0c3c81ca94aa9ecda8909baabf16bfd4d95602b0ad3263aaaeb14748d41e9e30c811671230b41b54e5cce08f3d3ef671a411850c165dad83824fb91380554f5dd9ea3005738c83e264d58b3b28c275a0409076922ff12b9b1421d70c958c22a29da81a7df5f93a7d5f32d187e82a1f34ed60c01e9bb0685c0f773cb324b0e8118c5a8cee62b795b8fa7d5e820aa08003462a5521d70beabebb7f74022163286256eaeab18148d7caf9a0057fe37e6de0f10c412dd62f013e62a21971bae6d3957fd326aaa809348da278e812637343a20c942263da247497748aa5c39b945bd112fe3afbf5508117b48b1017931e9dfa97e3a9eaffef3add91ed62ec2814eb9063ffb64943e0b302efb12e3ff680d99199e068714b0c0d6d295a6019a6e325def3cd58c7c20c2196ba7fe28d67b9bf385764d81c63c02f6333d4fc5dbf5e1171913e06b904367571b8d2811f7288c18be3831d907ebc7f03ab6014282bcc362f1a3b0d12bbfc9cd9ba1d255254d64a216151c040975fd726c51fe191b3c675fc6ebc79b9a1f123e15059955761732f66cbb13c45868881fbbe08b21cf677551120e80ef555a5db93283f5b99714e997028eb1380e1a3db0bdc55d269f736e2b9f584c2661e460d3a6ce2db9a1aa902a02b16d5b9f634e96c5d615d3e1be0c232e13723d6f9b93686b1b9bee950ed45e729b3bd6d448badc0816fb8b9360bf28",
"h2": "c3d489f4c7c6a6962801cad91047eb95",
"sigma": "35fcee70a4a7fea92ea95d53f6c0859b",
"h4": "bd093650d9bd27e682b48bc3ba52a0aa",
"file_key": "0a90ddb316b62c1fe52694065cb92573",
"h3_base": "c8b1566b6f0ed7b6cfea5eebaa1a7291f77f50c80dfd8269e9b4f253fff23fe0",
"h3_tries": [
{
"i": 1,
"digest": "41fd905b124c321e66a781f9eec59842d08689c872f4eaada61c921f8b6e6a8e",
"shifted": "20fd905b124c321e66a781f9eec59842d08689c872f4eaada61c921f8b6e6a8e",
"accepted": true
}
],
"r": "20fd905b124c321e66a781f9eec59842d08689c872f4eaada61c921f8b6e6a8e"
},
{
"name": "round 1001, stanza 0",
"round": 1001,
"signature": "b33bf3667cbd5a82de3a24b4e0e9fe5513cc1a0e840368c6e31f5fcfa79bea03f73896b25883abf2853d10337fb8fa41",
"message": "ce43c3353a7ad7aac3408cad0bf921b6a7dda89be75d9cb2b3b5a152cefc8afd",
"hash_to_g1": "8dafa08d032514b04972cd9bca0c40226294bc9dc8b02d10ed4b3913554571e04f20d7eb05b74cddf72a9992995ac5bb",
"body": "ad4937a39b57f8c494817575bf3cac373ed629b3580d374953f08df5c59e00f76abbe58ec09704b544464975a843255307d45413ad277661ac6d361afa687bd40f2745fb9c4498882fbb91269350ab975fc1a1a83d2c5f7d127786779c01e55ee512d80ed32c46da0c915a5459244507444e2b3f156d72748fa2c3ee40120dee",
"u": "ad4937a39b57f8c494817575bf3cac373ed629b3580d374953f08df5c59e00f76abbe58ec09704b544464975a843255307d45413ad277661ac6d361afa687bd40f2745fb9c4498882fbb91269350ab975fc1a1a83d2c5f7d127786779c01e55e",
"v": "e512d80ed32c46da0c915a5459244507",
"w": "444e2b3f156d72748fa2c3ee40120dee",
"pairing": "06bf5fa844026aff0c454df2da4f46f769b6db78c68bdfdafacc1aee0d9d57b40603c0a043478a4785c635587896068701fcbc9ef9f489e53c2f30709136404cbb04c9b0ba0b74e26708f53735209f6f5cfa76fefff64a2db62726745db1693711a09a514fc2925ac383494d6882edb9d2c5143f9f2e8b2b25dfcaf1ac03ca6e9e0bfa989f3e1ebbe0a63345bfe1b9e40657b0fdb63c0646e2fef7f48e73861a364fbc944380af8e989e897a0037e54a1766086a1ea7c9457f47ff7521ac175d0e80ac41a06b949e12ac4c131354371f34318d9559bbdbdb8a9b7bd415b4b64542f240d4d3b69f350614fce76cbeb83b09457cc90c73da60247b929ca72602ba0e3c47653f6e798ffdac42f85039f2d43b817647536f369cea55812d08aa1ca80b9854d9b951ded8c1fa0053377711320de0ca459a84983ce49d68446a5d1c757afeffc896b146c2198b3a171854910d04fa8559d6018affc7c4e35760dc1ac4d90c83821e383ecdaa7ee3eda64e3ac4fa43648e7e821caddcbcabf3e34f5ea30e962c6aa7e6de1e72b3362311c5506607b180a79920c14961b9f8c850227bca1c0b59acffc7a79bf48bfde53fde6031185598646a15c7eb55df63e7fe8f930c6be0e8d6ee695608114f511c83a3c98b2e376cedc16b41c6c94acfb7180287d4007e4eeaf3bb6cd8bf67014302f47626346526358b3acec4cd9f7b083cdeed60c632c8007d0e4d88e252e6a3b8a955d216d6991a2893a56117cdebee0c78d7364f54f45313d472de5dd1e426b3483100107614137b08c38b7f139ab8adb05e33",
"h2": "d1c48e9d72ef4e29581947627078779e",
"sigma": "34d65693a1c308f354881d36295c3299",
"h4": "b05c539a1ce0d4b2f881e2a899bd648b",
"file_key": "f41278a5098da6c677232146d9af6965",
"h3_base": "f89b77b992969b10442252a826f0380716867ee3f2270cd6705b4ffbe474c727",
"h3_tries": [
{
"i": 1,
"digest": "85e7c45f27c75fa2571403fc7cd8222e0dfbdddd7842f85e814854c507abdfc6",
"shifted": "42e7c45f27c75fa2571403fc7cd8222e0dfbdddd7842f85e814854c507abdfc6",
"accepted": true
}
],
"r": "42e7c45f27c75fa2571403fc7cd8222e0dfbdddd7842f85e814854c507abdfc6"
},
{
"name": "round 1004, stanza 0",
"round": 1004,
"signature": "a40658b820c0f8c10207524179a2031ba9537688a0d04e4851b58026be9a341fee3b96fb48ffad28483d84b40a5864aa",
"message": "dfb0ecda8fd28db758bd0c580c0bb9397b56225bd50f076bac68460e68d0ea00",
"hash_to_g1": "895a4b04764f8964e42a056c23d7b34808895603f605ee0f749f8be419420b53a0ba5e01caab02e8afd7ff28c6cd771f",
"body": "97b8304c3e87868e549a6293d19d65481bdbcf7cf67b9d5e3d798ade332deb499648fe2f23931ab55b0911ccdc8839560f5a72325eedc7302420bd87bcafd7f27f2eadbc90523a295e5ab476b357ca91b9a8b5e45a4dac972f20b37e97e8945d96ce47d18a7e845031e28207606a7ea78a4f271ed5ed8d3ed9420fe99200396a",
"u": "97b8304c3e87868e549a6293d19d65481bdbcf7cf67b9d5e3d798ade332deb499648fe2f23931ab55b0911ccdc8839560f5a72325eedc7302420bd87bcafd7f27f2eadbc90523a295e5ab476b357ca91b9a8b5e45a4dac972f20b37e97e8945d",
"v": "96ce47d18a7e845031e28207606a7ea7",
"w": "8a4f271ed5ed8d3ed9420fe99200396a",
"pairing": "0b57e9394946ebc2e4ec7478308fe77ab5b509f00727d46dec4d8635bb7934b4c485f3408c974d45468c2363a768ee18172c3f56f94c6bea5f8658cfc79bc3cafdf3dc418134f4cea86e14b1c73ca85456cb56ac4438862d5093447e97afd795169452925b396bb07823cd1d4a5b9a7b58355170a713a0a14a3ff568a27f57743890c26387ef0f15c49057d8cc74857e0874d72f661e9cecd3b97443aaf64e0703ed453ff9ffb659070d81a40fd0c92ed1221d5d0767e0bb6e6d72c3979fe57619cc78dbd491b3629b21668beab4bdcf787ab581c62211f17db4a61d2ff5946178d1d29448c7bce8a664220bb2fd928d1926ddc1fa2d65f47a60bee3f1375a49cad2a5d0c5406f51ccf6d18e537b820da2112350f6a97b2fc76111b7ec8c0ae11484bd6d622de8b58cbb79ad193d285a49333040cdcf4aabd532cf5465248d4234b41a72614aabfe23479926e6b6635d003901ecd863d063befa706baba0b7aba385e7396b78a20f8e7738c7ec14e340b80e8cfeb5509e8bb47807a82fea6b6215a3f4ce9786623a283a4b07d5aa07fcf9636122a6dee64db8b4280c24e2e909bc791cc9d11adf6cacd82823fdf43873171d52f3d9bc035d3f9bb63eaaaa27e3109b7324f2828e6dc2ce78324bff9a92b9c569ab51ed714e70afd1687d5188f60e1ab87bd7db3ffedec49b52dd0a09909be3cc96156b82d0ab49adfd64c24faf9cd574d9c585829f3fd608c7df754a58045f1545128a0030459cc766fbaf636ce19be4d4537ac181cd9bd2da65cb93257b72984bcf0c74b19247d15c680fd278",
"h2": "ed9e2e9ca7679f40d9d5461808d3902d",
"sigma": "7b50694d2d191b10e837c41f68b9ee8a",
"h4": "8aa64ea323262cff566c987b5467ae3a",
"file_key": "00e969bdf6cba1c18f2e9792c6679750",
"h3_base": "cbf54def509294ab547c383ea065b02d2bec599d6a41f41b3083dad3ff7b2459",
"h3_tries": [
{
"i": 1,
"digest": "060304f06ac573eee1c4ed5b125d6f8ae7c9f154c60156c4e37de84ebc9846cb",
"shifted": "030304f06ac573eee1c4ed5b125d6f8ae7c9f154c60156c4e37de84ebc9846cb",
"accepted": true
}
],
"r": "030304f06ac573eee1c4ed5b125d6f8ae7c9f154c60156c4e37de84ebc9846cb"
},
{
"name": "round 2000, stanza 0",
"round": 2000,
"signature": "b6cb8f482a0b15d45936a4c4ea08e98a087e71787caee3f4d07a8a9843b1bc5423c6b3c22f446488b3137eaca799c77e",
"message": "597962656abdc948a536fcd5ba8405e6bd95b9763f4a4da0727e8c98689d52c2",
"hash_to_g1": "906dc77479bc9962a8ed67fd00ad6af2a6c8d109926fdd6b897fe77526b2531b544b5e8703de23748b6ae6172b9986f5",
"body": "ab73f3818b2170ec27e8c6ad89232453199c2ceb781e920fb8058947ade9a12daf99775f384f575daae76fb76c1bb40e00754fd1515534b2f1c315108a568bb7405a5829eba26e3a1ac08178e73ac13bca55a0ef7eeb8980d0a4424b84ac47ff04cbb545b21b4ebcc651055043dd6f7b216b730fe903e9c7824eadef6522c2d9",
"u": "ab73f3818b2170ec27e8c6ad89232453199c2ceb781e920fb8058947ade9a12daf99775f384f575daae76fb76c1bb40e00754fd1515534b2f1c315108a568bb7405a5829eba26e3a1ac08178e73ac13bca55a0ef7eeb8980d0a4424b84ac47ff",
"v": "04cbb545b21b4ebcc651055043dd6f7b",
"w": "216b730fe903e9c7824eadef6522c2d9",
"pairing": "07999e22e3e3e73a814ff2ff0329f87749396dc9b6a2e6f0520b01df4f73935cce76c3197164eb129f03b72675d05d8318f73d35d748b4fadc36cb7bff193e44bc30a795377a5faaae2649fc89df82539b177defcd3122e1ef461f869e22ab80165c6c07fbc3ed5752921287c8dc5177cbbf19c14b84fce0393d4cd2bd9dc8f569964e88d82cca5df637019bf6b3f9230ca4d83f519082c62919b1d5138326cd97af77bf54a8257c677f1162c603f181f0f74dbc5c4558ade7adf44d6689213804028a36cb0597d58a1a777bb187479ae7e69214f632a53fdb93c9580bf71d1cf91076830ca73bf548417e9729a53ad400a89f83721daa9e2a1b963b9cd2b9a6c68bd17b61039d08f4ff9962deef188b597cbf5855dcefc6e4192d4ad4984a2a05929fc3c0043f53f63bca31ae676883ca550ac47c06dad52a95366ccec9f03a2eb6c4fdb15df0238a991f4245a740b00b1762bb3c76709333e758be369616ea68929eadc0eee12b1f074707db5153d2b07fa99db5bff8f6ba04f318c9f4abf6175c1d5471c150ffd8e1cd83ed6e26c3eaa821aa4c4724dbfd644b0df28a80134c0fc2334e34c2b591a79b531b116abf1363314b98b21a669ca179bb7065336df05315a8885f32db74d56884c01ab37ecd0dfcde9b4d23a3481bd487d6e5f523089f89ed52d7e50a48a591306eea76b353ea2c63f14826b8a785ce9a7cafddd5b5d6d6a89773c2b24a178b6e6d3f1f2002d7c409b2c7312df81c21af3ba95ec8646e64ac240a43e6e8245f3ec2532a10ea917c0dac568cb468bad84562acf72c",
"h2": "0b214ea01f127a78f8af587331314ce0",
"sigma": "0feafbe5ad0934c43efe5d2372ec239b",
"h4": "5097513c5c6ad5a8e614205284b46f9a",
"file_key": "71fc2233b5693c6f645a8dbde196ad43",
"h3_base": "2a1ca2b9377eae364c9874c19450c74919f88bd0e4d05153fcadc373db2d3989",
"h3_tries": [
{
"i": 1,
"digest": "59d0a91dbc2ea95a7ded3610fd282f2c0286459e49fe275bce5185501df3a106",
"shifted": "2cd0a91dbc2ea95a7ded3610fd282f2c0286459e49fe275bce5185501df3a106",
"accepted": true
}
],
"r": "2cd0a91dbc2ea95a7ded3610fd282f2c0286459e49fe275bce5185501df3a106"
},
{
"name": "round 1000, stanza 111: H3 accepts its try 4",
"round": 1000,
"signature": "b44679b9a59af2ec876b1a6b1ad52ea9b1615fc3982b19576350f93447cb1125e342b73a8dd2bacbe47e4b6b63ed5e39",
"message": "f652498d092acd949bad74e40683bf3824fb817980504a0c7e6722cfc5a9c0a3",
"hash_to_g1": "8f5a32d53837b00fbc0ee31ce9966435a41c5188a80ce9934d3c80588b6ad6f643ebda1b83ef89e44da9ced6205cdecf",
"body": "b326f73120b5a037953e1b58da50d242e8766a4ade2ac5113685210dfe09d63a2ae1e02e8f1dab5214c68d9fd739e6450ccf379e9e47323e993ac94d91af16d4b38157af7bd098ece86f9d2ceb06b93da6d295e1b18a6eba255a95ed50c869d5f6c14db7259bc069fe1b69cb2d562349e6407fe52ab31aa27b7cc4c859564e33",
"u": "b326f73120b5a037953e1b58da50d242e8766a4ade2ac5113685210dfe09d63a2ae1e02e8f1dab5214c68d9fd739e6450ccf379e9e47323e993ac94d91af16d4b38157af7bd098ece86f9d2ceb06b93da6d295e1b18a6eba255a95ed50c869d5",
"v": "f6c14db7259bc069fe1b69cb2d562349",
"w": "e6407fe52ab31aa27b7cc4c859564e33",
"pairing": "00585d6ec0a2617f28a00b0455e9ea364ec343489aa7f67f046ba13fc40a800d032c89a0ca5cc33761a02c2de95383650ecf9bbbc77ce2322cd225e6775e7a8e39ad0ed6e3bca1213ff44e52bce0a629e5c69cdd380e0448969b253d12e2baa8131b9e81906e44795535bbf276371d6db833ff9e0c96b76ed960e18c9c8a2b9032880bfebc681f0802d0f00b4768317c0246c202f18c369b5fe659353ee0dd803aed4fd66c98b6402ed811ca348741efff0f88ed32fdd65070bda0a63b30dfcd0c24962dad0b5587f8fc39630d37aea45f50ef458c000884b9b51ee2599496aa61b7b916ed873c6c7f11ef1db2a41cb003df3d757e4f61e5c13beb19d0fd9ebbcb15559e6252bbc5d0faae267dc7f5b25f5f2b4e3295bc4d17b308553e28599911d75b66f3f1d5d6a2795cf9bf3f154654d8bd8e64bea438cecaddee75093cf5efc7579ac55e0b5a76ae767264df544a0fdd0e95b9310d24d7bbb3a4df3bc3ae3d251d3970e483c5d4b10870409c7620531cb9d41670835f2306ac0acdd7524312eeb7b9d83de7c623724eba86ea0a7b10bbc6efecf440681271c5c3d980a975637dd26c99f632e003a9f54045bcb1df0abca2ce0afe6bb1cd383fc34efb72ae0afa3db33ac715a371e3fdfe1e28385e775b5e19e1a49ff265ce2238483c342803dd1ae3f72ecd82f17aa1207fa1f32f2c9f89c38488a381d987e90810753462d7003210c6f66b8ff590055b143b553c0825f4bac496509f88698485173da385b2230f44275eb55a3da686e12680fcb175062007100161ed9bf6de51976739c3",
"h2": "2271ed3feb6223f3f21e7fcecb89f30b",
"sigma": "d4b0a088cef9e39a0c051605e6dfd042",
"h4": "085c839d518ebc5636d8642df86b6f2b",
"file_key": "ee1cfc787b3da6f44da4a0e5a13d2118",
"h3_base": "a5dd9d066f9fdd547d25616b65c9ea76e5da38392ca02853a20ebb2c7d01fc11",
"h3_tries": [
{
"i": 1,
"digest": "f647f4537bc552e6d82a22abbef3397f1adfbe51933df3fda8b60e9d927fd9a1",
"shifted": "7b47f4537bc552e6d82a22abbef3397f1adfbe51933df3fda8b60e9d927fd9a1",
"accepted": false
},
{
"i": 2,
"digest": "f20b12601c3bae738eea421aba70ccfb7df494791c004bf5f028972258c1d15a",
"shifted": "790b12601c3bae738eea421aba70ccfb7df494791c004bf5f028972258c1d15a",
"accepted": false
},
{
"i": 3,
"digest": "f45606605279cfaffabaadda379d52a5ae0aa5453447244b702b1588e7be4200",
"shifted": "7a5606605279cfaffabaadda379d52a5ae0aa5453447244b702b1588e7be4200",
"accepted": false
},
{
"i": 4,
"digest": "a495752b48f0bcd717b4e3846ed0501b4085621321ca846b2710d805d0790699",
"shifted": "5295752b48f0bcd717b4e3846ed0501b4085621321ca846b2710d805d0790699",
"accepted": true
}
],
"r": "5295752b48f0bcd717b4e3846ed0501b4085621321ca846b2710d805d0790699"
}
]
}
''';

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,198 @@
// Helpers of the tests of the word lists: the base list of TestCheckList of
// Go and its edits, as test/vectors/wordlist_vectors.json writes them; a
// list of words that are their indices; the random sources of the vectors
// of Generate; and the String of the bytes of the dice of a case. They read
// no file.
import 'dart:collection';
import 'dart:typed_data';
import 'package:datekeys/src/bytes.dart';
import 'package:datekeys/src/random.dart';
import 'package:datekeys/src/sha256.dart';
import 'package:datekeys/src/wordkey.dart' show WordKeyException;
import 'package:test/test.dart';
import 'wordkey_support.dart' show fromWtf8;
typedef Json = Map<String, Object?>;
/// "ok", or the message of the [WordKeyException] that [f] throws.
String outcome(void Function() f) {
try {
f();
return 'ok';
} on WordKeyException catch (e) {
return e.message;
}
}
/// Word [i] of the base list of TestCheckList: "pal" and three letters,
/// palaaa, palaab, …, up to i = 17 575, palzzz.
String baseWord(int i) {
final letters = [i ~/ 676, i ~/ 26 % 26, i % 26];
return 'pal${String.fromCharCodes([for (final l in letters) 0x61 + l])}';
}
/// The words of a case of the vectors, as bytes: the first `size` words of
/// the base list, the word of each edit of `set` at its index, and the
/// words of `append` after them.
List<Uint8List> caseWords(Json c) {
final words = [
for (var i = 0; i < (c['size']! as int); i++) utf8Bytes(baseWord(i)),
];
for (final e in (c['set'] as List? ?? const []).cast<Json>()) {
words[e['at']! as int] = fromHex(e['word']! as String);
}
for (final w in (c['append'] as List? ?? const []).cast<String>()) {
words.add(fromHex(w));
}
return words;
}
/// [parts] joined by [separator].
Uint8List joinBytes(List<List<int>> parts, List<int> separator) => concatBytes([
for (var i = 0; i < parts.length; i++) ...[if (i > 0) separator, parts[i]],
]);
/// [bytes] repeated [count] times, as Go's bytes.Repeat.
Uint8List repeatBytes(List<int> bytes, int count) =>
concatBytes([for (var i = 0; i < count; i++) bytes]);
/// The 64 bits of [x], big-endian, in hexadecimal: Go's
/// `%016x` of math.Float64bits.
String doubleHex(double x) =>
toHex(Uint8List.sublistView(ByteData(8)..setFloat64(0, x)));
/// The double of the 64 bits [hex].
double hexDouble(String hex) =>
ByteData.sublistView(fromHex(hex)).getFloat64(0);
/// The words "0", "1", …, one less than [length]: a list whose words are
/// their indices, without storing them. generateWords reads only its length
/// and the words it draws, and the dice the same. With [mod], each word is
/// its index modulo [mod], so that a word comes back every [mod] positions,
/// and with [suffix], the index is followed by it: the lists of the dice
/// cases of the vectors with `mod` and `suffix`.
final class IndexWords extends ListBase<String> {
IndexWords(this._length, [this._mod = 0, this._suffix = '']);
final int _length;
final int _mod;
final String _suffix;
@override
int get length => _length;
@override
set length(int _) => throw UnsupportedError('a fixed length');
@override
String operator [](int i) {
RangeError.checkValidIndex(i, this);
return '${_mod == 0 ? i : i % _mod}$_suffix';
}
@override
void operator []=(int i, String value) =>
throw UnsupportedError('an unmodifiable list');
}
/// A source that counts the bytes that another one gives.
final class CountingSource implements RandomSource {
CountingSource(this._inner);
final RandomSource _inner;
/// The bytes given so far.
int read = 0;
@override
void fill(Uint8List out) {
_inner.fill(out);
read += out.length;
}
}
/// The bytes of [bytes], then nothing: a fill past them gives nothing and
/// throws a [StateError], where Go's io.Reader gives io.EOF, or the bytes
/// left and io.ErrUnexpectedEOF.
final class ReplaySource implements RandomSource {
ReplaySource(List<int> bytes) : _bytes = Uint8List.fromList(bytes);
final Uint8List _bytes;
int _at = 0;
@override
void fill(Uint8List out) {
if (_at + out.length > _bytes.length) throw StateError('no more bytes');
out.setRange(0, out.length, _bytes, _at);
_at += out.length;
}
}
/// SHA-256 of [label] and a 32-bit big-endian counter from 0, block after
/// block: the counter stream of the vectors.
final class CounterSource implements RandomSource {
CounterSource(List<int> label) : _label = Uint8List.fromList(label);
final Uint8List _label;
int _counter = 0;
Uint8List _block = Uint8List(0);
int _at = 0;
@override
void fill(Uint8List out) {
for (var n = 0; n < out.length;) {
if (_at == _block.length) {
final input = Uint8List(_label.length + 4)..setAll(0, _label);
ByteData.sublistView(input).setUint32(_label.length, _counter++);
_block = sha256(input);
_at = 0;
}
final k = out.length - n < _block.length - _at
? out.length - n
: _block.length - _at;
out.setRange(n, n + k, _block, _at);
n += k;
_at += k;
}
}
}
/// The source of the stream of a case of generate: `seeded`, the keystream
/// of [SeededRandomSource] of the seed; `counter`, a [CounterSource] of the
/// label; `bytes`, hex repeated `repeat` times, a [ReplaySource].
RandomSource streamOf(Json s) => switch (s['kind']) {
'seeded' => SeededRandomSource(utf8Bytes(s['seed']! as String)),
'counter' => CounterSource(utf8Bytes(s['seed']! as String)),
'bytes' => ReplaySource(
repeatBytes(fromHex(s['hex'] as String? ?? ''), s['repeat'] as int? ?? 0),
),
final kind => throw ArgumentError.value(kind, 'kind'),
};
/// The bytes that crypto/rand.Int reads for each draw of an index below
/// [size]: those of size − 1.
int drawSize(int size) => ((size - 1).bitLength + 7) ~/ 8;
/// The String whose [utf8Bytes] are [bytes], also when they hold a lone
/// surrogate, or null when no String has them, such as a byte FF: the
/// dice of a case of the vectors as diceWord and diceWords take them.
String? stringOf(Uint8List bytes) {
final s = fromWtf8(bytes);
return s != null && equalBytes(utf8Bytes(s), bytes) ? s : null;
}
/// Expects [f] to give what a case [c] of dice_word or dice_words of the
/// vectors gives, its word or its words, or to throw a [WordKeyException]
/// with the text of its error.
void expectDice(Object? Function() f, Json c) {
final name = c['name'];
final error = c['error'] as String?;
if (error == null) {
expect(f(), c['word'] ?? c['words'], reason: '$name');
} else {
expect(outcome(f), error, reason: '$name');
}
}

@ -0,0 +1,572 @@
// The word lists of the key of words (spec §38.1) against
// test/vectors/wordlist_vectors.json, whose expected values the Go reference
// computed (tool/wordlist_go_vectors.go): the constants and the pinned
// lists; the text of a list read as wordkey.List reads it; wordkey.CheckList
// with its texts, also on each code point up to U+017F; the words that
// wordkey.Generate draws from the same bytes; wordkey.Bits, bit for bit;
// and the dice of wordkey on lists of indices: DiceNumber, DiceWord and
// DiceWords with their texts, on the bytes of Go and on Strings, the white
// space of plane 0 at which the numbers are split, and the SHA-256 of
// DiceList. And the cases of TestCheckList, TestGenerate, TestBits and
// TestDiceNumber of Go, and those of TestDiceWord and TestDiceList that need
// no list of Go, as Go writes them. The vectors come from a Dart constant,
// so that these tests also run compiled to JavaScript; the lists of
// wordlists/, the CSPRNG of the platform and the alphabet and the white
// space of every code point are in wordlist_vm_test.dart.
import 'dart:convert';
import 'dart:math' as math;
import 'dart:typed_data';
import 'package:datekeys/datekeys.dart' as datekeys;
import 'package:datekeys/src/bytes.dart';
import 'package:datekeys/src/pathrule.dart' show codePointName;
import 'package:datekeys/src/random.dart';
import 'package:datekeys/src/sha256.dart';
import 'package:datekeys/src/wordkey.dart';
import 'package:datekeys/src/wordlist.dart';
import 'package:test/test.dart';
import 'random_support.dart' show seeded;
import 'vectors/wordlist_vectors.g.dart';
import 'wordkey_support.dart' show fromWtf8;
import 'wordlist_support.dart';
final Json vectors = jsonDecode(wordlistVectorsJson) as Json;
List<Json> cases(String name) => (vectors[name]! as List).cast<Json>();
void main() {
test('the constants and the pinned lists are those of Go', () {
expect(vectors['default_count'], defaultWordCount);
expect(vectors['min_list_size'], minListSize);
expect(vectors['min_words'], minWords);
expect(vectors['min_letters'], minLetters);
expect(vectors['dice_list_size'], diceListSize);
// Languages of Go, and the SHA-256 of the file of each of its lists.
final lists = cases('lists');
expect(wordListLanguages(), [for (final l in lists) l['lang']]);
expect(wordListSha256, {for (final l in lists) l['lang']: l['sha256']});
});
test('lib/datekeys.dart exports them, as the package wordkey of Go', () {
expect(datekeys.readWordList, readWordList);
expect(datekeys.checkWordList, checkWordList);
expect(datekeys.generateWords, generateWords);
expect(datekeys.wordBits, wordBits);
expect(datekeys.wordListLanguages, wordListLanguages);
expect(datekeys.wordListSha256, same(wordListSha256));
expect(datekeys.defaultWordCount, defaultWordCount);
expect(datekeys.minListSize, minListSize);
expect(datekeys.diceNumber, diceNumber);
expect(datekeys.diceWord, diceWord);
expect(datekeys.diceWords, diceWords);
expect(datekeys.diceList, diceList);
expect(datekeys.diceListSize, diceListSize);
});
group('checkWordList', () {
test('the cases of TestCheckList of Go', () {
// pal followed by three letters: palaaa, palaab, …
final base = [for (var i = 0; i < minListSize; i++) baseWord(i)];
checkWordList('es', base);
expect(
outcome(() => checkWordList('xx', base)),
'no alphabet for the language "xx"',
);
List<String> withWord(int i, String w) => [...base]..[i] = w;
for (final (list, want) in [
(base.sublist(0, minListSize - 1), '2047 words, fewer than 2048'),
(
withWord(5, 'dos palabras'),
'line 6, "dos palabras", is not one word',
),
(withWord(5, ' '), 'is not one word'),
(withWord(5, 'mi'), '"mi", is not one word of 3 or more letters'),
(withWord(5, 'casa\u200b'), 'invisible character U+200B'),
// Only the letters of the alphabet of the language, as the list
// writes them: no capitals, no Cyrillic U+0441 that looks like a
// Latin c, no digits, no carriage return of a file with CRLF lines.
(
withWord(5, 'Palaaf'),
'line 6, "Palaaf", holds U+0050, which is not in the alphabet of '
'"es"',
),
(
withWord(5, '\u0441asa'),
'holds U+0441, which is not in the alphabet',
),
(withWord(5, 'pal1'), 'holds U+0031'),
(withWord(5, 'palaaf\r'), r'line 6, "palaaf\r", holds U+000D'),
(
withWord(5, base[4]),
'line 6, "palaae", is the same word as "palaae"',
),
(
withWord(5, 'pala\u00e1e'),
'line 6, "pala\u00e1e", is the same word as "palaae"',
),
(
[...withWord(0, 'pap\u00e1'), 'papa'],
'"papa", is the same word as "pap\u00e1"',
),
]) {
expect(outcome(() => checkWordList('es', list)), contains(want));
}
// The hyphen of the compound words of the list of the EFF is a letter
// of en and not of es; an accent is a letter of es and not of en.
checkWordList('en', withWord(5, 't-shirt'));
expect(
outcome(() => checkWordList('es', withWord(5, 't-shirt'))),
'line 6, "t-shirt", holds U+002D, which is not in the alphabet of '
'"es"',
);
expect(
outcome(() => checkWordList('en', withWord(5, 'pala\u00e1f'))),
'line 6, "pala\u00e1f", holds U+00E1, which is not in the alphabet '
'of "en"',
);
});
test('refuses lists as wordkey.CheckList, with its texts', () {
final all = cases('check_list');
var refused = 0;
var strings = 0;
for (final c in all) {
final name = c['name']! as String;
final lang = c['lang']! as String;
final want = c['result']! as String;
final words = caseWords(c);
expect(
toHex(sha256(joinBytes(words, const [0x0a]))),
c['sha256'],
reason: name,
);
expect(
outcome(() => checkWordListUtf8(lang, words)),
want,
reason: name,
);
if (want != 'ok') refused++;
// The same words as Strings, where they have one: the bytes of a
// surrogate are a lone surrogate, as utf8Bytes writes it.
final asStrings = [for (final w in words) fromWtf8(w)];
if (asStrings.every((s) => s != null)) {
strings++;
expect(
outcome(() => checkWordList(lang, [for (final s in asStrings) s!])),
want,
reason: name,
);
}
}
expect(all, hasLength(greaterThan(80)));
expect(refused, greaterThan(70));
// All but three, whose bytes no String has.
expect(strings, all.length - 3);
});
test('the alphabet of each code point up to U+017F', () {
final results = cases('alphabet_results');
expect(
[for (final c in results) c['rune']],
[for (var r = 0; r < 0x180; r++) r],
);
// The first word is pala, the code point and zz.
final words = caseWords(const {'size': minListSize});
final accepted = <int>[];
for (final c in results) {
final r = c['rune']! as int;
words[0] = utf8Bytes('pala${String.fromCharCode(r)}zz');
final got = outcome(() => checkWordListUtf8('es', words));
expect(got, c['result'], reason: codePointName(r));
if (got == 'ok') accepted.add(r);
}
// a to z, á, é, í, ñ, ó, ú and ü: all that Go accepts in planes 0, 1
// and 14.
expect(
String.fromCharCodes(accepted),
'abcdefghijklmnopqrstuvwxyz'
'\u00e1\u00e9\u00ed\u00f1\u00f3\u00fa\u00fc',
);
final ok = ((vectors['alphabet']! as Json)['ok']! as List).cast<String>();
expect([for (final s in ok) s.runes.single], accepted);
});
});
test('parseWordList reads the text of a list as wordkey.List', () {
for (final c in cases('parse')) {
final name = c['name']! as String;
final lang = c['lang']! as String;
final lines = caseWords(c);
final text = concatBytes([
fromHex(c['prefix']! as String),
joinBytes(lines, fromHex(c['sep']! as String)),
fromHex(c['suffix']! as String),
]);
expect(toHex(sha256(text)), c['sha256'], reason: name);
final want = c['result']! as String;
expect(outcome(() => parseWordList(lang, text)), want, reason: name);
if (want == 'ok') {
expect(lines, hasLength(c['words']), reason: name);
expect(parseWordList(lang, text), [
for (final l in lines) decodeUtf8(l),
], reason: name);
}
}
});
test('readWordList refuses a language without a list and other bytes', () {
expect(
outcome(() => readWordList('xx', const [])),
'wordkey: no word list for "xx"; the lists are en, es',
);
final text = utf8Bytes('palaaa\n');
expect(
outcome(() => readWordList('es', text)),
'wordkey: the list "es" has the SHA-256 ${toHex(sha256(text))}, not '
'${wordListSha256['es']}',
);
// The language first, as Go's List looks for its list first.
expect(
outcome(() => readWordList('ES', text)),
'wordkey: no word list for "ES"; the lists are en, es',
);
});
group('generateWords', () {
test('draws the words of wordkey.Generate from the same bytes', () {
final all = cases('generate');
var drawn = 0;
for (final c in all) {
final name = c['name']! as String;
final size = c['size']! as int;
final n = c['n']! as int;
final read = c['read']! as int;
final error = c['error'] as String?;
final source = CountingSource(streamOf(c['stream']! as Json));
final list = IndexWords(size);
if (error == null) {
final words = generateWords(list, n, source);
expect(
[for (final w in words) int.parse(w)],
c['indices'],
reason: name,
);
expect(source.read, read, reason: name);
final next = c['next'] as String?;
if (next != null) {
expect(toHex(randomBytes(source, 4)), next, reason: name);
}
drawn++;
} else if (error.endsWith('EOF')) {
// The bytes end: the source throws, and generateWords lets it
// through, after the draws that Go made in full.
expect(
() => generateWords(list, n, source),
throwsStateError,
reason: name,
);
expect(source.read, read - read % drawSize(size), reason: name);
} else {
// The arguments, refused before anything is drawn.
expect(
outcome(() => generateWords(list, n, source)),
error,
reason: name,
);
expect(source.read, 0, reason: name);
}
}
expect(all, hasLength(greaterThan(40)));
expect(drawn, greaterThan(30));
});
test('the cases of TestGenerate of Go', () {
final list = IndexWords(7776);
// The same random bytes draw the same words: generateWords reads
// nothing else.
final a = generateWords(list, 6, seeded('TestGenerate'));
expect(generateWords(list, 6, seeded('TestGenerate')), a);
expect(a.toSet(), hasLength(6));
// The seed of TestGenerate of Go draws two indices only, 1793 and
// 2081, again and again until it runs out: Go's Generate then fails
// with EOF, and its two results compare equal (see the vectors).
expect(
() => generateWords(
list,
6,
ReplaySource(repeatBytes(const [7, 1, 200, 33], 64)),
),
throwsStateError,
);
for (final (n, want) in [
(5, 'at least 6 words, not 5'),
(list.length, '7776 words of a list of 7776'),
]) {
expect(
outcome(() => generateWords(list, n, ReplaySource(const []))),
contains(want),
);
}
// Without random bytes: the source throws, where Go's Generate fails
// with EOF.
expect(
() => generateWords(list, 6, ReplaySource(const [])),
throwsStateError,
);
});
});
group('wordBits', () {
double goBits(int size, int count) => hexDouble(
cases(
'bits',
).singleWhere((c) => c['size'] == size && c['count'] == count)['hex']!
as String,
);
test('the cases of TestBits of Go', () {
// Go: Bits(7776, 1) is math.Log2(7776).
expect(wordBits(7776, 1), goBits(7776, 1));
expect(wordBits(7776, 1), closeTo(math.log(7776) / math.ln2, 1e-12));
// 7 words of 7776 are a little under 90.5 bits, and 6 of 2048, the
// fewest that generateWords draws, a little under 66.
for (final (size, count, low, high) in [
(7776, 0, 0.0, 0.0),
(7776, 7, 90.469, 90.470),
(7776, 8, 103.393, 103.394),
(2048, 6, 65.989, 65.990),
]) {
expect(
wordBits(size, count),
inInclusiveRange(low, high),
reason: '$size, $count',
);
}
});
test('is Bits of Go, bit for bit', () {
for (final c in cases('bits')) {
final size = c['size']! as int;
final count = c['count']! as int;
final want = c['hex']! as String;
final got = wordBits(size, count);
if (hexDouble(want).isNaN) {
// The NaN of Go, 7ff8000000000001, is not that of Dart.
expect(got.isNaN, isTrue, reason: '$size, $count');
} else {
expect(doubleHex(got), want, reason: '$size, $count: ${c['bits']}');
}
}
for (final d in cases('bits_digests')) {
final sizes = (d['sizes']! as List).cast<int>();
final counts = (d['counts']! as List).cast<int>();
final digest = Sha256();
final b = ByteData(8);
for (var size = sizes[0]; size <= sizes[1]; size++) {
for (var count = counts[0]; count <= counts[1]; count++) {
b.setFloat64(0, wordBits(size, count));
digest.add(Uint8List.sublistView(b));
}
}
expect(toHex(digest.finish()), d['sha256'], reason: '${d['name']}');
}
});
});
group('dice', () {
// A list of 7776 words that are their indices: the dice read only the
// size of a list and the words they give. The lists of Go are in
// wordlist_vm_test.dart.
final indices = IndexWords(diceListSize);
test('the cases of TestDiceNumber of Go', () {
for (final (i, want) in [
(0, '11111'),
(1, '11112'),
(5, '11116'),
(6, '11121'),
(35, '11166'),
(36, '11211'),
(1295, '16666'),
(1296, '21111'),
(7775, '66666'),
]) {
expect(diceNumber(i), want, reason: '$i');
}
for (final i in [-1, 7776]) {
expect(
outcome(() => diceNumber(i)),
'wordkey: no dice give position $i of a list of 7776 words',
);
}
});
test('diceNumber is DiceNumber of Go', () {
final all = cases('dice_number');
for (final c in all) {
final i = c['i']! as int;
final error = c['error'] as String?;
if (error == null) {
expect(diceNumber(i), c['dice'], reason: '$i');
} else {
expect(outcome(() => diceNumber(i)), error, reason: '$i');
}
}
expect(all, hasLength(greaterThan(20)));
});
test('the cases of TestDiceWord of Go, on the list of the indices', () {
// Every position, there and back.
for (var i = 0; i < diceListSize; i++) {
expect(diceWord(indices, diceNumber(i)), '$i');
}
// Go quotes none of their characters: the full-width 1 of U+FF11 is
// printable.
for (final dice in [
'',
'1111',
'111111',
'11110',
'11117',
'a1111',
'1111 ',
'\uff111111',
]) {
expect(
outcome(() => diceWord(indices, dice)),
'wordkey: "$dice" is not five dice: five digits from 1 to 6',
);
}
expect(
outcome(() => diceWord(IndexWords(2048), '11111')),
'wordkey: dice draw from a list of 7776 words, not 2048',
);
});
test('diceWord is DiceWord of Go, on lists of indices', () {
var count = 0;
var strings = 0;
for (final c in cases('dice_word')) {
if (c['list'] != null) continue;
final list = IndexWords(c['size']! as int);
final dice = fromHex(c['dice']! as String);
expectDice(() => diceWordUtf8(list, dice), c);
final s = stringOf(dice);
if (s != null) {
expectDice(() => diceWord(list, s), c);
strings++;
}
count++;
}
expect(count, greaterThan(50));
// All but three, whose bytes no String has: a byte FF, five bytes
// from FF to FB and a sequence cut short.
expect(strings, count - 3);
});
test('diceWords is DiceWords of Go, on lists of indices', () {
var count = 0;
var strings = 0;
for (final c in cases('dice_words')) {
if (c['list'] != null) continue;
final list = IndexWords(
c['size']! as int,
c['mod'] as int? ?? 0,
c['suffix'] as String? ?? '',
);
final dice = fromHex(c['dice']! as String);
expectDice(() => diceWordsUtf8(list, dice), c);
final s = stringOf(dice);
if (s != null) {
expectDice(() => diceWords(list, s), c);
strings++;
}
count++;
}
expect(count, greaterThan(60));
// All but three, whose bytes no String has: the bytes A0 and 85
// alone, which are not U+00A0 and U+0085, and a byte FF.
expect(strings, count - 3);
});
test('diceWords splits at the white space of Go, and changes nothing '
'else', () {
// The tab, the line feed, U+00A0 and U+3000 separate the numbers.
expect(
diceWords(
indices,
'\u300011111\t11112\n11113\u00a011114\u300011115 11116\u00a0',
),
['0', '1', '2', '3', '4', '5'],
);
// A combining mark stays in its number, which is then not five dice:
// no NFD and no mark dropped, as normalizeWords would. Go's %q writes
// the mark as it is.
expect(
outcome(
() => diceWords(indices, '11111\u0301 11112 11113 11114 11115 11116'),
),
'wordkey: "11111\u0301" is not five dice: five digits from 1 to 6',
);
expect(
outcome(
() => diceWords(
indices,
'11111\u0301\u3000\u0301 11112 11113 11114 11115 11116',
),
),
'wordkey: "11111\u0301" is not five dice: five digits from 1 to 6',
);
// Nor is a full-width digit made an ASCII one.
expect(
outcome(
() => diceWords(
indices,
'\uff11\uff11\uff11\uff11\uff11 11112 11113 11114 11115 11116',
),
),
'wordkey: "\uff11\uff11\uff11\uff11\uff11" is not five dice: '
'five digits from 1 to 6',
);
// Every code point of plane 0 at which Go splits the numbers, and no
// other (the vectors have every plane in dice_space).
final split = <int>[];
for (var r = 0; r <= 0xffff; r++) {
if (r >= 0xd800 && r <= 0xdfff) continue;
final ch = String.fromCharCode(r);
final text = '11111${ch}11112 11113 11114 11115 11116 11121';
if (outcome(() => diceWords(indices, text)) == 'ok') split.add(r);
}
expect(split, (vectors['dice_space']! as Json)['split']);
});
test('diceList is DiceList of Go, on lists of indices', () {
for (final c in cases('dice_list')) {
if (c['list'] != null) continue;
final list = IndexWords(c['size']! as int);
final error = c['error'] as String?;
if (error != null) {
expect(
outcome(() => diceList(list)),
error,
reason: '${list.length}',
);
continue;
}
final text = diceList(list);
expect(text, startsWith('11111\t0\n11112\t1\n11113\t2\n'));
expect(text, endsWith('66665\t7774\n66666\t7775\n'));
final bytes = utf8Bytes(text);
expect(toHex(sha256(bytes)), c['sha256']);
expect(bytes, hasLength(c['bytes']));
}
// TestDiceList of Go: a list of 2048 words.
expect(
outcome(() => diceList(List.filled(2048, ''))),
'wordkey: dice draw from a list of 7776 words, not 2048',
);
});
});
}

@ -0,0 +1,367 @@
// The word lists against files, and at length: the copy of
// test/vectors/wordlist_vectors.json that wordlist_test.dart reads, a Dart
// constant for the tests compiled to JavaScript, is the JSON file byte for
// byte; checkWordList gives the result of Go's CheckList for every code
// point of planes 0, 1 and 14; readWordList reads wordlists/es.txt and
// wordlists/en.txt, the lists of datekeys-go, as Go's List reads the lists
// built into it (TestBuiltInLists), and generateWords draws from the Spanish
// one the words of Go; and,
// as TestGenerate and TestGenerateUniform of Go, the words drawn with the
// CSPRNG of the platform are a key, and each about as likely. And the dice
// on the two lists: the cases of TestDiceWord, TestDiceWords and
// TestDiceList of Go, the English list numbered for dice being the file of
// the EFF, byte for byte; the dice of the vectors on the lists of Go; and
// the white space of every code point of planes 0, 1 and 14, which is that
// of normalizeWords. On the VM only: they read files, use Random.secure or
// take a few seconds.
@TestOn('vm')
library;
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:datekeys/src/bytes.dart';
import 'package:datekeys/src/pathrule.dart' show codePointName;
import 'package:datekeys/src/sha256.dart';
import 'package:datekeys/src/wordkey.dart' show checkWords, normalizeWords;
import 'package:datekeys/src/wordlist.dart';
import 'package:test/test.dart';
import 'vectors/wordlist_vectors.g.dart';
import 'wordlist_support.dart';
void main() {
final vectors = jsonDecode(wordlistVectorsJson) as Json;
test('wordlist_vectors.g.dart holds wordlist_vectors.json', () {
final file = File('test/vectors/wordlist_vectors.json').readAsStringSync();
expect(wordlistVectorsJson, file);
});
test('the alphabet of every code point of planes 0, 1 and 14', () {
// The first word of the base list is pala, the code point and zz: the
// lines of every result, but for the surrogates, have Go's SHA-256.
final a = vectors['alphabet']! as Json;
final words = caseWords(const {'size': minListSize});
final digest = Sha256();
final accepted = <String>[];
var count = 0;
for (final p in (a['planes']! as List).cast<int>()) {
for (var r = p << 16; r <= (p << 16 | 0xffff); r++) {
if (r >= 0xd800 && r <= 0xdfff) continue;
final letter = String.fromCharCode(r);
words[0] = utf8Bytes('pala${letter}zz');
final result = outcome(() => checkWordListUtf8('es', words));
digest.add(utf8Bytes('${codePointName(r)} $result\n'));
count++;
if (result == 'ok') accepted.add(letter);
}
}
expect(count, a['count']);
expect(toHex(digest.finish()), a['sha256']);
expect(accepted, a['ok']);
});
group('the Spanish list of wordlists/', () {
final file = File('wordlists/es.txt').readAsBytesSync();
final es = readWordList('es', file);
List<Json> cases(String name) => (vectors[name]! as List).cast<Json>();
test('is the list of Go, with its pinned SHA-256 (TestBuiltInLists)', () {
expect(wordListLanguages(), ['en', 'es']);
final go = cases('lists').singleWhere((l) => l['lang'] == 'es');
expect(go['lang'], 'es');
expect(toHex(sha256(file)), wordListSha256['es']);
expect(file, hasLength(go['bytes']));
expect(es, hasLength(go['words']));
expect(es, hasLength(7776));
// wordlists/SOURCE.json records the pinned SHA-256 of each list.
final source =
jsonDecode(File('wordlists/SOURCE.json').readAsStringSync()) as Json;
final files = source['files']! as Json;
for (final lang in wordListLanguages()) {
expect(files['$lang.txt'], wordListSha256[lang], reason: lang);
}
// The words are the lines of the file, and they pass checkWordList.
expect(utf8Bytes('${es.join('\n')}\n'), file);
checkWordList('es', es);
expect(
outcome(() => readWordList('xx', file)),
'wordkey: no word list for "xx"; the lists are en, es',
);
});
test('readWordList refuses the list with a byte changed, more or less', () {
for (final changed in [
for (final i in [0, 1, file.length ~/ 2, file.length - 1])
Uint8List.fromList(file)..[i] ^= 0x20,
file.sublist(0, file.length - 1),
Uint8List.fromList([...file, 0x0a]),
]) {
expect(
outcome(() => readWordList('es', changed)),
'wordkey: the list "es" has the SHA-256 ${toHex(sha256(changed))}, '
'not ${wordListSha256['es']}',
);
}
});
test('generateWords draws from it the words of Go', () {
var drawn = 0;
for (final c in cases('generate')) {
if (c['list'] != 'es' || c['error'] != null) continue;
final name = c['name']! as String;
final words = generateWords(
es,
c['n']! as int,
streamOf(c['stream']! as Json),
);
final indices = (c['indices']! as List).cast<int>();
expect(words, [for (final i in indices) es[i]], reason: name);
if (c['words'] != null) expect(words, c['words'], reason: name);
drawn++;
}
expect(drawn, greaterThan(10));
});
test('the words drawn with the CSPRNG of the platform are a key '
'(TestGenerate)', () {
final words = generateWords(es);
expect(words, hasLength(defaultWordCount));
checkWords(normalizeWords(words.join(' ')));
expect(words.toSet(), hasLength(words.length));
for (final (n, want) in [
(5, 'at least 6 words, not 5'),
(es.length, '7776 words of a list of 7776'),
]) {
expect(outcome(() => generateWords(es, n)), contains(want));
}
});
// Over 7776·40 draws of one word, each index falls in its bucket of 64
// between 0.8 and 1.2 times the mean.
test('every word is about as likely (TestGenerateUniform)', () {
final index = {for (var i = 0; i < es.length; i++) es[i]: i};
const buckets = 64;
final count = List.filled(buckets, 0);
var draws = 0;
while (draws < es.length * 40) {
for (final w in generateWords(es, 6)) {
count[index[w]! * buckets ~/ es.length]++;
draws++;
}
}
final mean = draws / buckets;
for (var i = 0; i < buckets; i++) {
expect(
count[i],
inInclusiveRange(0.8 * mean, 1.2 * mean),
reason: 'bucket $i',
);
}
});
});
group('the English list of wordlists/', () {
final file = File('wordlists/en.txt').readAsBytesSync();
test('is the list of the EFF that Go builds in, in its order', () {
final en = readWordList('en', file);
final go = (vectors['lists']! as List).cast<Json>().singleWhere(
(l) => l['lang'] == 'en',
);
expect(toHex(sha256(file)), wordListSha256['en']);
expect(go['sha256'], wordListSha256['en']);
expect(file, hasLength(go['bytes']));
expect(en, hasLength(go['words']));
expect(utf8Bytes('${en.join('\n')}\n'), file);
// The dice 11111 give its first word and 66666 its last.
expect([en[0], en[1], en.last], ['abacus', 'abdomen', 'zoom']);
expect(en.where((w) => w.contains('-')), [
'drop-down',
'felt-tip',
't-shirt',
'yo-yo',
]);
});
});
group('the dice on the lists of wordlists/', () {
final lists = {
for (final lang in wordListLanguages())
lang: readWordList(lang, File('wordlists/$lang.txt').readAsBytesSync()),
};
final en = lists['en']!;
final es = lists['es']!;
List<Json> cases(String name) => (vectors[name]! as List).cast<Json>();
test('the cases of TestDiceWord of Go', () {
// Every position, there and back.
for (var i = 0; i < en.length; i++) {
expect(diceWord(en, diceNumber(i)), en[i]);
}
for (final (list, dice, want) in [
(en, '11111', 'abacus'),
(en, '11112', 'abdomen'),
(en, '35214', 'jovial'),
(en, '66666', 'zoom'),
(es, '11111', 'abad'),
(es, '35214', 'glaciar'),
(es, '66666', '\u00fatil'),
]) {
expect(diceWord(list, dice), want, reason: dice);
}
for (final dice in [
'',
'1111',
'111111',
'11110',
'11117',
'a1111',
'1111 ',
'\uff111111',
]) {
expect(
outcome(() => diceWord(en, dice)),
'wordkey: "$dice" is not five dice: five digits from 1 to 6',
);
}
expect(
outcome(() => diceWord(en.sublist(0, 2048), '11111')),
'wordkey: dice draw from a list of 7776 words, not 2048',
);
});
test('the cases of TestDiceWords of Go', () {
final words = diceWords(
en,
' 11111 11112\t11113\n11114 11115 11116 11121 ',
);
expect(
words.join(' '),
'abacus abdomen abdominal abide abiding ability ablaze',
);
checkWords(normalizeWords(words.join(' ')));
for (final (dice, want) in [
(
'11111 11112 11113 11114 11115',
'wordkey: a key of words needs at least 6 words, not 5',
),
('', 'wordkey: a key of words needs at least 6 words, not 0'),
(
'11111 11112 11113 11114 11115 1116',
'wordkey: "1116" is not five dice: five digits from 1 to 6',
),
(
'11111 11112 11113 11114 11115 11111',
'wordkey: the dice 11111 give "abacus" a second time; roll them '
'again',
),
(
'11111,11112 11113 11114 11115 11116 11121',
'wordkey: "11111,11112" is not five dice: five digits from 1 to 6',
),
]) {
expect(outcome(() => diceWords(en, dice)), want, reason: dice);
}
expect(
outcome(
() => diceWords(en.sublist(1), '11111 11112 11113 11114 11115 11116'),
),
'wordkey: dice draw from a list of 7776 words, not 7775',
);
});
test('the cases of TestDiceList of Go: for en, the file of the EFF', () {
// The SHA-256 of each list numbered for dice, as Go's TestDiceList
// and wordlists/README.md record them.
const hashes = {
'en':
'addd35536511597a02fa0a9ff1e5284677b8883b83e986e43f15a3db996b903e',
'es':
'611f779a33df74587e9dfb486bb0185a9dfd4d1384e75993a21247ad31cefddb',
};
final readme = File('wordlists/README.md').readAsStringSync();
expect(hashes.keys, wordListLanguages());
for (final MapEntry(key: lang, value: want) in hashes.entries) {
final list = lists[lang]!;
final text = diceList(list);
expect(toHex(sha256(utf8Bytes(text))), want, reason: lang);
expect(readme, contains('| `$lang` | `$want`'), reason: lang);
expect(text, endsWith('\n'), reason: lang);
final lines = text.substring(0, text.length - 1).split('\n');
expect(lines, hasLength(diceListSize), reason: lang);
expect(lines.first, '11111\t${list.first}', reason: lang);
expect(lines.last, '66666\t${list.last}', reason: lang);
}
expect(
outcome(() => diceList(List.filled(2048, ''))),
'wordkey: dice draw from a list of 7776 words, not 2048',
);
});
test('the dice of the vectors on the lists of Go', () {
var count = 0;
for (final name in ['dice_word', 'dice_words']) {
for (final c in cases(name)) {
final lang = c['list'] as String?;
if (lang == null) continue;
final list = lists[lang]!;
final dice = fromHex(c['dice']! as String);
final s = stringOf(dice)!;
if (name == 'dice_word') {
expectDice(() => diceWordUtf8(list, dice), c);
expectDice(() => diceWord(list, s), c);
} else {
expectDice(() => diceWordsUtf8(list, dice), c);
expectDice(() => diceWords(list, s), c);
}
count++;
}
}
for (final c in cases('dice_list')) {
final lang = c['list'] as String?;
if (lang == null) continue;
final text = utf8Bytes(diceList(lists[lang]!));
expect(toHex(sha256(text)), c['sha256'], reason: lang);
expect(text, hasLength(c['bytes']), reason: lang);
count++;
}
expect(count, greaterThan(15));
});
test('the white space of every code point of planes 0, 1 and 14', () {
// 11111, the code point and six more numbers on the list of the
// indices: the lines of every result, but for the surrogates, have
// Go's SHA-256, and the numbers are split at the white space of spec
// §38.1, at which normalizeWords splits the words of a key.
final s = vectors['dice_space']! as Json;
final indices = IndexWords(diceListSize);
final digest = Sha256();
final split = <int>[];
final words = <int>[];
var count = 0;
for (final p in (s['planes']! as List).cast<int>()) {
for (var r = p << 16; r <= (p << 16 | 0xffff); r++) {
if (r >= 0xd800 && r <= 0xdfff) continue;
final c = String.fromCharCode(r);
final result = outcome(
() => diceWords(
indices,
'11111${c}11112 11113 11114 11115 11116 11121',
),
);
digest.add(utf8Bytes('${codePointName(r)} $result\n'));
count++;
if (result == 'ok') split.add(r);
if (normalizeWords('a${c}b').length == 2) words.add(r);
}
}
expect(count, s['count']);
expect(toHex(digest.finish()), s['sha256']);
expect(split, s['split']);
expect(words, split);
});
});
}

242
testdata/README.md vendored

@ -1,7 +1,7 @@
# DateKeys test data
Official vectors, fixtures and corpora of the DateKeys Protocol Specification
v0.11 and of the draft v0.12, generated by the reference implementation.
v0.15, generated by the reference implementation.
Another implementation consumes them as they are: this file documents every
format, so that no Go code has to be read. The rules that decide each verdict
are in the specification; this file points to them, and states only what
@ -21,12 +21,15 @@ added since. The local gate (`scripts/check.sh`) and CI run it and fail if any
committed file changes: every file below is exactly what the implementation
computes today.
The `spec` field of every file is `"0.11"`, the version this module declares,
until the author approves the draft v0.12. What the draft changes, the texts
of the verdicts of a certificate and of a seal, the profile of a certificate
and the rules of the addresses and of the padding of a locator, is already in
the files: the verdicts and the lines of `security.json`, `security_cms.json`
and `mutations.json`, and the cases of `locator.json`, are those of the draft.
The `spec` field of every file is `"0.15"`, the version this module declares.
v0.15 adds the release object and a release in the caller's hand (§47.1,
§63 step 9.c): `vectors/release.json`, the files of `releases/`, and the
field `source` of `mutations.json`.
What v0.12 changes from v0.11, the texts of the verdicts of a certificate and
of a seal, the profile of a certificate and the rules of the addresses and of
the padding of a locator, is in the files: the verdicts and the lines of
`security.json`, `security_cms.json` and `mutations.json`, and the cases of
`locator.json`, are those of v0.12.
Conventions for every file:
@ -48,6 +51,10 @@ Conventions for every file:
| `vectors/dk1.json` | canonical `dk1_` strings, and rejected encodings with their code | §18, §19, §66 |
| `vectors/cbor.json` | the CBOR profile, and one block of vectors per schema, CONTROL_CBOR in the three formats | §58, CDDL |
| `vectors/tlock_ibe.json` | H2 of the tlock IBE: the serialization of an element of GT | §63 step 11 |
| `vectors/release.json` | the release object and drand's JSON, each with the result of step 10; the lookups of a local release archive | §47.1, §50, §63 step 10 (v0.15) |
| `releases/<round>.cbor` | the release object of each published round of the tests: 1000, 1001, 1004 and 2000 | §47.1 (v0.15) |
| `releases/archive_1000_1004.bin` | a local release archive, the informative format of §50, of rounds 1000 to 1004, two of them missing | §50 (v0.15) |
| `vectors/tlock_steps.json` | steps 10 and 11 for Quicknet value by value: the message of a round, its hash to G1, and the decryption of a tlock stanza with H2, H4, H3 and the file key | §63 steps 10 and 11 (v0.14) |
| `vectors/padding.json` | the padding of formats 2 and 3: P for each content length L, and the length of PAYLOAD_AGE | §29.1 |
| `vectors/paths.json` | the paths of a format 3 head: the rules of one entry, and those of the paths of a head | §29.5 |
| `vectors/path_fold.json` | the key of R7 of segments, and their NFD | §29.5, §29.5.1 |
@ -56,9 +63,10 @@ Conventions for every file:
| `vectors/security_cms.json` | security areas with a signature of `alg` 2 or a seal of `seal_type` 2, each with its context, verdicts, results and lines | §29.7, §29.10, §29.11 |
| `vectors/ed25519_strict.json` | Ed25519 signatures and the result of the strict profile of the author signature | §29.9 |
| `vectors/note.json` | the data of the public note and the result of its rules | §24.1, §29.6 |
| `vectors/resolved_ip.json` | the IP address a name of a locator resolves to, NAT64 included, and whether a reader may connect | §44.1 (v0.13) |
| `vectors/wordkey.json` | the key of words: the words of a text, what a writer refuses, and the identity the words derive | §38.1, §64 |
| `vectors/locator.json` | the extension `datekeys.capsule` of a `.dkk`, its envelope and its locator, and what a reader rejects and uses of them | §44.1, §64 |
| `vectors/mutations.json` | the mutation corpus: the 178 mutations of §64 and further cases | §63, §64 |
| `vectors/mutations.json` | the mutation corpus: the 178 mutations of §64 and further cases, each with the kind of its release source | §63, §64 |
| `vectors/inspect_differential.json` | 5110 mutations of fourteen fixtures with the verdict of steps 1 to 8 | §63 |
| `fixtures/<name>.dkc`, `<name>.json` | official capsules and every intermediate value | §67 |
| `fixtures/<name>.dkk`, `<name>.dkk.json` | official access keys | §68 |
@ -310,6 +318,141 @@ serialization at once. The same 576 bytes with the twelve coordinates of Fp in
reverse order, c0 first at every level as `Fp12.toBytes` of `@noble/curves`
writes them, give `0118eea9d5971745f71e3c94926f1717` and another FK_TIME.
## `vectors/release.json` and `releases/`
The release object of spec v0.15, §47.1: the release of a round as data,
the answer of the Release API, an entry of a Release Cache and a release the
caller gives from a file or from an archive. It is deterministic CBOR with
the profile of §58, a map of five keys, all required:
```text
0 → "datekeys-release"
1 → 1
2 → chain_hash (32 bytes)
3 → round (1 to 2^53 − 1)
4 → signature (1 to 96 bytes; 48 in Quicknet)
```
The object of a round above 255 measures 111 bytes. `releases/<round>.cbor`
is the object of each published round the fixtures use, 1000, 1001, 1004 and
2000, with the Quicknet chain hash: the release that opens each fixture, as a
file. The protocol gives the object no file extension; `.cbor` is the generic
one of CBOR (RFC 8949).
`release.json` has three lists:
- `objects`: an `encoding` in hexadecimal, the `round` of the DateKey it is
checked against, and the `result`, `ok` or a code, with the `text` of the
error of the reference. When the encoding decodes, `release` is what it
says: `round`, `signature` and `chain_hash`. The checks are those of step
10 for a release in the caller's hand (spec v0.15, §63): the size of the
object, from 1 to 1024 bytes, before anything else; its type and version;
its encoding and schema (all three `ERR_NON_CANONICAL_CBOR`, but a version
other than 1, `ERR_UNSUPPORTED_VERSION`); then, against the pinned profile
and the DateKey, the chain hash (`ERR_PROFILE_MISMATCH`), the round
(`ERR_ROUND_MISMATCH`) and the signature (`ERR_RELEASE_INVALID`), in that
order. A case with several faults gets the code of the first.
- `json`: drand's JSON, which a reader accepts too as the input of the
caller, never as the release object: an `input` whose first byte other than
a JSON space is `{`. It has `round` and `signature` in hexadecimal, of either
case, and may have `randomness`, which must then be SHA-256 of the
signature; it names no chain, so its `release` has no `chain_hash`. Any
failure to read it is `ERR_RELEASE_INVALID`, and so is one of more than
8192 bytes; then the round and the signature, as for an object.
- `archive`: the lookups of the local archive `releases/archive_1000_1004.bin`,
an informative format (spec v0.15, §50). It is the `header`, the
deterministic CBOR map `{0: "datekeys-release-archive", 1: 1, 2: chain_hash,
3: first round, 4: number of rounds}`, followed by the 48-byte signature of
each round, one after another; a round the archive lacks is 48 zero bytes.
This one holds rounds 1000 to 1004, and 1002 and 1003 are zeros. Each lookup
gives a `round` and its `result`: `ok` with the `encoding` of the release
object the archive supplies, `releases/<round>.cbor` for that round, or
`ERR_RELEASE_UNAVAILABLE` for a round the archive lacks or does not cover.
The texts are those of the reference, for an implementation that wants to
match them; the codes are normative.
## `vectors/tlock_steps.json`
Steps 10 and 11 of spec §63 for Quicknet, every intermediate value written
out, over the published releases of rounds 1000, 1001, 1004 and 2000 (spec
v0.14: the paragraphs "Mensaje de ronda y hash a G1" and "H3 y H4" after the
flow).
```json
{
"spec": "0.15",
"description": "…",
"profile": "datekeys:quicknet:v1",
"scheme": "bls-unchained-g1-rfc9380",
"chain_hash": "52db…",
"public_key": "83cf…",
"dst": "BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_NUL_",
"tags": { "h2": "4942452d4832", "h3": "4942452d4833", "h4": "4942452d4834" },
"vectors": [
{
"name": "round 1000, stanza 0",
"round": 1000,
"signature": "b446…",
"message": "f652…",
"hash_to_g1": "8f5a…",
"body": "a73e…", "u": "a73e…", "v": "f628…", "w": "b799…",
"pairing": "13dc…",
"h2": "…", "sigma": "…", "h4": "…", "file_key": "…",
"h3_base": "…",
"h3_tries": [ { "i": 1, "digest": "…", "shifted": "…", "accepted": true } ],
"r": "20fd…"
}
]
}
```
Every byte string is hex. The top-level fields are those of the pinned
profile (spec §12), the DST of the hash to G1 as text and the tags of H2, H3
and H4 as bytes: the ASCII of `IBE-H2`, `IBE-H3` and `IBE-H4`.
Step 10, the release:
- `signature`: the published signature of `round`, the release, compressed in
G1 (spec §12.2).
- `message`: M = SHA-256 of the round as 8 bytes big-endian, the message an
unchained drand scheme signs.
- `hash_to_g1`: H(M), hash_to_curve of RFC 9380 with the suite
`BLS12381G1_XMD:SHA-256_SSWU_RO_` and the DST `dst`, compressed. The
signature verifies: e(H(M), `public_key`) = e(`signature`, G2), with G2 the
generator of G2.
Step 11, one tlock stanza of the round:
- `body`: the stanza body U || V || W, 128 bytes, and `u`, `v` and `w` its
three parts: U compressed in G2, V and W of 16 bytes.
- `pairing`: e(`signature`, U), 576 bytes in the order of `tlock_ibe.json`.
- `h2`: SHA-256 of `IBE-H2` and `pairing`, truncated to 16 bytes.
- `sigma`: V XOR `h2`.
- `h4`: SHA-256 of `IBE-H4` and `sigma`, truncated to 16 bytes.
- `file_key`: W XOR `h4`, FK_TIME, the file key of OUTER_TIME_AGE.
- `h3_base`: SHA-256 of `IBE-H3`, `sigma` and `file_key`.
- `h3_tries`: the tries of H3, in order. Try `i` hashes the counter `i` as 2
bytes little-endian followed by `h3_base` (`digest`), then shifts the first
byte of the digest one bit to the right (`shifted`); the try is accepted
when `shifted`, read as a big-endian integer, is below the order r of the
groups (spec §12.2). Only the last try is accepted. The shift moves every
bit of the first byte; clearing only its top bit gives another r.
- `r`: the accepted `shifted`, the scalar of the check r·G2 = U.
The last vector is the first stanza of round 1000, in the order of the
generator, whose H3 needs at least three tries: it accepts its fourth, where
clearing the top bit would accept the second. A reader checks every value
in this order and the check r·G2 = U.
The generator chooses `sigma` and `file_key` per stanza, derives r, U, V and W
with its own H2, H3 and H4, and checks the result against the libraries the
reference uses: `message` against `DigestBeacon` of the drand scheme,
`hash_to_g1` against the pairing equation with the published signature, and
the body against `tlock.TimeUnlock`, `DecryptCCAonG2` of drand/kyber and the
tlock identity of `agewrap`, which give back `file_key` only if their H2, H3
and H4 are the ones written here.
## `vectors/padding.json`
The padding of the payload of a capsule of format 2 or 3, spec §29.1, where L
@ -457,7 +600,7 @@ in `security_cms.json`.
Security areas with an author signature of `alg` 2, a CMS signature with
certificates, or a time seal of `seal_type` 2, an RFC 3161 token: 135 cases,
each with the context of its capsule, the verdicts, the result of each signer
and the lines of the draft v0.12, §29.7, §29.10 and §29.11. They complete
and the lines of v0.12, §29.7, §29.10 and §29.11. They complete
`security.json`, whose areas have no valid signature or seal of these kinds.
The file is frozen: the certificates and the tokens are made once, with test
keys, so a second implementation reads them and must reach the same verdicts
@ -585,6 +728,28 @@ feed, a space at either end, U+202E, U+200B, a byte order mark, a
noncharacter, a byte that is not UTF-8 and the UTF-8 of a lone surrogate,
refused.
## `vectors/resolved_ip.json`
The IP address that the name of an https address of a locator resolves to,
which a reader checks on every connection (spec §44.1 of v0.13):
`ip`, `nat64`, the NAT64 prefix of the network that the reader knows, or ""
for none, and `result`, `ok`, or `error` with the text of the reference in
`error`.
```json
{ "name": "the well-known prefix with 192.168.1.10", "ip": "64:ff9b::c0a8:10a", "nat64": "", "result": "error", "error": "locator: an https address whose name resolves to 64:ff9b::c0a8:10a, an address of NAT64 that holds 192.168.1.10, an IP address that is not public" }
```
A public address is accepted. An address of NAT64 (RFC 6052) of
`64:ff9b::/96`, or of the prefix of the network, counts by the IPv4 address
it holds, at the positions of RFC 6052: the cases put a public one and one of
several blocks that are not public in each, and the prefix of the network in
each length of RFC 6052. A prefix of another length, with bits after its
length, outside `64:ff9b::/16` and the public IPv6 addresses, or of IPv4, is
refused. Among the addresses that are not public: IPv4-mapped, 6to4, Teredo,
link-local, unique local, loopback, and the local-use prefix of RFC 8215
without the prefix of the network.
## `vectors/wordkey.json`
The key of words of spec §38.1, the cases that §64 of v0.11 asks for, in
@ -648,6 +813,7 @@ reading flow (`capsule.Open`, §63) must fail.
"spec": true,
"dkc": { "base": "time_only.dkc", "edits": [[4, 1, "04"]] },
"release": { "round": 1000, "signature": "b446…" },
"source": "supplied",
"now": "2023-08-23T15:59:24Z",
"registry": "default",
"network": false,
@ -665,8 +831,9 @@ reading flow (`capsule.Open`, §63) must fail.
named "format 2: …" (66 to 98), the 23 of the list of format 2 (99 to 121),
5 further cases (122 to 126), the same 33 on the format 3 fixtures, named
"format 3: …" (127 to 159), the 48 of the list of format 3 (160 to 207), the
8 of the list of v0.11 that a capsule can hold (208 to 215), and 3 further
cases (216 to 218). A line of the lists of §64 with several values, such as
8 of the list of v0.11 that a capsule can hold (208 to 215), 3 further
cases (216 to 218), and the 4 cases of the source of the release of v0.15
(219 to 222). A line of the lists of §64 with several values, such as
"AREA_LEN 0, 511, 513 o 66048", is one case for each.
- `dkc`: the capsule, as edits of a fixture (see above). The reader gets it as a
seekable file, so that the `capsule_digest` of an offered `.dkk` is checked
@ -679,13 +846,24 @@ reading flow (`capsule.Open`, §63) must fail.
is asked for. The reader must verify it (§51): a case may serve a release of
another round, a round with the signature of another, or a signature that is
not the canonical encoding of a point (§12.2). `null` means that no release
is available (`ERR_RELEASE_UNAVAILABLE`). The release is supplied directly,
as the caller's own, so one that breaks the rules of step 10 gets the code
of step 10; a source that fetched it over a network would have discarded
it, and the code would be `ERR_RELEASE_UNAVAILABLE` at step 9 (spec §63
steps 9 and 10).
- `now`: the reader's clock, RFC 3339. No release is requested before the round
time of the DateKey.
is available (`ERR_RELEASE_UNAVAILABLE`). `chain_hash`, present in two
cases only, is the chain the release object names when it is not the
Quicknet chain.
- `source` (v0.15): what kind of source answers, spec v0.15 §63 step 9:
- `supplied`: the release is in the caller's hand, as a release object
read from a file would be.
The reader is given the release object of `release`, with the Quicknet
chain hash unless `chain_hash` says another, and decodes and verifies it
at step 10: one that breaks a rule of step 10 gets the code of step 10.
The clock is not compared with the round time (step 9.c): with a `now`
before it, the capsule opens all the same. Every case but two is
`supplied`.
- `network`: a network source, such as a drand relay. It is never asked
before the round time (step 9.c), and it verifies its answer with the
rules of step 10 and discards it when it fails, so the reader gets no
release: `ERR_RELEASE_UNAVAILABLE` at step 9.
- `now`: the reader's clock, RFC 3339. A network source is not asked before
the round time of the DateKey; a release in hand is not compared with it.
- `registry`: `default` pins exactly the Quicknet profile of
`profile_quicknet.json`; `empty` pins none.
- `extensions`: the extensions the application implements. Each entry is known
@ -698,9 +876,10 @@ reading flow (`capsule.Open`, §63) must fail.
data" and "known critical .dkk extension with invalid data", at steps 4, 14
and 9, depend on it. Absent: the application knows no extension, the state
of the base protocol V1.
- `network`: whether the failure may come after a release request. When false,
the reader must fail without requesting any release (§27, §63): every failure
of steps 1 to 8 and of step 9 before the request (9.a to 9.c).
- `network`: whether the failure may come after a release request, to a
network source or to the caller's release in hand. When false, the reader
must fail without requesting any release (§27, §63): every failure of steps
1 to 8 and of step 9 before the request (9.a to 9.c).
- `frozen`: the capsule was built once with age randomness; its bytes are kept
and never regenerated. These cases have no `base`.
- `error`, `step`: the expected code and the step of §63 that fails. For a
@ -710,6 +889,19 @@ reading flow (`capsule.Open`, §63) must fail.
format 3, and seven of the list of v0.11.
Every case reproduces offline: the recorded release stands in for the network.
What v0.15 changed in this file: every case gained `source`, `supplied` but
for two; the further case "round not reached yet", a valid release of round
1000 and a clock one nanosecond before its round time, was
`ERR_RELEASE_UNAVAILABLE` at step 9 and now opens (`ok`, step 0, with
`network` true), because the release is in the caller's hand; and four cases
were added at the end: the same capsule and clock with a network source,
still `ERR_RELEASE_UNAVAILABLE` at step 9 without any request; a release of
another round from a network source, discarded, `ERR_RELEASE_UNAVAILABLE` at
step 9, where the same release in hand is `ERR_ROUND_MISMATCH` at step 10;
and two release objects of another chain, `ERR_PROFILE_MISMATCH` at step 10,
one of them of another round too and with a clock behind. No other case
changed its result.
A reader that implements only steps 1 to 8 can replay every case whose `step` is
at most 8: 57 cases, 39 of them from §64. Steps 1 to 8 are summarised in "The
checks of steps 1 to 8" below.
@ -720,7 +912,8 @@ What happens between step 8 and the release request is spec §63 step 9: for
`time_and_key` only, an offered `.dkk` is checked as an object and then bound
to the capsule (9.a), at least one credential must be offered (9.b), and for
either policy a `now` before the round time of the DateKey fails without a
request (9.c); only then is the release requested. For `time_only` the
request to a network source (9.c), while a release in hand is not compared
with it; only then is the release requested. For `time_only` the
credentials play no part: the §64 case "access_policy=time_only with
time_and_key structure" offers a `.dkk` whose `capsule_digest` is that of the
unmutated capsule, and fails at step 12, not at step 9. The codes after the
@ -729,8 +922,9 @@ file (steps 11, 13 and 17), are those of spec §63 as well. In this corpus:
- identities are not examined before the release (spec §63 step 13);
- a `release` of `null` is `ERR_RELEASE_UNAVAILABLE` at step 9;
- every `release` is supplied directly, so an invalid one fails at step 10:
the source is not a network source, which would discard it at step 9;
- a `release` of a `supplied` case is in the caller's hand, so an invalid one
fails at step 10, and step 9.c does not apply to it; a `network` source
discards it at step 9, and is not asked before the round time;
- every `.dkk` offered decodes: the corpus checks step 9.a, not the decoding
of a `.dkk`, whose errors spec §63 also places at step 9.a.

110
testdata/SOURCE.json vendored

@ -1,140 +1,148 @@
{
"module": "g.activething.com/go/DateKeys",
"commit": "084728d3f7294cd93f644a5f87176a20e2a5de6e",
"commit": "aefc8f6dfe89037d71e22d5338a092ff21159429",
"files": {
"README.md": "3bd654992338f0450922da4907644eee20cf0792d2cea80fc26c5accec7e514c",
"README.md": "d26b3f507edf5afe89600f063cb509b9ef62a908b93ed476bff964b5a443bf4b",
"fixtures/empty_payload.dkc": "871e9bf05b52bbae17f3adfbbf97b46e7f0e53aa8f57bcaa506e43f36f53a9d4",
"fixtures/empty_payload.inspect.json": "373e5d012b023ad58bbb54cbdffe0bed9e50c637438a4083ddb74d5414c59f59",
"fixtures/empty_payload.json": "588c2573d99b953d490e3d9caaa392b804398b1f91d4f95492a01dd5e7e1f8ba",
"fixtures/empty_payload.json": "d1fc459ab76d4ee0231a8c6b7dfc212fcf8da90e7a392b30133f646b3a9df4db",
"fixtures/empty_payload.plaintext": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"fixtures/format2_empty_payload.dkc": "7aea2b5aa48b1a46053716f733d50fab9cd0b80b1be67631bcc06c5bb765dc21",
"fixtures/format2_empty_payload.inspect.json": "d0bb7356d3970986e6b197640f0b3b38abe9fabf1740b745171b358aa28903ff",
"fixtures/format2_empty_payload.json": "0ddce7b0888be7220d1de108d645cfec9fe15d2e33bc00180ae0a0f417a0f1a9",
"fixtures/format2_empty_payload.json": "699cc67dd448ba69ecc52ad97a1947175b46f9d64859a6fd018ecae8fbe12508",
"fixtures/format2_empty_payload.plaintext": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"fixtures/format2_time_and_key_portable.dkc": "600892659fe4890223e895876275f656995d170fda42b07fb2bec0ca51ce4b43",
"fixtures/format2_time_and_key_portable.dkk": "095b7bc516a22bf0c2366f0af3cd48bfe857a2354d6e2a9b285278b95e450fe0",
"fixtures/format2_time_and_key_portable.dkk.json": "7365f2050bd124daf15b3c623254073389e47e43b13e09fc6e03e79b292ecf0a",
"fixtures/format2_time_and_key_portable.dkk.json": "0f95e43881b140330415ca98a284913c22dab9af3b9e16da0f4d2b1b5229d768",
"fixtures/format2_time_and_key_portable.inspect.json": "522c9a98e5911c86f5f24f278971cf7c7588f6c88aaede3dd1129ee4e042868a",
"fixtures/format2_time_and_key_portable.json": "203e39ef29d74a2f28fb7d8530e01869ece0fa8c8e2c86e81a758eca15f39268",
"fixtures/format2_time_and_key_portable.json": "960bd78f54c91d0f8afcb9a1fdc18a7c7a7d74363ac1b77aa4ebef183d258dc6",
"fixtures/format2_time_and_key_portable.plaintext": "937492203d207d6fe36161b8696bf1f05b8b4cc56d855c44853f4b76aad3a05b",
"fixtures/format2_time_and_key_recipients.dkc": "1a44fd8708c92e2e0a10cfcb1d864a71331ea9af25d97e1a42e969dc898959e3",
"fixtures/format2_time_and_key_recipients.dkk": "2ad99b1556086ec311d7f0b3bd3aaba05e75f45c4fa22490b0d5e8bb0b1a222e",
"fixtures/format2_time_and_key_recipients.dkk.json": "57edcc56c16ba7e17e6b7ba079688f04431967a90ce3592f065c838a0c9b2a35",
"fixtures/format2_time_and_key_recipients.dkk.json": "9d7e89e390e253bc1a432fa36ca2c37abbd6e88a0ac2fc25e87c1b7bb442e7d1",
"fixtures/format2_time_and_key_recipients.inspect.json": "d975a9eddd45f5d59618ea2455d574d807e57daf08585e840d07986f261bf099",
"fixtures/format2_time_and_key_recipients.json": "2a1dd1fa810f0b76ccee04320061ffc664c744da1206d60dbb14e0ac01b9635a",
"fixtures/format2_time_and_key_recipients.json": "34abdf930940ff7ac7b28de597bda3fdcadc94a074912e5220153bd85f9e096c",
"fixtures/format2_time_and_key_recipients.plaintext": "0e9fd50e98a85953aa9cf07a11ee3c62bb3d7622f344f1c6ce744d1ed111659f",
"fixtures/format2_time_and_key_sixteen.dkc": "7aaac5c18f216bf53df326ecc817179640a53408cf25dfd50488910a762dc381",
"fixtures/format2_time_and_key_sixteen.inspect.json": "492cd0b0dca0030df9332b098d22b4f6aa4adfb57d5540de5325e3e6d5aa3667",
"fixtures/format2_time_and_key_sixteen.json": "5686913ae6c4dd94fc90a96d28d2f7f7ef6fdd5213416d27c7fd85a423be1023",
"fixtures/format2_time_and_key_sixteen.json": "30b8103e730e3cea5b8b39078b61022c8e3e168dec70c27a7aa69c83046853ee",
"fixtures/format2_time_and_key_sixteen.plaintext": "e5abfb7b5fdbf297277b6cc4729c15d85435e890b653c2e2342b7031ecd9eab9",
"fixtures/format2_time_only.dkc": "f5a40ac6b8a08a0c12db6114c2bca23522d6a77b512b509a217fb15f367813c4",
"fixtures/format2_time_only.inspect.json": "40a8683f5204c7b6369558e4775ae6bb6fed978097e9e660de64c06c167b043e",
"fixtures/format2_time_only.json": "db863e7480eae1e1a4df985aa0cfb8456de67a1f0f5a6bcb3dd5fadf2837eb06",
"fixtures/format2_time_only.json": "4a3c76f1a75fbc39399c5bd7f8c355565c2ea826ad1284dd056953af8aedb009",
"fixtures/format2_time_only.plaintext": "53b8ee821fb7b678e89d4f93da1812339f6cc1ab83aac6ed1432db99df784be5",
"fixtures/format2_time_only_bloque256.dkc": "aae769c30d04920801d8b293d30864fbe223c9c9353ec2b4907a1ee1996e39f9",
"fixtures/format2_time_only_bloque256.inspect.json": "767766414ad547f0ba95b40059e14b62c81b5489a2afcbc683bf227334d61be7",
"fixtures/format2_time_only_bloque256.json": "9c7db52db560ec1203e811a214d3c6dd5324dac586331332f774a3fccc6ad515",
"fixtures/format2_time_only_bloque256.json": "7dbd8dc320dbed995be9cb5830ca9a50d4fb8e956b1d468408f6199c97fc26f4",
"fixtures/format2_time_only_bloque256.plaintext": "53b8ee821fb7b678e89d4f93da1812339f6cc1ab83aac6ed1432db99df784be5",
"fixtures/format2_time_only_extensions.dkc": "fb406100d5703a2e888983b3175ed34a09a34469cc722256e5cf535dd728fbe9",
"fixtures/format2_time_only_extensions.inspect.json": "1595d793c1d35bfdaa36576b75f53d734a9e07c2a8a12036295dbaee7f5a7f5a",
"fixtures/format2_time_only_extensions.json": "5f48a438c8220951df7734fb4fd2172206827145597c43307d12514ce6c3c85a",
"fixtures/format2_time_only_extensions.json": "bfe30126441ea1b1b2e9b7cb0cbbce71d5f26f98b77004893b46ebf4be6b573f",
"fixtures/format2_time_only_extensions.plaintext": "1129768e195e2f1e50b7a6f926b6eebef120212c29b5642c8a662c503b2a9131",
"fixtures/format3_area_1024.dkc": "41ea2eed0293e4fef7f4a307b7f16aaf1339f5bf6f4ded7a6a9ae1aebeb0133c",
"fixtures/format3_area_1024.inspect.json": "06e6b347926242ae5540f16a053f6a3545743986989bc0be8c39918bce968686",
"fixtures/format3_area_1024.json": "d2722c99bf6c543a1eeb1fdd9cf57506d71b0a324b33458865b043698b7729d3",
"fixtures/format3_area_1024.json": "06319a474d9e6c545185aa282be407908f98cb97a1ad5128fc0d557adc45695d",
"fixtures/format3_area_1024.plaintext": "043830350a287cba1fd50f6c063f70a74209895ff0cf03147bb4e5ccdfc206b5",
"fixtures/format3_bloque256.dkc": "ff18444f434164ba8e7b26d38c76c7855dc6b0593b2fc8b4e9a95dbf9252d55d",
"fixtures/format3_bloque256.inspect.json": "d0007080da5ce079c6ffa3a56bf8ce519d2846a31cc1082fd027f401e4f7bade",
"fixtures/format3_bloque256.json": "9fe4131d6e108a8ed2206ae33ced33ed6ca770b7a0111748cf208fcdd4a916c4",
"fixtures/format3_bloque256.json": "e551a2224454cd5a416d6e91e2ab0947249a906dac3ef028a3dd45ee441e62b9",
"fixtures/format3_bloque256.plaintext": "9ff2843e40bc1280dbfea8dce9386a42d06e8b43742c2cc6257540770cb53c73",
"fixtures/format3_comment_only.dkc": "7f98a89413f08655bbbab28b96585dfa6173c1705dd81a900deba2100d19f2ef",
"fixtures/format3_comment_only.inspect.json": "fb56eca8bf42c8c47fde4a1d6b2580fcff386f2f58b566820731dce388542196",
"fixtures/format3_comment_only.json": "8731bcb3641d7f99f63729e85f1e2960d3f38a6ac64bb3321369bfe3e21fa2b1",
"fixtures/format3_comment_only.json": "1aff9f9c3531e269fc48b25c4e224e6b547ba1d5eba187ed6afa3eaff82c26f8",
"fixtures/format3_comment_only.plaintext": "bc5b05885e608f036d8a14fde8738a8c53b395b71c3bcee99c1eab37ea23e80e",
"fixtures/format3_note.dkc": "da1bee54231252a0fd98439e24588125c5521f6e5a2c6641b499e6b22192c0eb",
"fixtures/format3_note.inspect.json": "dcebb62407097c757bb62552be5d315155ba8a35dec175e95c3f6fddd6e81869",
"fixtures/format3_note.json": "b2778f8991c2ad9b464d0f45f495c94aae0da97a646df1ce401cf8847b9ce02c",
"fixtures/format3_note.json": "70bae49ca3ee84dcd4fecc572d500ce61cb014cc1e43385ae172cf414e10fa41",
"fixtures/format3_note.plaintext": "0468737c5141be936f59d2823122e87661d4ae155a1df036b4cad1ea6620c17b",
"fixtures/format3_seal_unsupported.dkc": "ae3219fbdbd1de4cef6fade1a3fb3f6e5d5e2e8af54d9516b05f0a48136913ad",
"fixtures/format3_seal_unsupported.inspect.json": "b3a7a1038192394c1f844fed994011646f3e78d1cf311c18cb5c936249b95f14",
"fixtures/format3_seal_unsupported.json": "96e9338350ade00226b56e8461e54fbfdda1266de4e63e4c25eef6f84c96801a",
"fixtures/format3_seal_unsupported.json": "fedb92f17376cb90d91bce6777e152739d63bee884809ec9458dd5610d939d66",
"fixtures/format3_seal_unsupported.plaintext": "0f865221d26545762712271faf835cb2e9980f8fb15c9d3b94fb6747cf16c1df",
"fixtures/format3_sealed.dkc": "dde5a072d8783227d28279d06d3d226a1fb967c766da626f889d1c6fd76ac9c7",
"fixtures/format3_sealed.inspect.json": "b984a0755332bad838025e47f8e917b9f18b9bb5c068c2d1ef0070db8e42849c",
"fixtures/format3_sealed.json": "acfec2917e798cd1e3f2b38e1ff4f6cee7474ca6b7684e739c8143b291fe91e2",
"fixtures/format3_sealed.json": "b925f7daae6d21c139b529a10900b9f67adb121b18670682969da3d1faa4e382",
"fixtures/format3_sealed.plaintext": "aea0f5feb40acd81ca3b02dd21ea15510234da3ab52b374322f3206e7632d47b",
"fixtures/format3_security_v2.dkc": "3d02b39ace010d74604554e378d22fe5ce00cecd998c0f797d657b17620b8912",
"fixtures/format3_security_v2.inspect.json": "dba4d21f1d4e228a17c761bae9a4b8c5a91cd9c0123e3141d3782a43c139321e",
"fixtures/format3_security_v2.json": "78218ca96fdfe6629853c4b8826e2ba11ee010677e54169ba8286ff9d00c9d6a",
"fixtures/format3_security_v2.json": "47bf9cf26e04f1c87eaf669d3d3811846bffd188dc6a90b3ac96cc45ea1ff256",
"fixtures/format3_security_v2.plaintext": "0c58ef40e4b1c7afde0f6e0a1f4ed7e3d45405757c5143a095f0c2b58042669f",
"fixtures/format3_signature_unsupported.dkc": "e8e3106d8d73bb7b845062e0fe42af21df7d7cd8f63c335cab8dedb3e690df31",
"fixtures/format3_signature_unsupported.inspect.json": "6db653db27604cb07e2cb2c23545fb68542c121e85002762f26c6d39e63bf00c",
"fixtures/format3_signature_unsupported.json": "427dd9201e57c2c6242722bc5b2882dd310225c40b883f9339cdd6c04f87b751",
"fixtures/format3_signature_unsupported.json": "1e2e173ede53f38fb368289fc616325b18c7e07fd87d5eda28ace180087f151e",
"fixtures/format3_signature_unsupported.plaintext": "9fe05e6b3a463371b33fc6a81b81d538e572789a8d03ace9f752a931f4ca4728",
"fixtures/format3_signed.dkc": "3c7d3c9e24c02853a0c7761b93bea1120b27fce396468d8d0f68e53aeb668c5e",
"fixtures/format3_signed.inspect.json": "7c37054d542869e766147350e2fa72695f209d39a03726757008e2c2291b0e97",
"fixtures/format3_signed.json": "9d602cda39ce124b604410101a63bd981d21677f9bebb4eda5e4dedbd93531bb",
"fixtures/format3_signed.json": "725b6cdb41ad9a5d34ec5327f7b0f1b667510fea6a9b1fb714be582ed55eaaed",
"fixtures/format3_signed.plaintext": "3de3ccab0ac74f95a76aa45c0f85e1749d4b4a051d87e81828eff6bf24372000",
"fixtures/format3_signed_cms.dkc": "d658f8d5ac2c5550c07b8f8fd6883b2f6dc02ceafc47d436ea02d8950b2548d2",
"fixtures/format3_signed_cms.inspect.json": "afadf530e8146687b25c03f26100ebff18e7f481e0ef09378816bad582270de5",
"fixtures/format3_signed_cms.json": "f05befb5fa9aafa2ee55fc7f3abe4832878b1950ae3b2e20915936ce20f12a9d",
"fixtures/format3_signed_cms.json": "eac7b9c2d2470ef140f41cf7c94e32657e2949a40f621a07340f7d2342ee7dc1",
"fixtures/format3_signed_cms.plaintext": "31c35eeeee856277b605fe44203a8f4786bb8f591eda3b6ee58252df5b3cf2f0",
"fixtures/format3_single.dkc": "9f68664af8733255084be9036a100b75d27bd16106bf0acff94ce469dd1d1743",
"fixtures/format3_single.inspect.json": "7878da921c17aada50e00d5911ea97e8558633a1684fb96acbd00d6f1b117529",
"fixtures/format3_single.json": "c99a175287c9555b74e8ae813326f3d7cdce0692a0144ee8e47158775970bcd4",
"fixtures/format3_single.json": "0a31c6d416ec3e6acd891172881f4f5738c36e01c9583be48f0376324641d17b",
"fixtures/format3_single.plaintext": "74f9dd84d07e95a31e6dc063bf65ce414197acf84aac445eabc76fa4e3f24936",
"fixtures/format3_time_and_key_portable.dkc": "680d29962e575689a31543df28433dae7737abd9a793e9cae92ef40920d09636",
"fixtures/format3_time_and_key_portable.dkk": "54cc64d849395234b3e093e47f432b72781ccc13f455c9ef394e3554ab566751",
"fixtures/format3_time_and_key_portable.dkk.json": "36d343d729d126990754be34f0f67c9faf1529b7d8946e6b34b4d0de5b46b744",
"fixtures/format3_time_and_key_portable.dkk.json": "a3aff664132ec3d6da8f016c44978733ad8b9e500dec08d5c08a1a1c39a09071",
"fixtures/format3_time_and_key_portable.inspect.json": "f269af86f5bf84c22a1038fd78db146af93166150755eb1ca35cf15e224035b4",
"fixtures/format3_time_and_key_portable.json": "ca6623323ada21445c1c131cf278b060c2b22abc670f0889b30540f0abbb8dc6",
"fixtures/format3_time_and_key_portable.json": "0a545aab8299c5af039b57092276cf5db62e73ef74e6e1046834f6886a34bbf0",
"fixtures/format3_time_and_key_portable.plaintext": "e6684cf607c102bfa4d6977742d5a7520b0e09483282181bd6d8f5f4ba5f7726",
"fixtures/format3_tree.dkc": "217f378faaf795f6a9c416b564fb8931bb2e896918aee870120fd14f9a5da7d1",
"fixtures/format3_tree.inspect.json": "643a9dfdc2d0c44b8a1636909c66ed81bfd8c50df2a4cad6566832a8e47ba938",
"fixtures/format3_tree.json": "1d11d2f12603542039ac6b396ffec69e92bde2689fd54dfc9ef800b6b9f7746b",
"fixtures/format3_tree.json": "1d2ed3e28c5075ead9898757b971298273c4b20acee27911286dc250aa7d0143",
"fixtures/format3_tree.plaintext": "f69ac5f450966f7d0e9161aa37451d4260b194a750e3e132c02e8a15ba561cfa",
"fixtures/format3_unsigned.dkc": "317ab722ae3812a25ddd78b4c98c586363e5587c8d3634c881ce7c421af19168",
"fixtures/format3_unsigned.inspect.json": "2f52f7286d6bd4c846ddd63b10b4989b25d17501a989a2e9deb25e4db0859e1a",
"fixtures/format3_unsigned.json": "8ab91d2505d8c29eb09a5ac6060b16c48f5b5618e82ac8f28ecbe926df4ec009",
"fixtures/format3_unsigned.json": "bce5d7fcf60ddb553e2bbe5b501892ae7a13488b4095fdad598dc3207690dfb3",
"fixtures/format3_unsigned.plaintext": "25527e5e2e1ce02056d4419fb89f7b0ce35e4920f93217f58dcf62a4377f8af5",
"fixtures/time_and_key_portable.dkc": "2e97878078bae6358037a9c264f379a3cbe839f767d69836b0343f35657b2972",
"fixtures/time_and_key_portable.dkk": "e528fa2c832c91119f0684bb9d6fb3c4c2d0d55183482890e7c4fe92f668426a",
"fixtures/time_and_key_portable.dkk.json": "b057c25c9950533c01122cb907a43242b7538a7d427f8fa3cfa34ab6dfb7e390",
"fixtures/time_and_key_portable.dkk.json": "4535028d6559cd368a44a6f03ebf8bcbcc2bdac4fcf13374aae541618b81c99f",
"fixtures/time_and_key_portable.inspect.json": "238c1f8ca6a6bf69f20bf26f5676e89a0b07e83b4362628560fc2f7522a202c9",
"fixtures/time_and_key_portable.json": "26467c1b6feafde9b6b49742a87bdb648c1effff6ac99b824561566282ea60ba",
"fixtures/time_and_key_portable.json": "389f36834ffb86a4c60950872a540caf8a8a94f65d02f56ce5f7922e06bf933c",
"fixtures/time_and_key_portable.plaintext": "937492203d207d6fe36161b8696bf1f05b8b4cc56d855c44853f4b76aad3a05b",
"fixtures/time_and_key_portable_extension.dkk": "0bf463a7c65627b7dda2234d728df89ec5b835816a2a37b91497d8fecc5ea548",
"fixtures/time_and_key_portable_extension.dkk.json": "89a96dd9dd1fe30187758d78211a6fbcb4b8cb7487e3a2f224e38874b246e834",
"fixtures/time_and_key_portable_extension.dkk.json": "e6f4015f10403926a8e2d3399f78ba99a48ce6c4760e24174c1521046c23efb2",
"fixtures/time_and_key_recipients.dkc": "69ac110380f5d768b5b6afaa157a50ed17d8ceccfbd4604ffa5b6da38539b635",
"fixtures/time_and_key_recipients.dkk": "19f6c47150c3194712d454f43c7392b7344e6b4e7b074d83e9ca5f563a8e072f",
"fixtures/time_and_key_recipients.dkk.json": "c3712a6afc1e0ad73615ec4329a0009261b32536fd630aff3b01f28b9384b6e9",
"fixtures/time_and_key_recipients.dkk.json": "f206ed1a51fc6aac7b2faabd2e3519224f68f7b9b9643653dbdf5b6139f042e0",
"fixtures/time_and_key_recipients.inspect.json": "4b32c63d18febe0772837fbcd75a0c971e31378bf799201b720a9d32bdcd8c2b",
"fixtures/time_and_key_recipients.json": "a00a49e7140fff35f253e42d13d221cfb339a2e59b7b53dbb3b8a32dd00cfe4b",
"fixtures/time_and_key_recipients.json": "2cdbc03ef027879b36c68de56e205960e774858a3ff170aba66d630de27c7303",
"fixtures/time_and_key_recipients.plaintext": "0e9fd50e98a85953aa9cf07a11ee3c62bb3d7622f344f1c6ce744d1ed111659f",
"fixtures/time_only.dkc": "99e915810d595f1092700b728f5e5081d78efe83f5343e76325b1bcc2c33ccf2",
"fixtures/time_only.inspect.json": "a4d45f945d6ba6616c01e120ac1133785e5279fea7dcab706b5feee287be8884",
"fixtures/time_only.json": "cfb7a43154189692ef3a1f08e9a12b5855df1b95c10ae13e05935160a3f9aaaa",
"fixtures/time_only.json": "9e66fedbfcf6ffec45648d8afdb7592eecd645751703051d1f60af1d0b7f9f01",
"fixtures/time_only.plaintext": "53b8ee821fb7b678e89d4f93da1812339f6cc1ab83aac6ed1432db99df784be5",
"fixtures/time_only_extensions.dkc": "0446c9b73e267adcb24e5cc89afba2544a386ec9a050016e06517a4a57aa2085",
"fixtures/time_only_extensions.inspect.json": "6f957b028da8a4a495b5e951ced0b91e0678128dac4e962b02d024b9439a0ba1",
"fixtures/time_only_extensions.json": "c5b6b253c03a95a3878538d98c8114041042f8dce8dbbb382727651781f4a146",
"fixtures/time_only_extensions.json": "4bb636805cc681ba1c74aa426f5afda72580f4350929a720da49eeccee3eb2be",
"fixtures/time_only_extensions.plaintext": "1129768e195e2f1e50b7a6f926b6eebef120212c29b5642c8a662c503b2a9131",
"vectors/cbor.json": "79d750994eafc4fa718b0997fbb0a70673dc08a129efcd7d0ddc2db922406913",
"vectors/dk1.json": "f5547be887d6ca405518636925018fdec22a5027009651705b07aec80151314a",
"vectors/ed25519_strict.json": "342d866584435b291832d34deb9ce17aef10d99db148b85443e39e9bed321d0a",
"vectors/head_schema.json": "3c7bcf57aa22943cd17005ea9ce426c0b3e7c365a0527a790b5e9e1973f9753f",
"vectors/inspect_differential.json": "e8c99d025ec761690e71ee0c6adfcfd5b680cdcb89024463d8ebbc24be6b0774",
"vectors/locator.json": "01370395ae53b363b5b0d0e2733fcb6fe0e20d7c64a5d20325ed3aa92beec859",
"vectors/mutations.json": "30719f97cba6e95fba0e077a5418cee50e216efd86080334c7d7e2d8c6dc247a",
"vectors/note.json": "d345861417b5fb8e3b1a56f39fdc58c7539cff85240496de3fd6edf7322a9ce2",
"vectors/padding.json": "53d71fc9679d6eda3ba7b7a15752927a1a5fe026bdbd7f93b0ce3569a6a4b22a",
"vectors/path_fold.json": "94c708bf04379984326f786ba1a954a94dc958fa06013c525e7f7a2c14f856bc",
"vectors/paths.json": "3466da7dd82d82c1c43fe956eb91e674065d159c9326e3bc0dcbbe2c6b774251",
"vectors/profile_quicknet.json": "c15ecb111635ecae2084da8511efbee133e97ff07c1c951658b036ce05b69781",
"vectors/quicknet_rounds.json": "0f11bf5c5da88b1e929bb39439001a3a1f8447a85a4b3a25296d40d71a261e50",
"vectors/security.json": "158df388fe881b75989e319eaadc88437b5031cd62f6c8cfc9cc421c3eacff89",
"vectors/security_cms.json": "1ef9c74f1998fc06ab459ab885e3654bf4375f5baa276ea2a1de3f08e64a32b4",
"vectors/tlock_ibe.json": "27e9d9ebac4f07700661d2b4c524b10d065c9698e9acc68baa3d2c01bdbb24f2",
"vectors/wordkey.json": "882593e1ed63cb5cfa6231a1bdc4060a04be5233db1a971d9dcbfff3031c071a"
"releases/1000.cbor": "5d2e86210d2e8d64ce36e55edf3ff6c8997fda4bc06fec7fd5feb0dd6cab8293",
"releases/1001.cbor": "2b55dcc09dfe8fa97192aa6d9a85f9fc50206142d52f66329261cfe9e03de755",
"releases/1004.cbor": "aabdffe0fb944d8796528a6682fdbafb448b1e5da164ee039b6c3ee7f354e766",
"releases/2000.cbor": "9e37be0004850faaa8541658a90ee8aba0832fccf2b695df42c89cb3f7de29ff",
"releases/archive_1000_1004.bin": "bb53d542abd704f3af9f6436c9178f65bf812a06630607b3aad3a09eaed0cce1",
"vectors/cbor.json": "715c8e7ca88d17c4e68a8764350217f108e96484e59282d384a032169d36bfb8",
"vectors/dk1.json": "e2b849b1f606e7961a8571c305dcd0c4374f03c8943a3a715b20a9a43002ea44",
"vectors/ed25519_strict.json": "eb47ac6b5e879ca3e115f6551b81e5b6fe5bf5050aa7b829804e915705c3a1ad",
"vectors/head_schema.json": "29493360d4cf97c3ad488a8ce58221804b17511523756cea1efb87e6fbc13444",
"vectors/inspect_differential.json": "bdc5210415084cde71aa84fbaa7ebbcd81e0f1800b411c6dbacc5e553b4021dd",
"vectors/locator.json": "02476c2f5e421bfc35e2f7b2498ab1d395fd7ef5971fb46dd16fe0abfb6f7a11",
"vectors/mutations.json": "e3ce6a57a57e49bfdb726fb8e9e6e36711c65a23b08e751aab00f8c4dbfcade3",
"vectors/note.json": "f02feea92b22c98227c21e725b3d3e8b303ec647c4cab3fd9b4b71261273818e",
"vectors/padding.json": "7cd6ac71fd978e21c5f93870a211035f98028b9020422f727e407c477e4514bb",
"vectors/path_fold.json": "75e4fa473da4b394d32ac107a5e9559b0d3358ce1b39e5d7403366aa35c2efff",
"vectors/paths.json": "a33ecdbd6a191d693600e18879e15a5813d77b133d46f30c5535aae72eeaeb04",
"vectors/profile_quicknet.json": "e291d5167cdce9b9e24993571a7f349e35fbbcfea793665883ec9ec8d479b498",
"vectors/quicknet_rounds.json": "bf990896dddc51a91e309143fede773adeae918ef47433e0ab6132a4456ce9a8",
"vectors/release.json": "97bd46e055024a00f6a765f840b47ebfea5dad1e08a88c70d2cf42a77df6d2ba",
"vectors/resolved_ip.json": "7c554e7c3f272a62a89c3f3e97203dc7d5dc50290bbe356f4a8efd44a19eea70",
"vectors/security.json": "6045492767cbeb02fce5b6faf6cd0e179ffe96c898c8c023793e4a138b0277f0",
"vectors/security_cms.json": "4915fa3cfe93b1ad92e91a68bba7517c3b2dc3e33fd9def7340b3a045eff99cf",
"vectors/tlock_ibe.json": "5c1def934c89c1638187058e9dcb76ac9fffd148885a9869a1dc7b19d2df76b6",
"vectors/tlock_steps.json": "661c5214c30ea3ea08e7f54f779346b6e838e68a0732ea2110ddcbf07a25cd35",
"vectors/wordkey.json": "1ef9f07d84e7d99d68433a89371c79a407c4e10f33547210bfdf1d7378956d6b"
}
}

@ -1,6 +1,6 @@
{
"description": "time_only capsule with an empty payload",
"spec": "0.11",
"spec": "0.15",
"format": 1,
"file": "empty_payload.dkc",
"sha256": "871e9bf05b52bbae17f3adfbbf97b46e7f0e53aa8f57bcaa506e43f36f53a9d4",

@ -1,6 +1,6 @@
{
"description": "format 2 time_only capsule with an empty content: L = 0, P = 256",
"spec": "0.11",
"spec": "0.15",
"format": 2,
"file": "format2_empty_payload.dkc",
"sha256": "7aea2b5aa48b1a46053716f733d50fab9cd0b80b1be67631bcc06c5bb765dc21",

@ -1,6 +1,6 @@
{
"description": "portable X25519 .dkk of format2_time_and_key_portable.dkc",
"spec": "0.11",
"spec": "0.15",
"file": "format2_time_and_key_portable.dkk",
"sha256": "095b7bc516a22bf0c2366f0af3cd48bfe857a2354d6e2a9b285278b95e450fe0",
"credential_id": "e3c7be83cbf1fbd6b115c96411b3bd01",

@ -1,6 +1,6 @@
{
"description": "format 2 time_and_key capsule with one credential, a portable .dkk, and 15 dummies",
"spec": "0.11",
"spec": "0.15",
"format": 2,
"file": "format2_time_and_key_portable.dkc",
"sha256": "600892659fe4890223e895876275f656995d170fda42b07fb2bec0ca51ce4b43",

@ -1,6 +1,6 @@
{
"description": "portable X25519 .dkk of format2_time_and_key_recipients.dkc",
"spec": "0.11",
"spec": "0.15",
"file": "format2_time_and_key_recipients.dkk",
"sha256": "2ad99b1556086ec311d7f0b3bd3aaba05e75f45c4fa22490b0d5e8bb0b1a222e",
"credential_id": "93cedf68421710e83908ec683b104436",

@ -1,6 +1,6 @@
{
"description": "format 2 time_and_key capsule for three known X25519 recipients and a portable .dkk, and 12 dummies",
"spec": "0.11",
"spec": "0.15",
"format": 2,
"file": "format2_time_and_key_recipients.dkc",
"sha256": "1a44fd8708c92e2e0a10cfcb1d864a71331ea9af25d97e1a42e969dc898959e3",

@ -1,6 +1,6 @@
{
"description": "format 2 time_and_key capsule for sixteen known X25519 recipients, without dummies",
"spec": "0.11",
"spec": "0.15",
"format": 2,
"file": "format2_time_and_key_sixteen.dkc",
"sha256": "7aaac5c18f216bf53df326ecc817179640a53408cf25dfd50488910a762dc381",

@ -1,6 +1,6 @@
{
"description": "format 2 time_only capsule, padding code 2 (reforzado): L = 78000, P = 79872, two STREAM chunks",
"spec": "0.11",
"spec": "0.15",
"format": 2,
"file": "format2_time_only.dkc",
"sha256": "f5a40ac6b8a08a0c12db6114c2bca23522d6a77b512b509a217fb15f367813c4",

@ -1,6 +1,6 @@
{
"description": "format 2 time_only capsule with the content of format2_time_only and padding code 1 (bloque256): L = 78000, P = 78080",
"spec": "0.11",
"spec": "0.15",
"format": 2,
"file": "format2_time_only_bloque256.dkc",
"sha256": "aae769c30d04920801d8b293d30864fbe223c9c9353ec2b4907a1ee1996e39f9",

@ -1,6 +1,6 @@
{
"description": "format 2 time_only capsule with a noncritical PUBLIC_HEADER extension and a noncritical CONTROL_CBOR extension",
"spec": "0.11",
"spec": "0.15",
"format": 2,
"file": "format2_time_only_extensions.dkc",
"sha256": "fb406100d5703a2e888983b3175ed34a09a34469cc722256e5cf535dd728fbe9",

@ -1,6 +1,6 @@
{
"description": "format 3 time_only capsule with a security area of 1024 bytes, as a later version may write it, holding the empty security",
"spec": "0.11",
"spec": "0.15",
"format": 3,
"file": "format3_area_1024.dkc",
"sha256": "41ea2eed0293e4fef7f4a307b7f16aaf1339f5bf6f4ded7a6a9ae1aebeb0133c",

@ -1,6 +1,6 @@
{
"description": "format 3 time_only capsule with padding code 1 (bloque256) and one file of 20000 bytes",
"spec": "0.11",
"spec": "0.15",
"format": 3,
"file": "format3_bloque256.dkc",
"sha256": "ff18444f434164ba8e7b26d38c76c7855dc6b0593b2fc8b4e9a95dbf9252d55d",

@ -1,6 +1,6 @@
{
"description": "format 3 time_only capsule with a comment of two lines, the second one with a TAB, a declared author and no files",
"spec": "0.11",
"spec": "0.15",
"format": 3,
"file": "format3_comment_only.dkc",
"sha256": "7f98a89413f08655bbbab28b96585dfa6173c1705dd81a900deba2100d19f2ef",

@ -1,6 +1,6 @@
{
"description": "format 3 time_only capsule with a single file, nota.txt, and the public note «Cartas del viaje a Lisboa» in the noncritical array of PUBLIC_HEADER (spec v0.11, §24.1)",
"spec": "0.11",
"spec": "0.15",
"format": 3,
"file": "format3_note.dkc",
"sha256": "da1bee54231252a0fd98439e24588125c5521f6e5a2c6641b499e6b22192c0eb",

@ -1,6 +1,6 @@
{
"description": "format 3 time_only capsule with an author-signature of alg 4294967295, as in format3_signature_unsupported, and a seal of seal_type 4294967295, reserved for tests, with a random token of 32 bytes: verdicts F1 and S1",
"spec": "0.11",
"spec": "0.15",
"format": 3,
"file": "format3_seal_unsupported.dkc",
"sha256": "ae3219fbdbd1de4cef6fade1a3fb3f6e5d5e2e8af54d9516b05f0a48136913ad",

@ -1,6 +1,6 @@
{
"description": "format 3 time_only capsule with a single file, nota.txt, signed with alg 1 by the test key of format3_signed and sealed with seal_type 2 by a test time-stamping authority before the round time: verdicts F4 and S4, with SEAL_SUBJECT and the token in the record",
"spec": "0.11",
"spec": "0.15",
"format": 3,
"file": "format3_sealed.dkc",
"sha256": "dde5a072d8783227d28279d06d3d226a1fb967c766da626f889d1c6fd76ac9c7",

@ -1,6 +1,6 @@
{
"description": "format 3 time_only capsule whose security is of version 2: verdict X",
"spec": "0.11",
"spec": "0.15",
"format": 3,
"file": "format3_security_v2.dkc",
"sha256": "3d02b39ace010d74604554e378d22fe5ce00cecd998c0f797d657b17620b8912",

@ -1,6 +1,6 @@
{
"description": "format 3 time_only capsule with an author-signature of alg 4294967295, a random key of 32 bytes and a random signature of 64: verdicts F1 and S0",
"spec": "0.11",
"spec": "0.15",
"format": 3,
"file": "format3_signature_unsupported.dkc",
"sha256": "e8e3106d8d73bb7b845062e0fe42af21df7d7cd8f63c335cab8dedb3e690df31",

@ -1,6 +1,6 @@
{
"description": "format 3 time_only capsule with a single file, nota.txt, signed with alg 1 by a test key whose seed the record gives: verdict F4, and the commitments and the message of the signature",
"spec": "0.11",
"spec": "0.15",
"format": 3,
"file": "format3_signed.dkc",
"sha256": "3c7d3c9e24c02853a0c7761b93bea1120b27fce396468d8d0f68e53aeb668c5e",

@ -1,6 +1,6 @@
{
"description": "format 3 time_only capsule with a single file, nota.txt, signed with alg 2 by two test certificates, an ECDSA P-256 one and an RSA 2048 one, each sealed by a test time-stamping authority before the round time: verdict F6, with the certificates, the commitments, SIGNERS and the result of each signer in the record",
"spec": "0.11",
"spec": "0.15",
"format": 3,
"file": "format3_signed_cms.dkc",
"sha256": "d658f8d5ac2c5550c07b8f8fd6883b2f6dc02ceafc47d436ea02d8950b2548d2",

@ -1,6 +1,6 @@
{
"description": "format 3 time_only capsule with a single file, nota.txt, with its mtime",
"spec": "0.11",
"spec": "0.15",
"format": 3,
"file": "format3_single.dkc",
"sha256": "9f68664af8733255084be9036a100b75d27bd16106bf0acff94ce469dd1d1743",

@ -1,6 +1,6 @@
{
"description": "portable X25519 .dkk of format3_time_and_key_portable.dkc",
"spec": "0.11",
"spec": "0.15",
"file": "format3_time_and_key_portable.dkk",
"sha256": "54cc64d849395234b3e093e47f432b72781ccc13f455c9ef394e3554ab566751",
"credential_id": "bdb483fba42daf0b409f44d23033f362",

@ -1,6 +1,6 @@
{
"description": "format 3 time_and_key capsule with one credential, a portable .dkk, and 15 dummies",
"spec": "0.11",
"spec": "0.15",
"format": 3,
"file": "format3_time_and_key_portable.dkc",
"sha256": "680d29962e575689a31543df28433dae7737abd9a793e9cae92ef40920d09636",

@ -1,6 +1,6 @@
{
"description": "format 3 time_only capsule with five files in three folders, one of them over two STREAM chunks and one without mtime, a comment of two lines and a declared author",
"spec": "0.11",
"spec": "0.15",
"format": 3,
"file": "format3_tree.dkc",
"sha256": "217f378faaf795f6a9c416b564fb8931bb2e896918aee870120fd14f9a5da7d1",

@ -1,6 +1,6 @@
{
"description": "format 3 time_only capsule with a single file, nota.txt, as format3_signed, without a signature: the area of 32 KiB of spec v0.11 holds the empty security, and P is the one of format3_signed",
"spec": "0.11",
"spec": "0.15",
"format": 3,
"file": "format3_unsigned.dkc",
"sha256": "317ab722ae3812a25ddd78b4c98c586363e5587c8d3634c881ce7c421af19168",

@ -1,6 +1,6 @@
{
"description": "portable X25519 .dkk of time_and_key_portable.dkc",
"spec": "0.11",
"spec": "0.15",
"file": "time_and_key_portable.dkk",
"sha256": "e528fa2c832c91119f0684bb9d6fb3c4c2d0d55183482890e7c4fe92f668426a",
"credential_id": "3955e944a3c60cfa1fd6485e9693c77d",

@ -1,6 +1,6 @@
{
"description": "time_and_key capsule whose only recipient is a portable .dkk",
"spec": "0.11",
"spec": "0.15",
"format": 1,
"file": "time_and_key_portable.dkc",
"sha256": "2e97878078bae6358037a9c264f379a3cbe839f767d69836b0343f35657b2972",

@ -1,6 +1,6 @@
{
"description": "portable X25519 .dkk of time_and_key_portable.dkc with a noncritical extension: the credential of time_and_key_portable.dkk re-issued with org.example.delivery",
"spec": "0.11",
"spec": "0.15",
"file": "time_and_key_portable_extension.dkk",
"sha256": "0bf463a7c65627b7dda2234d728df89ec5b835816a2a37b91497d8fecc5ea548",
"credential_id": "3955e944a3c60cfa1fd6485e9693c77d",

@ -1,6 +1,6 @@
{
"description": "portable X25519 .dkk of time_and_key_recipients.dkc",
"spec": "0.11",
"spec": "0.15",
"file": "time_and_key_recipients.dkk",
"sha256": "19f6c47150c3194712d454f43c7392b7344e6b4e7b074d83e9ca5f563a8e072f",
"credential_id": "b89292aedf6d05d584cec9a871ce8735",

@ -1,6 +1,6 @@
{
"description": "time_and_key capsule for two known X25519 recipients and a portable .dkk",
"spec": "0.11",
"spec": "0.15",
"format": 1,
"file": "time_and_key_recipients.dkc",
"sha256": "69ac110380f5d768b5b6afaa157a50ed17d8ceccfbd4604ffa5b6da38539b635",

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save

Powered by TurnKey Linux.