-
Notifications
You must be signed in to change notification settings - Fork 1
/
symmetric_block_mode.go
74 lines (51 loc) · 2.05 KB
/
symmetric_block_mode.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package ecies
import (
"crypto/cipher"
"io"
)
var CBCCipherMode = SymmetricCipherMode{
Encryptor: CBCEncrypt,
Decryptor: CBCDecrypt,
}
// CBCEncrypt performs Cipher Block Chaining (CBC) encryption using the block cipher specified in
// the parameters
func CBCEncrypt(rand io.Reader, params *ECIESParams, key, plaintext, authenticationData []byte) ([]byte, error) {
blockCipher, err := params.Cipher(key)
if err != nil {
return nil, err
}
iv, err := GenerateIV(params.BlockSize, rand)
if err != nil {
return nil, err
}
return SymmetricBlockModeEncrypt(cipher.NewCBCEncrypter, blockCipher, iv, key, plaintext), nil
}
// CBCDecrypt performs Cipher Block Chaining (CBC) decryption using the block cipher specified in
// the parameters
func CBCDecrypt(rand io.Reader, params *ECIESParams, key, ciphertext, authenticationData []byte) ([]byte, error) {
blockCipher, err := params.Cipher(key)
if err != nil {
return nil, err
}
return SymmetricBlockModeDecrypt(cipher.NewCBCDecrypter, blockCipher, ciphertext[:params.BlockSize], key, ciphertext[params.BlockSize:]), nil
}
// Performs sysmmetric encrypion using the specified block cipher
func SymmetricBlockModeEncrypt(str func(cipher.Block, []byte) cipher.BlockMode, blockCipher cipher.Block, iv []byte, key, plaintext []byte) (ciphertext []byte) {
// Initialize the cipher
blockModeCipher := str(blockCipher, iv)
// Creates a byte sink the size of plaintext plus iv
ciphertext = make([]byte, len(plaintext)+len(iv))
// First params.BlockSize bytes are filled with the iv
copy(ciphertext, iv)
// The remaining bytes are filled with the encrypted message
blockModeCipher.CryptBlocks(ciphertext[len(iv):], plaintext)
return
}
// Performs sysmmetric decryption using the specified block cipher
func SymmetricBlockModeDecrypt(str func(cipher.Block, []byte) cipher.BlockMode, blockCipher cipher.Block, iv []byte, key, ciphertext []byte) []byte {
// Initialize the cipher
blockModeCipher := str(blockCipher, iv)
// Decrypt the ciphertext
blockModeCipher.CryptBlocks(ciphertext, ciphertext)
return ciphertext
}