Skip to content

Commit 299f1c2

Browse files
committed
Convert scrypt C code to Go
1 parent 79182db commit 299f1c2

File tree

2 files changed

+120
-95
lines changed

2 files changed

+120
-95
lines changed

ltcutil/scrypt/scrypt.c

-91
This file was deleted.

ltcutil/scrypt/scrypt.go

+120-4
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,132 @@
11
package scrypt
22

3-
// void scrypt_aux(unsigned char*);
4-
import "C"
5-
63
import (
74
"crypto/sha256"
5+
"math/bits"
6+
"sync"
7+
"unsafe"
88

99
"golang.org/x/crypto/pbkdf2"
1010
)
1111

12+
type scratch = [1024][32]uint32
13+
14+
var pool = sync.Pool{New: func() interface{} {
15+
return &scratch{}
16+
}}
17+
1218
func Scrypt(x []byte) []byte {
1319
X := pbkdf2.Key(x, x, 1, 128, sha256.New)
14-
C.scrypt_aux((*C.uchar)(&X[0]))
20+
scrypt((*[32]uint32)(unsafe.Pointer(&X[0])))
1521
return pbkdf2.Key(x, X, 1, 32, sha256.New)
1622
}
23+
24+
func scrypt(X *[32]uint32) {
25+
var (
26+
A = (*[16]uint32)(X[:16])
27+
B = (*[16]uint32)(X[16:])
28+
V = pool.Get().(*scratch)
29+
)
30+
31+
for i := 0; i < len(V); i++ {
32+
V[i] = *X
33+
salsa8(A, B)
34+
salsa8(B, A)
35+
}
36+
37+
for i := 0; i < len(V); i++ {
38+
j := X[16] % uint32(len(V))
39+
for k := 0; k < len(X); k++ {
40+
X[k] ^= V[j][k]
41+
}
42+
salsa8(A, B)
43+
salsa8(B, A)
44+
}
45+
46+
pool.Put(V)
47+
}
48+
49+
func salsa8(A, B *[16]uint32) {
50+
A[0] ^= B[0]
51+
A[1] ^= B[1]
52+
A[2] ^= B[2]
53+
A[3] ^= B[3]
54+
A[4] ^= B[4]
55+
A[5] ^= B[5]
56+
A[6] ^= B[6]
57+
A[7] ^= B[7]
58+
A[8] ^= B[8]
59+
A[9] ^= B[9]
60+
A[10] ^= B[10]
61+
A[11] ^= B[11]
62+
A[12] ^= B[12]
63+
A[13] ^= B[13]
64+
A[14] ^= B[14]
65+
A[15] ^= B[15]
66+
67+
x00, x01, x02, x03 := A[0], A[1], A[2], A[3]
68+
x04, x05, x06, x07 := A[4], A[5], A[6], A[7]
69+
x08, x09, x10, x11 := A[8], A[9], A[10], A[11]
70+
x12, x13, x14, x15 := A[12], A[13], A[14], A[15]
71+
72+
for i := 0; i < 4; i++ {
73+
// Columns
74+
x04 ^= bits.RotateLeft32(x00+x12, 7)
75+
x09 ^= bits.RotateLeft32(x05+x01, 7)
76+
x14 ^= bits.RotateLeft32(x10+x06, 7)
77+
x03 ^= bits.RotateLeft32(x15+x11, 7)
78+
79+
x08 ^= bits.RotateLeft32(x04+x00, 9)
80+
x13 ^= bits.RotateLeft32(x09+x05, 9)
81+
x02 ^= bits.RotateLeft32(x14+x10, 9)
82+
x07 ^= bits.RotateLeft32(x03+x15, 9)
83+
84+
x12 ^= bits.RotateLeft32(x08+x04, 13)
85+
x01 ^= bits.RotateLeft32(x13+x09, 13)
86+
x06 ^= bits.RotateLeft32(x02+x14, 13)
87+
x11 ^= bits.RotateLeft32(x07+x03, 13)
88+
89+
x00 ^= bits.RotateLeft32(x12+x08, 18)
90+
x05 ^= bits.RotateLeft32(x01+x13, 18)
91+
x10 ^= bits.RotateLeft32(x06+x02, 18)
92+
x15 ^= bits.RotateLeft32(x11+x07, 18)
93+
94+
// Rows
95+
x01 ^= bits.RotateLeft32(x00+x03, 7)
96+
x06 ^= bits.RotateLeft32(x05+x04, 7)
97+
x11 ^= bits.RotateLeft32(x10+x09, 7)
98+
x12 ^= bits.RotateLeft32(x15+x14, 7)
99+
100+
x02 ^= bits.RotateLeft32(x01+x00, 9)
101+
x07 ^= bits.RotateLeft32(x06+x05, 9)
102+
x08 ^= bits.RotateLeft32(x11+x10, 9)
103+
x13 ^= bits.RotateLeft32(x12+x15, 9)
104+
105+
x03 ^= bits.RotateLeft32(x02+x01, 13)
106+
x04 ^= bits.RotateLeft32(x07+x06, 13)
107+
x09 ^= bits.RotateLeft32(x08+x11, 13)
108+
x14 ^= bits.RotateLeft32(x13+x12, 13)
109+
110+
x00 ^= bits.RotateLeft32(x03+x02, 18)
111+
x05 ^= bits.RotateLeft32(x04+x07, 18)
112+
x10 ^= bits.RotateLeft32(x09+x08, 18)
113+
x15 ^= bits.RotateLeft32(x14+x13, 18)
114+
}
115+
116+
A[0] += x00
117+
A[1] += x01
118+
A[2] += x02
119+
A[3] += x03
120+
A[4] += x04
121+
A[5] += x05
122+
A[6] += x06
123+
A[7] += x07
124+
A[8] += x08
125+
A[9] += x09
126+
A[10] += x10
127+
A[11] += x11
128+
A[12] += x12
129+
A[13] += x13
130+
A[14] += x14
131+
A[15] += x15
132+
}

0 commit comments

Comments
 (0)