From c341585dcbbc556be1d942a47bd3cb6658bb6e3daf333ce833d699ac092edbf2 Mon Sep 17 00:00:00 2001 From: Sergey Matveev Date: Sat, 27 Sep 2025 17:23:56 +0300 Subject: [PATCH] Separate /load into /data and /tbs That allows us to sign common additional tbs data and make no distinction between included and detached data. --- PUBKEY-CM.pub | Bin 206 -> 208 bytes PUBKEY-CM.pub.asc | 9 ++- c/lib/cm/pub.c | 41 ++++++---- c/lib/cm/pub.h | 4 +- go/cm/cmd/cmenctool/main.go | 10 +-- go/cm/cmd/cmkeytool/main.go | 18 ++--- go/cm/cmd/cmsigtool/main.go | 18 ++--- go/cm/sign/pub.go | 72 ++++++++++-------- go/cm/sign/signed.go | 36 +++++---- spec/cm/encrypted/authcrypt | 2 +- .../kem/mceliece6960119-x25519-hkdf-shake256 | 5 +- spec/cm/pub/index | 28 +++---- spec/cm/pub/mceliece6960119-x25519 | 4 +- spec/cm/signed/index | 6 +- spec/schema/tcl | 2 +- tcl/schemas/{pub-load.tcl => pub-data.tcl} | 2 +- tcl/schemas/pub.tcl | 10 +-- tcl/schemas/signed.tcl | 14 ++-- 18 files changed, 153 insertions(+), 128 deletions(-) rename tcl/schemas/{pub-load.tcl => pub-data.tcl} (94%) diff --git a/PUBKEY-CM.pub b/PUBKEY-CM.pub index 5e6bc0f10fb3397b40840454685fb1835bd809512f1bb5bac856757653ec75dc..015e8c7919c75d210f5bf9cf7b47c5dd67b048017d0ae17ae747e9388439944c 100644 GIT binary patch delta 42 scmX@dc!5#L+toWbIaj}+G>HKWI1iU36>}aeISdjxl9E`GI8lBb02#gxPyhe` delta 41 scmcb>c#cut+toWbIaj}+G>HKWIFIDyC#G;7EIAAmI#@PQX&oa201SQ&f&c&j diff --git a/PUBKEY-CM.pub.asc b/PUBKEY-CM.pub.asc index 45e9c40..5a3c330 100644 --- a/PUBKEY-CM.pub.asc +++ b/PUBKEY-CM.pub.asc @@ -1,7 +1,8 @@ -----BEGIN PGP SIGNATURE----- -iHUEABYKAB0WIQTbL/jtRAp+lJhvt3bSI36ECQhstwUCaGEDswAKCRDSI36ECQhs -twPcAPwLJuuTjhU3y6sSRNqr/69Q452vv1a2TWUNxTCyxCPd0wD/fWPvM/PxO8aW -lt/Yfko5vPVbnwFP/GczCzugHFGWZws= -=ydWw +iJEEABYKADkWIQTbL/jtRAp+lJhvt3bSI36ECQhstwUCaNf4oBsUgAAAAAAEAA5t +YW51MiwyLjUrMS4xMSwyLDMACgkQ0iN+hAkIbLcCQAEAzsCbtqjkxqxtKWuK5qYb +dDgrkPU2J7c4nq8OVnvLfXoBANcnFYroJtAKt3xQYO9I3My8vLBH68pkFHFj9WTR +sPIO +=HAQ6 -----END PGP SIGNATURE----- diff --git a/c/lib/cm/pub.c b/c/lib/cm/pub.c index 25b9601..678ff53 100644 --- a/c/lib/cm/pub.c +++ b/c/lib/cm/pub.c @@ -61,7 +61,7 @@ KEKSCMPubParse( (*failReason) = "schema failed"; return KEKSErrUnsatisfiedSchema; } - size_t idx = KEKSItemsGetByKey(items, KEKSItemsGetByKey(items, 0, "load"), "v"); + size_t idx = KEKSItemsGetByKey(items, 0, "data"); cer->pub = KEKSItemsGetByKey(items, idx, "pub"); cer->pub = items->list[cer->pub].atom.v.list.head; cer->sub = KEKSItemsGetByKey(items, idx, "sub"); @@ -74,7 +74,7 @@ KEKSCMPubParse( return KEKSErrNo; } if (items->list[idx].atom.v.list.len != 1) { - (*failReason) = "len(/load/sigs) != 1"; + (*failReason) = "len(/sigs) != 1"; return KEKSErrUnsatisfiedSchema; } cer->sig = items->list[idx].atom.v.list.head; @@ -154,24 +154,37 @@ KEKSCMPubVerify( size_t off = 0; if (!KEKSItemsEncode( &(cer->items), - KEKSItemsGetByKey(&(cer->items), 0, "load"), + KEKSItemsGetByKey(&(cer->items), 0, "data"), &off, buf, cap)) { - (*failReason) = "can not prepare tbs: load"; + (*failReason) = "can not prepare tbs: data"; return false; } - size_t off2 = 0; - if (!KEKSItemsEncode( - &(cer->items), - KEKSItemsGetByKey(&(cer->items), cer->sig, "tbs"), - &off2, - buf + off, - cap - off)) { - (*failReason) = "can not prepare tbs: tbs"; - return false; + { + size_t off2 = 0; + if (!KEKSItemsEncode( + &(cer->items), + KEKSItemsGetByKey(&(cer->items), 0, "tbs"), + &off2, + buf + off, + cap - off)) { + (*failReason) = "can not prepare tbs: tbs"; + return false; + } + off += off2; + off2 = 0; + if (!KEKSItemsEncode( + &(cer->items), + KEKSItemsGetByKey(&(cer->items), cer->sig, "tbs"), + &off2, + buf + off, + cap - off)) { + (*failReason) = "can not prepare tbs: sig-tbs"; + return false; + } + off += off2; } - off += off2; for (size_t i = 0; opts.sigVerifiers[i].algo != NULL; i++) { if (!KEKSStrEqual(&(pubA->atom), opts.sigVerifiers[i].algo)) { diff --git a/c/lib/cm/pub.h b/c/lib/cm/pub.h index ac831d0..50cfc51 100644 --- a/c/lib/cm/pub.h +++ b/c/lib/cm/pub.h @@ -15,9 +15,9 @@ // @item .items // Holds parsed @ref{KEKSItems} items. // @item .pub -// Items index of the first @code{/load/v/pub}, certificate's public key. +// Items index of the first @code{/data/pub}, certificate's public key. // @item .sub -// Items index of the @code{/load/v/sub}, certificate's subject. +// Items index of the @code{/data/sub}, certificate's subject. // @item .sig // Items index of the first @code{/sigs}, certificate's signature. // @item .cid diff --git a/go/cm/cmd/cmenctool/main.go b/go/cm/cmd/cmenctool/main.go index ed64e53..e0e5576 100644 --- a/go/cm/cmd/cmenctool/main.go +++ b/go/cm/cmd/cmenctool/main.go @@ -122,18 +122,18 @@ func main() { if err != nil { log.Fatalln("public key:", len(pubs), ":", err) } - load := signed.PubLoad() - if !load.Can(sign.KUKEM) { + pubData := signed.PubData() + if !pubData.Can(sign.KUKEM) { log.Println( "public key:", len(pubs), ": does not have", sign.KUKEM, "key usage", ) } - if len(load.Pub) != 1 { + if len(pubData.Pub) != 1 { log.Fatalln("public key:", len(pubs), ": expected single public key") } - pubs = append(pubs, load.Pub[0]) - pubIds = append(pubIds, load.Id) + pubs = append(pubs, pubData.Pub[0]) + pubIds = append(pubIds, pubData.Id) } } fdPubR.Close() diff --git a/go/cm/cmd/cmkeytool/main.go b/go/cm/cmd/cmkeytool/main.go index 545c391..8481ce9 100644 --- a/go/cm/cmd/cmkeytool/main.go +++ b/go/cm/cmd/cmkeytool/main.go @@ -166,9 +166,9 @@ func main() { } var prvRaw []byte - var pubLoad map[string]any + var pubData map[string]any if doCertify { - pubLoad = (*signed.Load.V).(map[string]any) + pubData = (*signed.Data).(map[string]any) } else { var pub []byte switch *algo { @@ -201,7 +201,7 @@ func main() { } } { - pubLoad = map[string]any{ + pubData = map[string]any{ "sub": sub, "pub": []cm.AV{{A: *algo, V: pub}}, } @@ -216,28 +216,28 @@ func main() { default: log.Fatal("unsupported algorithm") } - _, err = keks.Encode(hasher, pubLoad["pub"], nil) + _, err = keks.Encode(hasher, pubData["pub"], nil) if err != nil { log.Fatal(err) } - pubLoad["id"] = hasher.Sum(nil) + pubData["id"] = hasher.Sum(nil) if err != nil { log.Fatal(err) } } if len(ku) > 0 { - pubLoad["ku"] = ku + pubData["ku"] = ku } } { - pubLoadAny := any(pubLoad) - signed = &sign.Signed{Load: sign.Load{T: "pub", V: &pubLoadAny}} + pubLoadAny := any(pubData) + signed = &sign.Signed{TBS: sign.SDTBS{T: "pub"}, Data: &pubLoadAny} } if doCertify { if err = signed.CertifyWith( - caPubs[0].PubLoad(), caPrv, since, till, + caPubs[0].PubData(), caPrv, since, till, ); err != nil { log.Fatal(err) } diff --git a/go/cm/cmd/cmsigtool/main.go b/go/cm/cmd/cmsigtool/main.go index af99ab0..c0ef13d 100644 --- a/go/cm/cmd/cmsigtool/main.go +++ b/go/cm/cmd/cmsigtool/main.go @@ -72,7 +72,7 @@ func main() { fdPubR := os.NewFile(FdPubR, "pub-in") fdPrvR := os.NewFile(FdPrvR, "prv-in") - var pubs []*sign.PubLoad + var pubs []*sign.PubData var err error { data := mustReadAll(fdPubR) @@ -82,7 +82,7 @@ func main() { if err != nil { log.Fatal(err) } - pubs = append(pubs, signed.PubLoad()) + pubs = append(pubs, signed.PubData()) } fdPubR.Close() } @@ -155,8 +155,8 @@ func main() { if err != nil { log.Fatal(err) } - if signed.Load.T != *typ { - log.Fatalln("differing load type:", signed.Load.T) + if signed.TBS.T != *typ { + log.Fatalln("differing load type:", signed.TBS.T) } for _, sig := range signed.Sigs { sid := sig.TBS["sid"].([]byte) @@ -166,17 +166,17 @@ func main() { continue } signerFound = true - var tbs *sign.TBS - tbs, err = sig.TBSGet() + var sigTBS *sign.SigTBS + sigTBS, err = sig.TBSGet() if err != nil { log.Fatal(err) } if len(encryptedTo) > 0 { - if len(tbs.EncryptedTo) == 0 { + if len(sigTBS.EncryptedTo) == 0 { log.Fatalln(hex.EncodeToString(sid), "missing encrypted-to") } found := false - for _, their := range tbs.EncryptedTo { + for _, their := range sigTBS.EncryptedTo { for _, our := range encryptedTo { if bytes.Equal(our, their) { found = true @@ -268,7 +268,7 @@ func main() { } } var signed sign.Signed - signed.Load.T = *typ + signed.TBS.T = *typ tbs := make(map[string]any) if !*noWhen { tbs["when"] = time.Now().UTC().Truncate(time.Millisecond) diff --git a/go/cm/sign/pub.go b/go/cm/sign/pub.go index 898b6a5..fedc13d 100644 --- a/go/cm/sign/pub.go +++ b/go/cm/sign/pub.go @@ -45,8 +45,8 @@ var ( ErrBadSigAlgo = errors.New("bad signature algo") ) -// Public key load. -type PubLoad struct { +// Public key' contents. +type PubData struct { KU map[string]*struct{} `keks:"ku"` Sub map[string]string `keks:"sub"` Crit []map[string]any `keks:"crit"` @@ -54,7 +54,7 @@ type PubLoad struct { Id []byte `keks:"id"` } -// Parse KEKS-encoded data as Signed with the PubLoad (certificate) contents. +// Parse KEKS-encoded data as Signed with the PubData (certificate) contents. func PubParse(data []byte) (signed *Signed, tail []byte, err error) { { var magic keks.Magic @@ -84,23 +84,23 @@ func PubParse(data []byte) (signed *Signed, tail []byte, err error) { } tail = d.B signed = &sd - if sd.Load.T != "pub" { + if sd.TBS.T != "pub" { err = errors.New("PubParse: wrong load type") } return } // Check if public key has desired ku capability. -func (pub *PubLoad) Can(ku string) (yes bool) { +func (pub *PubData) Can(ku string) (yes bool) { _, yes = pub.KU[ku] return } -// Sign the provided Signed, having PubLoad payload with the provided -// parent's PubLoad and prv key. Certification CID will be automatically +// Sign the provided Signed, having PubData payload with the provided +// parent's PubData and prv key. Certification CID will be automatically // generated UUIDv7. since and till times must not have nanoseconds part. func (signed *Signed) CertifyWith( - parent *PubLoad, + parent *PubData, prv Iface, since, till time.Time, ) error { @@ -116,7 +116,7 @@ func (signed *Signed) CertifyWith( // Verify signature of signed data. ErrSigInvalid will be returned in // case of invalid signature. -func (pub *PubLoad) CheckSignature(algo string, signed, signature []byte) (err error) { +func (pub *PubData) CheckSignature(algo string, signed, signature []byte) (err error) { if !pub.Can(KUSig) || len(pub.Pub) != 1 { err = errors.New("pub can not sign") return @@ -156,7 +156,7 @@ func (pub *PubLoad) CheckSignature(algo string, signed, signature []byte) (err e // Verify signature of signed data, by providing prehashed data. // ErrSigInvalid will be returned in case of invalid signature. -func (pub *PubLoad) CheckSignaturePrehash( +func (pub *PubData) CheckSignaturePrehash( algo string, prehash, signature []byte, ) (err error) { @@ -208,11 +208,11 @@ func (pub *PubLoad) CheckSignaturePrehash( return } -// Verify Signed PubLoad certification signature with provided parent. +// Verify Signed PubData certification signature with provided parent. // If prehasher is specified, then prehashed signature mode is used. // Currently only single signature can be verified. func (signed *Signed) CertificationCheckSignatureFrom( - parent *PubLoad, + parent *PubData, prehasher *hash.Hash, ) (err error) { if !parent.Can(KUSig) || len(parent.Pub) != 1 { @@ -225,7 +225,10 @@ func (signed *Signed) CertificationCheckSignatureFrom( } if prehasher == nil { var tbs bytes.Buffer - if _, err = keks.Encode(&tbs, signed.Load, nil); err != nil { + if _, err = keks.Encode(&tbs, signed.Data, nil); err != nil { + return + } + if _, err = keks.Encode(&tbs, signed.TBS, nil); err != nil { return } if _, err = keks.Encode(&tbs, sig.TBS, nil); err != nil { @@ -233,7 +236,10 @@ func (signed *Signed) CertificationCheckSignatureFrom( } return parent.CheckSignature(sig.Sign.A, tbs.Bytes(), sig.Sign.V) } else { - if _, err = keks.Encode(*prehasher, signed.Load, nil); err != nil { + if _, err = keks.Encode(*prehasher, signed.Data, nil); err != nil { + return + } + if _, err = keks.Encode(*prehasher, signed.TBS, nil); err != nil { return } if _, err = keks.Encode(*prehasher, sig.TBS, nil); err != nil { @@ -246,38 +252,38 @@ func (signed *Signed) CertificationCheckSignatureFrom( return errors.New("can not find necessary sid") } -// Get PubLoad from Signed. +// Get PubData from Signed. // Returns nil if Signed does not hold it (or it is not yet parsed). -func (signed *Signed) PubLoad() *PubLoad { - if signed.Load.T != "pub" || signed.Load.V == nil { +func (signed *Signed) PubData() *PubData { + if signed.TBS.T != "pub" || signed.Data == nil { return nil } - v, ok := (*signed.Load.V).(map[string]any) + v, ok := (*signed.Data).(map[string]any) if !ok { return nil } - var pubLoad PubLoad - err := keks.Map2Struct(&pubLoad, v) + var pubData PubData + err := keks.Map2Struct(&pubData, v) if err != nil { return nil } - return &pubLoad + return &pubData } -// Verify signed Signed PubLoad certification against pubs chain of +// Verify signed Signed PubData certification against pubs chain of // public keys at specified point of time t. func (signed *Signed) CertificationVerify(pubs []*Signed, t time.Time) (err error) { if len(signed.Sigs) == 0 { return errors.New("no sigs") } - var tbs *TBS - tbs, err = signed.Sigs[0].TBSGet() + var sigTBS *SigTBS + sigTBS, err = signed.Sigs[0].TBSGet() if err != nil { return } { - exp := tbs.Exp + exp := sigTBS.Exp if t.Before(exp[0]) || t.Equal(exp[0]) { err = errors.New("pub is not active") return @@ -287,26 +293,26 @@ func (signed *Signed) CertificationVerify(pubs []*Signed, t time.Time) (err erro return } } - sid := tbs.SID - if bytes.Equal(sid, signed.PubLoad().Id) { - return signed.CertificationCheckSignatureFrom(signed.PubLoad(), nil) + sid := sigTBS.SID + if bytes.Equal(sid, signed.PubData().Id) { + return signed.CertificationCheckSignatureFrom(signed.PubData(), nil) } type FPR [FPRLen]byte idToPub := make(map[FPR]*Signed, len(pubs)) for _, cer := range pubs { - pubLoad := cer.PubLoad() - if !pubLoad.Can(KUSig) || len(pubLoad.Pub) != 1 { + pubData := cer.PubData() + if !pubData.Can(KUSig) || len(pubData.Pub) != 1 { err = errors.New("pub can not sign") return } - idToPub[FPR(pubLoad.Id)] = cer + idToPub[FPR(pubData.Id)] = cer } signer := idToPub[FPR(sid)] if signer == nil { - err = fmt.Errorf("no pub found for sid: %v", tbs.SID) + err = fmt.Errorf("no pub found for sid: %v", sigTBS.SID) return } - err = signed.CertificationCheckSignatureFrom(signer.PubLoad(), nil) + err = signed.CertificationCheckSignatureFrom(signer.PubData(), nil) if err != nil { return } diff --git a/go/cm/sign/signed.go b/go/cm/sign/signed.go index 8a41b3a..9997d84 100644 --- a/go/cm/sign/signed.go +++ b/go/cm/sign/signed.go @@ -32,20 +32,19 @@ import ( const SignedMagic = keks.Magic("cm/signed") -type Load struct { - V *any `keks:"v,omitempty"` +type SDTBS struct { T string `keks:"t"` } -type TBS struct { +type SigTBS struct { EncryptedTo [][]byte `keks:"encrypted-to"` Exp []time.Time `keks:"exp"` SID []byte `keks:"sid"` CID uuid.UUID `keks:"cid"` } -func (sig *Sig) TBSGet() (*TBS, error) { - var tbs TBS +func (sig *Sig) TBSGet() (*SigTBS, error) { + var tbs SigTBS return &tbs, keks.Map2Struct(&tbs, sig.TBS) } @@ -55,7 +54,8 @@ type Sig struct { } type Signed struct { - Load Load `keks:"load"` + TBS SDTBS `keks:"tbs"` + Data *any `keks:"data,omitempty"` Pubs *[]*Signed `keks:"pubs,omitempty"` Sigs []*Sig `keks:"sigs,omitempty"` } @@ -93,38 +93,44 @@ func Parse(data []byte) (signed *Signed, tail []byte, err error) { return } -// Sign Signed's contents and tbs corresponding data with the +// Sign Signed's contents and sig-tbs corresponding data with the // provided prv signer, having parent certififer. Signature is // appended to the signed.Sigs. parent must have "sig" key-usage. func (signed *Signed) SignWith( - parent *PubLoad, + parent *PubData, prv Iface, - tbs map[string]any, + sigTBS map[string]any, ) (err error) { if !parent.Can(KUSig) || len(parent.Pub) != 1 { return errors.New("parent can not sign") } - tbs["sid"] = parent.Id + sigTBS["sid"] = parent.Id var tbsRaw []byte if prv.Mode() == mode.Pure { var b bytes.Buffer - if _, err = keks.Encode(&b, signed.Load, nil); err != nil { + if _, err = keks.Encode(&b, signed.Data, nil); err != nil { return } - if _, err = keks.Encode(&b, tbs, nil); err != nil { + if _, err = keks.Encode(&b, signed.TBS, nil); err != nil { + return + } + if _, err = keks.Encode(&b, sigTBS, nil); err != nil { return } tbsRaw = b.Bytes() } else { - if _, err = keks.Encode(*prv.Prehasher(), signed.Load, nil); err != nil { + if _, err = keks.Encode(*prv.Prehasher(), signed.Data, nil); err != nil { + return + } + if _, err = keks.Encode(*prv.Prehasher(), signed.TBS, nil); err != nil { return } - if _, err = keks.Encode(*prv.Prehasher(), tbs, nil); err != nil { + if _, err = keks.Encode(*prv.Prehasher(), sigTBS, nil); err != nil { return } tbsRaw = (*prv.Prehasher()).Sum(nil) } - sig := Sig{TBS: tbs} + sig := Sig{TBS: sigTBS} sig.Sign.A = prv.Algo() sig.Sign.V, err = prv.Sign(rand.Reader, tbsRaw, crypto.Hash(0)) if err != nil { diff --git a/spec/cm/encrypted/authcrypt b/spec/cm/encrypted/authcrypt index 047fb0f..67034d8 100644 --- a/spec/cm/encrypted/authcrypt +++ b/spec/cm/encrypted/authcrypt @@ -1,6 +1,6 @@ Public-key based [cm/kem/]s provides sender authentication *only* if "/kem/*/from" field is specified. It should contain public -key's "/load/v/id", but may be equal to 256-bit zeros, to explicitly +key's "/data/id", but may be equal to 256-bit zeros, to explicitly specify that sender's public key is used, but it is anonymous and hidden. It is not specified how recipient should find corresponding sender's key that way -- implementation/protocol specific. diff --git a/spec/cm/kem/mceliece6960119-x25519-hkdf-shake256 b/spec/cm/kem/mceliece6960119-x25519-hkdf-shake256 index 9436d2f..c0a2e90 100644 --- a/spec/cm/kem/mceliece6960119-x25519-hkdf-shake256 +++ b/spec/cm/kem/mceliece6960119-x25519-hkdf-shake256 @@ -56,6 +56,5 @@ X25519 public key, computes shared secrets, combines them and derives KEK. KEM combiner nearly fully resembles: => https://datatracker.ietf.org/doc/draft-josefsson-chempat/ Chempat -If sender/recipient's public key structure contains -"/load/v/prehash" field, then it could be used as already -calculated values of SHAKE256 calls of PRK. +If sender/recipient's public key structure contains "/data/prehash" field, +then it could be used as already calculated values of SHAKE256 calls of PRK. diff --git a/spec/cm/pub/index b/spec/cm/pub/index index ec16a97..ea0e0ca 100644 --- a/spec/cm/pub/index +++ b/spec/cm/pub/index @@ -2,9 +2,9 @@ do-backs Public key is the [cm/signed/] structure. Stored in a file, it should begin with "cm/pub" [encoding/MAGIC]. -Its "/load/t" equals to "pub". "/load/v" contains "cm/pub/load": +Its "/tbs/t" equals to "pub". "/data" contains: -<< [schemas/pub-load.tcl] +<< [schemas/pub-data.tcl] sub: Subject is a map of arbitrary strings. Currently no constraints on @@ -32,7 +32,7 @@ ku: above. It *must* be absent if empty. crit: Optional critical (in terms of X.509) extensions. Non-critical - ones may be placed outside that map, directly in cm/pub/load. + ones may be placed outside that map, directly in /data. It *must* be absent if empty. Values are extension specific. [cm/signed/]'s "tbs" *must* contain additional fields: @@ -48,20 +48,20 @@ Example minimal certified public key may look like: MAGIC cm/pub MAP { - load {MAP { + tbs {MAP { t {STR pub} - v {MAP { - id {BIN "6aee..."} - pub {LIST { - {MAP { - a {STR ed25519-blake2b} - v {BIN "c1bf..."} - }} - }} - sub {MAP { - N {STR test} + }} + data {MAP { + id {BIN "6aee..."} + pub {LIST { + {MAP { + a {STR ed25519-blake2b} + v {BIN "c1bf..."} }} }} + sub {MAP { + N {STR test} + }} }} sigs {LIST { {MAP { diff --git a/spec/cm/pub/mceliece6960119-x25519 b/spec/cm/pub/mceliece6960119-x25519 index 68599cf..fd38517 100644 --- a/spec/cm/pub/mceliece6960119-x25519 +++ b/spec/cm/pub/mceliece6960119-x25519 @@ -12,7 +12,7 @@ mceliece6960119 public key and 32-byte X25519 one. Public key's fingerprint should be calculated using SHAKE128. => https://keccak.team/ SHAKE XOF function -Optional "/load/v/prehash" field can contain the SHAKE256 hash -of the concatenated public keys in "/load/v/pub/0", that could +Optional "/data/prehash" field can contain the SHAKE256 hash +of the concatenated public keys in "/data/pub/0", that could save resources during [cm/kem/mceliece6960119-x25519-hkdf-shake256] KDF calculations. diff --git a/spec/cm/signed/index b/spec/cm/signed/index index 52ba038..a172be6 100644 --- a/spec/cm/signed/index +++ b/spec/cm/signed/index @@ -20,15 +20,15 @@ unless it is a [cm/pub/]lic key. Signature is created by signing the: - [detached-data] || /load || /sig/./tbs + data || /tbs || /sig/./tbs -If no "/load/v" is provided, then the data is detached from the +If no "/data" is provided, then the data is detached from the "cm/signed" structure itself and is fed into hasher before that structure. You can provide it any way you wish, but for keeping that detached data closely to the "cm/signed", you should use the following approach: - prehash || BLOB(detached-data) || cm/signed + prehash || BLOB(data) || cm/signed << [schemas/prehash.tcl] diff --git a/spec/schema/tcl b/spec/schema/tcl index 01d28bc..a664a4c 100644 --- a/spec/schema/tcl +++ b/spec/schema/tcl @@ -30,7 +30,7 @@ And [cm/pub/] as: << [schemas/pub.tcl] << [schemas/fpr.tcl] -<< [schemas/pub-load.tcl] +<< [schemas/pub-data.tcl] << [schemas/pub-sig-tbs.tcl] schema.tcl calls "schemas {s0 cmds0 s1 cmds1 ...}" command to produce diff --git a/tcl/schemas/pub-load.tcl b/tcl/schemas/pub-data.tcl similarity index 94% rename from tcl/schemas/pub-load.tcl rename to tcl/schemas/pub-data.tcl index dbc7d8f..3bdfcf1 100644 --- a/tcl/schemas/pub-load.tcl +++ b/tcl/schemas/pub-data.tcl @@ -1,4 +1,4 @@ -pub-load { +pub-data { {field . {map}} {field id {with fpr}} {field crit {} !exists} diff --git a/tcl/schemas/pub.tcl b/tcl/schemas/pub.tcl index 6e1c0ef..f2ca6d9 100644 --- a/tcl/schemas/pub.tcl +++ b/tcl/schemas/pub.tcl @@ -1,14 +1,14 @@ pub { {field . {map}} - {field load {with load}} - {field sigs {list} {of sig} >0 optional} + {field tbs {with tbs}} + {field data {with pub-data}} {field pubs {list} {of pub} >0 optional} + {field sigs {list} {of sig} >0 optional} } -load { +tbs { {field . {map}} {field t {str} =pub} - {field v {with pub-load}} } av { @@ -24,5 +24,5 @@ sig { } schema-include fpr.tcl -schema-include pub-load.tcl +schema-include pub-data.tcl schema-include pub-sig-tbs.tcl diff --git a/tcl/schemas/signed.tcl b/tcl/schemas/signed.tcl index 3ff6548..0edbb4a 100644 --- a/tcl/schemas/signed.tcl +++ b/tcl/schemas/signed.tcl @@ -3,24 +3,24 @@ schema-include fpr.tcl signed { {field . {map}} - {field load {with load}} - {field sigs {list} {of sig} >0 optional} + {field tbs {with tbs}} + {# field data is optional, arbitrary type} {field pubs {list} {of type map} >0 optional} + {field sigs {list} {of sig} >0 optional} } -load { +tbs { {field . {map}} - {field t {str} >0} - {# field v is optional, arbitrary type} + {field t {str} >0} {# type of the data we sign} } sig { {field . {map}} - {field tbs {with tbs}} + {field tbs {with sig-tbs}} {field sign {with av}} } -tbs { +sig-tbs { {field . {map}} {field sid {with fpr}} {field nonce {bin} >0 optional} {# random bytes} -- 2.51.0