"crypto/hkdf"
"crypto/rand"
"crypto/sha3"
+ "encoding/hex"
"errors"
"flag"
+ "fmt"
"hash"
"io"
+ "io/fs"
"log"
"os"
+ "path"
"strconv"
+ "strings"
"github.com/google/uuid"
"go.cypherpunks.su/balloon/v3"
X25519KeyLen = 32
)
+var (
+ PrvDir = flag.String("prvs", "prvs", "Path to directory with private keys")
+ PubDir = flag.String("pubs", "pubs", "Path to directory with public keys")
+)
+
func blake2bHash() hash.Hash {
h, err := blake2b.New512(nil)
if err != nil {
return h
}
-func parsePrv(data []byte) (av cm.AV, tail []byte, err error) {
+func pubParse(pth string) (pubData *sign.PubData, err error) {
+ var data []byte
+ data, err = os.ReadFile(pth)
+ if err != nil {
+ return
+ }
+ var signed *sign.Signed
+ signed, _, err = sign.PubParse(data)
+ if err != nil {
+ return
+ }
+ 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
+}
+
+func findPub(id []byte) (pub *sign.PubData, err error) {
+ pth := path.Join(
+ *PubDir, strings.ToUpper(hex.EncodeToString(id)),
+ )
+ if _, err = os.Stat(pth); err != nil {
+ if errors.Is(err, fs.ErrNotExist) {
+ err = nil
+ }
+ return
+ }
+ return pubParse(pth)
+}
+
+func findPrv(id []byte) (av *cm.AV, err error) {
+ data, err := os.ReadFile(path.Join(
+ *PrvDir, strings.ToUpper(hex.EncodeToString(id)),
+ ))
+ if err != nil {
+ if errors.Is(err, fs.ErrNotExist) {
+ err = nil
+ }
+ return
+ }
data, err = cmballoon.PossibleInteractiveDecrypt(data)
if err != nil {
return
return
}
}
- if err = d.UnmarshalStruct(&av); err != nil {
- return
+ var v cm.AV
+ if err = d.UnmarshalStruct(&v); err == nil {
+ av = &v
}
- tail = d.B
return
}
log.SetFlags(log.Lshortfile)
flag.Usage = usage
setId := flag.String("id", "", "Set that /id instead of autogeneration")
- includeTo := flag.Bool("include-to", false, `Include "to" field in KEMs`)
+ assumeToHex := flag.String("assume-to", "",
+ `Assume that hexadecimal "to" value if missing`)
+ assumeFromHex := flag.String("assume-from", "",
+ `Assume that hexadecimal "from" value if missing`)
+ noFrom := flag.Bool("no-from", false, `Do not include "from" field in KEMs`)
+ noTo := flag.Bool("no-to", false, `Do not include "to" field in KEMs`)
passphrase := flag.Bool("p", false, "Use passphrase")
balloonS := flag.Int("balloon-s", 1<<17, "Balloon's space cost")
balloonT := flag.Int("balloon-t", 4, "Balloon's time cost")
doDecrypt := flag.Bool("d", false, "Decrypt")
parallel := flag.Int("parallel", cmhash.DefaultNumCPU, "Parallel cryptors")
noblob := flag.Bool("embed", false, "Include payload into container")
- flag.Parse()
-
- fdPubR := os.NewFile(FdPubR, "pub-in")
+ fromPth := flag.String("from", "", "Path to sender's public key for authentication")
var pubs []cm.AV
var pubIds [][]byte
- if data, err := io.ReadAll(fdPubR); err == nil {
- for len(data) > 0 {
- var signed *sign.Signed
- signed, data, err = sign.PubParse(data)
- if err != nil {
- log.Fatalln("public key:", len(pubs), ":", err)
- }
- pubData := signed.PubData()
- if !pubData.Can(sign.KUKEM) {
- log.Println(
- "public key:", len(pubs), ": does not have",
- sign.KUKEM, "key usage",
- )
- }
- if len(pubData.Pub) != 1 {
- log.Fatalln("public key:", len(pubs), ": expected single public key")
- }
- pubs = append(pubs, pubData.Pub[0])
- pubIds = append(pubIds, pubData.Id)
+ flag.Func("to", "Path to recipient's public key", func(v string) error {
+ pubData, err := pubParse(v)
+ if err != nil {
+ log.Fatalln(v, ":", err)
+ }
+ pubs = append(pubs, pubData.Pub[0])
+ pubIds = append(pubIds, pubData.Id)
+ return nil
+ })
+ flag.Parse()
+
+ var err error
+ var assumeTo []byte
+ if *assumeToHex != "" {
+ assumeTo, err = hex.DecodeString(*assumeToHex)
+ if err != nil {
+ log.Fatal(err)
+ }
+ }
+ var assumeFrom []byte
+ if *assumeFromHex != "" {
+ assumeFrom, err = hex.DecodeString(*assumeFromHex)
+ if err != nil {
+ log.Fatal(err)
}
}
- fdPubR.Close()
- fdPrvR := os.NewFile(FdPrvR, "prv-in")
- var prvs []*cm.AV
- if data, err := io.ReadAll(fdPrvR); err == nil {
- for len(data) > 0 {
- var av cm.AV
- av, data, err = parsePrv(data)
- if err != nil {
- log.Fatalln("private key:", len(prvs), ":", err)
- }
- prvs = append(prvs, &av)
+ var fromA string
+ var fromPrv, fromPub, fromId []byte
+ if *fromPth != "" {
+ var pubData *sign.PubData
+ 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
+ fromId = pubData.Id
+ switch fromA {
+ case sntrup761x25519.SNTRUP761X25519, mceliece6960119x25519.ClassicMcEliece6960119X25519:
+ fromPub = pubData.Pub[0].V
+ fromPub = fromPub[len(fromPub)-X25519KeyLen:]
+ default:
+ log.Fatal("from: unsupported algorithm")
}
+ var prv *cm.AV
+ prv, err = findPrv(pubData.Id)
+ if err != nil {
+ log.Fatalln("from:", err)
+ }
+ if prv == nil {
+ log.Fatal("from: can not find corresponding private key")
+ }
+ fromPrv = prv.V[len(prv.V)-X25519KeyLen:]
}
- fdPrvR.Close()
- var err error
var cek []byte
if *doDecrypt {
{
continue
}
case sntrup761x25519.SNTRUP761X25519HKDFBLAKE2b:
- if len(prvs) == 0 {
- log.Println(kemIdx, kem.A, "skipping because no private key specified")
- continue
- }
if kem.Encap == nil {
log.Fatalln("missing encap")
}
if len(kem.Encap) != scheme.CiphertextSize()+X25519KeyLen {
log.Fatalln("invalid encap len")
}
- for _, prv := range prvs {
- if prv.A != sntrup761x25519.SNTRUP761X25519 {
+ if len(kem.To) == 0 {
+ if assumeTo == nil {
+ log.Println(kemIdx, kem.A,
+ `skipping because no "to" specified`)
continue
}
- if len(prv.V) != scheme.PrivateKeySize()+X25519KeyLen {
- log.Fatalln("invalid private keys len")
- }
- var ourSNTRUP sntrup761kem.PrivateKey
- ourSNTRUP, err = scheme.UnmarshalBinaryPrivateKey(
- prv.V[:scheme.PrivateKeySize()],
- )
- if err != nil {
- log.Fatal(err)
+ kem.To = assumeTo
+ }
+ var prv *cm.AV
+ prv, err = findPrv(kem.To)
+ if err != nil {
+ log.Fatal(err)
+ }
+ if prv == nil {
+ log.Println(kemIdx, kem.A,
+ "skipping because no private key found")
+ continue
+ }
+ if prv.A != sntrup761x25519.SNTRUP761X25519 {
+ log.Fatalln(kemIdx, kem.A, "differing algorithm")
+ }
+ if len(prv.V) != scheme.PrivateKeySize()+X25519KeyLen {
+ log.Fatalln("invalid private keys len")
+ }
+ var from *sign.PubData
+ if kem.From != nil {
+ if bytes.Equal(kem.From, bytes.Repeat([]byte{0}, 32)) {
+ kem.From = assumeFrom
}
- x25519 := ecdh.X25519()
- var ourX25519 *ecdh.PrivateKey
- ourX25519, err = x25519.NewPrivateKey(
- prv.V[scheme.PrivateKeySize():],
- )
+ from, err = findPub(kem.From)
if err != nil {
- log.Fatal(err)
+ log.Fatalln("from:", err)
}
- theirSNTRUP := kem.Encap[:scheme.CiphertextSize()]
- var keySNTRUP []byte
- keySNTRUP, err = scheme.Decapsulate(ourSNTRUP, theirSNTRUP)
- if err != nil {
- continue
+ if from == nil {
+ log.Fatalln(kemIdx, kem.A, "can not find public key")
}
- var theirX25519 *ecdh.PublicKey
- theirX25519, err = x25519.NewPublicKey(
- kem.Encap[scheme.CiphertextSize():],
- )
+ }
+ var ourSNTRUP sntrup761kem.PrivateKey
+ ourSNTRUP, err = scheme.UnmarshalBinaryPrivateKey(
+ prv.V[:scheme.PrivateKeySize()],
+ )
+ if err != nil {
+ log.Fatal(err)
+ }
+ x25519 := ecdh.X25519()
+ var ourX25519 *ecdh.PrivateKey
+ ourX25519, err = x25519.NewPrivateKey(
+ prv.V[scheme.PrivateKeySize():],
+ )
+ if err != nil {
+ log.Fatal(err)
+ }
+ theirSNTRUP := kem.Encap[:scheme.CiphertextSize()]
+ var keySNTRUP []byte
+ keySNTRUP, err = scheme.Decapsulate(ourSNTRUP, theirSNTRUP)
+ if err != nil {
+ log.Fatalln(kemIdx, kem.A, "decapsulate:", err)
+ }
+ var theirX25519 *ecdh.PublicKey
+ theirX25519, err = x25519.NewPublicKey(
+ kem.Encap[scheme.CiphertextSize():],
+ )
+ if err != nil {
+ log.Fatal(err)
+ }
+ var keyX25519 []byte
+ keyX25519, err = ourX25519.ECDH(theirX25519)
+ if err != nil {
+ log.Fatal(err)
+ }
+ {
+ var ourSNTRUPPub []byte
+ ourSNTRUPPub, err = ourSNTRUP.Public().MarshalBinary()
if err != nil {
log.Fatal(err)
}
- var keyX25519 []byte
- keyX25519, err = ourX25519.ECDH(theirX25519)
+ ctHash := blake2b.Sum512(kem.Encap)
+ pkHash := blake2b.Sum512(append(
+ ourSNTRUPPub,
+ ourX25519.PublicKey().Bytes()...,
+ ))
+ ikm := bytes.Join([][]byte{
+ keySNTRUP[:], keyX25519, ctHash[:], pkHash[:],
+ }, []byte{})
+ var prk []byte
+ prk, err = hkdf.Extract(blake2bHash, ikm, nil)
if err != nil {
log.Fatal(err)
}
- {
-
- var ourSNTRUPPub []byte
- ourSNTRUPPub, err = ourSNTRUP.Public().MarshalBinary()
+ if from != nil {
+ fromPub = from.Pub[0].V
+ fromPub = fromPub[len(fromPub)-X25519KeyLen:]
+ theirX25519, err = x25519.NewPublicKey(fromPub)
if err != nil {
log.Fatal(err)
}
- ctHash := blake2b.Sum512(kem.Encap)
- pkHash := blake2b.Sum512(append(
- ourSNTRUPPub,
- ourX25519.PublicKey().Bytes()...,
- ))
- ikm := bytes.Join([][]byte{
- keySNTRUP[:], keyX25519, ctHash[:], pkHash[:],
- }, []byte{})
- var prk []byte
- prk, err = hkdf.Extract(blake2bHash, ikm, nil)
+ keyX25519, err = ourX25519.ECDH(theirX25519)
if err != nil {
log.Fatal(err)
}
- var kek []byte
- kek, err = hkdf.Expand(
+ prk, err = hkdf.Expand(
blake2bHash,
prk,
- string(append(
- []byte(cmenc.SNTRUP761X25519Info),
- encrypted.Id[:]...)),
- chacha20poly1305.KeySize,
+ cmenc.SNTRUP761X25519AuthInfo,
+ blake2b.Size,
)
if err != nil {
log.Fatal(err)
}
- var cekp []byte
- cekp, err = chapoly.Unwrap(kek, kem.CEK)
+ ikm = bytes.Join([][]byte{
+ keyX25519, fromPub, ourX25519.PublicKey().Bytes(),
+ }, []byte{})
+ prk, err = hkdf.Extract(blake2bHash, ikm, prk)
if err != nil {
- log.Println(kemIdx, kem.A, err, ", skipping")
- continue
- }
- if len(cekp) != chapoly.CEKLen {
- log.Println(kemIdx, kem.A, "wrong key len, skipping")
- continue
+ log.Fatal(err)
}
- cek = cekp
- break
}
+ var kek []byte
+ kek, err = hkdf.Expand(
+ blake2bHash,
+ prk,
+ string(append(
+ []byte(cmenc.SNTRUP761X25519Info),
+ encrypted.Id[:]...)),
+ chacha20poly1305.KeySize)
+ if err != nil {
+ log.Fatal(err)
+ }
+ var cekp []byte
+ cekp, err = chapoly.Unwrap(kek, kem.CEK)
+ if err != nil {
+ log.Fatalln(kemIdx, kem.A, "unwrap:", err)
+ }
+ if len(cekp) != chapoly.CEKLen {
+ log.Fatalln(kemIdx, kem.A, "wrong key len, skipping")
+ }
+ cek = cekp
+ break
}
case mceliece6960119x25519.ClassicMcEliece6960119X25519HKDFSHAKE256:
- if len(prvs) == 0 {
- log.Println(kemIdx, kem.A, "skipping because no private key specified")
- continue
- }
if kem.Encap == nil {
log.Fatalln("missing encap")
}
if len(kem.Encap) != mceliece6960119.CiphertextSize+X25519KeyLen+chacha20poly1305.Overhead {
log.Fatalln("invalid encap len")
}
- for _, prv := range prvs {
- if prv.A != mceliece6960119x25519.ClassicMcEliece6960119X25519 {
+ if len(kem.To) == 0 {
+ if assumeTo == nil {
+ log.Println(kemIdx, kem.A,
+ `skipping because no "to" specified`)
continue
}
- if len(prv.V) != mceliece6960119.PrivateKeySize+X25519KeyLen {
- log.Fatalln("invalid private keys len")
+ kem.To = assumeTo
+ }
+ var prv *cm.AV
+ prv, err = findPrv(kem.To)
+ if err != nil {
+ log.Fatal(err)
+ }
+ if prv == nil {
+ log.Println(kemIdx, kem.A,
+ "skipping because no private key found")
+ continue
+ }
+ if prv.A != mceliece6960119x25519.ClassicMcEliece6960119X25519 {
+ continue
+ }
+ if len(prv.V) != mceliece6960119.PrivateKeySize+X25519KeyLen {
+ log.Fatalln("invalid private keys len")
+ }
+ var from *sign.PubData
+ if kem.From != nil {
+ if bytes.Equal(kem.From, bytes.Repeat([]byte{0}, 32)) {
+ kem.From = assumeFrom
+ }
+ from, err = findPub(kem.From)
+ if err != nil {
+ log.Fatalln("from:", err)
+ }
+ if from == nil {
+ log.Fatalln(kemIdx, kem.A, "can not find public key")
}
- var ourMcEliece *mceliece6960119.PrivateKey
- ourMcEliece, err = mceliece6960119.UnmarshalBinaryPrivateKey(
- prv.V[:len(prv.V)-X25519KeyLen],
+ }
+ var ourMcEliece *mceliece6960119.PrivateKey
+ ourMcEliece, err = mceliece6960119.UnmarshalBinaryPrivateKey(
+ prv.V[:len(prv.V)-X25519KeyLen],
+ )
+ if err != nil {
+ log.Fatal(err)
+ }
+ x25519 := ecdh.X25519()
+ var ourX25519 *ecdh.PrivateKey
+ ourX25519, err = x25519.NewPrivateKey(prv.V[len(prv.V)-X25519KeyLen:])
+ if err != nil {
+ log.Fatal(err)
+ }
+ theirMcEliece := (kem.Encap)[:len(kem.Encap)-X25519KeyLen-chacha20poly1305.Overhead]
+ theirX2559Encap := (kem.Encap)[len(kem.Encap)-X25519KeyLen-chacha20poly1305.Overhead:]
+ var keyMcEliece []byte
+ keyMcEliece, err = mceliece6960119.Decapsulate(
+ ourMcEliece, theirMcEliece,
+ )
+ if err != nil {
+ log.Fatal(err)
+ }
+ var theirX25519 *ecdh.PublicKey
+ {
+ var decapKeymat []byte
+ decapKeymat, err = hkdf.Expand(
+ cmhash.NewSHAKE256,
+ keyMcEliece,
+ string(append(
+ []byte(cmenc.ClassicMcEliece6960119X25519DecapInfo),
+ encrypted.Id[:]...)),
+ chacha20poly1305.KeySize+chacha20poly1305.NonceSizeX,
)
if err != nil {
log.Fatal(err)
}
- x25519 := ecdh.X25519()
- var ourX25519 *ecdh.PrivateKey
- ourX25519, err = x25519.NewPrivateKey(prv.V[len(prv.V)-X25519KeyLen:])
+ decapKey := decapKeymat[:chacha20poly1305.KeySize]
+ decapNonce := decapKeymat[chacha20poly1305.KeySize:]
+ var aead cipher.AEAD
+ aead, err = chacha20poly1305.NewX(decapKey)
if err != nil {
log.Fatal(err)
}
- theirMcEliece := (kem.Encap)[:len(kem.Encap)-X25519KeyLen-chacha20poly1305.Overhead]
- theirX2559Encap := (kem.Encap)[len(kem.Encap)-X25519KeyLen-chacha20poly1305.Overhead:]
- var keyMcEliece []byte
- keyMcEliece, err = mceliece6960119.Decapsulate(
- ourMcEliece, theirMcEliece,
- )
+ var theirX25519Raw []byte
+ theirX25519Raw, err = aead.Open(
+ nil,
+ decapNonce,
+ theirX2559Encap,
+ theirMcEliece)
if err != nil {
log.Fatal(err)
}
- var theirX25519 *ecdh.PublicKey
- {
- var decapKeymat []byte
- decapKeymat, err = hkdf.Expand(
- cmhash.NewSHAKE256,
- keyMcEliece,
- string(append(
- []byte(cmenc.ClassicMcEliece6960119X25519DecapInfo),
- encrypted.Id[:]...)),
- chacha20poly1305.KeySize+chacha20poly1305.NonceSizeX,
- )
- if err != nil {
- log.Fatal(err)
- }
- decapKey := decapKeymat[:chacha20poly1305.KeySize]
- decapNonce := decapKeymat[chacha20poly1305.KeySize:]
- var aead cipher.AEAD
- aead, err = chacha20poly1305.NewX(decapKey)
- if err != nil {
- log.Fatal(err)
- }
- var theirX25519Raw []byte
- theirX25519Raw, err = aead.Open(
- nil,
- decapNonce,
- theirX2559Encap,
- theirMcEliece)
- if err != nil {
- log.Fatal(err)
- }
- theirX25519, err = x25519.NewPublicKey(theirX25519Raw)
- if err != nil {
- log.Fatal(err)
- }
+ theirX25519, err = x25519.NewPublicKey(theirX25519Raw)
+ if err != nil {
+ log.Fatal(err)
}
- var keyX25519 []byte
- keyX25519, err = ourX25519.ECDH(theirX25519)
+ }
+ var keyX25519 []byte
+ keyX25519, err = ourX25519.ECDH(theirX25519)
+ if err != nil {
+ log.Fatal(err)
+ }
+ {
+ ourMcEliecePub := ourMcEliece.Public()
+ var ourMcEliecePubRaw []byte
+ ourMcEliecePubRaw, err = ourMcEliecePub.MarshalBinary()
if err != nil {
log.Fatal(err)
}
- {
- ourMcEliecePub := ourMcEliece.Public()
- var ourMcEliecePubRaw []byte
- ourMcEliecePubRaw, err = ourMcEliecePub.MarshalBinary()
+ pkHash := cmhash.NewSHAKE256()
+ pkHash.Write(ourMcEliecePubRaw)
+ pkHash.Write(ourX25519.PublicKey().Bytes())
+ ikm := bytes.Join([][]byte{
+ keyMcEliece, keyX25519,
+ sha3.SumSHAKE256(kem.Encap, 64),
+ pkHash.Sum(nil),
+ }, []byte{})
+ var prk []byte
+ prk, err = hkdf.Extract(cmhash.NewSHAKE256, ikm, nil)
+ if err != nil {
+ log.Fatal(err)
+ }
+ if from != nil {
+ fromPub = from.Pub[0].V
+ fromPub = fromPub[len(fromPub)-X25519KeyLen:]
+ theirX25519, err = x25519.NewPublicKey(fromPub)
if err != nil {
log.Fatal(err)
}
- pkHash := cmhash.NewSHAKE256()
- pkHash.Write(ourMcEliecePubRaw)
- pkHash.Write(ourX25519.PublicKey().Bytes())
- ikm := bytes.Join([][]byte{
- keyMcEliece, keyX25519,
- sha3.SumSHAKE256(kem.Encap, 64),
- pkHash.Sum(nil),
- }, []byte{})
- var prk []byte
- prk, err = hkdf.Extract(cmhash.NewSHAKE256, ikm, nil)
+ keyX25519, err = ourX25519.ECDH(theirX25519)
if err != nil {
log.Fatal(err)
}
- var kek []byte
- kek, err = hkdf.Expand(
+ prk, err = hkdf.Expand(
cmhash.NewSHAKE256,
prk,
- string(append(
- []byte(cmenc.ClassicMcEliece6960119X25519Info),
- encrypted.Id[:]...)),
- chacha20poly1305.KeySize,
+ cmenc.ClassicMcEliece6960119X25519AuthInfo,
+ 64,
)
if err != nil {
log.Fatal(err)
}
- var cekp []byte
- cekp, err = chapoly.Unwrap(kek, kem.CEK)
+ ikm = bytes.Join([][]byte{
+ keyX25519, fromPub, ourX25519.PublicKey().Bytes(),
+ }, []byte{})
+ prk, err = hkdf.Extract(cmhash.NewSHAKE256, ikm, prk)
if err != nil {
- log.Println(kemIdx, kem.A, err, ", skipping")
- continue
- }
- if len(cekp) != chapoly.CEKLen {
- log.Println(kemIdx, kem.A, "wrong key len, skipping")
- continue
+ log.Fatal(err)
}
- cek = cekp
- break
}
+ var kek []byte
+ kek, err = hkdf.Expand(
+ cmhash.NewSHAKE256,
+ prk,
+ string(append(
+ []byte(cmenc.ClassicMcEliece6960119X25519Info),
+ encrypted.Id[:]...)),
+ chacha20poly1305.KeySize,
+ )
+ if err != nil {
+ log.Fatal(err)
+ }
+ var cekp []byte
+ cekp, err = chapoly.Unwrap(kek, kem.CEK)
+ if err != nil {
+ log.Fatalln(kemIdx, kem.A, "unwrap:", err)
+ }
+ if len(cekp) != chapoly.CEKLen {
+ log.Fatalln(kemIdx, kem.A, "wrong key len, skipping")
+ }
+ cek = cekp
+ break
}
default:
log.Println("unsupported KEM:", kem.A)
log.Fatal(err)
}
var ourPrvX25519 *ecdh.PrivateKey
- ourPrvX25519, err = ecdh.X25519().GenerateKey(rand.Reader)
+ ourPrvX25519, err = x25519.GenerateKey(rand.Reader)
if err != nil {
log.Fatal(err)
}
if err != nil {
log.Fatal(err)
}
+ if fromPrv != nil {
+ if fromA != sntrup761x25519.SNTRUP761X25519 {
+ log.Fatal("differing sender/recipient algorithms")
+ }
+ ourPrvX25519, err = x25519.NewPrivateKey(fromPrv)
+ if err != nil {
+ log.Fatal(err)
+ }
+ keyX25519, err = ourPrvX25519.ECDH(theirX25519)
+ if err != nil {
+ log.Fatal(err)
+ }
+ prk, err = hkdf.Expand(
+ blake2bHash,
+ prk,
+ cmenc.SNTRUP761X25519AuthInfo,
+ blake2b.Size,
+ )
+ if err != nil {
+ log.Fatal(err)
+ }
+ ikm = bytes.Join([][]byte{
+ keyX25519, fromPub, theirX25519.Bytes(),
+ }, []byte{})
+ prk, err = hkdf.Extract(blake2bHash, ikm, prk)
+ if err != nil {
+ log.Fatal(err)
+ }
+ if *noFrom {
+ kem.From = bytes.Repeat([]byte{0}, 32)
+ } else {
+ kem.From = fromId
+ }
+ }
var kek []byte
kek, err = hkdf.Expand(
blake2bHash,
}
kem.CEK = cekp
}
- if *includeTo {
+ if !*noTo {
kem.To = pubIds[pubId]
}
kems = append(kems, kem)
if err != nil {
log.Fatal(err)
}
+ if fromPrv != nil {
+ if fromA != mceliece6960119x25519.ClassicMcEliece6960119X25519 {
+ log.Fatal("differing sender/recipient algorithms")
+ }
+ ourPrvX25519, err = x25519.NewPrivateKey(fromPrv)
+ if err != nil {
+ log.Fatal(err)
+ }
+ keyX25519, err = ourPrvX25519.ECDH(theirX25519)
+ if err != nil {
+ log.Fatal(err)
+ }
+ prk, err = hkdf.Expand(
+ cmhash.NewSHAKE256,
+ prk,
+ cmenc.ClassicMcEliece6960119X25519AuthInfo,
+ 64,
+ )
+ if err != nil {
+ log.Fatal(err)
+ }
+ ikm = bytes.Join([][]byte{
+ keyX25519, fromPub, theirX25519.Bytes(),
+ }, []byte{})
+ prk, err = hkdf.Extract(cmhash.NewSHAKE256, ikm, prk)
+ if err != nil {
+ log.Fatal(err)
+ }
+ if *noFrom {
+ kem.From = bytes.Repeat([]byte{0}, 32)
+ } else {
+ kem.From = fromId
+ }
+ }
var kek []byte
kek, err = hkdf.Expand(
cmhash.NewSHAKE256,
}
kem.CEK = cekp
}
- if *includeTo {
+ if !*noTo {
kem.To = pubIds[pubId]
}
kems = append(kems, kem)