PUBKEY-CM.pub.asc | 10 +++++----- c/lib/cm/pub.c | 1 - c/lib/cm/pub.h | 2 +- go/cm/.gitignore | 2 +- go/cm/ai/enc.go | 9 +++++++++ go/cm/ai/hash.go | 16 ++++++++++++++++ go/cm/ai/sign.go | 14 ++++++++++++++ go/cm/cmd/cmenctool/main.go | 97 +++++++++++++++++++++-------------------------------- go/cm/cmd/cmhshtool/main.go | 27 ++++++++++++++------------- go/cm/cmd/cmkeytool/main.go | 65 ++++++++++++++++++++++++++++------------------------- go/cm/cmd/cmsigtool/main.go | 14 +++++++++++--- go/cm/enc/balloon/decap.go | 5 ++--- go/cm/enc/balloon/possible.go | 3 ++- go/cm/enc/mceliece6960119-x25519/algo.go | 6 ------ go/cm/enc/mk-schemas | 3 +++ go/cm/enc/sntrup761-x25519/algo.go | 6 ------ go/cm/hash/algo.go | 37 ++++++++++++------------------------- go/cm/hash/blake2b/algo.go | 7 ------- go/cm/hash/gost/algo.go | 8 -------- go/cm/hash/mk-schemas | 3 +++ go/cm/hash/shake.go | 9 --------- go/cm/prv/.gitignore | 1 + go/cm/prv/mk-schemas | 3 +++ go/cm/prv/prv.go | 40 ++++++++++++++++++++++++++++++++++++++++ go/cm/prv/schemas.go | 24 ++++++++++++++++++++++++ go/cm/sign/.gitignore | 3 +-- go/cm/sign/cert.go | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++++ go/cm/sign/ed25519-blake2b/algo.go | 7 ------- go/cm/sign/ed25519-blake2b/signer.go | 7 ++++--- go/cm/sign/gost/gost.go | 12 +++--------- go/cm/sign/gost/kp.go | 7 ++++--- go/cm/sign/gost/signer.go | 9 +++++---- go/cm/sign/gost/verify.go | 5 +++-- go/cm/sign/mk-schemas | 3 +++ go/cm/sign/prv.go | 57 +++++++++++------------------------------------------ go/cm/sign/pub.go | 205 +++++++++++------------------------------------------ go/cm/sign/schema.go | 19 ++----------------- go/cm/sign/signed.go | 23 ++++++++++------------- go/cm/sign/slhdsa/kp.go | 8 +------- go/cm/sign/slhdsa/signer.go | 7 ++++--- go/cm/sign/storage.go | 5 ----- go/cm/utils/mk-bin | 13 +++++++------ spec/cm/prv/ed25519-blake2b | 6 +++--- spec/cm/prv/gost3410 | 3 ++- spec/cm/prv/mceliece6960119-x25519 | 6 +++--- spec/cm/prv/slh-dsa-shake-256s | 4 ++-- spec/cm/prv/sntrup761-x25519 | 5 +++-- spec/cm/pub/ed25519-blake2b | 5 +++-- spec/cm/pub/gost3410 | 4 +++- spec/cm/pub/index | 19 ++++--------------- spec/cm/pub/mceliece6960119-x25519 | 3 +++ spec/cm/pub/slh-dsa-shake-256s | 4 +++- spec/cm/pub/sntrup761-x25519 | 7 +++---- spec/cm/signed/ed25519-blake2b | 4 ++++ spec/cm/signed/ed25519ph-blake2b-merkle | 4 ++++ spec/cm/signed/gost3410 | 4 +++- spec/cm/signed/gost3410-merkle | 5 +++-- spec/cm/signed/slh-dsa-shake-256s | 7 +++---- spec/cm/signed/slh-dsa-shake-256s-merkle | 4 +++- tcl/schemas/prv-all.tcl | 6 ++++++ tcl/schemas/prv-ed25519-blake2b.tcl | 5 +++++ tcl/schemas/prv-gost3410.tcl | 11 +++++++++++ tcl/schemas/prv-mceliece6960119-x25519.tcl | 5 +++++ tcl/schemas/prv-slh-dsa-shake-256s.tcl | 5 +++++ tcl/schemas/prv-sntrup761-x25519.tcl | 5 +++++ tcl/schemas/pub-all.tcl | 6 ++++++ tcl/schemas/pub-data.tcl | 2 +- tcl/schemas/pub-ed25519-blake2b.tcl | 5 +++++ tcl/schemas/pub-gost3410.tcl | 11 +++++++++++ tcl/schemas/pub-mceliece6960119-x25519.tcl | 5 +++++ tcl/schemas/pub-slh-dsa-shake-256s.tcl | 5 +++++ tcl/schemas/pub-sntrup761-x25519.tcl | 5 +++++ tcl/schemas/pub.tcl | 7 +------ tcl/schemas/sign-ed25519-blake2b.tcl | 17 +++++++++++++++++ tcl/schemas/sign-gost3410.tcl | 23 +++++++++++++++++++++++ tcl/schemas/sign-slh-dsa-shake-256s.tcl | 17 +++++++++++++++++ diff --git a/PUBKEY-CM.pub b/PUBKEY-CM.pub index 87a73debeb5f4738b6255fca4ec74569c7605ace4957ea80429fee7ccae0d61e..1290a62160c3aee31ca3494ffded07db6389e73d1e903f959ddc91d689e2ab16 100644 Binary files a/PUBKEY-CM.pub and b/PUBKEY-CM.pub differ diff --git a/PUBKEY-CM.pub.asc b/PUBKEY-CM.pub.asc index 924d0d3dd889b0eee2590d5d58c9dbb8b56dfe6d8fe50ec618934972fa6e82be..7436a92b933542804023752ac775db194b8bd9ad660f70a64f25150436a2338e 100644 --- a/PUBKEY-CM.pub.asc +++ b/PUBKEY-CM.pub.asc @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNATURE----- -iJEEABYKADkWIQTbL/jtRAp+lJhvt3bSI36ECQhstwUCacEuihsUgAAAAAAEAA5t -YW51MiwyLjUrMS4xMiwyLDMACgkQ0iN+hAkIbLfD8QD/R+hzk3R2uP69t1LGDBbk -n7h0da3p2yRkT0Eh6K9cAtIBAInJfn7V+vYPms7paIU3oxojxj8vd2WFkyrVNYwt -A4oD -=RBh9 +iJEEABYKADkWIQTbL/jtRAp+lJhvt3bSI36ECQhstwUCadoxfBsUgAAAAAAEAA5t +YW51MiwyLjUrMS4xMiwyLDMACgkQ0iN+hAkIbLenaQEA9RLqQPEXV7sgVrUR80K6 +e9sSuUhMEzWUUjUCEu2+1J0A/3VNrliMzR6prAhB7UXCrBOpDhGlora4YScCUhDP +twUM +=zlWl -----END PGP SIGNATURE----- diff --git a/c/lib/cm/pub.c b/c/lib/cm/pub.c index 678ff53c199acb2273a78ccdce1e384104697ca4b62e605a3235a76e5aba3ede..2b9e4f593c8b58c57da1a82f4c8e95237f97d5390fc688e69f3a4a16de83b041 100644 --- a/c/lib/cm/pub.c +++ b/c/lib/cm/pub.c @@ -63,7 +63,6 @@ return KEKSErrUnsatisfiedSchema; } 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"); cer->pubId = items->list[KEKSItemsGetByKey(items, idx, "id")].atom.v.str.ptr; cer->sig = 0; diff --git a/c/lib/cm/pub.h b/c/lib/cm/pub.h index 50cfc510a050d1d18832c240541265518edf125aa632e986f2cb0d16de7ab038..cafccfeacf558c4da04fd8936d57ff96442ce37f92cb108bbe17f279cf4f6019 100644 --- a/c/lib/cm/pub.h +++ b/c/lib/cm/pub.h @@ -15,7 +15,7 @@ // @table @code // @item .items // Holds parsed @ref{KEKSItems} items. // @item .pub -// Items index of the first @code{/data/pub}, certificate's public key. +// Items index of the @code{/data/pub}, certificate's public key. // @item .sub // Items index of the @code{/data/sub}, certificate's subject. // @item .sig diff --git a/go/cm/.gitignore b/go/cm/.gitignore index 0d4fc74eabf5d2926e07ccfc30c1331b127e0cc099886da019aebdffa59643ab..40df1fe73e10a37fd7c7c504443b0e2d8e9a2e2c9ba0f32c616d6c095444c5aa 100644 --- a/go/cm/.gitignore +++ b/go/cm/.gitignore @@ -1 +1 @@ -bin/ +/bin/ diff --git a/go/cm/ai/enc.go b/go/cm/ai/enc.go new file mode 100644 index 0000000000000000000000000000000000000000..b0b5f3dc05a59facde222eac5b97810b2be72f8c57d1fe794f72b3af9cc8ecaa --- /dev/null +++ b/go/cm/ai/enc.go @@ -0,0 +1,9 @@ +package ai + +const ( + BalloonBLAKE2bHKDF = "balloon-blake2b-hkdf" + ClassicMcEliece6960119X25519 = "mceliece6960119-x25519" + ClassicMcEliece6960119X25519HKDFSHAKE256 = "mceliece6960119-x25519-hkdf-shake256" + SNTRUP761X25519 = "sntrup761-x25519" + SNTRUP761X25519HKDFBLAKE2b = "sntrup761-x25519-hkdf-blake2b" +) diff --git a/go/cm/ai/hash.go b/go/cm/ai/hash.go new file mode 100644 index 0000000000000000000000000000000000000000..e8e9e624d1069167de147eefdebf2ce0aa52e3a7d907e07b6286de2c67030ecc --- /dev/null +++ b/go/cm/ai/hash.go @@ -0,0 +1,16 @@ +package ai + +const ( + BLAKE2b = "blake2b" + BLAKE2b256 = "blake2b256" + BLAKE2bMerkle = "blake2b-merkle" + SHA2512 = "sha2-512" + SHAKE128 = "shake128" + SHAKE128Merkle = "shake128-merkle" + SHAKE256 = "shake256" + SHAKE256Merkle = "shake256-merkle" + Streebog256 = "streebog256" + Streebog256Merkle = "streebog256-merkle" + Streebog512 = "streebog512" + Streebog512Merkle = "streebog512-merkle" +) diff --git a/go/cm/ai/sign.go b/go/cm/ai/sign.go new file mode 100644 index 0000000000000000000000000000000000000000..8d33cf2bb48728bdb32e60f73416ed3a001d76c96eb31ae2c6953f7907c1e2e9 --- /dev/null +++ b/go/cm/ai/sign.go @@ -0,0 +1,14 @@ +package ai + +const ( + Ed25519BLAKE2b = "ed25519-blake2b" + Ed25519PhBLAKE2b = "ed25519ph-blake2b" + Ed25519PhBLAKE2bMerkle = "ed25519ph-blake2b-merkle" + GOST3410256A = "gost3410-256A" + GOST3410256AMerkle = "gost3410-256A-merkle" + GOST3410512C = "gost3410-512C" + GOST3410512CMerkle = "gost3410-512C-merkle" + SLHDSASHAKE256s = "slh-dsa-shake-256s" + SLHDSASHAKE256sMerkle = "slh-dsa-shake-256s-merkle" + SLHDSASHAKE256sPh = "slh-dsa-shake-256s-ph" +) diff --git a/go/cm/cmd/cmenctool/main.go b/go/cm/cmd/cmenctool/main.go index cf56b27d4120e43632b0127bd6931215bebf16dcb2f54f0acf15dc6bcb8c1d60..596a909a4cb3a9f46fcd1e5b68d557d2fd7a6da1c8fd706e8cd240c5018a253d 100644 --- a/go/cm/cmd/cmenctool/main.go +++ b/go/cm/cmd/cmenctool/main.go @@ -42,16 +42,16 @@ "golang.org/x/crypto/chacha20poly1305" "go.stargrave.org/keks" "go.stargrave.org/keks/cm" + "go.stargrave.org/keks/cm/ai" cmenc "go.stargrave.org/keks/cm/enc" cmballoon "go.stargrave.org/keks/cm/enc/balloon" ballooncost "go.stargrave.org/keks/cm/enc/balloon/cost" chapoly "go.stargrave.org/keks/cm/enc/chapoly" - mceliece6960119x25519 "go.stargrave.org/keks/cm/enc/mceliece6960119-x25519" mceliece6960119 "go.stargrave.org/keks/cm/enc/mceliece6960119-x25519/mceliece6960119" - sntrup761x25519 "go.stargrave.org/keks/cm/enc/sntrup761-x25519" sntrup761kem "go.stargrave.org/keks/cm/enc/sntrup761-x25519/sntrup761/kem" sntrup761 "go.stargrave.org/keks/cm/enc/sntrup761-x25519/sntrup761/kem/ntruprime/sntrup761" cmhash "go.stargrave.org/keks/cm/hash" + cmprv "go.stargrave.org/keks/cm/prv" "go.stargrave.org/keks/cm/sign" "go.stargrave.org/keks/schema" "go.stargrave.org/keks/types" @@ -80,9 +80,6 @@ pubData = signed.PubData() if !pubData.Can(sign.KUKEM) { err = fmt.Errorf("does not have %s key usage", sign.KUKEM) return - } - if len(pubData.Pub) != 1 { - err = errors.New("single public key expected") } return } @@ -101,7 +98,7 @@ } return pubDataFromSigned(signed) } -func findPrv(id []byte) (av *cm.AV, err error) { +func findPrv(id []byte) (*cm.AV, error) { data, err := os.ReadFile(path.Join( *PrvDir, strings.ToUpper(hex.EncodeToString(id)), )) @@ -109,36 +106,17 @@ if err != nil { if errors.Is(err, fs.ErrNotExist) { err = nil } - return + return nil, err } data, err = cmballoon.PossibleInteractiveDecrypt(data) if err != nil { - return + return nil, err } - { - var magic keks.Magic - magic, data = keks.StripMagic(data) - if magic != sign.PrvMagic { - err = errors.New("wrong magic") - return - } + prv, err := cmprv.Parse(data) + if err != nil { + return nil, err } - sign.PrvParse(data) - d := keks.NewDecoderFromBytes(data, &keks.DecodeOpts{MaxStrLen: 1 << 16}) - { - var v any - if v, err = d.Decode(); err != nil { - return - } - if err = schema.Check("prv", sign.PrvSchemas, v); err != nil { - return - } - } - var v cm.AV - if err = d.UnmarshalStruct(&v); err == nil { - av = &v - } - return + return &cm.AV{A: prv.A, V: prv.V}, err } func main() { @@ -171,7 +149,7 @@ pubData, err := pubParse(pth) if err != nil { log.Fatalln(pth, ":", err) } - pubs = append(pubs, pubData.Pub[0]) + pubs = append(pubs, pubData.Pub) pubIds = append(pubIds, pubData.Id) pubPrehashes = append(pubPrehashes, pubData.Prehash) } @@ -200,14 +178,11 @@ pubData, err = pubParse(*fromPth) if err != nil { log.Fatalln("from:", err) } - if len(pubData.Pub) != 1 { - log.Fatal("from: expected single public key") - } - fromA = pubData.Pub[0].A + fromA = pubData.Pub.A fromId = pubData.Id switch fromA { - case sntrup761x25519.SNTRUP761X25519, mceliece6960119x25519.ClassicMcEliece6960119X25519: - fromPub = pubData.Pub[0].V + case ai.SNTRUP761X25519, ai.ClassicMcEliece6960119X25519: + fromPub = pubData.Pub.V fromPub = fromPub[len(fromPub)-X25519KeyLen:] default: log.Fatal("from: unsupported algorithm") @@ -220,7 +195,12 @@ } if prv == nil { log.Fatal("from: can not find corresponding private key") } - fromPrv = prv.V[len(prv.V)-X25519KeyLen:] + switch fromA { + case ai.SNTRUP761X25519, ai.ClassicMcEliece6960119X25519: + fromPrv = prv.V[len(prv.V)-X25519KeyLen:] + default: + log.Fatal("from: unsupported algorithm") + } } var cek []byte @@ -253,11 +233,11 @@ } for _, kem := range v.(map[string]any)["kem"].([]any) { kemMap := kem.(map[string]any) switch kemMap["a"] { - case cmballoon.BalloonBLAKE2bHKDF: + case ai.BalloonBLAKE2bHKDF: err = schema.Check("kem-balloon-blake2b-hkdf", cmenc.EncryptedSchemas, kem) - case sntrup761x25519.SNTRUP761X25519HKDFBLAKE2b: + case ai.SNTRUP761X25519HKDFBLAKE2b: fallthrough - case mceliece6960119x25519.ClassicMcEliece6960119X25519HKDFSHAKE256: + case ai.ClassicMcEliece6960119X25519HKDFSHAKE256: err = schema.Check("kem-with-encap", cmenc.EncryptedSchemas, kem) default: log.Fatal("unsupported KEM algorithm") @@ -282,7 +262,7 @@ id = *encrypted.Id } for kemIdx, kem := range encrypted.KEM { switch kem.A { - case cmballoon.BalloonBLAKE2bHKDF: + case ai.BalloonBLAKE2bHKDF: if !*passphrase { log.Println(kemIdx, kem.A, "skipping because no -passwd") continue @@ -301,7 +281,7 @@ if len(cek) != chapoly.CEKLen { log.Println(kemIdx, kem.A, "wrong key len, skipping") continue } - case sntrup761x25519.SNTRUP761X25519HKDFBLAKE2b: + case ai.SNTRUP761X25519HKDFBLAKE2b: if kem.Encap == nil { log.Fatalln("missing encap") } @@ -327,7 +307,7 @@ log.Println(kemIdx, kem.A, "skipping because no private key found") continue } - if prv.A != sntrup761x25519.SNTRUP761X25519 { + if prv.A != ai.SNTRUP761X25519 { log.Fatalln(kemIdx, kem.A, "differing algorithm") } if len(prv.V) != scheme.PrivateKeySize()+X25519KeyLen { @@ -404,7 +384,7 @@ if err != nil { log.Fatal(err) } if from != nil { - fromPub = from.Pub[0].V + fromPub = from.Pub.V fromPub = fromPub[len(fromPub)-X25519KeyLen:] theirX25519, err = x25519.NewPublicKey(fromPub) if err != nil { @@ -451,7 +431,7 @@ } cek = cekp break } - case mceliece6960119x25519.ClassicMcEliece6960119X25519HKDFSHAKE256: + case ai.ClassicMcEliece6960119X25519HKDFSHAKE256: if kem.Encap == nil { log.Fatalln("missing encap") } @@ -476,7 +456,7 @@ log.Println(kemIdx, kem.A, "skipping because no private key found") continue } - if prv.A != mceliece6960119x25519.ClassicMcEliece6960119X25519 { + if prv.A != ai.ClassicMcEliece6960119X25519 { continue } if len(prv.V) != mceliece6960119.PrivateKeySize+X25519KeyLen { @@ -565,7 +545,8 @@ } { var pkHash []byte if signed, _ := PubDir.Get(kem.To); signed != nil { - ourPub, err := pubDataFromSigned(signed) + var ourPub *sign.PubData + ourPub, err = pubDataFromSigned(signed) if err != nil { log.Fatalln("our from:", err) } @@ -596,7 +577,7 @@ if err != nil { log.Fatal(err) } if from != nil { - fromPub = from.Pub[0].V + fromPub = from.Pub.V fromPub = fromPub[len(fromPub)-X25519KeyLen:] theirX25519, err = x25519.NewPublicKey(fromPub) if err != nil { @@ -699,7 +680,7 @@ } salt := make([]byte, cmballoon.SaltLen) rand.Read(salt) kem := cmenc.KEM{ - A: cmballoon.BalloonBLAKE2bHKDF, + A: ai.BalloonBLAKE2bHKDF, Salt: salt, BalloonCost: &ballooncost.Cost{ S: uint64(*balloonS), @@ -729,7 +710,7 @@ kems = append(kems, kem) } for pubId, pub := range pubs { switch pub.A { - case sntrup761x25519.SNTRUP761X25519: + case ai.SNTRUP761X25519: scheme := sntrup761.Scheme() if len(pub.V) != scheme.PublicKeySize()+X25519KeyLen { log.Fatalln("invalid public keys len") @@ -767,7 +748,7 @@ if err != nil { log.Fatal(err) } kem := cmenc.KEM{ - A: sntrup761x25519.SNTRUP761X25519HKDFBLAKE2b, + A: ai.SNTRUP761X25519HKDFBLAKE2b, Encap: append(ciphertext, ourPubX25519.Bytes()...), } { @@ -782,7 +763,7 @@ if err != nil { log.Fatal(err) } if fromPrv != nil { - if fromA != sntrup761x25519.SNTRUP761X25519 { + if fromA != ai.SNTRUP761X25519 { log.Fatal("differing sender/recipient algorithms") } ourPrvX25519, err = x25519.NewPrivateKey(fromPrv) @@ -838,7 +819,7 @@ if !*noTo { kem.To = pubIds[pubId] } kems = append(kems, kem) - case mceliece6960119x25519.ClassicMcEliece6960119X25519: + case ai.ClassicMcEliece6960119X25519: if len(pub.V) != mceliece6960119.PublicKeySize+X25519KeyLen { log.Fatalln("invalid public keys len") } @@ -867,9 +848,7 @@ if err != nil { log.Fatal(err) } ourPubX25519 := ourPrvX25519.PublicKey() - kem := cmenc.KEM{ - A: mceliece6960119x25519.ClassicMcEliece6960119X25519HKDFSHAKE256, - } + kem := cmenc.KEM{A: ai.ClassicMcEliece6960119X25519HKDFSHAKE256} { var decapKeymat []byte decapKeymat, err = hkdf.Expand( @@ -919,7 +898,7 @@ if err != nil { log.Fatal(err) } if fromPrv != nil { - if fromA != mceliece6960119x25519.ClassicMcEliece6960119X25519 { + if fromA != ai.ClassicMcEliece6960119X25519 { log.Fatal("differing sender/recipient algorithms") } ourPrvX25519, err = x25519.NewPrivateKey(fromPrv) diff --git a/go/cm/cmd/cmhshtool/main.go b/go/cm/cmd/cmhshtool/main.go index 4df2beeea03a0192a03f716fcc11d577047e91f770c5c8093c7f195ba28480b1..03eb22512f0328e5c327c4e42865f1e271501cc5c81f67e7778e7dbc6a3627d2 100644 --- a/go/cm/cmd/cmhshtool/main.go +++ b/go/cm/cmd/cmhshtool/main.go @@ -26,6 +26,7 @@ "go.stargrave.org/gogost/v7/gost34112012256" "go.stargrave.org/gogost/v7/gost34112012512" "go.stargrave.org/keks" + "go.stargrave.org/keks/cm/ai" cmhash "go.stargrave.org/keks/cm/hash" cmblake2b "go.stargrave.org/keks/cm/hash/blake2b" "go.stargrave.org/keks/cm/hash/gost" @@ -35,33 +36,33 @@ func main() { workers := flag.Int("p", cmhash.DefaultNumCPU, "Parallel workers") chunkLenK := flag.Int("c", merkle.DefaultChunkLen/1024, "Chunk size, KiB") - algo := flag.String("a", cmhash.BLAKE2bMerkle, "Algorithm to use") + algo := flag.String("a", ai.BLAKE2bMerkle, "Algorithm to use") list := flag.Bool("list", false, "List available algorithms") mmap := flag.String("mmap", "", "Use that mmap-ed file instead of stdin") flag.Parse() if *list { - fmt.Println(cmhash.BLAKE2bMerkle) - fmt.Println(cmhash.SHA2512 + "-merkle") - fmt.Println(cmhash.SHAKE128Merkle) - fmt.Println(cmhash.SHAKE256Merkle) - fmt.Println(cmhash.Streebog256Merkle) - fmt.Println(cmhash.Streebog512Merkle) + fmt.Println(ai.BLAKE2bMerkle) + fmt.Println(ai.SHA2512 + "-merkle") + fmt.Println(ai.SHAKE128Merkle) + fmt.Println(ai.SHAKE256Merkle) + fmt.Println(ai.Streebog256Merkle) + fmt.Println(ai.Streebog512Merkle) return } chunkLen := 1024 * *chunkLenK var hasher *merkle.Hasher switch *algo { - case cmhash.BLAKE2bMerkle: + case ai.BLAKE2bMerkle: hasher = cmblake2b.NewMerkleHasher(chunkLen, *workers).(*merkle.Hasher) - case cmhash.SHA2512 + "-merkle": + case ai.SHA2512 + "-merkle": hasher = merkle.NewHasherPrefixed(sha512.New, chunkLen, *workers) - case cmhash.SHAKE128Merkle: + case ai.SHAKE128Merkle: hasher = cmhash.NewSHAKE128MerkleHasher(chunkLen, *workers).(*merkle.Hasher) - case cmhash.SHAKE256Merkle: + case ai.SHAKE256Merkle: hasher = cmhash.NewSHAKE256MerkleHasher(chunkLen, *workers).(*merkle.Hasher) - case cmhash.Streebog256Merkle: + case ai.Streebog256Merkle: hasher = gost.NewMerkleHasher(gost34112012256.New, chunkLen, *workers).(*merkle.Hasher) - case cmhash.Streebog512Merkle: + case ai.Streebog512Merkle: hasher = gost.NewMerkleHasher(gost34112012512.New, chunkLen, *workers).(*merkle.Hasher) default: log.Fatal("unknown -a") diff --git a/go/cm/cmd/cmkeytool/main.go b/go/cm/cmd/cmkeytool/main.go index 9520620b74c5be5aed3cabb6e5acd6ebe8d488974158c63e15daabfaa82b3e9a..7b93c9a140b9699225168aef259ce68b0a9c3cc4f3766ff42d992053656b00ef 100644 --- a/go/cm/cmd/cmkeytool/main.go +++ b/go/cm/cmd/cmkeytool/main.go @@ -32,9 +32,11 @@ "time" "go.stargrave.org/keks" "go.stargrave.org/keks/cm" + "go.stargrave.org/keks/cm/ai" mceliece6960119x25519 "go.stargrave.org/keks/cm/enc/mceliece6960119-x25519" sntrup761x25519 "go.stargrave.org/keks/cm/enc/sntrup761-x25519" cmhash "go.stargrave.org/keks/cm/hash" + cmprv "go.stargrave.org/keks/cm/prv" "go.stargrave.org/keks/cm/sign" ed25519blake2b "go.stargrave.org/keks/cm/sign/ed25519-blake2b" "go.stargrave.org/keks/cm/sign/gost" @@ -74,8 +76,7 @@ sinceRaw := flag.String("since", "", "Optional notBefore, \"2006-01-02 15:04:05\" format") lifetime := flag.Uint("lifetime", 365, "Lifetime of the certification, days") - algo := flag.String("algo", ed25519blake2b.Ed25519BLAKE2b, - "Public key algorithm") + algo := flag.String("algo", ai.Ed25519BLAKE2b, "Public key algorithm") certify := flag.Bool("c", false, "Certify public key") verify := flag.Bool("v", false, "Verify provided -pub with -ca-pub") prvsDir := flag.String("prvs", os.Getenv("CM_PRVS"), @@ -88,12 +89,12 @@ log.SetFlags(log.Lshortfile) if *doList { algos := []string{ - ed25519blake2b.Ed25519BLAKE2b, - gost.GOST3410256A, - gost.GOST3410512C, - sntrup761x25519.SNTRUP761X25519, - mceliece6960119x25519.ClassicMcEliece6960119X25519, - slhdsa.SLHDSASHAKE256s, + ai.Ed25519BLAKE2b, + ai.GOST3410256A, + ai.GOST3410512C, + ai.SNTRUP761X25519, + ai.ClassicMcEliece6960119X25519, + ai.SLHDSASHAKE256s, } sort.Strings(algos) for _, s := range algos { @@ -131,7 +132,12 @@ )) if err != nil { log.Fatal(err) } - caPrv, _, err = sign.PrvParse(data) + var prv *cmprv.Prv + prv, err = cmprv.Parse(data) + if err != nil { + log.Fatal(err) + } + caPrv, _, err = sign.Prv2IfaceAndPub(prv) if err != nil { log.Fatal(err) } @@ -186,16 +192,16 @@ pubData = (*signed.Data).(map[string]any) } else { var pub []byte switch *algo { - case ed25519blake2b.Ed25519BLAKE2b: + case ai.Ed25519BLAKE2b: prvRaw, pub, err = ed25519blake2b.NewKeypair() - case gost.GOST3410256A, gost.GOST3410512C: + case ai.GOST3410256A, ai.GOST3410512C: prvRaw, pub, err = gost.NewKeypair(*algo) - case sntrup761x25519.SNTRUP761X25519: + case ai.SNTRUP761X25519: prvRaw, pub, err = sntrup761x25519.NewKeypair() - case mceliece6960119x25519.ClassicMcEliece6960119X25519: + case ai.ClassicMcEliece6960119X25519: prvRaw, pub, err = mceliece6960119x25519.NewKeypair() - case slhdsa.SLHDSASHAKE256s: - prvRaw, pub, err = slhdsa.NewKeypair(*algo) + case ai.SLHDSASHAKE256s: + prvRaw, pub, err = slhdsa.NewKeypair() default: err = errors.New("unknown -algo specified") } @@ -204,18 +210,15 @@ log.Fatal(err) } var pubId []byte { - pubData = map[string]any{ - "sub": sub, - "pub": []cm.AV{{A: *algo, V: pub}}, - } + pubData = map[string]any{"sub": sub, "pub": cm.AV{A: *algo, V: pub}} var hasher hash.Hash switch *algo { - case ed25519blake2b.Ed25519BLAKE2b, sntrup761x25519.SNTRUP761X25519: - hasher = cmhash.ByName(cmhash.BLAKE2b256) - case gost.GOST3410256A, gost.GOST3410512C: - hasher = cmhash.ByName(cmhash.Streebog256) - case mceliece6960119x25519.ClassicMcEliece6960119X25519, slhdsa.SLHDSASHAKE256s: - hasher = cmhash.ByName(cmhash.SHAKE128) + case ai.Ed25519BLAKE2b, ai.SNTRUP761X25519: + hasher = cmhash.ByName(ai.BLAKE2b256) + case ai.GOST3410256A, ai.GOST3410512C: + hasher = cmhash.ByName(ai.Streebog256) + case ai.ClassicMcEliece6960119X25519, ai.SLHDSASHAKE256s: + hasher = cmhash.ByName(ai.SHAKE128) default: log.Fatal("unsupported algorithm") } @@ -227,10 +230,10 @@ pubId = hasher.Sum(nil) pubData["id"] = pubId hasher = nil switch *algo { - case sntrup761x25519.SNTRUP761X25519: - hasher = cmhash.ByName(cmhash.BLAKE2b) - case mceliece6960119x25519.ClassicMcEliece6960119X25519: - hasher = cmhash.ByName(cmhash.SHAKE256) + case ai.SNTRUP761X25519: + hasher = cmhash.ByName(ai.BLAKE2b) + case ai.ClassicMcEliece6960119X25519: + hasher = cmhash.ByName(ai.SHAKE256) } if hasher != nil { _, err = hasher.Write(pub) @@ -245,12 +248,12 @@ pubData["ku"] = ku } { var buf bytes.Buffer - if _, err = keks.Encode(&buf, sign.PrvMagic, nil); err != nil { + if _, err = keks.Encode(&buf, cmprv.Magic, nil); err != nil { log.Fatal(err) } if _, err = keks.Encode( &buf, - sign.Prv{A: *algo, V: prvRaw, PubId: pubId}, + cmprv.Prv{A: *algo, V: prvRaw, PubId: pubId}, nil, ); err != nil { log.Fatal(err) diff --git a/go/cm/cmd/cmsigtool/main.go b/go/cm/cmd/cmsigtool/main.go index 414a56b7e8959a09745b894f899433f0f030cd10d7e6687e296171c6104eb8f7..49cc459b77bfb5236a75b5bb9ac25638f47696c6298b2001b55a3e76430ba016 100644 --- a/go/cm/cmd/cmsigtool/main.go +++ b/go/cm/cmd/cmsigtool/main.go @@ -31,6 +31,7 @@ "go.stargrave.org/keks" cmballoon "go.stargrave.org/keks/cm/enc/balloon" cmhash "go.stargrave.org/keks/cm/hash" + cmprv "go.stargrave.org/keks/cm/prv" "go.stargrave.org/keks/cm/sign" "go.stargrave.org/keks/cm/sign/mode" "go.stargrave.org/keks/schema" @@ -91,9 +92,16 @@ data, err = cmballoon.PossibleInteractiveDecrypt(data) if err != nil { log.Fatal(err) } - signer, _, err = sign.PrvParse(data) - if err != nil { - log.Fatal(err) + { + var prv *cmprv.Prv + prv, err = cmprv.Parse(data) + if err != nil { + log.Fatal(err) + } + signer, _, err = sign.Prv2IfaceAndPub(prv) + if err != nil { + log.Fatal(err) + } } } diff --git a/go/cm/enc/balloon/decap.go b/go/cm/enc/balloon/decap.go index c9040e8c81870304ead87977263478ee36a5be13bdaf65b56b66da4ce5afce93..5ab18d269d942ec36b1682f8566b6c770731e55aabcddf9b3c1b21abd40f86a8 100644 --- a/go/cm/enc/balloon/decap.go +++ b/go/cm/enc/balloon/decap.go @@ -28,9 +28,8 @@ "golang.org/x/crypto/chacha20poly1305" ) const ( - BalloonBLAKE2bHKDF = "balloon-blake2b-hkdf" - SaltLen = 16 - HKDFInfo = "cm/encrypted/balloon-blake2b-hkdf" + SaltLen = 16 + HKDFInfo = "cm/encrypted/balloon-blake2b-hkdf" ) func blake2bHash() hash.Hash { diff --git a/go/cm/enc/balloon/possible.go b/go/cm/enc/balloon/possible.go index a273c8cfb5e81a73d7487605887a95312ecb651b680d1a561aa9fd0b63683578..abfbef3833c61d3abfcb7ce07167b5d3970ab3e23989389bde29b414299fc12a 100644 --- a/go/cm/enc/balloon/possible.go +++ b/go/cm/enc/balloon/possible.go @@ -20,6 +20,7 @@ "bytes" "errors" "go.stargrave.org/keks" + "go.stargrave.org/keks/cm/ai" cmenc "go.stargrave.org/keks/cm/enc" "go.stargrave.org/keks/cm/enc/chapoly" "go.stargrave.org/keks/schema" @@ -54,7 +55,7 @@ err = errors.New("unsupported encryption DEM") return } if len(encrypted.KEM) != 1 || - encrypted.KEM[0].A != BalloonBLAKE2bHKDF || + encrypted.KEM[0].A != ai.BalloonBLAKE2bHKDF || len(encrypted.Payload) == 0 { err = errors.New("wrong encryption KEM") return diff --git a/go/cm/enc/mceliece6960119-x25519/algo.go b/go/cm/enc/mceliece6960119-x25519/algo.go deleted file mode 100644 index 852bb583ba5c71391927ad35dae94a26a56865012a4c70d2a6ac6aaccd709255..0000000000000000000000000000000000000000 --- a/go/cm/enc/mceliece6960119-x25519/algo.go +++ /dev/null @@ -1,6 +0,0 @@ -package mceliece6960119x25519 - -const ( - ClassicMcEliece6960119X25519 = "mceliece6960119-x25519" - ClassicMcEliece6960119X25519HKDFSHAKE256 = "mceliece6960119-x25519-hkdf-shake256" -) diff --git a/go/cm/enc/mk-schemas b/go/cm/enc/mk-schemas new file mode 100755 index 0000000000000000000000000000000000000000..e72687b43208bcd39bb83edb99fd1d84aaa7b41754db92fa1669ecbf0c93111e --- /dev/null +++ b/go/cm/enc/mk-schemas @@ -0,0 +1,3 @@ +#!/bin/sh -e + +exec redo-ifchange encrypted.schema.keks diff --git a/go/cm/enc/sntrup761-x25519/algo.go b/go/cm/enc/sntrup761-x25519/algo.go deleted file mode 100644 index f148ee03490428216910b88648ecc80afe18bfcff411aee9f92dfcdd3e0a0084..0000000000000000000000000000000000000000 --- a/go/cm/enc/sntrup761-x25519/algo.go +++ /dev/null @@ -1,6 +0,0 @@ -package sntrup761x25519 - -const ( - SNTRUP761X25519 = "sntrup761-x25519" - SNTRUP761X25519HKDFBLAKE2b = "sntrup761-x25519-hkdf-blake2b" -) diff --git a/go/cm/hash/algo.go b/go/cm/hash/algo.go index b31ea9eb0cc0b4560e462dcef76f1dcc4c026268b92b8bd755723e516201ca34..46bbd8d8cbe681f8105e135d4c6b8a4d0a79655a5fbbcf4656f830d9844ec7fd 100644 --- a/go/cm/hash/algo.go +++ b/go/cm/hash/algo.go @@ -23,62 +23,49 @@ "go.stargrave.org/gogost/v7/gost34112012256" "go.stargrave.org/gogost/v7/gost34112012512" "golang.org/x/crypto/blake2b" + "go.stargrave.org/keks/cm/ai" cmblake2b "go.stargrave.org/keks/cm/hash/blake2b" "go.stargrave.org/keks/cm/hash/gost" "go.stargrave.org/keks/cm/hash/merkle" ) -const ( - BLAKE2b = "blake2b" - BLAKE2b256 = "blake2b256" - SHA2512 = "sha2-512" - SHAKE128 = "shake128" - SHAKE256 = "shake256" - Streebog256 = "streebog256" - Streebog512 = "streebog512" - - BLAKE2bMerkle = "blake2b-merkle" - Streebog256Merkle = "streebog256-merkle" - Streebog512Merkle = "streebog512-merkle" -) - var DefaultNumCPU = max(1, runtime.NumCPU()/2) func ByName(name string) hash.Hash { switch name { - case Streebog256, gost.GOST3410256A: + case ai.Streebog256, ai.GOST3410256A: return gost34112012256.New() - case Streebog256Merkle, gost.GOST3410256AMerkle: + case ai.Streebog256Merkle, ai.GOST3410256AMerkle: return gost.NewMerkleHasher(gost34112012256.New, merkle.DefaultChunkLen, DefaultNumCPU) - case Streebog512, gost.GOST3410512C: + case ai.Streebog512, ai.GOST3410512C: return gost34112012512.New() - case Streebog512Merkle, gost.GOST3410512CMerkle: + case ai.Streebog512Merkle, ai.GOST3410512CMerkle: return gost.NewMerkleHasher(gost34112012512.New, merkle.DefaultChunkLen, DefaultNumCPU) - case BLAKE2b, cmblake2b.Ed25519BLAKE2b, cmblake2b.Ed25519PhBLAKE2b: + case ai.BLAKE2b, ai.Ed25519BLAKE2b, ai.Ed25519PhBLAKE2b: h, err := blake2b.New512(nil) if err != nil { panic(err) } return h - case BLAKE2bMerkle, cmblake2b.Ed25519PhBLAKE2bMerkle: + case ai.BLAKE2bMerkle, ai.Ed25519PhBLAKE2bMerkle: return cmblake2b.NewMerkleHasher( merkle.DefaultChunkLen, DefaultNumCPU) - case BLAKE2b256: + case ai.BLAKE2b256: h, err := blake2b.New256(nil) if err != nil { panic(err) } return h - case SHAKE128: + case ai.SHAKE128: return NewSHAKE128() - case SHAKE256, SLHDSASHAKE256s, SLHDSASHAKE256sPh: + case ai.SHAKE256, ai.SLHDSASHAKE256s, ai.SLHDSASHAKE256sPh: return NewSHAKE256() - case SHAKE128Merkle: + case ai.SHAKE128Merkle: return NewSHAKE128MerkleHasher( merkle.DefaultChunkLen, DefaultNumCPU) - case SHAKE256Merkle, SLHDSASHAKE256sMerkle: + case ai.SHAKE256Merkle, ai.SLHDSASHAKE256sMerkle: return NewSHAKE256MerkleHasher( merkle.DefaultChunkLen, DefaultNumCPU) } diff --git a/go/cm/hash/blake2b/algo.go b/go/cm/hash/blake2b/algo.go deleted file mode 100644 index 36b3f3f853a30558e32a5e867408a2efb681b06446e271463d222969feb15927..0000000000000000000000000000000000000000 --- a/go/cm/hash/blake2b/algo.go +++ /dev/null @@ -1,7 +0,0 @@ -package ed25519blake2b - -const ( - Ed25519BLAKE2b = "ed25519-blake2b" - Ed25519PhBLAKE2b = "ed25519ph-blake2b" - Ed25519PhBLAKE2bMerkle = "ed25519ph-blake2b-merkle" -) diff --git a/go/cm/hash/gost/algo.go b/go/cm/hash/gost/algo.go deleted file mode 100644 index 910c9bb972603852e40e8a7e9164bb8f2922bb78006231e82c45ecd4ed75d066..0000000000000000000000000000000000000000 --- a/go/cm/hash/gost/algo.go +++ /dev/null @@ -1,8 +0,0 @@ -package gost - -const ( - GOST3410256A = "gost3410-256A" - GOST3410512C = "gost3410-512C" - GOST3410256AMerkle = "gost3410-256A-merkle" - GOST3410512CMerkle = "gost3410-512C-merkle" -) diff --git a/go/cm/hash/mk-schemas b/go/cm/hash/mk-schemas new file mode 100755 index 0000000000000000000000000000000000000000..0a24e6cce7efa2ec69dfb68ee9650b7f12196b9f78d6fdeebd155ceaeadd739e --- /dev/null +++ b/go/cm/hash/mk-schemas @@ -0,0 +1,3 @@ +#!/bin/sh -e + +exec redo-ifchange prehash.schema.keks diff --git a/go/cm/hash/shake.go b/go/cm/hash/shake.go index 72a02fa8197b43fb14b6280c64e6d5b565a75dee0f8ac10539ea294c123099a0..3e1d72f4359266c0767cabec17d48fe99fa84105b50d66128f5c6b479f6d2c31 100644 --- a/go/cm/hash/shake.go +++ b/go/cm/hash/shake.go @@ -23,15 +23,6 @@ "go.stargrave.org/keks/cm/hash/merkle" ) -const ( - SHAKE128Merkle = "shake128-merkle" - SHAKE256Merkle = "shake256-merkle" - - SLHDSASHAKE256s = "slh-dsa-shake-256s" - SLHDSASHAKE256sPh = "slh-dsa-shake-256s-ph" - SLHDSASHAKE256sMerkle = "slh-dsa-shake-256s-merkle" -) - type SHAKE struct { xof *sha3.SHAKE l int diff --git a/go/cm/prv/.gitignore b/go/cm/prv/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..6db42b2d29bb35f6c81ffa753a8d35c28746581b83dea7f2fea68bdc6eaad836 --- /dev/null +++ b/go/cm/prv/.gitignore @@ -0,0 +1 @@ +/prv-all.schema.keks diff --git a/go/cm/prv/mk-schemas b/go/cm/prv/mk-schemas new file mode 100755 index 0000000000000000000000000000000000000000..4eb8ebbb13c1a1bdcb844fabf6d59d1f48c96da6c2217ef611ee2e9487cdb0f3 --- /dev/null +++ b/go/cm/prv/mk-schemas @@ -0,0 +1,3 @@ +#!/bin/sh -e + +exec redo-ifchange prv-all.schema.keks diff --git a/go/cm/prv/prv.go b/go/cm/prv/prv.go new file mode 100644 index 0000000000000000000000000000000000000000..d15c507526e67e9816589e66984db00666139628dd0e00b7fccac267cbfc7441 --- /dev/null +++ b/go/cm/prv/prv.go @@ -0,0 +1,40 @@ +package prv + +import ( + _ "embed" + "errors" + + "go.stargrave.org/keks" + "go.stargrave.org/keks/schema" +) + +const Magic = keks.Magic("cm/prv") + +type Prv struct { + A string `keks:"a"` + V []byte `keks:"v"` + PubId []byte `keks:"pub-id,omitempty"` +} + +func Parse(data []byte) (*Prv, error) { + { + var magic keks.Magic + magic, data = keks.StripMagic(data) + if magic != "" && magic != Magic { + return nil, errors.New("wrong magic") + } + } + d := keks.NewDecoderFromBytes(data, &keks.DecodeOpts{MaxStrLen: 1 << 16}) + var v any + v, err := d.Decode() + if err != nil { + return nil, err + } + err = schema.Check("prv", PrvSchemas, v) + if err != nil { + return nil, err + } + var s Prv + err = keks.Map2Struct(&s, v.(map[string]any)) + return &s, nil +} diff --git a/go/cm/prv/schemas.go b/go/cm/prv/schemas.go new file mode 100644 index 0000000000000000000000000000000000000000..1fcad7203f3e8b55570a0c4f97144015a2a15d96c37c0074aeda9ae248089d11 --- /dev/null +++ b/go/cm/prv/schemas.go @@ -0,0 +1,24 @@ +package prv + +import ( + _ "embed" + + "go.stargrave.org/keks" + "go.stargrave.org/keks/schema" +) + +//go:embed prv-all.schema.keks +var PrvRaw []byte + +var PrvSchemas map[string][][]any + +func init() { + var magic keks.Magic + magic, PrvRaw = keks.StripMagic(PrvRaw) + if magic != schema.Magic { + panic("wrong magic in prv*.schema.keks") + } + if err := keks.NewDecoderFromBytes(PrvRaw, nil).DecodeStruct(&PrvSchemas); err != nil { + panic(err) + } +} diff --git a/go/cm/sign/.gitignore b/go/cm/sign/.gitignore index cf6a0c0c5170c292a49bd7aaa2206e3915a19e104767762236f2e39fd1fad311..b9a8bddebd599b9e9eaefeda4426f623f18652d6fae1e55c3b634a2514505bb6 100644 --- a/go/cm/sign/.gitignore +++ b/go/cm/sign/.gitignore @@ -1,3 +1,2 @@ -/prv.schema.keks -/pub.schema.keks +/pub-all.schema.keks /signed.schema.keks diff --git a/go/cm/sign/cert.go b/go/cm/sign/cert.go new file mode 100644 index 0000000000000000000000000000000000000000..31f0f05110a900a45d2ee8a6f130998e3aad3ec2cb48bd9c707efcc3c42a6bdb --- /dev/null +++ b/go/cm/sign/cert.go @@ -0,0 +1,138 @@ +// KEKS/CM -- KEKS-encoded cryptographic messages +// Copyright (C) 2024-2026 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 sign + +import ( + "bytes" + "encoding/hex" + "errors" + "fmt" + "hash" + "time" + + "github.com/google/uuid" + "go.stargrave.org/keks" +) + +// 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 *PubData, + prv Iface, + since, till time.Time, +) error { + cid, err := uuid.NewV7() + if err != nil { + return err + } + return signed.SignWith(parent, prv, map[string]any{ + "cid": cid, + "exp": []time.Time{since, till}, + }) +} + +// 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 *PubData, + prehasher *hash.Hash, +) (err error) { + if !parent.Can(KUSig) { + err = errors.New("parent can not sign") + return + } + for _, sig := range signed.Sigs { + if !bytes.Equal(sig.TBS["sid"].([]byte), parent.Id) { + continue + } + if prehasher == nil { + var tbs bytes.Buffer + 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 { + return + } + return parent.CheckSignature(sig.Sign.A, tbs.Bytes(), sig.Sign.V) + } else { + 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 { + return + } + return parent.CheckSignaturePrehash( + sig.Sign.A, (*prehasher).Sum(nil), sig.Sign.V) + } + } + return errors.New("can not find necessary sid") +} + +// Verify signed Signed PubData certification against pubs storage of +// public keys at specified point of time t. +func (signed *Signed) CertificationVerify(pubs PubStorage, t time.Time) (err error) { + if len(signed.Sigs) == 0 { + return errors.New("no sigs") + } + + var sigTBS *SigTBS + sigTBS, err = signed.Sigs[0].TBSGet() + if err != nil { + return + } + { + exp := sigTBS.Exp + if t.Before(exp[0]) || t.Equal(exp[0]) { + err = errors.New("pub is not active") + return + } + if t.After(exp[1]) || t.Equal(exp[1]) { + err = errors.New("pub is expired") + return + } + } + sid := sigTBS.SID + if bytes.Equal(sid, signed.PubData().Id) { + return signed.CertificationCheckSignatureFrom(signed.PubData(), nil) + } + var signer *Signed + signer, err = pubs.Get(sid) + if err != nil { + return + } + if signer == nil { + err = fmt.Errorf("no pub found for sid: %s", hex.EncodeToString(sid)) + return + } + pubData := signer.PubData() + if !pubData.Can(KUSig) { + err = errors.New("pub can not sign") + return + } + err = signed.CertificationCheckSignatureFrom(pubData, nil) + if err != nil { + return + } + return signer.CertificationVerify(pubs, t) +} diff --git a/go/cm/sign/ed25519-blake2b/algo.go b/go/cm/sign/ed25519-blake2b/algo.go deleted file mode 100644 index 36b3f3f853a30558e32a5e867408a2efb681b06446e271463d222969feb15927..0000000000000000000000000000000000000000 --- a/go/cm/sign/ed25519-blake2b/algo.go +++ /dev/null @@ -1,7 +0,0 @@ -package ed25519blake2b - -const ( - Ed25519BLAKE2b = "ed25519-blake2b" - Ed25519PhBLAKE2b = "ed25519ph-blake2b" - Ed25519PhBLAKE2bMerkle = "ed25519ph-blake2b-merkle" -) diff --git a/go/cm/sign/ed25519-blake2b/signer.go b/go/cm/sign/ed25519-blake2b/signer.go index 0d36fe15f7dd8d456cc8a124022e3c3d1faea3217859bc267d66341ac9d74c57..fdb9fb8d7d0d656b4e681a0fbdb5fb634f892025825b3a9a59054ed8feddae24 100644 --- a/go/cm/sign/ed25519-blake2b/signer.go +++ b/go/cm/sign/ed25519-blake2b/signer.go @@ -21,6 +21,7 @@ "errors" "hash" "io" + "go.stargrave.org/keks/cm/ai" cmhash "go.stargrave.org/keks/cm/hash" cmblake2b "go.stargrave.org/keks/cm/hash/blake2b" "go.stargrave.org/keks/cm/hash/merkle" @@ -65,11 +66,11 @@ func (s *Signer) Algo() string { switch s.mode { case mode.Pure: - return Ed25519BLAKE2b + return ai.Ed25519BLAKE2b case mode.Prehash: - return Ed25519PhBLAKE2b + return ai.Ed25519PhBLAKE2b case mode.Merkle: - return Ed25519PhBLAKE2bMerkle + return ai.Ed25519PhBLAKE2bMerkle } return "" } diff --git a/go/cm/sign/gost/gost.go b/go/cm/sign/gost/gost.go index 1827df5107ce63162c056cb1ca0d6315dcebfb559f5456f3f91d3014ba409660..92e09cf2209364879f268884f9c96181bccfa8fa6d0741c87cc03771b1a805d6 100644 --- a/go/cm/sign/gost/gost.go +++ b/go/cm/sign/gost/gost.go @@ -17,20 +17,14 @@ package gost import ( "go.stargrave.org/gogost/v7/gost3410" -) - -const ( - GOST3410256A = "gost3410-256A" - GOST3410512C = "gost3410-512C" - GOST3410256AMerkle = "gost3410-256A-merkle" - GOST3410512CMerkle = "gost3410-512C-merkle" + "go.stargrave.org/keks/cm/ai" ) func CurveByName(name string) (curve *gost3410.Curve) { switch name { - case GOST3410256A: + case ai.GOST3410256A: curve = gost3410.CurveIdtc26gost341012256paramSetA() - case GOST3410512C: + case ai.GOST3410512C: curve = gost3410.CurveIdtc26gost341012512paramSetC() } return diff --git a/go/cm/sign/gost/kp.go b/go/cm/sign/gost/kp.go index 65c9e73b3be88f88862732b29b6f9f208db901f87774cdf99d1719e83ac45664..bd87916d4b4ad13966761a19d68014090e8c86699c600ef7a929044b109f1bb4 100644 --- a/go/cm/sign/gost/kp.go +++ b/go/cm/sign/gost/kp.go @@ -30,11 +30,12 @@ return } prv = make([]byte, curve.PointSize()) rand.Read(prv) - var pk *gost3410.PrivateKey - pk, err = gost3410.NewPrivateKeyBE(curve, prv) + var sk *gost3410.PrivateKey + sk, err = gost3410.NewPrivateKeyBE(curve, prv) if err != nil { return } - _, pub, err = NewSigner(pk.RawBE()) + prv = sk.RawBE() + _, pub, err = NewSigner(sk.RawBE()) return } diff --git a/go/cm/sign/gost/signer.go b/go/cm/sign/gost/signer.go index ce241279ec3a5f8882f4fd22ea99361ca33932c8d087d58288870d1ae6e2c3b0..24de4a290153ee248b6c0e885c0e3fc8cd27b9f6fe91c9c1ffdd22dd7400a8fd 100644 --- a/go/cm/sign/gost/signer.go +++ b/go/cm/sign/gost/signer.go @@ -25,6 +25,7 @@ "go.stargrave.org/gogost/v7/gost3410" "go.stargrave.org/gogost/v7/gost34112012256" "go.stargrave.org/gogost/v7/gost34112012512" + "go.stargrave.org/keks/cm/ai" cmhash "go.stargrave.org/keks/cm/hash" hashgost "go.stargrave.org/keks/cm/hash/gost" "go.stargrave.org/keks/cm/hash/merkle" @@ -70,14 +71,14 @@ func (s *Signer) Algo() string { switch s.Prv.C.PointSize() { case 32: if s.mode == mode.Merkle { - return GOST3410256AMerkle + return ai.GOST3410256AMerkle } - return GOST3410256A + return ai.GOST3410256A case 64: if s.mode == mode.Merkle { - return GOST3410512CMerkle + return ai.GOST3410512CMerkle } - return GOST3410512C + return ai.GOST3410512C default: return "" } diff --git a/go/cm/sign/gost/verify.go b/go/cm/sign/gost/verify.go index 07da1fc10506929ea208243998ae1b1d0374929560ffa3bf8fa5bfd1c42bb979..4203416f010b4f482787e45d2666a21a9a104137bbae1825c4545109ba5c7342 100644 --- a/go/cm/sign/gost/verify.go +++ b/go/cm/sign/gost/verify.go @@ -23,6 +23,7 @@ "go.stargrave.org/gogost/v7/gost3410" "go.stargrave.org/gogost/v7/gost34112012256" "go.stargrave.org/gogost/v7/gost34112012512" + "go.stargrave.org/keks/cm/ai" ) func Verify(algo string, pub, signed, signature []byte) (valid bool, err error) { @@ -33,9 +34,9 @@ return } var hasher hash.Hash switch algo { - case GOST3410256A: + case ai.GOST3410256A: hasher = gost34112012256.New() - case GOST3410512C: + case ai.GOST3410512C: hasher = gost34112012512.New() } _, err = io.Copy(hasher, bytes.NewReader(signed)) diff --git a/go/cm/sign/mk-schemas b/go/cm/sign/mk-schemas new file mode 100755 index 0000000000000000000000000000000000000000..ab381ee80093c8550b237c75470c251ddd56a0119e28ad9e7b80290c0cd3753f --- /dev/null +++ b/go/cm/sign/mk-schemas @@ -0,0 +1,3 @@ +#!/bin/sh -e + +exec redo-ifchange pub-all.schema.keks signed.schema.keks diff --git a/go/cm/sign/prv.go b/go/cm/sign/prv.go index 5cb8ac9a67446e320ecbd1bdf65bef30609d25d83a923297968a1b137d753447..75159f661e58a775e48f1b81c3f40b73b3afc4957b9f851e0019cb04a169bedd 100644 --- a/go/cm/sign/prv.go +++ b/go/cm/sign/prv.go @@ -16,60 +16,25 @@ package sign import ( - "errors" "fmt" - "go.stargrave.org/keks" - "go.stargrave.org/keks/cm" + "go.stargrave.org/keks/cm/ai" + cmprv "go.stargrave.org/keks/cm/prv" ed25519blake2b "go.stargrave.org/keks/cm/sign/ed25519-blake2b" "go.stargrave.org/keks/cm/sign/gost" "go.stargrave.org/keks/cm/sign/slhdsa" - "go.stargrave.org/keks/schema" ) -const PrvMagic = keks.Magic("cm/prv") - -type Prv struct { - A string `keks:"a"` - V []byte `keks:"v"` - PubId []byte `keks:"pub-id,omitempty"` -} - -// Parse private key contained in KEKS-encoded structure. -func PrvParse(data []byte) (prv Iface, pub []byte, err error) { - { - var magic keks.Magic - magic, data = keks.StripMagic(data) - if magic != "" && magic != PrvMagic { - err = errors.New("wrong magic") - return - } - } - d := keks.NewDecoderFromBytes(data, &keks.DecodeOpts{MaxStrLen: 1 << 16}) - { - var v any - v, err = d.Decode() - if err != nil { - return - } - err = schema.Check("prv", PrvSchemas, v) - if err != nil { - return - } - } - var av cm.AV - if err = d.UnmarshalStruct(&av); err != nil { - return - } - switch av.A { - case ed25519blake2b.Ed25519BLAKE2b: - prv, pub, err = ed25519blake2b.NewSigner(av.V) - case gost.GOST3410256A, gost.GOST3410512C: - prv, pub, err = gost.NewSigner(av.V) - case slhdsa.SLHDSASHAKE256s: - prv, pub, err = slhdsa.NewSigner(av.V) +func Prv2IfaceAndPub(s *cmprv.Prv) (prv Iface, pub []byte, err error) { + switch s.A { + case ai.Ed25519BLAKE2b: + prv, pub, err = ed25519blake2b.NewSigner(s.V) + case ai.GOST3410256A, ai.GOST3410512C: + prv, pub, err = gost.NewSigner(s.V) + case ai.SLHDSASHAKE256s: + prv, pub, err = slhdsa.NewSigner(s.V) default: - err = fmt.Errorf("unknown private key algo: %s", av.A) + err = fmt.Errorf("unknown private key algo: %s", s.A) } return } diff --git a/go/cm/sign/pub.go b/go/cm/sign/pub.go index 650f5d1b1731f3676e5004933eb48b4309d4a03330dbf31d0f637b89e9430750..b8a8ef57ea7033191b2506a47946fca46ed6eb175db338e81a5d037f92137821 100644 --- a/go/cm/sign/pub.go +++ b/go/cm/sign/pub.go @@ -16,17 +16,11 @@ package sign import ( - "bytes" - "encoding/hex" "errors" - "fmt" - "hash" - "time" - - "github.com/google/uuid" "go.stargrave.org/keks" "go.stargrave.org/keks/cm" + "go.stargrave.org/keks/cm/ai" ed25519blake2b "go.stargrave.org/keks/cm/sign/ed25519-blake2b" "go.stargrave.org/keks/cm/sign/gost" "go.stargrave.org/keks/cm/sign/slhdsa" @@ -51,7 +45,7 @@ type PubData struct { KU map[string]*struct{} `keks:"ku"` Sub map[string]string `keks:"sub"` Crit []map[string]any `keks:"crit"` - Pub []cm.AV `keks:"pub"` + Pub cm.AV `keks:"pub"` Id []byte `keks:"id"` Prehash [][]byte `keks:"prehash"` } @@ -67,29 +61,22 @@ return } } d := keks.NewDecoderFromBytes(data, nil) - { - var v any - v, err = d.Decode() - if err != nil { - return - } - err = schema.Check("pub", PubSchemas, v) - if err != nil { - return - } + var v any + v, err = d.Decode() + if err != nil { + return } - d = keks.NewDecoderFromBytes(data, nil) - var sd Signed - err = d.DecodeStruct(&sd) + err = schema.Check("pub", PubSchemas, v) if err != nil { return } - if sd.TBS.T == "pub" { - tail = d.B - signed = &sd - } else { - err = errors.New("PubParse: wrong load type") + var sd Signed + err = keks.Map2Struct(&sd, v.(map[string]any)) + if err != nil { + return } + tail = d.B + signed = &sd return } @@ -99,55 +86,36 @@ _, yes = pub.KU[ku] return } -// 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 *PubData, - prv Iface, - since, till time.Time, -) error { - cid, err := uuid.NewV7() - if err != nil { - return err - } - return signed.SignWith(parent, prv, map[string]any{ - "cid": cid, - "exp": []time.Time{since, till}, - }) -} - // Verify signature of signed data. ErrSigInvalid will be returned in // case of invalid signature. func (pub *PubData) CheckSignature(algo string, signed, signature []byte) (err error) { - if !pub.Can(KUSig) || len(pub.Pub) != 1 { + if !pub.Can(KUSig) { err = errors.New("pub can not sign") return } - key := pub.Pub[0] var valid bool - switch key.A { - case ed25519blake2b.Ed25519BLAKE2b: - if algo != ed25519blake2b.Ed25519BLAKE2b { + switch pub.Pub.A { + case ai.Ed25519BLAKE2b: + if algo != ai.Ed25519BLAKE2b { return ErrBadSigAlgo } - valid, err = ed25519blake2b.Verify(key.V, signed, signature) + valid, err = ed25519blake2b.Verify(pub.Pub.V, signed, signature) if !valid { err = ErrSigInvalid } - case gost.GOST3410256A, gost.GOST3410512C: - if algo != key.A { + case ai.GOST3410256A, ai.GOST3410512C: + if algo != pub.Pub.A { return ErrBadSigAlgo } - valid, err = gost.Verify(key.A, key.V, signed, signature) + valid, err = gost.Verify(pub.Pub.A, pub.Pub.V, signed, signature) if !valid { err = ErrSigInvalid } - case slhdsa.SLHDSASHAKE256s: - if algo != slhdsa.SLHDSASHAKE256s { + case ai.SLHDSASHAKE256s: + if algo != ai.SLHDSASHAKE256s { return ErrBadSigAlgo } - valid, err = slhdsa.Verify(key.A, key.V, signed, signature) + valid, err = slhdsa.Verify(pub.Pub.A, pub.Pub.V, signed, signature) if !valid { err = ErrSigInvalid } @@ -163,45 +131,44 @@ func (pub *PubData) CheckSignaturePrehash( algo string, prehash, signature []byte, ) (err error) { - if !pub.Can(KUSig) || len(pub.Pub) != 1 { + if !pub.Can(KUSig) { err = errors.New("pub can not sign") return } - key := pub.Pub[0] var valid bool - switch key.A { - case ed25519blake2b.Ed25519BLAKE2b: + switch pub.Pub.A { + case ai.Ed25519BLAKE2b: switch algo { - case ed25519blake2b.Ed25519PhBLAKE2b: - case ed25519blake2b.Ed25519PhBLAKE2bMerkle: + case ai.Ed25519PhBLAKE2b: + case ai.Ed25519PhBLAKE2bMerkle: default: return ErrBadSigAlgo } - valid, err = ed25519blake2b.VerifyPrehash(key.V, prehash, signature) + valid, err = ed25519blake2b.VerifyPrehash(pub.Pub.V, prehash, signature) if !valid { err = ErrSigInvalid } - case gost.GOST3410256A, gost.GOST3410512C: + case ai.GOST3410256A, ai.GOST3410512C: switch algo { - case gost.GOST3410256A: - case gost.GOST3410256AMerkle: - case gost.GOST3410512C: - case gost.GOST3410512CMerkle: + case ai.GOST3410256A: + case ai.GOST3410256AMerkle: + case ai.GOST3410512C: + case ai.GOST3410512CMerkle: default: return ErrBadSigAlgo } - valid, err = gost.VerifyPrehash(key.A, key.V, prehash, signature) + valid, err = gost.VerifyPrehash(pub.Pub.A, pub.Pub.V, prehash, signature) if !valid { err = ErrSigInvalid } - case slhdsa.SLHDSASHAKE256s: + case ai.SLHDSASHAKE256s: switch algo { - case slhdsa.SLHDSASHAKE256sPh: - case slhdsa.SLHDSASHAKE256sMerkle: + case ai.SLHDSASHAKE256sPh: + case ai.SLHDSASHAKE256sMerkle: default: return ErrBadSigAlgo } - valid, err = slhdsa.VerifyPrehash(algo, key.V, prehash, signature) + valid, err = slhdsa.VerifyPrehash(algo, pub.Pub.V, prehash, signature) if !valid { err = ErrSigInvalid } @@ -211,50 +178,6 @@ } return } -// 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 *PubData, - prehasher *hash.Hash, -) (err error) { - if !parent.Can(KUSig) || len(parent.Pub) != 1 { - err = errors.New("parent can not sign") - return - } - for _, sig := range signed.Sigs { - if !bytes.Equal(sig.TBS["sid"].([]byte), parent.Id) { - continue - } - if prehasher == nil { - var tbs bytes.Buffer - 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 { - return - } - return parent.CheckSignature(sig.Sign.A, tbs.Bytes(), sig.Sign.V) - } else { - 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 { - return - } - return parent.CheckSignaturePrehash( - sig.Sign.A, (*prehasher).Sum(nil), sig.Sign.V) - } - } - return errors.New("can not find necessary sid") -} - // Get PubData from Signed. // Returns nil if Signed does not hold it (or it is not yet parsed). func (signed *Signed) PubData() *PubData { @@ -272,51 +195,3 @@ return nil } return &pubData } - -// Verify signed Signed PubData certification against pubs storage of -// public keys at specified point of time t. -func (signed *Signed) CertificationVerify(pubs PubStorage, t time.Time) (err error) { - if len(signed.Sigs) == 0 { - return errors.New("no sigs") - } - - var sigTBS *SigTBS - sigTBS, err = signed.Sigs[0].TBSGet() - if err != nil { - return - } - { - exp := sigTBS.Exp - if t.Before(exp[0]) || t.Equal(exp[0]) { - err = errors.New("pub is not active") - return - } - if t.After(exp[1]) || t.Equal(exp[1]) { - err = errors.New("pub is expired") - return - } - } - sid := sigTBS.SID - if bytes.Equal(sid, signed.PubData().Id) { - return signed.CertificationCheckSignatureFrom(signed.PubData(), nil) - } - var signer *Signed - signer, err = pubs.Get(sid) - if err != nil { - return - } - if signer == nil { - err = fmt.Errorf("no pub found for sid: %s", hex.EncodeToString(sid)) - return - } - pubData := signer.PubData() - if !pubData.Can(KUSig) || len(pubData.Pub) != 1 { - err = errors.New("pub can not sign") - return - } - err = signed.CertificationCheckSignatureFrom(pubData, nil) - if err != nil { - return - } - return signer.CertificationVerify(pubs, t) -} diff --git a/go/cm/sign/schema.go b/go/cm/sign/schema.go index 97cc4ef59c1d3be81276bd09f8aa6a1ad5e2a461af273ec3453c6cdc0a6facec..552279b40147c4f21c6db2c53f460132e35499ef3469f1614aa513cf561ce1a6 100644 --- a/go/cm/sign/schema.go +++ b/go/cm/sign/schema.go @@ -25,15 +25,11 @@ //go:embed signed.schema.keks var SignedSchemasRaw []byte -//go:embed prv.schema.keks -var PrvSchemasRaw []byte - -//go:embed pub.schema.keks +//go:embed pub-all.schema.keks var PubSchemasRaw []byte var ( SignedSchemas map[string][][]any - PrvSchemas map[string][][]any PubSchemas map[string][][]any ) @@ -48,20 +44,9 @@ SignedSchemasRaw, nil, ).DecodeStruct(&SignedSchemas); err != nil { panic(err) } - - magic, PrvSchemasRaw = keks.StripMagic(PrvSchemasRaw) - if magic != schema.Magic { - panic("wrong magic in prv.schema.keks") - } - if err := keks.NewDecoderFromBytes( - PrvSchemasRaw, nil, - ).DecodeStruct(&PrvSchemas); err != nil { - panic(err) - } - magic, PubSchemasRaw = keks.StripMagic(PubSchemasRaw) if magic != schema.Magic { - panic("wrong magic in pub.schema.keks") + panic("wrong magic in pub-all.schema.keks") } if err := keks.NewDecoderFromBytes( PubSchemasRaw, nil, diff --git a/go/cm/sign/signed.go b/go/cm/sign/signed.go index 77ec571e50c43d984e01fb92254de5f1e404ac770c7128318834e6617c58fd5e..9ee540a61494c5d25bc375e0c119708970ee898ea190057b1112c4c5695f9f41 100644 --- a/go/cm/sign/signed.go +++ b/go/cm/sign/signed.go @@ -72,20 +72,17 @@ return } } d := keks.NewDecoderFromBytes(data, nil) - { - var v any - v, err = d.Decode() - if err != nil { - return - } - err = schema.Check("signed", SignedSchemas, v) - if err != nil { - return - } + var v any + v, err = d.Decode() + if err != nil { + return + } + err = schema.Check("signed", SignedSchemas, v) + if err != nil { + return } - d = keks.NewDecoderFromBytes(data, nil) var sd Signed - err = d.DecodeStruct(&sd) + err = keks.Map2Struct(&sd, v.(map[string]any)) if err != nil { return } @@ -102,7 +99,7 @@ parent *PubData, prv Iface, sigTBS map[string]any, ) (err error) { - if !parent.Can(KUSig) || len(parent.Pub) != 1 { + if !parent.Can(KUSig) { return errors.New("parent can not sign") } sigTBS["sid"] = parent.Id diff --git a/go/cm/sign/slhdsa/kp.go b/go/cm/sign/slhdsa/kp.go index 67724308c1c5d07b5db48a801cd63421c97aec7aebcf1d99740dee751a671c0a..9fa8526d65b0ce2933b348f3eedd0baeb891d43637dbd1e0bff1d4032197dbe5 100644 --- a/go/cm/sign/slhdsa/kp.go +++ b/go/cm/sign/slhdsa/kp.go @@ -21,13 +21,7 @@ "go.stargrave.org/keks/cm/sign/slhdsa/circl" ) -const ( - SLHDSASHAKE256s = "slh-dsa-shake-256s" - SLHDSASHAKE256sPh = "slh-dsa-shake-256s-ph" - SLHDSASHAKE256sMerkle = "slh-dsa-shake-256s-merkle" -) - -func NewKeypair(algo string) (prv, pub []byte, err error) { +func NewKeypair() (prv, pub []byte, err error) { pk, sk, err := circl.GenerateKey(rand.Reader, circl.SHAKE_256s) if err != nil { return diff --git a/go/cm/sign/slhdsa/signer.go b/go/cm/sign/slhdsa/signer.go index 2b52d08d11f6c78a98f08d8ee12f325e80ed98f1974c28916da9c98a5ea26948..31440c7bf5e3bcd1cb67c9de7ac8b3d295be82a862de810d811a0b8a6205872a 100644 --- a/go/cm/sign/slhdsa/signer.go +++ b/go/cm/sign/slhdsa/signer.go @@ -21,6 +21,7 @@ "errors" "hash" "io" + "go.stargrave.org/keks/cm/ai" "go.stargrave.org/keks/cm/sign/slhdsa/circl" cmhash "go.stargrave.org/keks/cm/hash" @@ -67,11 +68,11 @@ func (s *Signer) Algo() string { switch s.mode { case mode.Pure: - return SLHDSASHAKE256s + return ai.SLHDSASHAKE256s case mode.Prehash: - return SLHDSASHAKE256sPh + return ai.SLHDSASHAKE256sPh case mode.Merkle: - return SLHDSASHAKE256sMerkle + return ai.SLHDSASHAKE256sMerkle } return "" } diff --git a/go/cm/sign/storage.go b/go/cm/sign/storage.go index 170a0c6c7d4dac6823dfbe5ff2fe9a33733287fa040264cbb52c81b9b9bfaae7..99dd8e99971b4aefeb819fc9005337a0050d7b6a3712ca82d2643b12302fbeed 100644 --- a/go/cm/sign/storage.go +++ b/go/cm/sign/storage.go @@ -17,8 +17,6 @@ package sign import ( "encoding/hex" - "errors" - "io/fs" "os" "path" "strings" @@ -38,9 +36,6 @@ data, err = os.ReadFile(path.Join( s.Dir, strings.ToUpper(hex.EncodeToString(id)), )) if err != nil { - if errors.Is(err, fs.ErrNotExist) { - return - } return } signed, _, err = PubParse(data) diff --git a/go/cm/utils/mk-bin b/go/cm/utils/mk-bin index d2cebd0f6b06f80003f6b368d57200434aee7cfb1af1ddb126435f18b60cea6b..5977fe44a9a4699931d513d06abc8258cfdb984539ac6ba910760fe06e233f8c 100755 --- a/go/cm/utils/mk-bin +++ b/go/cm/utils/mk-bin @@ -8,12 +8,13 @@ GO_LDFLAGS="${GO_LDFLAGS:--s}" root="$(dirname "$(realpath -- "$0")")" cd "$root/.." -[ -d vendor ] && mod_vendor="-mod=vendor" || redo-ifchange \ - enc/encrypted.schema.keks \ - hash/prehash.schema.keks \ - sign/prv.schema.keks \ - sign/pub.schema.keks \ - sign/signed.schema.keks +[ -d vendor ] && mod_vendor="-mod=vendor" || { + for w in enc hash prv sign ; do + cd $w + ./mk-schemas + cd "$root/.." + done +} mkdir -p bin for cmd in enc hsh key sig ; do cmd=cm${cmd}tool diff --git a/spec/cm/prv/ed25519-blake2b b/spec/cm/prv/ed25519-blake2b index c81cc1c9afc61947b50803827f5b28638da3e699d16a9f1692455d6112ef1924..c543613e717ab0dfbbed110bb6e7b570b9a262f9994482a6d7d95b90e8cd7c5e 100644 --- a/spec/cm/prv/ed25519-blake2b +++ b/spec/cm/prv/ed25519-blake2b @@ -1,6 +1,6 @@ -[cm/prv/] with Ed25519-BLAKE2b. +[cm/prv/] with Ed25519. 32-byte Ed25519 private key is used, as described in EdDSA RFC. In many libraries it is called "seed". => https://datatracker.ietf.org/doc/html/rfc8032.html EdDSA -"ed25519-blake2b" algorithm identifier is used, however actually no -hash is involved in private key storage. + +<< [schemas/prv-ed25519-blake2b.tcl] diff --git a/spec/cm/prv/gost3410 b/spec/cm/prv/gost3410 index 5026c53432c9472758e34e8248ac6f474b26903cdac3c08978c939bb81da9bc1..fc020dbcd50a37df980c60ba6469242491eee0a5908eb883f99df58916d6d891 100644 --- a/spec/cm/prv/gost3410 +++ b/spec/cm/prv/gost3410 @@ -3,4 +3,5 @@ GOST R 34.10-2012 is signing/key-aggreement algorithm. => https://datatracker.ietf.org/doc/html/rfc7091.html RFC 7091, GOST R 34.10-2012 Big-endian private key representation must be used. Only twisted Edwards curves are used. -Following algorithm identifiers are used: "gost3410-256A", "gost3410-512C". + +<< [schemas/prv-gost3410.tcl] diff --git a/spec/cm/prv/mceliece6960119-x25519 b/spec/cm/prv/mceliece6960119-x25519 index e2aebe7fa50bc86757fe9c07d15261794f0b602d5835fc8206a2993ae34e5e7c..a61b6e207fb67b37293b2ce2b26d0a26a6136d7a13f07277bf1dd7cdf12df9aa 100644 --- a/spec/cm/prv/mceliece6960119-x25519 +++ b/spec/cm/prv/mceliece6960119-x25519 @@ -1,6 +1,6 @@ [cm/prv/] with Classic McEliece 6960-119 + X25519. => https://classic.mceliece.org/ Classic McEliece => https://datatracker.ietf.org/doc/html/rfc7748.html X25519 -Concatenation of Classic McEliece 6960-119 13948-byte private key -and X25519's 32-byte one. -"mceliece6960119-x25519" algorithm identifier is used. +Concatenation of Classic McEliece 6960-119 and X25519 private keys. + +<< [schemas/prv-mceliece6960119-x25519.tcl] diff --git a/spec/cm/prv/slh-dsa-shake-256s b/spec/cm/prv/slh-dsa-shake-256s index 41ebc3a76fd80bfc690546467e20bf60c7c8f91963c6f53b1339bf4b11720720..b61eae9feb034eed4086d3434f7b63ad18b50ef88804f2af50f8a4d4e9a7cbf2 100644 --- a/spec/cm/prv/slh-dsa-shake-256s +++ b/spec/cm/prv/slh-dsa-shake-256s @@ -1,5 +1,5 @@ [cm/prv/] with SLH-DSA-SHAKE-256s. 255-bit security level, small variant and simple parameters. => https://csrc.nist.gov/pubs/fips/205/final SLH-DSA -Value is 128 byte private key. -"slh-dsa-shake-256s" algorithm identifier is used. + +<< [schemas/prv-slh-dsa-shake-256s.tcl] diff --git a/spec/cm/prv/sntrup761-x25519 b/spec/cm/prv/sntrup761-x25519 index 8810f7592013b2d711e9f6ef923e04a435956a38b8edd4094db522e41f5031f4..f94f65113cb9c0e41d95e6aa60a692199f2f86a10698b7250c61c0b7a5c13200 100644 --- a/spec/cm/prv/sntrup761-x25519 +++ b/spec/cm/prv/sntrup761-x25519 @@ -1,5 +1,6 @@ [cm/prv/] with Streamlined NTRU Prime 761 + X25519. => https://ntruprime.cr.yp.to/ NTRU Prime => https://datatracker.ietf.org/doc/html/rfc7748.html X25519 -It is a concatenation of SNTRUP's 1763-byte and X25519's 32-byte keys. -"sntrup761-x25519" algorithm identifier is used. +It is a concatenation of SNTRUP and X25519 private keys. + +<< [schemas/prv-sntrup761-x25519.tcl] diff --git a/spec/cm/pub/ed25519-blake2b b/spec/cm/pub/ed25519-blake2b index 5d391e8cc86205640c2b5ec9ac19d1e330eff77dc707072680927b41e26abd6c..e1d1f3ac37556a50b91408792a9eb0f6e2e93e2484a53feaaeb6aee19ecdcc99 100644 --- a/spec/cm/pub/ed25519-blake2b +++ b/spec/cm/pub/ed25519-blake2b @@ -1,4 +1,4 @@ -[cm/pub/] with Ed25519-BLAKE2b. +[cm/pub/] with Ed25519. Same calculation and serialisation rules must be used as with [cm/signed/ed25519-blake2b]. @@ -7,4 +7,5 @@ Public key's fingerprint should be calculated using BLAKE2b hash with 256 bit output length specified. => https://datatracker.ietf.org/doc/html/rfc7693.html RFC 7693, BLAKE2b -Algorithm identifier for the public key: "ed25519-blake2b". +Its /data/pub contents: +<< [schemas/pub-ed25519-blake2b.tcl] diff --git a/spec/cm/pub/gost3410 b/spec/cm/pub/gost3410 index b097acf9770c1465173188b93b5e4f78c92145c915f8208fff070020d88991d0..a0752bb90a99a2987704e36f3d11dc02375bbb1c7610990f2d15a33374620e94 100644 --- a/spec/cm/pub/gost3410 +++ b/spec/cm/pub/gost3410 @@ -1,4 +1,6 @@ [cm/pub/] with GOST R 34.10-2012 ([cm/signed/gost3410]). Public key must be in "BE(X)||BE(Y)" format. -Algorithm identifiers for the public key: "gost3410-256A", "gost3410-512C". Public key's fingerprint should be calculated using big-endian Streebog-256. + +Its /data/pub contents: +<< [schemas/pub-gost3410.tcl] diff --git a/spec/cm/pub/index b/spec/cm/pub/index index ea0e0cae86620f98d09bdd1708db46d55850a02e37337432a060a4b3672ffb43..6077724dc9caf59a0a19a4bba2776b53c3edcad0b52cc2f0f5909cec6a66380a 100644 --- a/spec/cm/pub/index +++ b/spec/cm/pub/index @@ -12,16 +12,7 @@ what fields must be present. Each application defines them on its own. But you may mimic X.509's subject with keys like "CN", "C", "O" and similar ones. pub: - Public key container itself may contain multiple public keys. - That is *solely* intended for tasks requiring more than single - key usage. For example NNCP uses one X25519 for (DH) encryption, one - X25519 for online authentication and one ed25519 for signing purposes. - All those three keys are used together. That public key's key usage - field should contain something like "nncp". - => http://www.nncpgo.org NNCP - If your keypair is intended for general purposes like signing of - arbitrary data, then single public key *should* be used, with a key - usage like "sig". + Public key container itself. id: Public key(s)'s fingerprint *should* be generated as 256-bit hash over the encoded "pub" field, if not stated otherwise for @@ -53,11 +44,9 @@ t {STR pub} }} data {MAP { id {BIN "6aee..."} - pub {LIST { - {MAP { - a {STR ed25519-blake2b} - v {BIN "c1bf..."} - }} + pub {MAP { + a {STR ed25519-blake2b} + v {BIN "c1bf..."} }} sub {MAP { N {STR test} diff --git a/spec/cm/pub/mceliece6960119-x25519 b/spec/cm/pub/mceliece6960119-x25519 index fd38517a1ccb8d6bc7ac88362c7dd2da0c7cae2848b98e00bd47dfc1dac85dbd..24c9d6800f354b0c74138ecdb501ed44622b396466ef2b51d4976d7348831c8c 100644 --- a/spec/cm/pub/mceliece6960119-x25519 +++ b/spec/cm/pub/mceliece6960119-x25519 @@ -16,3 +16,6 @@ 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. + +Its /data/pub contents: +<< [schemas/pub-mceliece6960119-x25519.tcl] diff --git a/spec/cm/pub/slh-dsa-shake-256s b/spec/cm/pub/slh-dsa-shake-256s index fe319bde32218d9162d7e6271e594717c9e288f67c4443aa8eb0bd386a9aa272..61c28abb23f2b5c0e2145513353a947017ffa3c1eae7e1abe12c788452e0efa0 100644 --- a/spec/cm/pub/slh-dsa-shake-256s +++ b/spec/cm/pub/slh-dsa-shake-256s @@ -1,5 +1,7 @@ [cm/pub/] with SLH-DSA-SHAKE-256s. 255-bit security level, small variant. => https://csrc.nist.gov/pubs/fips/205/final SLH-DSA -"slh-dsa-shake-256s" algorithm identifier is used. Public key's fingerprint should be calculated using SHAKE128. + +Its /data/pub contents: +<< [schemas/pub-slh-dsa-shake-256s.tcl] diff --git a/spec/cm/pub/sntrup761-x25519 b/spec/cm/pub/sntrup761-x25519 index 96afab51a7d34717daed7c342fbab99b85bf44ff56ee9585989c48eeef8c93f0..de5ff6b7aae3d9daf3b1ac93511f7d5b43ef8658b6dd8d6df8eb2fef3bce72ec 100644 --- a/spec/cm/pub/sntrup761-x25519 +++ b/spec/cm/pub/sntrup761-x25519 @@ -5,10 +5,9 @@ Combined Streamlined NTRU Prime 761 and X25519 public keys are used for KEM purposes, so should have "kem" key usage set. -Its algorithm identifier is "sntrup761-x25519". -Its public key value is a concatenation of 1158-byte -SNTRUP761 public key and 32-byte X25519 one. - Public key's fingerprint should be calculated using BLAKE2b hash with 256 bit output length specified. => https://datatracker.ietf.org/doc/html/rfc7693.html RFC 7693, BLAKE2b + +Its /data/pub contents: +<< [schemas/pub-sntrup761-x25519.tcl] diff --git a/spec/cm/signed/ed25519-blake2b b/spec/cm/signed/ed25519-blake2b index 6d95709bdea15143314accf4080d027cd0c85e65b22e43c320e20111bef4c693..2017f204f9a0290a563b27f05007e5944abe86d4aa81bc0d5d112e4ceb953746 100644 --- a/spec/cm/signed/ed25519-blake2b +++ b/spec/cm/signed/ed25519-blake2b @@ -1,4 +1,5 @@ [cm/signed/] with Ed25519-BLAKE2b. +[cm/pub/ed25519-blake2b] public keys are used. EdDSA with Edwards25519 is used similarly as in RFC 8032. But BLAKE2b is used instead of SHA2-512 hash. @@ -13,3 +14,6 @@ HashEdDSA *must* be used otherwise, using BLAKE2b-512 as a hash, using "ed25519ph-blake2b" algorithm identifier for signature. + +Its /sigs/*/sign contents: +<< [schemas/sign-ed25519-blake2b.tcl] diff --git a/spec/cm/signed/ed25519ph-blake2b-merkle b/spec/cm/signed/ed25519ph-blake2b-merkle index 447c7d3a07834867971cb840e1519219c2f871c924adb4c9b9fc30f4db2ac1e6..ee18945bae2445ef0dab709392621c66d7df9f3b8b0ce063771c8888e50c3dea 100644 --- a/spec/cm/signed/ed25519ph-blake2b-merkle +++ b/spec/cm/signed/ed25519ph-blake2b-merkle @@ -1,6 +1,10 @@ [cm/signed/] with Ed25519-BLAKE2b with Merkle-tree hashing. +[cm/pub/ed25519-blake2b] public keys are used. It is similar to [cm/signed/ed25519-blake2b], but HashEdDSA mode is used with [cm/hashed/blake2b-merkle] hashing. "ed25519ph-blake2b-merkle" algorithm identifier is used in signature. + +Its /sigs/*/sign contents: +<< [schemas/sign-ed25519-blake2b.tcl] diff --git a/spec/cm/signed/gost3410 b/spec/cm/signed/gost3410 index 0bc7ccd03694b8bf7cac3b4317854b3a770684699e079ae1d1abf565db468a5a..b57938f8dfbb0c3a04927a799c5525a287dbec6e25e4f2aa18965cac3c216de3 100644 --- a/spec/cm/signed/gost3410 +++ b/spec/cm/signed/gost3410 @@ -1,4 +1,5 @@ [cm/signed/] with GOST R 34.10-2012. +[cm/pub/gost3410] public keys are used. => https://datatracker.ietf.org/doc/html/rfc7091.html RFC 7091, GOST R 34.10-2012 GOST R 34.10-2012 must be used with Streebog (GOST R 34.11-2012) @@ -6,4 +7,5 @@ hash function. Its digest must be big-endian serialised. Signature is in "BE(R)||BE(S)" format. => https://datatracker.ietf.org/doc/html/rfc6986.html RFC 6986, GOST R 34.11-2012 -Algorithm identifiers for the signature: "gost3410-256A", "gost3410-512C". +Its /sigs/*/sign contents: +<< [schemas/sign-gost3410.tcl] diff --git a/spec/cm/signed/gost3410-merkle b/spec/cm/signed/gost3410-merkle index 26c599a176659514f325e2453c7c6d71d6cbe2b704080ef69c83a7883219400a..c8e6690b389cad258719a393e84bdc2e4e55efdb8fceff4d3080e93f4ad59bf7 100644 --- a/spec/cm/signed/gost3410-merkle +++ b/spec/cm/signed/gost3410-merkle @@ -1,7 +1,8 @@ [cm/signed/] with GOST R 34.10-2012 with Merkle-tree hashing. +[cm/pub/gost3410] public keys are used. It is similar to [cm/signed/gost3410], but [cm/hashed/streebog-merkle] hashing is used. -Algorithm identifiers for the signature: -"gost3410-256A-merkle", "gost3410-512C-merkle". +Its /sigs/*/sign contents: +<< [schemas/sign-gost3410.tcl] diff --git a/spec/cm/signed/slh-dsa-shake-256s b/spec/cm/signed/slh-dsa-shake-256s index 2707a2f357337ddbfae7ef015a810b940f12f9859cb55fd340cec5ca55c8ea91..2de91110bd472607e7dc5e28e166a9a5b3d02a712af173b7226931d050785278 100644 --- a/spec/cm/signed/slh-dsa-shake-256s +++ b/spec/cm/signed/slh-dsa-shake-256s @@ -1,8 +1,7 @@ [cm/signed/] with SLH-DSA-SHAKE-256s. +[cm/pub/slh-dsa-shake-256s] public keys are used. 255-bit security level, small variant. => https://csrc.nist.gov/pubs/fips/205/final SLH-DSA -"slh-dsa-shake-256s" algorithm identifier -must be used for the signature in pure signing mode. -"slh-dsa-shake-256s-ph" is used in prehash mode. -Algorithm identifiers are also used as a context in the signature. +Its /sigs/*/sign contents: +<< [schemas/sign-slh-dsa-shake-256s.tcl] diff --git a/spec/cm/signed/slh-dsa-shake-256s-merkle b/spec/cm/signed/slh-dsa-shake-256s-merkle index 76e41311e900a97a87c2ddb0cdc55349d130e4d48225a752ab6e78af18190713..cbea0cdd3526baeb643eecac9e48d5ea5623432e72a23d378dde2f5e923dacd7 100644 --- a/spec/cm/signed/slh-dsa-shake-256s-merkle +++ b/spec/cm/signed/slh-dsa-shake-256s-merkle @@ -1,6 +1,8 @@ [cm/signed/] with SLH-DSA-SHAKE-256s with Merkle-tree hashing. +[cm/pub/slh-dsa-shake-256s] public keys are used. It is similar to [cm/signed/slh-dsa-shake-256s], but [cm/hashed/shake-merkle] SHAKE256 Merkle-tree hashing is used. -"slh-dsa-shake-256s-merkle" algorithm identifier is used for the signature. +Its /sigs/*/sign contents: +<< [schemas/sign-slh-dsa-shake-256s.tcl] diff --git a/tcl/schemas/prv-all.tcl b/tcl/schemas/prv-all.tcl new file mode 100644 index 0000000000000000000000000000000000000000..79e20954d56bc1f3b703005c7f0eaecc1ccbb12780366c16ab7c50e008723961 --- /dev/null +++ b/tcl/schemas/prv-all.tcl @@ -0,0 +1,6 @@ +schema-include prv.tcl +schema-include prv-ed25519-blake2b.tcl +schema-include prv-gost3410.tcl +schema-include prv-mceliece6960119-x25519.tcl +schema-include prv-slh-dsa-shake-256s.tcl +schema-include prv-sntrup761-x25519.tcl diff --git a/tcl/schemas/prv-ed25519-blake2b.tcl b/tcl/schemas/prv-ed25519-blake2b.tcl new file mode 100644 index 0000000000000000000000000000000000000000..9d179cfb5b8f0aa3d2768b36707ee6a46d1da604ff1a003cb7e66abdbeccf778 --- /dev/null +++ b/tcl/schemas/prv-ed25519-blake2b.tcl @@ -0,0 +1,5 @@ +prv-ed25519-blake2b { + {field . {map} len=~} + {field a {str} =ed25519-blake2b} + {field v {bin} len=32} +} diff --git a/tcl/schemas/prv-gost3410.tcl b/tcl/schemas/prv-gost3410.tcl new file mode 100644 index 0000000000000000000000000000000000000000..3a816af1d757d9382707191012f3e08e28dd4272aa14f96b0a13dc2565ae2e6d --- /dev/null +++ b/tcl/schemas/prv-gost3410.tcl @@ -0,0 +1,11 @@ +prv-gost3410-256A { + {field . {map} len=~} + {field a {str} =gost3410-256A} + {field v {bin} len=32} +} + +prv-gost3410-512C { + {field . {map} len=~} + {field a {str} =gost3410-512C} + {field v {bin} len=64} +} diff --git a/tcl/schemas/prv-mceliece6960119-x25519.tcl b/tcl/schemas/prv-mceliece6960119-x25519.tcl new file mode 100644 index 0000000000000000000000000000000000000000..5d205e8e4f6573a0a863b1822ad13dfc6d6c44c19bc826f0e3a76e37407fe478 --- /dev/null +++ b/tcl/schemas/prv-mceliece6960119-x25519.tcl @@ -0,0 +1,5 @@ +prv-mceliece6960119-x25519 { + {field . {map} len=~} + {field a {str} =mceliece6960119-x25519} + {field v {bin} len=13980} +} diff --git a/tcl/schemas/prv-slh-dsa-shake-256s.tcl b/tcl/schemas/prv-slh-dsa-shake-256s.tcl new file mode 100644 index 0000000000000000000000000000000000000000..5d2e9d44a0b2c90db8a3248785c3c1134377281be4b53f229401308cb5e1ff77 --- /dev/null +++ b/tcl/schemas/prv-slh-dsa-shake-256s.tcl @@ -0,0 +1,5 @@ +prv-slh-dsa-shake-256s { + {field . {map} len=~} + {field a {str} =slh-dsa-shake-256s} + {field v {bin} len=128} +} diff --git a/tcl/schemas/prv-sntrup761-x25519.tcl b/tcl/schemas/prv-sntrup761-x25519.tcl new file mode 100644 index 0000000000000000000000000000000000000000..06837a30464be066221168750473e6d516758a3af6599ef67495da259fde58f9 --- /dev/null +++ b/tcl/schemas/prv-sntrup761-x25519.tcl @@ -0,0 +1,5 @@ +prv-sntrup761-x25519.tcl { + {field . {map} len=~} + {field a {str} =sntrup761-x25519} + {field v {bin} len=1795} +} diff --git a/tcl/schemas/pub-all.tcl b/tcl/schemas/pub-all.tcl new file mode 100644 index 0000000000000000000000000000000000000000..7f7d7b4db591609ea8bd65b0b0d22756053e58dafc1cb17b78793e96b02ed612 --- /dev/null +++ b/tcl/schemas/pub-all.tcl @@ -0,0 +1,6 @@ +schema-include pub.tcl +schema-include pub-ed25519-blake2b.tcl +schema-include pub-gost3410.tcl +schema-include pub-mceliece6960119-x25519.tcl +schema-include pub-slh-dsa-shake-256s.tcl +schema-include pub-sntrup761-x25519.tcl diff --git a/tcl/schemas/pub-data.tcl b/tcl/schemas/pub-data.tcl index 7a65c0d7be079acee4c093cc7532e48443fed3d7b2a59019627df9ec2f8f665f..b0cf8612d276817a1d1db03a31c8ac4e738443ff3eccb24368fb5d1887f60c1a 100644 --- a/tcl/schemas/pub-data.tcl +++ b/tcl/schemas/pub-data.tcl @@ -3,7 +3,7 @@ {field . {map} len=~} {field id {with fpr}} {field crit {} !exists} {field ku {set} >0 optional} - {field pub {list} {of av} >0} + {field pub {with av}} {field sub {map} {of type str} >0} {field prehash {list} {of type bin} >0 optional} } diff --git a/tcl/schemas/pub-ed25519-blake2b.tcl b/tcl/schemas/pub-ed25519-blake2b.tcl new file mode 100644 index 0000000000000000000000000000000000000000..0478ed7a263f0a6a46a6317101c86b457bc79f7eec6fc2ed55ca54c39623b891 --- /dev/null +++ b/tcl/schemas/pub-ed25519-blake2b.tcl @@ -0,0 +1,5 @@ +pub-ed25519-blake2b { + {field . {map}} + {field a {str} =ed25519-blake2b} + {field v {bin} len=32} +} diff --git a/tcl/schemas/pub-gost3410.tcl b/tcl/schemas/pub-gost3410.tcl new file mode 100644 index 0000000000000000000000000000000000000000..c583d579e653ed1463623561c9ceb7ad6a8f44177dc032dc7331ff2766212b43 --- /dev/null +++ b/tcl/schemas/pub-gost3410.tcl @@ -0,0 +1,11 @@ +pub-gost3410-256A { + {field . {map}} + {field a {str} =gost3410-256A} + {field v {bin} len=64} +} + +pub-gost3410-512C { + {field . {map}} + {field a {str} =gost3410-512C} + {field v {bin} len=128} +} diff --git a/tcl/schemas/pub-mceliece6960119-x25519.tcl b/tcl/schemas/pub-mceliece6960119-x25519.tcl new file mode 100644 index 0000000000000000000000000000000000000000..90a46383ebf3e10983f7afb133632901f75e1fdaf802445ff793b683ecd18ee0 --- /dev/null +++ b/tcl/schemas/pub-mceliece6960119-x25519.tcl @@ -0,0 +1,5 @@ +pub-mceliece6960119-x25519 { + {field . {map}} + {field a {str} =mceliece6960119-x25519} + {field v {bin} len=1047351} +} diff --git a/tcl/schemas/pub-slh-dsa-shake-256s.tcl b/tcl/schemas/pub-slh-dsa-shake-256s.tcl new file mode 100644 index 0000000000000000000000000000000000000000..2b6c8e8151af403039465a1e6932b301e34c341fcc775f30e2e3a96874c92919 --- /dev/null +++ b/tcl/schemas/pub-slh-dsa-shake-256s.tcl @@ -0,0 +1,5 @@ +pub-slh-dsa-shake-256s { + {field . {map}} + {field a {str} =slh-dsa-shake-256s} + {field v {bin} len=128} +} diff --git a/tcl/schemas/pub-sntrup761-x25519.tcl b/tcl/schemas/pub-sntrup761-x25519.tcl new file mode 100644 index 0000000000000000000000000000000000000000..fb21cbcffe5d7d929c34b5d515e11b184224b66941e704808538c3c826592116 --- /dev/null +++ b/tcl/schemas/pub-sntrup761-x25519.tcl @@ -0,0 +1,5 @@ +pub-sntrup761 { + {field . {map}} + {field a {str} =sntrup761-x25519} + {field v {bin} len=1190} +} diff --git a/tcl/schemas/pub.tcl b/tcl/schemas/pub.tcl index 76a314534abbf2ed38a5834b8c489d532cdb260ec955840f5371f69cf3e61245..f7a2e45e529ad2084ab7ed9907eeb274871e9c4897a0acd5feff0b4bd191b56a 100644 --- a/tcl/schemas/pub.tcl +++ b/tcl/schemas/pub.tcl @@ -11,18 +11,13 @@ {field . {map}} {field t {str} =pub} } -av { - {field . {map}} - {field a {str} >0} - {field v {bin}} -} - sig { {field . {map} len=~} {field tbs {with pub-sig-tbs}} {field sign {with av}} } +schema-include av.tcl schema-include fpr.tcl schema-include pub-data.tcl schema-include pub-sig-tbs.tcl diff --git a/tcl/schemas/sign-ed25519-blake2b.tcl b/tcl/schemas/sign-ed25519-blake2b.tcl new file mode 100644 index 0000000000000000000000000000000000000000..ee2ea6ee779ce8edcb95cdc2f54202f704f6fe02a9c6964276f1749751ba4142 --- /dev/null +++ b/tcl/schemas/sign-ed25519-blake2b.tcl @@ -0,0 +1,17 @@ +sign-ed25519-blake2b { + {field . {map}} + {field a {str} =ed25519-blake2b} + {field v {bin} len=64} +} + +sign-ed25519ph-blake2b { + {field . {map}} + {field a {str} =ed25519ph-blake2b} + {field v {bin} len=64} +} + +sign-ed25519ph-blake2b-merkle { + {field . {map}} + {field a {str} =ed25519ph-blake2b-merkle} + {field v {bin} len=64} +} diff --git a/tcl/schemas/sign-gost3410.tcl b/tcl/schemas/sign-gost3410.tcl new file mode 100644 index 0000000000000000000000000000000000000000..f2a265eaa1d3024c0360a2b293253e57fc151e403420f9e8fe7731a7ff42d6cb --- /dev/null +++ b/tcl/schemas/sign-gost3410.tcl @@ -0,0 +1,23 @@ +sign-gost3410-256A { + {field . {map}} + {field a {str} =gost3410-256A} + {field v {bin} len=64} +} + +sign-gost3410-512C { + {field . {map}} + {field a {str} =gost3410-512C} + {field v {bin} len=128} +} + +sign-gost3410-256A-merkle { + {field . {map}} + {field a {str} =gost3410-256A-merkle} + {field v {bin} len=64} +} + +sign-gost3410-512C-merkle { + {field . {map}} + {field a {str} =gost3410-512C-merkle} + {field v {bin} len=128} +} diff --git a/tcl/schemas/sign-slh-dsa-shake-256s.tcl b/tcl/schemas/sign-slh-dsa-shake-256s.tcl new file mode 100644 index 0000000000000000000000000000000000000000..496edeb4dbf391b481e16e1b72fa458d50c9cda13f681e4b9a574f3b0b466e9d --- /dev/null +++ b/tcl/schemas/sign-slh-dsa-shake-256s.tcl @@ -0,0 +1,17 @@ +sign-slh-dsa-shake-256s { + {field . {map}} + {field a {str} =slh-dsa-shake-256s} + {field v {bin} len=29792} +} + +sign-slh-dsa-shake-256s-ph { + {field . {map}} + {field a {str} =slh-dsa-shake-256s-ph} + {field v {bin} len=29792} +} + +sign-slh-dsa-shake-256s-ph { + {field . {map}} + {field a {str} =slh-dsa-shake-256s-merkle} + {field v {bin} len=29792} +}