From 48f6143c390ce0014677dab6c569eecf0114171fd29e4ddb06985612ab3ec13e Mon Sep 17 00:00:00 2001 From: Sergey Matveev Date: Thu, 5 Jun 2025 16:01:19 +0300 Subject: [PATCH] Simplify cm/hashed --- go/cm/cmd/cmhshtool/main.go | 12 +++++---- go/cm/cmd/cmsigtool/main.go | 16 ++++++------ go/cm/hash/.gitignore | 1 + go/cm/hash/hash.go | 7 ----- go/cm/hash/prehash.go | 48 ++++++++++++++++++++++++++++++++++ go/cm/sign/signed.go | 5 ---- go/cm/utils/mk-bin | 6 ++++- spec/cm/hashed/index | 11 +++++--- spec/cm/signed/index | 3 ++- tcl/schemas/hashed.tcl | 9 +------ tcl/schemas/prehash.tcl | 4 +++ tcl/schemas/signed-prehash.tcl | 4 --- tcl/schemas/signed.tcl | 2 -- 13 files changed, 84 insertions(+), 44 deletions(-) create mode 100644 go/cm/hash/.gitignore delete mode 100644 go/cm/hash/hash.go create mode 100644 go/cm/hash/prehash.go create mode 100644 tcl/schemas/prehash.tcl delete mode 100644 tcl/schemas/signed-prehash.tcl diff --git a/go/cm/cmd/cmhshtool/main.go b/go/cm/cmd/cmhshtool/main.go index e4ddc5b..d8119ed 100644 --- a/go/cm/cmd/cmhshtool/main.go +++ b/go/cm/cmd/cmhshtool/main.go @@ -75,10 +75,12 @@ func main() { if err != nil { log.Fatal(err) } - s := cmhash.Hashed{ - Algo: []string{*algo}, - Typ: "data", - Hash: [][]byte{hasher.Sum(nil)}, + _, err = keks.Encode(os.Stdout, cmhash.Magic, nil) + if err != nil { + log.Fatal(err) + } + _, err = keks.Encode(os.Stdout, map[string][]byte{*algo: hasher.Sum(nil)}, nil) + if err != nil { + log.Fatal(err) } - keks.Encode(os.Stdout, s, nil) } diff --git a/go/cm/cmd/cmsigtool/main.go b/go/cm/cmd/cmsigtool/main.go index 81a48b8..af99ab0 100644 --- a/go/cm/cmd/cmsigtool/main.go +++ b/go/cm/cmd/cmsigtool/main.go @@ -104,17 +104,17 @@ func main() { if err != nil { log.Fatal(err) } - var prehash sign.Prehash - err = schema.Check("prehash", sign.SignedSchemas, v) + var prehash cmhash.Prehash + err = schema.Check("prehash", cmhash.PrehashSchemas, v) if err == nil { err = decoder.UnmarshalStruct(&prehash) } var signed sign.Signed hashers := make(map[string]hash.Hash) - if err == nil && prehash.T == mode.PrehashT { - dsts := make([]io.Writer, 0, len(prehash.Sigs)+1) + if err == nil && prehash.T == cmhash.PrehashT { + dsts := make([]io.Writer, 0, len(prehash.Algos)+1) dsts = append(dsts, os.Stdout) - for algo := range prehash.Sigs { + for algo := range prehash.Algos { hasher := cmhash.ByName(algo) if hasher == nil { log.Fatalln("prehash: unsupported algorithm:", algo) @@ -245,9 +245,9 @@ func main() { log.Fatal(err) } } else { - if _, err = keks.Encode(os.Stdout, sign.Prehash{ - T: mode.PrehashT, - Sigs: map[string]*struct{}{signer.Algo(): nil}, + if _, err = keks.Encode(os.Stdout, cmhash.Prehash{ + T: cmhash.PrehashT, + Algos: map[string]*struct{}{signer.Algo(): nil}, }, nil); err != nil { log.Fatal(err) } diff --git a/go/cm/hash/.gitignore b/go/cm/hash/.gitignore new file mode 100644 index 0000000..43d54db --- /dev/null +++ b/go/cm/hash/.gitignore @@ -0,0 +1 @@ +/prehash.schema.keks diff --git a/go/cm/hash/hash.go b/go/cm/hash/hash.go deleted file mode 100644 index 2491f4b..0000000 --- a/go/cm/hash/hash.go +++ /dev/null @@ -1,7 +0,0 @@ -package hash - -type Hashed struct { - Algo []string `keks:"a"` - Typ string `keks:"t"` - Hash [][]byte `keks:"hash"` -} diff --git a/go/cm/hash/prehash.go b/go/cm/hash/prehash.go new file mode 100644 index 0000000..bf52813 --- /dev/null +++ b/go/cm/hash/prehash.go @@ -0,0 +1,48 @@ +// GoKEKS/CM -- KEKS-encoded cryptographic messages +// Copyright (C) 2024-2025 Sergey Matveev +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, version 3 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this program. If not, see . + +package hash + +import ( + _ "embed" + + "go.cypherpunks.su/keks" + "go.cypherpunks.su/keks/schema" +) + +const PrehashT = "prehash" + +type Prehash struct { + T string `keks:"t"` + Algos map[string]*struct{} `keks:"algos"` +} + +//go:embed prehash.schema.keks +var PrehashSchemasRaw []byte + +var PrehashSchemas map[string][][]any + +func init() { + var magic keks.Magic + magic, PrehashSchemasRaw = keks.StripMagic(PrehashSchemasRaw) + if magic != schema.Magic { + panic("wrong magic in prehash.schema.keks") + } + if err := keks.NewDecoderFromBytes( + PrehashSchemasRaw, nil, + ).DecodeStruct(&PrehashSchemas); err != nil { + panic(err) + } +} diff --git a/go/cm/sign/signed.go b/go/cm/sign/signed.go index d5c03fb..1b7e41e 100644 --- a/go/cm/sign/signed.go +++ b/go/cm/sign/signed.go @@ -32,11 +32,6 @@ import ( const SignedMagic = keks.Magic("cm/signed") -type Prehash struct { - Sigs map[string]*struct{} `keks:"sigs"` - T string `keks:"t"` -} - type Load struct { V *any `keks:"v,omitempty"` T string `keks:"t"` diff --git a/go/cm/utils/mk-bin b/go/cm/utils/mk-bin index ee59438..027a422 100755 --- a/go/cm/utils/mk-bin +++ b/go/cm/utils/mk-bin @@ -8,7 +8,11 @@ GO_LDFLAGS="${GO_LDFLAGS:--s}" root="$(dirname "$(realpath -- "$0")")" cd "$root/.." -redo-ifchange sign/signed.schema.keks sign/pub.schema.keks enc/encrypted.schema.keks +redo-ifchange \ + enc/encrypted.schema.keks \ + hash/prehash.schema.keks \ + sign/pub.schema.keks \ + sign/signed.schema.keks mkdir -p bin for cmd in enc hsh key sig ; do cmd=cm${cmd}tool diff --git a/spec/cm/hashed/index b/spec/cm/hashed/index index fe01c5d..17db7aa 100644 --- a/spec/cm/hashed/index +++ b/spec/cm/hashed/index @@ -6,6 +6,11 @@ Stored in a file, it should begin with "cm/hashed" [encoding/MAGIC]. << [schemas/hashed.tcl] -"/a" tells what algorithms will be used to hash the data. -"/t" tells the type of the data inside. -"/hash" contains the hash values for all corresponding "/a" algorithms. +It is just a single map of algorithm identifiers with hashes. + +Hashed data is provided any way you wish. Consider using "prehash" +structure similarly as [cm/signed/] does: + +<< [schemas/prehash.tcl] + + prehash || BLOB(data) || cm/hashed diff --git a/spec/cm/signed/index b/spec/cm/signed/index index 48d6782..03a13a5 100644 --- a/spec/cm/signed/index +++ b/spec/cm/signed/index @@ -30,10 +30,11 @@ following approach: prehash || BLOB(detached-data) || cm/signed -<< [schemas/signed-prehash.tcl] +<< [schemas/prehash.tcl] With "prehash" you initialise your hashers used during signing process and feed BLOB's contents (not the encoded BLOB itself!) into the them. +prehash'es /algos must contain /sigs/*/sign/a identifiers: "/sigs/*/tbs/when" is optional signing time. diff --git a/tcl/schemas/hashed.tcl b/tcl/schemas/hashed.tcl index 1a10da8..7504f19 100644 --- a/tcl/schemas/hashed.tcl +++ b/tcl/schemas/hashed.tcl @@ -1,8 +1 @@ -ai {{field . {str} >0}} - -hashed { - {field a {list} {of ai} >0} - {field t {str} >0} - {field v {bin blob} optional} - {field hash {list} {of bin} >0} -} +hashed {{field . {map} {of bin} >0}} diff --git a/tcl/schemas/prehash.tcl b/tcl/schemas/prehash.tcl new file mode 100644 index 0000000..312b92c --- /dev/null +++ b/tcl/schemas/prehash.tcl @@ -0,0 +1,4 @@ +prehash { + {field t {str} =prehash} + {field algos {set} >0} {# set of hash algorithm identifiers} +} diff --git a/tcl/schemas/signed-prehash.tcl b/tcl/schemas/signed-prehash.tcl deleted file mode 100644 index 5170544..0000000 --- a/tcl/schemas/signed-prehash.tcl +++ /dev/null @@ -1,4 +0,0 @@ -prehash { - {field t {str} =prehash} - {field sigs {set} >0} {# set of /sigs/*/sign/a} -} diff --git a/tcl/schemas/signed.tcl b/tcl/schemas/signed.tcl index 8748d86..1d9160a 100644 --- a/tcl/schemas/signed.tcl +++ b/tcl/schemas/signed.tcl @@ -27,5 +27,3 @@ tbs { {# recipient's fingerprints} {field encrypted-to {list} {of fpr} >0 optional} } - -schema-include signed-prehash.tcl -- 2.50.0