From 70d63a6bf27a20a699b9d5a251abae333ca8b5fb Mon Sep 17 00:00:00 2001 From: Hector Chu Date: Mon, 24 Feb 2025 17:48:02 +0000 Subject: [PATCH] Convert scrypt C code to Go --- ltcutil/scrypt/scrypt.c | 91 ------------------------------- ltcutil/scrypt/scrypt.go | 115 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 111 insertions(+), 95 deletions(-) delete mode 100644 ltcutil/scrypt/scrypt.c diff --git a/ltcutil/scrypt/scrypt.c b/ltcutil/scrypt/scrypt.c deleted file mode 100644 index 16a011bbf7..0000000000 --- a/ltcutil/scrypt/scrypt.c +++ /dev/null @@ -1,91 +0,0 @@ -#include -#include - -#define ROTL(a, b) (((a) << (b)) | ((a) >> (32 - (b)))) - -static inline void xor_salsa8(uint32_t B[16], const uint32_t Bx[16]) -{ - uint32_t x00,x01,x02,x03,x04,x05,x06,x07,x08,x09,x10,x11,x12,x13,x14,x15; - int i; - - x00 = (B[ 0] ^= Bx[ 0]); - x01 = (B[ 1] ^= Bx[ 1]); - x02 = (B[ 2] ^= Bx[ 2]); - x03 = (B[ 3] ^= Bx[ 3]); - x04 = (B[ 4] ^= Bx[ 4]); - x05 = (B[ 5] ^= Bx[ 5]); - x06 = (B[ 6] ^= Bx[ 6]); - x07 = (B[ 7] ^= Bx[ 7]); - x08 = (B[ 8] ^= Bx[ 8]); - x09 = (B[ 9] ^= Bx[ 9]); - x10 = (B[10] ^= Bx[10]); - x11 = (B[11] ^= Bx[11]); - x12 = (B[12] ^= Bx[12]); - x13 = (B[13] ^= Bx[13]); - x14 = (B[14] ^= Bx[14]); - x15 = (B[15] ^= Bx[15]); - - for (i = 0; i < 8; i += 2) { - /* Operate on columns. */ - x04 ^= ROTL(x00 + x12, 7); x09 ^= ROTL(x05 + x01, 7); - x14 ^= ROTL(x10 + x06, 7); x03 ^= ROTL(x15 + x11, 7); - - x08 ^= ROTL(x04 + x00, 9); x13 ^= ROTL(x09 + x05, 9); - x02 ^= ROTL(x14 + x10, 9); x07 ^= ROTL(x03 + x15, 9); - - x12 ^= ROTL(x08 + x04, 13); x01 ^= ROTL(x13 + x09, 13); - x06 ^= ROTL(x02 + x14, 13); x11 ^= ROTL(x07 + x03, 13); - - x00 ^= ROTL(x12 + x08, 18); x05 ^= ROTL(x01 + x13, 18); - x10 ^= ROTL(x06 + x02, 18); x15 ^= ROTL(x11 + x07, 18); - - /* Operate on rows. */ - x01 ^= ROTL(x00 + x03, 7); x06 ^= ROTL(x05 + x04, 7); - x11 ^= ROTL(x10 + x09, 7); x12 ^= ROTL(x15 + x14, 7); - - x02 ^= ROTL(x01 + x00, 9); x07 ^= ROTL(x06 + x05, 9); - x08 ^= ROTL(x11 + x10, 9); x13 ^= ROTL(x12 + x15, 9); - - x03 ^= ROTL(x02 + x01, 13); x04 ^= ROTL(x07 + x06, 13); - x09 ^= ROTL(x08 + x11, 13); x14 ^= ROTL(x13 + x12, 13); - - x00 ^= ROTL(x03 + x02, 18); x05 ^= ROTL(x04 + x07, 18); - x10 ^= ROTL(x09 + x08, 18); x15 ^= ROTL(x14 + x13, 18); - } - - B[ 0] += x00; - B[ 1] += x01; - B[ 2] += x02; - B[ 3] += x03; - B[ 4] += x04; - B[ 5] += x05; - B[ 6] += x06; - B[ 7] += x07; - B[ 8] += x08; - B[ 9] += x09; - B[10] += x10; - B[11] += x11; - B[12] += x12; - B[13] += x13; - B[14] += x14; - B[15] += x15; -} - -void scrypt_aux(uint32_t X[32]) -{ - uint32_t V[32768], i, j, k; - - for (i = 0; i < 1024; i++) { - memcpy(&V[i * 32], X, 128); - xor_salsa8(&X[0], &X[16]); - xor_salsa8(&X[16], &X[0]); - } - - for (i = 0; i < 1024; i++) { - j = 32 * (X[16] & 1023); - for (k = 0; k < 32; k++) - X[k] ^= V[j + k]; - xor_salsa8(&X[0], &X[16]); - xor_salsa8(&X[16], &X[0]); - } -} diff --git a/ltcutil/scrypt/scrypt.go b/ltcutil/scrypt/scrypt.go index f2e780a798..300135cd53 100644 --- a/ltcutil/scrypt/scrypt.go +++ b/ltcutil/scrypt/scrypt.go @@ -1,16 +1,123 @@ package scrypt -// void scrypt_aux(unsigned char*); -import "C" - import ( "crypto/sha256" + "math/bits" + "unsafe" "golang.org/x/crypto/pbkdf2" ) func Scrypt(x []byte) []byte { X := pbkdf2.Key(x, x, 1, 128, sha256.New) - C.scrypt_aux((*C.uchar)(&X[0])) + scrypt((*[32]uint32)(unsafe.Pointer(&X[0]))) return pbkdf2.Key(x, X, 1, 32, sha256.New) } + +func scrypt(X *[32]uint32) { + var ( + V [1024][32]uint32 + A = (*[16]uint32)(X[:16]) + B = (*[16]uint32)(X[16:]) + ) + + for i := 0; i < len(V); i++ { + V[i] = *X + salsa8(A, B) + salsa8(B, A) + } + + for i := 0; i < len(V); i++ { + j := X[16] % uint32(len(V)) + for k := 0; k < len(X); k++ { + X[k] ^= V[j][k] + } + salsa8(A, B) + salsa8(B, A) + } +} + +func salsa8(A, B *[16]uint32) { + A[0] ^= B[0] + A[1] ^= B[1] + A[2] ^= B[2] + A[3] ^= B[3] + A[4] ^= B[4] + A[5] ^= B[5] + A[6] ^= B[6] + A[7] ^= B[7] + A[8] ^= B[8] + A[9] ^= B[9] + A[10] ^= B[10] + A[11] ^= B[11] + A[12] ^= B[12] + A[13] ^= B[13] + A[14] ^= B[14] + A[15] ^= B[15] + + x00, x01, x02, x03 := A[0], A[1], A[2], A[3] + x04, x05, x06, x07 := A[4], A[5], A[6], A[7] + x08, x09, x10, x11 := A[8], A[9], A[10], A[11] + x12, x13, x14, x15 := A[12], A[13], A[14], A[15] + + for i := 0; i < 4; i++ { + // Columns + x04 ^= bits.RotateLeft32(x00+x12, 7) + x09 ^= bits.RotateLeft32(x05+x01, 7) + x14 ^= bits.RotateLeft32(x10+x06, 7) + x03 ^= bits.RotateLeft32(x15+x11, 7) + + x08 ^= bits.RotateLeft32(x04+x00, 9) + x13 ^= bits.RotateLeft32(x09+x05, 9) + x02 ^= bits.RotateLeft32(x14+x10, 9) + x07 ^= bits.RotateLeft32(x03+x15, 9) + + x12 ^= bits.RotateLeft32(x08+x04, 13) + x01 ^= bits.RotateLeft32(x13+x09, 13) + x06 ^= bits.RotateLeft32(x02+x14, 13) + x11 ^= bits.RotateLeft32(x07+x03, 13) + + x00 ^= bits.RotateLeft32(x12+x08, 18) + x05 ^= bits.RotateLeft32(x01+x13, 18) + x10 ^= bits.RotateLeft32(x06+x02, 18) + x15 ^= bits.RotateLeft32(x11+x07, 18) + + // Rows + x01 ^= bits.RotateLeft32(x00+x03, 7) + x06 ^= bits.RotateLeft32(x05+x04, 7) + x11 ^= bits.RotateLeft32(x10+x09, 7) + x12 ^= bits.RotateLeft32(x15+x14, 7) + + x02 ^= bits.RotateLeft32(x01+x00, 9) + x07 ^= bits.RotateLeft32(x06+x05, 9) + x08 ^= bits.RotateLeft32(x11+x10, 9) + x13 ^= bits.RotateLeft32(x12+x15, 9) + + x03 ^= bits.RotateLeft32(x02+x01, 13) + x04 ^= bits.RotateLeft32(x07+x06, 13) + x09 ^= bits.RotateLeft32(x08+x11, 13) + x14 ^= bits.RotateLeft32(x13+x12, 13) + + x00 ^= bits.RotateLeft32(x03+x02, 18) + x05 ^= bits.RotateLeft32(x04+x07, 18) + x10 ^= bits.RotateLeft32(x09+x08, 18) + x15 ^= bits.RotateLeft32(x14+x13, 18) + } + + A[0] += x00 + A[1] += x01 + A[2] += x02 + A[3] += x03 + A[4] += x04 + A[5] += x05 + A[6] += x06 + A[7] += x07 + A[8] += x08 + A[9] += x09 + A[10] += x10 + A[11] += x11 + A[12] += x12 + A[13] += x13 + A[14] += x14 + A[15] += x15 +}