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)
}
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)
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)
}
--- /dev/null
+/prehash.schema.keks
+++ /dev/null
-package hash
-
-type Hashed struct {
- Algo []string `keks:"a"`
- Typ string `keks:"t"`
- Hash [][]byte `keks:"hash"`
-}
--- /dev/null
+// GoKEKS/CM -- KEKS-encoded cryptographic messages
+// Copyright (C) 2024-2025 Sergey Matveev <stargrave@stargrave.org>
+//
+// 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 <http://www.gnu.org/licenses/>.
+
+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)
+ }
+}
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"`
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
<< [schemas/hashed.tcl]\r
-"/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]\r
+
+ prehash || BLOB(data) || cm/hashed
prehash || BLOB(detached-data) || cm/signed
-<< [schemas/signed-prehash.tcl]\r
+<< [schemas/prehash.tcl]\r
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.
-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}}
--- /dev/null
+prehash {
+ {field t {str} =prehash}
+ {field algos {set} >0} {# set of hash algorithm identifiers}
+}
+++ /dev/null
-prehash {
- {field t {str} =prehash}
- {field sigs {set} >0} {# set of /sigs/*/sign/a}
-}
{# recipient's fingerprints}
{field encrypted-to {list} {of fpr} >0 optional}
}
-
-schema-include signed-prehash.tcl