-
Notifications
You must be signed in to change notification settings - Fork 2
/
crypto.go
133 lines (107 loc) · 2.88 KB
/
crypto.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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package util
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/hex"
"fmt"
"io"
"math/big"
"golang.org/x/crypto/blake2b"
crypto "github.com/libp2p/go-libp2p-crypto"
)
const (
// HashLength is the standard size of hash values
HashLength = 32
)
// Hash represents a hash value
type Hash [HashLength]byte
// EmptyHash is an empty Hash
var EmptyHash = Hash([HashLength]byte{})
// Bytes gets the byte representation of the underlying hash.
func (h Hash) Bytes() []byte { return h[:] }
// Big converts a hash to a big integer.
func (h Hash) Big() *big.Int { return new(big.Int).SetBytes(h[:]) }
// Equal checks equality between h and o
func (h Hash) Equal(o Hash) bool { return bytes.Equal(h.Bytes(), o.Bytes()) }
// HexStr returns the hex string version of the hash beginning with 0x
func (h Hash) HexStr() string {
return ToHex(h[:])
}
// Hex is like HexStr but returns bytes
func (h Hash) Hex() []byte {
dst := make([]byte, hex.EncodedLen(len(h)))
hex.Encode(dst, h[:])
return dst
}
// SS returns a short version of HexStr with the middle
// characters truncated when length is at least 32
func (h Hash) SS() string {
s := h.HexStr()
if len(s) >= 32 {
return fmt.Sprintf("%s...%s", string(s)[0:10], string(s)[len(s)-10:])
}
return s
}
// IsEmpty checks whether the hash is empty (having zero values)
func (h Hash) IsEmpty() bool {
return h == EmptyHash
}
// HexToHash creates an Hash from hex string
func HexToHash(hex string) (Hash, error) {
bs, err := FromHex(hex)
if err != nil {
return EmptyHash, err
}
return BytesToHash(bs), nil
}
// BytesToHash copies b to a Hash
func BytesToHash(b []byte) Hash {
var h Hash
copy(h[:], b)
return h
}
// StrToHash converts a string to a Hash
func StrToHash(s string) Hash {
return BytesToHash([]byte(s))
}
// GenerateKeyPair generates private and public keys
func GenerateKeyPair(r io.Reader) (crypto.PrivKey, crypto.PubKey, error) {
return crypto.GenerateEd25519Key(r)
}
// Encrypt encrypts a plaintext
func Encrypt(plaintext []byte, key []byte) ([]byte, error) {
c, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
cipherText := make([]byte, aes.BlockSize+len(plaintext))
iv := cipherText[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
return nil, err
}
stream := cipher.NewCTR(c, iv)
stream.XORKeyStream(cipherText[aes.BlockSize:], plaintext)
return cipherText, nil
}
// Decrypt decrypts a ciphertext
func Decrypt(ciphertext []byte, key []byte) ([]byte, error) {
iv := ciphertext[:aes.BlockSize]
data := ciphertext[aes.BlockSize:]
c, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
stream := cipher.NewCTR(c, iv)
stream.XORKeyStream(data, data)
return data, nil
}
// Blake2b256 returns blake2b 256bit hash of v
func Blake2b256(v []byte) []byte {
hash, _ := blake2b.New256(nil)
if _, err := hash.Write(v); err != nil {
panic(err)
}
return hash.Sum(nil)
}