What the official SDK says when it seals: the recovery annex, §7.6 and §71
The SHOULDs of the official SDK that the CLI did not follow yet. encrypt
writes next to the .dkc the recovery annex, FILE.dkc.recuperacion.txt
(spec §62.1, rule 27): datekeys.RecoveryAnnex, annex/recovery.md, which is
§79 of the specification under a title with its version and SHA-256, the
same for every capsule; TestRecoveryAnnex checks it against the text of
SpecVersion. -no-recovery leaves it out. encrypt also says what opening the
capsule years later will take (rule 26): the .dkc, a credential of a
time_and_key capsule, and the release of its round, which an archive of
releases or a cache service must keep if drand no longer serves it; and
beyond one year it recommends time_and_key to a time_only capsule (§7.6).
profile.Status and StatusOf give the state of a pinned profile in the
registry of §71, which DateKeys does not publish yet: Quicknet is active.
encrypt writes no capsule with a profile that is not active, and decrypt
and inspect warn when the profile of a capsule is compromised.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
8 hours ago
package datekeys
import (
"crypto/sha256"
"fmt"
"os"
"strings"
"testing"
)
// recoveryAnnex is the text of RecoveryAnnex for the specification spec:
// 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.
func recoveryAnnex ( spec [ ] byte ) ( string , error ) {
text := string ( spec )
i := strings . Index ( text , "\n## 79. " )
if i < 0 {
return "" , fmt . Errorf ( "the specification %s has no §79" , SpecVersion )
}
return fmt . Sprintf ( "# 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%s, cuyo texto tiene el SHA-256 %x. Es el mismo para toda cápsula: no lleva ningún dato de esta. " +
"Su licencia es CC BY-ND 4.0, Atribución-SinDerivadas 4.0 Internacional " +
"(https://creativecommons.org/licenses/by-nd/4.0/deed.es): se puede copiar y compartir sin cambios, citando su origen.\n\n%s\n" ,
What the official SDK says when it seals: the recovery annex, §7.6 and §71
The SHOULDs of the official SDK that the CLI did not follow yet. encrypt
writes next to the .dkc the recovery annex, FILE.dkc.recuperacion.txt
(spec §62.1, rule 27): datekeys.RecoveryAnnex, annex/recovery.md, which is
§79 of the specification under a title with its version and SHA-256, the
same for every capsule; TestRecoveryAnnex checks it against the text of
SpecVersion. -no-recovery leaves it out. encrypt also says what opening the
capsule years later will take (rule 26): the .dkc, a credential of a
time_and_key capsule, and the release of its round, which an archive of
releases or a cache service must keep if drand no longer serves it; and
beyond one year it recommends time_and_key to a time_only capsule (§7.6).
profile.Status and StatusOf give the state of a pinned profile in the
registry of §71, which DateKeys does not publish yet: Quicknet is active.
encrypt writes no capsule with a profile that is not active, and decrypt
and inspect warn when the profile of a capsule is compromised.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
8 hours ago
SpecVersion , sha256 . Sum256 ( spec ) , strings . TrimRight ( text [ i + 1 : ] , " \n" ) ) , nil
}
func TestRecoveryAnnex ( t * testing . T ) {
spec , err := os . ReadFile ( "spec/DateKeys_Protocol_Specification_v" + SpecVersion + ".md" )
if err != nil {
t . Fatal ( err )
}
want , err := recoveryAnnex ( spec )
if err != nil {
t . Fatal ( err )
}
if os . Getenv ( "DATEKEYS_WRITE_ANNEX" ) == "1" {
if err := os . WriteFile ( "annex/recovery.md" , [ ] byte ( want ) , 0 o644 ) ; err != nil {
t . Fatal ( err )
}
t . Skip ( "wrote annex/recovery.md; build the package again to embed it" )
}
if RecoveryAnnex != want {
t . Fatalf ( "annex/recovery.md is not §79 of the specification %s: write it again with DATEKEYS_WRITE_ANNEX=1 go test -run TestRecoveryAnnex ." , SpecVersion )
}
for _ , s := range [ ] string { "## 79. Anexo informativo: recuperación sin software DateKeys" , "### 79.8 Lo que el anexo no comprueba" , "DateKeys v" + SpecVersion + "," } {
if ! strings . Contains ( RecoveryAnnex , s ) {
t . Errorf ( "the annex lacks %q" , s )
}
}
if ! strings . HasSuffix ( RecoveryAnnex , "conforme.\n" ) || strings . Contains ( RecoveryAnnex , "\r" ) {
t . Errorf ( "the annex ends with %q" , RecoveryAnnex [ len ( RecoveryAnnex ) - 20 : ] )
}
}