Newer
Older
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
package curl
import (
"github.com/iotaledger/goshimmer/packages/ternary"
"math"
)
const (
HASH_LENGTH = 243
STATE_LENGTH = ternary.NUMBER_OF_TRITS_IN_A_TRYTE * HASH_LENGTH
)
var (
TRUTH_TABLE = ternary.Trits{1, 0, -1, 2, 1, -1, 0, 2, -1, 1, 0}
)
type Hash interface {
Initialize()
InitializeCurl(trits *[]int8, length int, rounds int)
Reset()
Absorb(trits *[]int8, offset int, length int)
Squeeze(resp []int8, offset int, length int) []int
}
type Curl struct {
Hash
state ternary.Trits
hashLength int
rounds int
}
func NewCurl(hashLength int, rounds int) *Curl {
this := &Curl{
hashLength: hashLength,
rounds: rounds,
}
this.Reset()
return this
}
func (curl *Curl) Initialize() {
curl.InitializeCurl(nil, 0, curl.rounds)
}
func (curl *Curl) InitializeCurl(trinary ternary.Trits, length int, rounds int) {
curl.rounds = rounds
if trinary != nil {
curl.state = trinary
} else {
curl.state = make(ternary.Trits, STATE_LENGTH)
}
}
func (curl *Curl) Reset() {
curl.InitializeCurl(nil, 0, curl.rounds)
}
func (curl *Curl) Absorb(trinary ternary.Trits, offset int, length int) {
for {
limit := int(math.Min(HASH_LENGTH, float64(length)))
copy(curl.state, trinary[offset:offset+limit])
curl.Transform()
offset += HASH_LENGTH
length -= HASH_LENGTH
if length <= 0 {
break
}
}
}
func (curl *Curl) Squeeze(resp ternary.Trits, offset int, length int) ternary.Trits {
for {
limit := int(math.Min(HASH_LENGTH, float64(length)))
copy(resp[offset:offset+limit], curl.state)
curl.Transform()
offset += HASH_LENGTH
length -= HASH_LENGTH
if length <= 0 {
break
}
}
return resp
}
func (curl *Curl) Transform() {
var index = 0
for round := 0; round < curl.rounds; round++ {
stateCopy := make(ternary.Trits, STATE_LENGTH)
copy(stateCopy, curl.state)
for i := 0; i < STATE_LENGTH; i++ {
incr := 364
if index >= 365 {
incr = -365
}
index2 := index + incr
curl.state[i] = TRUTH_TABLE[stateCopy[index]+(stateCopy[index2]<<2)+5]
index = index2
}
}
}