package main import ( "crypto/rand" "crypto/sha512" "encoding/binary" "golang.org/x/crypto/ed25519" ) func NewKey() (PubKey, EncKey, error) { pub, sec, err := ed25519.GenerateKey(rand.Reader) if err != nil { return PubKey{}, EncKey{}, err } var keyNum uint64 if err := binary.Read(rand.Reader, binary.BigEndian, &keyNum); err != nil { return PubKey{}, EncKey{}, err } pubKey := PubKey{ PKAlg: PKAlg, KeyNum: keyNum, } copy(pubKey.PubKey[:], pub) encKey := EncKey{ PKAlg: PKAlg, KDFAlg: KDFAlg, KeyNum: keyNum, } copy(encKey.SecKey[:], sec) checkSum := sha512.Sum512(sec) copy(encKey.Checksum[:], checkSum[:len(encKey.Checksum)]) rand.Read(encKey.Salt[:]) return pubKey, encKey, nil } func Generate(pubkeyfile, seckeyfile, comment string, rounds int) error { pubKey, encKey, err := NewKey() if err != nil { return err } if rounds > 0 { pass, err := AskPassword(nil, true) if err != nil { return err } encKey.Kdf(pass, rounds) } sb64, err := Marshal(encKey) if err != nil { return err } sfile := File{ Comment: comment + " secret key", RawKey: sb64, } if err := sfile.WriteFile(seckeyfile, SecMode); err != nil { return err } pb64, err := Marshal(pubKey) if err != nil { return err } pfile := File{ Comment: comment + " public key", RawKey: pb64, } if err := pfile.WriteFile(pubkeyfile, PubMode); err != nil { return err } return nil }