Skip to content

Commit a1f2b7e

Browse files
committed
Faster scrypt
1 parent b332858 commit a1f2b7e

File tree

3 files changed

+109
-8
lines changed

3 files changed

+109
-8
lines changed

ltcutil/scrypt/scrypt.c

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#include <stdint.h>
2+
#include <string.h>
3+
4+
#define ROTL(a, b) (((a) << (b)) | ((a) >> (32 - (b))))
5+
6+
static inline void xor_salsa8(uint32_t B[16], const uint32_t Bx[16])
7+
{
8+
uint32_t x00,x01,x02,x03,x04,x05,x06,x07,x08,x09,x10,x11,x12,x13,x14,x15;
9+
int i;
10+
11+
x00 = (B[ 0] ^= Bx[ 0]);
12+
x01 = (B[ 1] ^= Bx[ 1]);
13+
x02 = (B[ 2] ^= Bx[ 2]);
14+
x03 = (B[ 3] ^= Bx[ 3]);
15+
x04 = (B[ 4] ^= Bx[ 4]);
16+
x05 = (B[ 5] ^= Bx[ 5]);
17+
x06 = (B[ 6] ^= Bx[ 6]);
18+
x07 = (B[ 7] ^= Bx[ 7]);
19+
x08 = (B[ 8] ^= Bx[ 8]);
20+
x09 = (B[ 9] ^= Bx[ 9]);
21+
x10 = (B[10] ^= Bx[10]);
22+
x11 = (B[11] ^= Bx[11]);
23+
x12 = (B[12] ^= Bx[12]);
24+
x13 = (B[13] ^= Bx[13]);
25+
x14 = (B[14] ^= Bx[14]);
26+
x15 = (B[15] ^= Bx[15]);
27+
28+
for (i = 0; i < 8; i += 2) {
29+
/* Operate on columns. */
30+
x04 ^= ROTL(x00 + x12, 7); x09 ^= ROTL(x05 + x01, 7);
31+
x14 ^= ROTL(x10 + x06, 7); x03 ^= ROTL(x15 + x11, 7);
32+
33+
x08 ^= ROTL(x04 + x00, 9); x13 ^= ROTL(x09 + x05, 9);
34+
x02 ^= ROTL(x14 + x10, 9); x07 ^= ROTL(x03 + x15, 9);
35+
36+
x12 ^= ROTL(x08 + x04, 13); x01 ^= ROTL(x13 + x09, 13);
37+
x06 ^= ROTL(x02 + x14, 13); x11 ^= ROTL(x07 + x03, 13);
38+
39+
x00 ^= ROTL(x12 + x08, 18); x05 ^= ROTL(x01 + x13, 18);
40+
x10 ^= ROTL(x06 + x02, 18); x15 ^= ROTL(x11 + x07, 18);
41+
42+
/* Operate on rows. */
43+
x01 ^= ROTL(x00 + x03, 7); x06 ^= ROTL(x05 + x04, 7);
44+
x11 ^= ROTL(x10 + x09, 7); x12 ^= ROTL(x15 + x14, 7);
45+
46+
x02 ^= ROTL(x01 + x00, 9); x07 ^= ROTL(x06 + x05, 9);
47+
x08 ^= ROTL(x11 + x10, 9); x13 ^= ROTL(x12 + x15, 9);
48+
49+
x03 ^= ROTL(x02 + x01, 13); x04 ^= ROTL(x07 + x06, 13);
50+
x09 ^= ROTL(x08 + x11, 13); x14 ^= ROTL(x13 + x12, 13);
51+
52+
x00 ^= ROTL(x03 + x02, 18); x05 ^= ROTL(x04 + x07, 18);
53+
x10 ^= ROTL(x09 + x08, 18); x15 ^= ROTL(x14 + x13, 18);
54+
}
55+
56+
B[ 0] += x00;
57+
B[ 1] += x01;
58+
B[ 2] += x02;
59+
B[ 3] += x03;
60+
B[ 4] += x04;
61+
B[ 5] += x05;
62+
B[ 6] += x06;
63+
B[ 7] += x07;
64+
B[ 8] += x08;
65+
B[ 9] += x09;
66+
B[10] += x10;
67+
B[11] += x11;
68+
B[12] += x12;
69+
B[13] += x13;
70+
B[14] += x14;
71+
B[15] += x15;
72+
}
73+
74+
void scrypt_aux(uint32_t X[32])
75+
{
76+
uint32_t V[32768], i, j, k;
77+
78+
for (i = 0; i < 1024; i++) {
79+
memcpy(&V[i * 32], X, 128);
80+
xor_salsa8(&X[0], &X[16]);
81+
xor_salsa8(&X[16], &X[0]);
82+
}
83+
84+
for (i = 0; i < 1024; i++) {
85+
j = 32 * (X[16] & 1023);
86+
for (k = 0; k < 32; k++)
87+
X[k] ^= V[j + k];
88+
xor_salsa8(&X[0], &X[16]);
89+
xor_salsa8(&X[16], &X[0]);
90+
}
91+
}

ltcutil/scrypt/scrypt.go

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package scrypt
2+
3+
// void scrypt_aux(unsigned char*);
4+
import "C"
5+
6+
import (
7+
"crypto/sha256"
8+
9+
"golang.org/x/crypto/pbkdf2"
10+
)
11+
12+
func Scrypt(x []byte) []byte {
13+
X := pbkdf2.Key(x, x, 1, 128, sha256.New)
14+
C.scrypt_aux((*C.uchar)(&X[0]))
15+
return pbkdf2.Key(x, X, 1, 32, sha256.New)
16+
}

wire/blockheader.go

+2-8
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,8 @@ import (
99
"io"
1010
"time"
1111

12-
"golang.org/x/crypto/scrypt"
13-
1412
"github.com/ltcsuite/ltcd/chaincfg/chainhash"
13+
"github.com/ltcsuite/ltcd/ltcutil/scrypt"
1514
)
1615

1716
// MaxBlockHeaderPayload is the maximum number of bytes a block header can be.
@@ -61,15 +60,10 @@ func (h *BlockHeader) BlockHash() chainhash.Hash {
6160
// PowHash returns the litecoin scrypt hash of this block header. This value is
6261
// used to check the PoW on blocks advertised on the network.
6362
func (h *BlockHeader) PowHash() chainhash.Hash {
64-
var powHash chainhash.Hash
65-
6663
buf := bytes.NewBuffer(make([]byte, 0, MaxBlockHeaderPayload))
6764
_ = writeBlockHeader(buf, 0, h)
6865

69-
scryptHash, _ := scrypt.Key(buf.Bytes(), buf.Bytes(), 1024, 1, 1, 32)
70-
copy(powHash[:], scryptHash)
71-
72-
return powHash
66+
return *(*chainhash.Hash)(scrypt.Scrypt(buf.Bytes()))
7367
}
7468

7569
// BtcDecode decodes r using the litecoin protocol encoding into the receiver.

0 commit comments

Comments
 (0)