// Encrypt secures a message with the current timestamp. func Encrypt(key *Key, plaintext []byte) *Box { if key == nil { return nil } now := uint64(time.Now().UnixNano()) sbkey := cekdf(key, now) defer zero(sbkey[:]) sbox, ok := secretbox.Seal(plaintext, sbkey) if !ok { return nil } var tagKey [k512Size]byte copy(tagKey[:], sbkey[k512Size:]) defer zero(tagKey[:]) tag := tagTimestamp(tagKey, now) return &Box{ Data: sbox, Timestamp: now, Tag: tag, } }
// Seal secures a message using public key cryptography. It uses // ephemeral Curve25519 key pairs for encryption, but does not // digitally sign the box. func Seal(msg []byte, pub *[PublicKeySize]byte) (box []byte, ok bool) { epriv, epub, ok := GenerateKey() if !ok { return } sk := SharedKey(epriv, pub) defer secretbox.Zero(sk[:]) sbox, ok := secretbox.Seal(msg, sk) if !ok { return } box = make([]byte, len(sbox)+PublicKeySize+3) box[0] = BoxVersion box[1] = TypeSingle box[2] = CipherDualCurve25519 copy(box[3:PublicKeySize+3], epub[:]) copy(box[3+PublicKeySize:], sbox) return }
// Seal secures and authenticates the message using the password // to generate a key. func Seal(password, msg []byte) (box []byte, ok bool) { key, salt, ok := generateKey(password) if !ok { return } boxLength := len(msg) + secretbox.Overhead + 32 + saltLength box = make([]byte, boxLength) copy(box[:saltLength], salt) saltTag := keccakMac(key[:saltLength], salt) copy(box[saltLength:saltLength*2], saltTag) var sbKey [secretbox.KeySize]byte copy(sbKey[:], key[saltLength:]) sbox, ok := secretbox.Seal(msg, &sbKey) secretbox.Zero(sbKey[:]) if !ok { box = nil return } copy(box[2*saltLength:], sbox) ok = true return }