OSDN Git Service

new repo
[bytom/vapor.git] / vendor / github.com / tendermint / go-crypto / symmetric.go
1 package crypto
2
3 import (
4         "errors"
5
6         . "github.com/tendermint/tmlibs/common"
7         "golang.org/x/crypto/nacl/secretbox"
8 )
9
10 const nonceLen = 24
11 const secretLen = 32
12
13 // secret must be 32 bytes long. Use something like Sha256(Bcrypt(passphrase))
14 // The ciphertext is (secretbox.Overhead + 24) bytes longer than the plaintext.
15 // NOTE: call crypto.MixEntropy() first.
16 func EncryptSymmetric(plaintext []byte, secret []byte) (ciphertext []byte) {
17         if len(secret) != secretLen {
18                 PanicSanity(Fmt("Secret must be 32 bytes long, got len %v", len(secret)))
19         }
20         nonce := CRandBytes(nonceLen)
21         nonceArr := [nonceLen]byte{}
22         copy(nonceArr[:], nonce)
23         secretArr := [secretLen]byte{}
24         copy(secretArr[:], secret)
25         ciphertext = make([]byte, nonceLen+secretbox.Overhead+len(plaintext))
26         copy(ciphertext, nonce)
27         secretbox.Seal(ciphertext[nonceLen:nonceLen], plaintext, &nonceArr, &secretArr)
28         return ciphertext
29 }
30
31 // secret must be 32 bytes long. Use something like Sha256(Bcrypt(passphrase))
32 // The ciphertext is (secretbox.Overhead + 24) bytes longer than the plaintext.
33 func DecryptSymmetric(ciphertext []byte, secret []byte) (plaintext []byte, err error) {
34         if len(secret) != secretLen {
35                 PanicSanity(Fmt("Secret must be 32 bytes long, got len %v", len(secret)))
36         }
37         if len(ciphertext) <= secretbox.Overhead+nonceLen {
38                 return nil, errors.New("Ciphertext is too short")
39         }
40         nonce := ciphertext[:nonceLen]
41         nonceArr := [nonceLen]byte{}
42         copy(nonceArr[:], nonce)
43         secretArr := [secretLen]byte{}
44         copy(secretArr[:], secret)
45         plaintext = make([]byte, len(ciphertext)-nonceLen-secretbox.Overhead)
46         _, ok := secretbox.Open(plaintext[:0], ciphertext[nonceLen:], &nonceArr, &secretArr)
47         if !ok {
48                 return nil, errors.New("Ciphertext decryption failed")
49         }
50         return plaintext, nil
51 }