]> Cypherpunks repositories - keks.git/commitdiff
Per pub id makes more sense
authorSergey Matveev <stargrave@stargrave.org>
Mon, 17 Feb 2025 15:49:27 +0000 (18:49 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Mon, 17 Feb 2025 16:34:52 +0000 (19:34 +0300)
go/cm/cmd/enctool/main.go
go/cm/cmd/enctool/prv-encrypted.t
go/cm/cmd/keytool/main.go
go/cm/enc/balloon/decap.go
go/cm/sign/pub.go
go/cm/sign/signed.go
spec/cm/pub-load.cddl
spec/cm/pub.texi

index 4910826b56905b0b7927e1e252ba7a9fedf8665cea29ce0c68dbd306b4a2a2ac..d3789f3e55ed8f7f5eca5c2505e5d30b7d3c3e51dc328a27238d592a5f89c339 100644 (file)
@@ -152,7 +152,8 @@ func main() {
        doDecrypt := flag.Bool("d", false, "Decrypt")
        parallel := flag.Int("parallel", runtime.NumCPU(), "Parallel cryptors")
        noblob := flag.Bool("no-stream", false, "Include payload into container")
-       var pubs []*sign.Pub
+       var pubs []cm.AV
+       var pubIds []uuid.UUID
        flag.Func("pub", "Path to public key to encrypt to", func(v string) error {
                signed, err := sign.PubParse(mustReadFile(v))
                if err != nil {
@@ -169,7 +170,8 @@ func main() {
                if len(load.Pub) != 1 {
                        return errors.New("expected single public key")
                }
-               pubs = append(pubs, &load.Pub[0])
+               pubs = append(pubs, load.Pub[0])
+               pubIds = append(pubIds, load.Id)
                return err
        })
        var prvs []*cm.AV
@@ -488,7 +490,7 @@ func main() {
                        }
                        kems = append(kems, kem)
                }
-               for _, pub := range pubs {
+               for pubId, pub := range pubs {
                        switch pub.A {
                        case sntrup4591761x25519.SNTRUP4591761X25519:
                                if len(pub.V) != sntrup4591761.PublicKeySize+32 {
@@ -554,7 +556,7 @@ func main() {
                                        kem.CEK = cekp.Bytes()
                                }
                                if *includeTo {
-                                       kem.To = &pub.Id
+                                       kem.To = &pubIds[pubId]
                                }
                                kems = append(kems, kem)
                        case mceliece6960119x25519.ClassicMcEliece6960119X25519:
@@ -622,7 +624,7 @@ func main() {
                                        kem.CEK = cekp.Bytes()
                                }
                                if *includeTo {
-                                       kem.To = &pub.Id
+                                       kem.To = &pubIds[pubId]
                                }
                                kems = append(kems, kem)
                        default:
index dc9ba92f34f1d9066ef39351abd4b50f43ec29bcd13440e9b619bdf816707a3c..a621ec7a2da7b89785625b84b046756efd8216e325568989c5b8469d50fe51dc 100755 (executable)
@@ -9,7 +9,7 @@ cmkeytool -algo sntrup4591761-x25519 -ku kem -subj A=KEY \
     -prv $TMPDIR/enc.prv -pub $TMPDIR/enc.pub
 dd if=/dev/urandom of=$TMPDIR/enc.data bs=12K count=1 2>/dev/null
 export ENCTOOL_PASSPHRASE=$(dd if=/dev/urandom bs=32 count=1 2>/dev/null | xxd -p)
-test_expect_success "key encrypting" "cmenctool -p -no-blob \
+test_expect_success "key encrypting" "cmenctool -p -no-stream \
     <$TMPDIR/enc.prv >$TMPDIR/enc.prv.enc"
 test_expect_success "data encrypting" "cmenctool -pub $TMPDIR/enc.pub \
     <$TMPDIR/enc.data >$TMPDIR/enc.enc"
index 1b74bfc09c14162851539e3a7718d8a00a1f393f457cbe6620c4156a3b6e853c..c82642880a3101fe5101132ed4618f8d9086b0888614944824d23ad36b6f3f76 100644 (file)
@@ -205,30 +205,26 @@ func main() {
                        }
                }
                {
-                       pubMap := sign.Pub{A: *algo, V: pub}
-                       {
-                               av := cm.AV{A: *algo, V: pub}
-                               var hasher hash.Hash
-                               switch av.A {
-                               case ed25519blake2b.Ed25519BLAKE2b, sntrup4591761x25519.SNTRUP4591761X25519:
-                                       hasher = cmhash.ByName(cmhash.BLAKE2b256)
-                               case gost.GOST3410256A, gost.GOST3410512C:
-                                       hasher = cmhash.ByName(cmhash.Streebog256)
-                               case mceliece6960119x25519.ClassicMcEliece6960119X25519:
-                                       hasher = cmhash.ByName(cmhash.SHAKE128)
-                               default:
-                                       log.Fatal("unsupported algorithm")
-                               }
-                               _, err = keks.Encode(hasher, av, nil)
-                               if err != nil {
-                                       log.Fatal(err)
-                               }
-                               pubMap.Id, err = uuid.NewRandomFromReader(bytes.NewReader(hasher.Sum(nil)))
-                               if err != nil {
-                                       log.Fatal(err)
-                               }
+                       pubLoad = &sign.PubLoad{Subj: subj, Pub: []cm.AV{{A: *algo, V: pub}}}
+                       var hasher hash.Hash
+                       switch *algo {
+                       case ed25519blake2b.Ed25519BLAKE2b, sntrup4591761x25519.SNTRUP4591761X25519:
+                               hasher = cmhash.ByName(cmhash.BLAKE2b256)
+                       case gost.GOST3410256A, gost.GOST3410512C:
+                               hasher = cmhash.ByName(cmhash.Streebog256)
+                       case mceliece6960119x25519.ClassicMcEliece6960119X25519:
+                               hasher = cmhash.ByName(cmhash.SHAKE128)
+                       default:
+                               log.Fatal("unsupported algorithm")
+                       }
+                       _, err = keks.Encode(hasher, pubLoad.Pub, nil)
+                       if err != nil {
+                               log.Fatal(err)
+                       }
+                       pubLoad.Id, err = uuid.NewRandomFromReader(bytes.NewReader(hasher.Sum(nil)))
+                       if err != nil {
+                               log.Fatal(err)
                        }
-                       pubLoad = &sign.PubLoad{Subj: subj, Pub: []sign.Pub{pubMap}}
                }
                if len(ku) > 0 {
                        pubLoad.KU = &ku
index 32a16da0314a2f1efd01c92b06de392175ca3cfa7270f0867ef81736c2eef6bb..b7ab13b0be6c2ba216b3fd17d8caf0883c55a48a8f8ec122cc68c0f94fa7e75c 100644 (file)
@@ -29,7 +29,7 @@ import (
 
 const (
        BalloonBLAKE2bHKDF = "balloon-blake2b-hkdf"
-       SaltLen            = 8
+       SaltLen            = 16
        HKDFInfo           = "keks/cm/encrypted/balloon-blake2b-hkdf"
 )
 
index 4b8a89b78fcc5e220d66b07b112c2db4e8112ac9defb0157815b78faa1294706..add13b425f3ee88b05fe53908561afbb5eb2dbbbdccf443577ca5dda8b8a017b 100644 (file)
@@ -25,6 +25,7 @@ import (
        "github.com/google/uuid"
 
        "go.cypherpunks.su/keks"
+       "go.cypherpunks.su/keks/cm"
        ed25519blake2b "go.cypherpunks.su/keks/cm/sign/ed25519-blake2b"
        "go.cypherpunks.su/keks/cm/sign/gost"
 )
@@ -40,19 +41,13 @@ var (
        ErrBadSigAlgo = errors.New("bad signature algo")
 )
 
-// Public key.
-type Pub struct {
-       A  string    `keks:"a"`
-       V  []byte    `keks:"v"`
-       Id uuid.UUID `keks:"id"`
-}
-
 // Public key load.
 type PubLoad struct {
        KU   *map[string]*struct{} `keks:"ku,omitempty"`
        Subj map[string]string     `keks:"sub"`
        Crit *[]map[string]any     `keks:"crit,omitempty"`
-       Pub  []Pub                 `keks:"pub"`
+       Pub  []cm.AV               `keks:"pub"`
+       Id   uuid.UUID             `keks:"id"`
 }
 
 // Parse Signed contents as PubLoad (certificate) and check its
@@ -109,8 +104,11 @@ func (signed *Signed) PubParse() error {
        if len(load.Pub) == 0 {
                return errors.New("PubParse: empty pub")
        }
+       if load.Id == uuid.Nil {
+               return errors.New("PubParse: empty id")
+       }
        for _, pub := range load.Pub {
-               if len(pub.A) == 0 || len(pub.V) == 0 || pub.Id == uuid.Nil {
+               if len(pub.A) == 0 || len(pub.V) == 0 {
                        return errors.New("PubParse: non-filled pub")
                }
        }
@@ -251,7 +249,7 @@ func (signed *Signed) CertificationCheckSignatureFrom(
                return
        }
        sig := signed.Sigs[0]
-       if sig.TBS.SID != parent.Pub[0].Id {
+       if sig.TBS.SID != parent.Id {
                err = errors.New("sid != parent pub id")
                return
        }
@@ -303,7 +301,7 @@ func (signed *Signed) CertificationVerify(pubs []*Signed, t time.Time) (err erro
                }
        }
        sid := signed.Sigs[0].TBS.SID
-       if sid == signed.PubLoad().Pub[0].Id {
+       if sid == signed.PubLoad().Id {
                return signed.CertificationCheckSignatureFrom(signed.PubLoad(), nil)
        }
        idToPub := make(map[uuid.UUID]*Signed, len(pubs))
@@ -313,7 +311,7 @@ func (signed *Signed) CertificationVerify(pubs []*Signed, t time.Time) (err erro
                        err = errors.New("pub can not sign")
                        return
                }
-               idToPub[pubLoad.Pub[0].Id] = cer
+               idToPub[pubLoad.Id] = cer
        }
        signer := idToPub[sid]
        if signer == nil {
index 18dc57bd316d6754276bbe11b3bc595219e103fb7ecfbb954188c985eacd38ef..361174e8994a74a6bc8dff90b287a29292a5be8f672083d14cc7692626964121 100644 (file)
@@ -123,7 +123,7 @@ func (signed *Signed) SignWith(parent *PubLoad, prv Iface, sigTBS SigTBS) (err e
        if !parent.Can(KUSig) || len(parent.Pub) != 1 {
                return errors.New("parent can not sign")
        }
-       sigTBS.SID = parent.Pub[0].Id
+       sigTBS.SID = parent.Id
        var tbs []byte
        if prv.Mode() == mode.Pure {
                var b bytes.Buffer
index 2c5edb60d514907d05add94602b1893e1e86cdfacc41a1aa4a110c98f67ef0db..fd3d96b4541ea894d6c5d2ba87732bde75d41d89da2f64bf0fa1fbac6af66b19 100644 (file)
@@ -3,7 +3,8 @@ av = {a: ai, v: bytes}
 
 cm-pub-load = {
     ? ku: set,
-    pub: [+ {av, id: uuid}],
+    id: uuid,
+    pub: [+ av],
     sub: {text => text}, ; subject
     ? crit: {+ crit-ext-type => any},
     * text => any
index 784c4b520d1b36bd1b93b44b02d6859d10be3394c2920127f3e494d72d27a2d4..7c00ce688e0f6408fe79d1b520cd4b8db81750e8141d824519d1f8daccdda508 100644 (file)
@@ -42,6 +42,11 @@ Each public key contain the key itself, its algorithm identifier and key
 identifier, that @strong{should} be generated as an UUIDv4 based on the
 hash of the key.
 
+@item id
+
+Public key(s)'s identifier @strong{should} be generated as an UUIDv4
+based on the hash of the encoded @code{pub} field.
+
 @item ku
 Intended public key(s) usage.
 Application-specific example with multiple public keys is described
@@ -73,15 +78,16 @@ datetime (no nanoseconds).
 
 @end table
 
-Example minimal public key may look like:
+Example minimal certified public key may look like:
 
 @verbatim
 {
     "load": {
         "t": "pub",
         "v": {
-            "pub": [{"a": "gost3410-256A", "v": 'pubkey', "id": UUID(hash(pub))}],
-            "sub": {"CN": "Test", "O": "Testers"},
+            "id": UUID(hash(pub)),
+            "pub": [{"a": "gost3410-256A", "v"}],
+            "sub": {"n": "test"},
         },
     },
     "sigs": [{