/
hash.go
130 lines (115 loc) · 3.34 KB
/
hash.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
// Copyright (C) 2017, 2018, 2019 EGAAS S.A.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or (at
// your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
package crypto
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"hash"
"github.com/AplaProject/go-apla/packages/consts"
log "github.com/sirupsen/logrus"
"golang.org/x/crypto/sha3"
)
type hashProvider int
const (
_SHA256 hashProvider = iota
)
// GetHMAC returns HMAC hash
func GetHMAC(secret string, message string) ([]byte, error) {
switch hmacProv {
case _SHA256:
mac := hmac.New(sha256.New, []byte(secret))
mac.Write([]byte(message))
return mac.Sum(nil), nil
default:
return nil, ErrUnknownProvider
}
}
// GetHMACWithTimestamp allows add timestamp
func GetHMACWithTimestamp(secret string, message string, timestamp string) ([]byte, error) {
switch hmacProv {
case _SHA256:
mac := hmac.New(sha256.New, []byte(secret))
mac.Write([]byte(message))
mac.Write([]byte(timestamp))
return mac.Sum(nil), nil
default:
return nil, ErrUnknownProvider
}
}
// Hash returns hash of passed bytes
func Hash(msg []byte) ([]byte, error) {
if len(msg) == 0 {
log.WithFields(log.Fields{"type": consts.CryptoError, "error": ErrHashingEmpty.Error()}).Debug(ErrHashingEmpty.Error())
}
switch hashProv {
case _SHA256:
return hashSHA256(msg), nil
default:
return nil, ErrUnknownProvider
}
}
// DoubleHash returns double hash of passed bytes
func DoubleHash(msg []byte) ([]byte, error) {
if len(msg) == 0 {
log.WithFields(log.Fields{"type": consts.CryptoError, "error": ErrHashingEmpty.Error()}).Debug(ErrHashingEmpty.Error())
}
switch hashProv {
case _SHA256:
return hashDoubleSHA256(msg), nil
default:
return nil, ErrUnknownProvider
}
}
func hashSHA256(msg []byte) []byte {
if len(msg) == 0 {
log.Debug(ErrHashingEmpty.Error())
}
hash := sha256.Sum256(msg)
return hash[:]
}
//TODO Replace hashDoubleSHA256 with this method
func hashDoubleSHA3(msg []byte) ([]byte, error) {
if len(msg) == 0 {
log.Debug(ErrHashingEmpty.Error())
}
return hashSHA3256(msg), nil
}
//In the previous version of this function (api v 1.0) this func worked in another way.
//First, hash has been calculated from input data
//Second, obtained hash has been converted to hex
//Third, hex value has been hashed once more time
//In this variant second step is omitted.
func hashDoubleSHA256(msg []byte) []byte {
firstHash := sha256.Sum256(msg)
secondHash := sha256.Sum256(firstHash[:])
return secondHash[:]
}
func hashSHA3256(msg []byte) []byte {
hash := make([]byte, 64)
sha3.ShakeSum256(hash, msg)
return hash[:]
}
func NewHash() hash.Hash {
return sha256.New()
}
func HashHex(input []byte) (string, error) {
hash, err := Hash(input)
if err != nil {
return "", err
}
return hex.EncodeToString(hash), nil
}