package main import ( "bytes" "crypto/sha512" "encoding/binary" "dim13.org/signify/bhash" "golang.org/x/crypto/ed25519" ) var ( PKAlg = [2]byte{'E', 'd'} KDFAlg = [2]byte{'B', 'K'} ) type Sig struct { PKAlg [2]byte KeyNum uint64 Sig [ed25519.SignatureSize]byte } type PubKey struct { PKAlg [2]byte KeyNum uint64 PubKey [ed25519.PublicKeySize]byte } type EncKey struct { PKAlg [2]byte KDFAlg [2]byte KDFRounds uint32 Salt [16]byte Checksum [8]byte KeyNum uint64 SecKey [ed25519.PrivateKeySize]byte } func (v *EncKey) XOR(key []byte) { if len(key) != len(v.SecKey) { panic("invalid key len") } for i := range key { v.SecKey[i] ^= key[i] } } func (v *EncKey) IsValid(pass []byte) bool { if v.KDFRounds > 0 { key := bhash.Pbkdf(pass, v.Salt[:], int(v.KDFRounds), len(v.SecKey)) v.XOR(key) } sum := sha512.Sum512(v.SecKey[:]) return bytes.Equal(sum[:len(v.Checksum)], v.Checksum[:]) } func Unmarshal(b []byte, v interface{}) error { buf := bytes.NewReader(b) if err := binary.Read(buf, binary.BigEndian, v); err != nil { return err } return nil } func Marshal(v interface{}) ([]byte, error) { buf := new(bytes.Buffer) if err := binary.Write(buf, binary.BigEndian, v); err != nil { return nil, err } return buf.Bytes(), nil }