aboutsummaryrefslogtreecommitdiff
path: root/key/enc.go
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2017-07-18 01:14:06 +0200
committerDimitri Sokolyuk <demon@dim13.org>2017-07-18 01:14:06 +0200
commit77a47c251ecac64ed625c7963aa9bb2c4f09fcbd (patch)
treecf544fbae0e4708e787307d8652ee688a3a8b0bc /key/enc.go
parent9016e5ac116959e6795b7e65eab90228be5f0240 (diff)
Split
Diffstat (limited to 'key/enc.go')
-rw-r--r--key/enc.go59
1 files changed, 59 insertions, 0 deletions
diff --git a/key/enc.go b/key/enc.go
new file mode 100644
index 0000000..2f2d48d
--- /dev/null
+++ b/key/enc.go
@@ -0,0 +1,59 @@
+package key
+
+import (
+ "bytes"
+ "crypto/sha512"
+
+ "golang.org/x/crypto/ed25519"
+)
+
+type Enc struct {
+ PKAlg [2]byte
+ KDFAlg [2]byte
+ KDFRounds uint32
+ Salt [16]byte
+ Checksum [8]byte
+ KeyNum [8]byte
+ Key [ed25519.PrivateKeySize]byte
+}
+
+func (v *Enc) Sign(message []byte) *Sig {
+ sig := &Sig{PKAlg: v.PKAlg, KeyNum: v.KeyNum}
+ copy(sig.Sig[:], ed25519.Sign(ed25519.PrivateKey(v.Key[:]), message))
+ return sig
+}
+
+func (v *Enc) Check() error {
+ if v.PKAlg != pkAlg {
+ return ErrInvalidPK
+ }
+ if v.KDFAlg != kdfAlg {
+ return ErrInvalidKDF
+ }
+ sum := sha512.Sum512(v.Key[:])
+ if !bytes.Equal(sum[:len(v.Checksum)], v.Checksum[:]) {
+ return ErrInvalidKey
+ }
+ return nil
+}
+
+func (v *Enc) MarshalBinary() ([]byte, error) {
+ return Marshal(v)
+}
+
+func ParseEnc(data []byte, d KeyDeriver) (*Enc, error) {
+ var enc *Enc
+ if err := Unmarshal(data, enc); err != nil {
+ return nil, err
+ }
+ if d != nil && enc.KDFRounds > 0 {
+ xor, err := d.DeriveKey(enc.Salt[:], int(enc.KDFRounds), len(enc.Key))
+ if err != nil {
+ return nil, err
+ }
+ for i := range xor {
+ enc.Key[i] ^= xor[i]
+ }
+ }
+ return enc, enc.Check()
+}