Skip to content

Commit 8d68e96

Browse files
committed
Added Lyra2RE algo
1 parent f366619 commit 8d68e96

24 files changed

+3307
-3687
lines changed

Makefile.am

+1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ sgminer_SOURCES += algorithm/fresh.c algorithm/fresh.h
6969
sgminer_SOURCES += algorithm/whirlcoin.c algorithm/whirlcoin.h
7070
sgminer_SOURCES += algorithm/neoscrypt.c algorithm/neoscrypt.h
7171
sgminer_SOURCES += algorithm/whirlpoolx.c algorithm/whirlpoolx.h
72+
sgminer_SOURCES += algorithm/lyra2re.c algorithm/lyra2re.h algorithm/lyra2.c algorithm/lyra2.h algorithm/sponge.c algorithm/sponge.h
7273

7374
bin_SCRIPTS = $(top_srcdir)/kernel/*.cl
7475

algorithm.c

+51-2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "algorithm/whirlcoin.h"
3333
#include "algorithm/neoscrypt.h"
3434
#include "algorithm/whirlpoolx.h"
35+
#include "algorithm/lyra2re.h"
3536

3637
#include "compat.h"
3738

@@ -54,7 +55,8 @@ const char *algorithm_type_str[] = {
5455
"Fresh",
5556
"Whirlcoin",
5657
"Neoscrypt",
57-
"WhirlpoolX"
58+
"WhirlpoolX",
59+
"Lyra2RE"
5860
};
5961

6062
void sha256(const unsigned char *message, unsigned int len, unsigned char *digest)
@@ -653,6 +655,50 @@ static cl_int queue_whirlpoolx_kernel(struct __clState *clState, struct _dev_blk
653655
return status;
654656
}
655657

658+
static cl_int queue_lyra2RE_kernel(struct __clState *clState, struct _dev_blk_ctx *blk, __maybe_unused cl_uint threads)
659+
{
660+
cl_kernel *kernel;
661+
unsigned int num;
662+
cl_int status = 0;
663+
cl_ulong le_target;
664+
665+
le_target = *(cl_ulong *)(blk->work->device_target + 24);
666+
flip80(clState->cldata, blk->work->data);
667+
status = clEnqueueWriteBuffer(clState->commandQueue, clState->CLbuffer0, true, 0, 80, clState->cldata, 0, NULL, NULL);
668+
669+
// blake - search
670+
kernel = &clState->kernel;
671+
num = 0;
672+
673+
CL_SET_ARG(clState->padbuffer8);
674+
CL_SET_ARG(blk->work->blk.ctx_a);
675+
CL_SET_ARG(blk->work->blk.ctx_b);
676+
CL_SET_ARG(blk->work->blk.ctx_c);
677+
CL_SET_ARG(blk->work->blk.ctx_d);
678+
CL_SET_ARG(blk->work->blk.ctx_e);
679+
CL_SET_ARG(blk->work->blk.ctx_f);
680+
CL_SET_ARG(blk->work->blk.ctx_g);
681+
CL_SET_ARG(blk->work->blk.ctx_h);
682+
CL_SET_ARG(blk->work->blk.cty_a);
683+
CL_SET_ARG(blk->work->blk.cty_b);
684+
CL_SET_ARG(blk->work->blk.cty_c);
685+
686+
// bmw - search1
687+
kernel = clState->extra_kernels;
688+
CL_SET_ARG_0(clState->padbuffer8);
689+
// groestl - search2
690+
CL_NEXTKERNEL_SET_ARG_0(clState->padbuffer8);
691+
// skein - search3
692+
CL_NEXTKERNEL_SET_ARG_0(clState->padbuffer8);
693+
// jh - search4
694+
num = 0;
695+
CL_NEXTKERNEL_SET_ARG(clState->padbuffer8);
696+
CL_SET_ARG(clState->outputBuffer);
697+
CL_SET_ARG(le_target);
698+
699+
return status;
700+
}
701+
656702
typedef struct _algorithm_settings_t {
657703
const char *name; /* Human-readable identifier */
658704
algorithm_type_t type; //common algorithm type
@@ -728,6 +774,8 @@ static algorithm_settings_t algos[] = {
728774

729775
{ "fresh", ALGO_FRESH, "", 1, 256, 256, 0, 0, 0xFF, 0xFFFFULL, 0x0000ffffUL, 4, 4 * 16 * 4194304, 0, fresh_regenhash, queue_fresh_kernel, gen_hash, NULL},
730776

777+
{ "lyra2re", ALGO_LYRA2RE, "", 1, 128, 128, 0, 0, 0xFF, 0xFFFFULL, 0x0000ffffUL, 4, 2 * 8 * 4194304 , 0, lyra2re_regenhash, queue_lyra2RE_kernel, gen_hash, NULL},
778+
731779
// kernels starting from this will have difficulty calculated by using fuguecoin algorithm
732780
#define A_FUGUE(a, b, c) \
733781
{ a, ALGO_FUGUE, "", 1, 256, 256, 0, 0, 0xFF, 0xFFFFULL, 0x0000ffffUL, 0, 0, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, b, queue_sph_kernel, c, NULL}
@@ -737,7 +785,6 @@ static algorithm_settings_t algos[] = {
737785
#undef A_FUGUE
738786

739787
{ "whirlcoin", ALGO_WHIRL, "", 1, 1, 1, 0, 0, 0xFF, 0xFFFFULL, 0x0000ffffUL, 3, 8 * 16 * 4194304, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, whirlcoin_regenhash, queue_whirlcoin_kernel, sha256, NULL},
740-
741788
{ "whirlpoolx", ALGO_WHIRL, "", 1, 1, 1, 0, 0, 0xFF, 0xFFFFULL, 0x0000ffffUL, 0, 0, 0, whirlpoolx_regenhash, queue_sph_kernel, gen_hash, NULL },
742789

743790
// Terminator (do not remove)
@@ -812,6 +859,8 @@ static const char *lookup_algorithm_alias(const char *lookup_alias, uint8_t *nfa
812859
ALGO_ALIAS("keccak", "maxcoin");
813860
ALGO_ALIAS("whirlpool", "whirlcoin");
814861
ALGO_ALIAS("whirlpoolx", "whirlpoolx");
862+
ALGO_ALIAS("Lyra2RE", "lyra2re");
863+
ALGO_ALIAS("lyra2", "lyra2re");
815864

816865
#undef ALGO_ALIAS
817866
#undef ALGO_ALIAS_NF

algorithm.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ typedef enum {
2525
ALGO_NIST,
2626
ALGO_FRESH,
2727
ALGO_WHIRL,
28-
ALGO_NEOSCRYPT
28+
ALGO_NEOSCRYPT,
29+
ALGO_LYRA2RE
2930
} algorithm_type_t;
3031

3132
extern const char *algorithm_type_str[];

algorithm/lyra2.c

+208
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
/**
2+
* Implementation of the Lyra2 Password Hashing Scheme (PHS).
3+
*
4+
* Author: The Lyra PHC team (http://www.lyra-kdf.net/) -- 2014.
5+
*
6+
* This software is hereby placed in the public domain.
7+
*
8+
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
9+
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
11+
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
12+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
13+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
14+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
15+
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
16+
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
17+
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
18+
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19+
*/
20+
#include <stdio.h>
21+
#include <stdlib.h>
22+
#include <string.h>
23+
#include <time.h>
24+
#include "lyra2.h"
25+
#include "sponge.h"
26+
27+
/**
28+
* Executes Lyra2 based on the G function from Blake2b. This version supports salts and passwords
29+
* whose combined length is smaller than the size of the memory matrix, (i.e., (nRows x nCols x b) bits,
30+
* where "b" is the underlying sponge's bitrate). In this implementation, the "basil" is composed by all
31+
* integer parameters (treated as type "unsigned int") in the order they are provided, plus the value
32+
* of nCols, (i.e., basil = kLen || pwdlen || saltlen || timeCost || nRows || nCols).
33+
*
34+
* @param K The derived key to be output by the algorithm
35+
* @param kLen Desired key length
36+
* @param pwd User password
37+
* @param pwdlen Password length
38+
* @param salt Salt
39+
* @param saltlen Salt length
40+
* @param timeCost Parameter to determine the processing time (T)
41+
* @param nRows Number or rows of the memory matrix (R)
42+
* @param nCols Number of columns of the memory matrix (C)
43+
*
44+
* @return 0 if the key is generated correctly; -1 if there is an error (usually due to lack of memory for allocation)
45+
*/
46+
int LYRA2(void *K, uint64_t kLen, const void *pwd, uint64_t pwdlen, const void *salt, uint64_t saltlen, uint64_t timeCost, uint64_t nRows, uint64_t nCols) {
47+
48+
//============================= Basic variables ============================//
49+
int64_t row = 2; //index of row to be processed
50+
int64_t prev = 1; //index of prev (last row ever computed/modified)
51+
int64_t rowa = 0; //index of row* (a previous row, deterministically picked during Setup and randomly picked while Wandering)
52+
int64_t tau; //Time Loop iterator
53+
int64_t step = 1; //Visitation step (used during Setup and Wandering phases)
54+
int64_t window = 2; //Visitation window (used to define which rows can be revisited during Setup)
55+
int64_t gap = 1; //Modifier to the step, assuming the values 1 or -1
56+
int64_t i; //auxiliary iteration counter
57+
//==========================================================================/
58+
59+
//========== Initializing the Memory Matrix and pointers to it =============//
60+
//Tries to allocate enough space for the whole memory matrix
61+
i = (int64_t) ((int64_t) nRows * (int64_t) ROW_LEN_BYTES);
62+
uint64_t *wholeMatrix = (uint64_t*)malloc(i);
63+
if (wholeMatrix == NULL) {
64+
return -1;
65+
}
66+
memset(wholeMatrix, 0, i);
67+
68+
//Allocates pointers to each row of the matrix
69+
uint64_t **memMatrix = (uint64_t**)malloc(nRows * sizeof (uint64_t*));
70+
if (memMatrix == NULL) {
71+
return -1;
72+
}
73+
//Places the pointers in the correct positions
74+
uint64_t *ptrWord = wholeMatrix;
75+
for (i = 0; i < nRows; i++) {
76+
memMatrix[i] = ptrWord;
77+
ptrWord += ROW_LEN_INT64;
78+
}
79+
//==========================================================================/
80+
81+
//============= Getting the password + salt + basil padded with 10*1 ===============//
82+
//OBS.:The memory matrix will temporarily hold the password: not for saving memory,
83+
//but this ensures that the password copied locally will be overwritten as soon as possible
84+
85+
//First, we clean enough blocks for the password, salt, basil and padding
86+
uint64_t nBlocksInput = ((saltlen + pwdlen + 6 * sizeof (uint64_t)) / BLOCK_LEN_BLAKE2_SAFE_BYTES) + 1;
87+
byte *ptrByte = (byte*) wholeMatrix;
88+
memset(ptrByte, 0, nBlocksInput * BLOCK_LEN_BLAKE2_SAFE_BYTES);
89+
90+
//Prepends the password
91+
memcpy(ptrByte, pwd, pwdlen);
92+
ptrByte += pwdlen;
93+
94+
//Concatenates the salt
95+
memcpy(ptrByte, salt, saltlen);
96+
ptrByte += saltlen;
97+
98+
//Concatenates the basil: every integer passed as parameter, in the order they are provided by the interface
99+
memcpy(ptrByte, &kLen, sizeof (uint64_t));
100+
ptrByte += sizeof (uint64_t);
101+
memcpy(ptrByte, &pwdlen, sizeof (uint64_t));
102+
ptrByte += sizeof (uint64_t);
103+
memcpy(ptrByte, &saltlen, sizeof (uint64_t));
104+
ptrByte += sizeof (uint64_t);
105+
memcpy(ptrByte, &timeCost, sizeof (uint64_t));
106+
ptrByte += sizeof (uint64_t);
107+
memcpy(ptrByte, &nRows, sizeof (uint64_t));
108+
ptrByte += sizeof (uint64_t);
109+
memcpy(ptrByte, &nCols, sizeof (uint64_t));
110+
ptrByte += sizeof (uint64_t);
111+
112+
//Now comes the padding
113+
*ptrByte = 0x80; //first byte of padding: right after the password
114+
ptrByte = (byte*) wholeMatrix; //resets the pointer to the start of the memory matrix
115+
ptrByte += nBlocksInput * BLOCK_LEN_BLAKE2_SAFE_BYTES - 1; //sets the pointer to the correct position: end of incomplete block
116+
*ptrByte ^= 0x01; //last byte of padding: at the end of the last incomplete block
117+
//==========================================================================/
118+
119+
//======================= Initializing the Sponge State ====================//
120+
//Sponge state: 16 uint64_t, BLOCK_LEN_INT64 words of them for the bitrate (b) and the remainder for the capacity (c)
121+
uint64_t *state = (uint64_t*)malloc(16 * sizeof (uint64_t));
122+
if (state == NULL) {
123+
return -1;
124+
}
125+
initState(state);
126+
//==========================================================================/
127+
128+
//================================ Setup Phase =============================//
129+
//Absorbing salt, password and basil: this is the only place in which the block length is hard-coded to 512 bits
130+
ptrWord = wholeMatrix;
131+
for (i = 0; i < nBlocksInput; i++) {
132+
absorbBlockBlake2Safe(state, ptrWord); //absorbs each block of pad(pwd || salt || basil)
133+
ptrWord += BLOCK_LEN_BLAKE2_SAFE_BYTES; //goes to next block of pad(pwd || salt || basil)
134+
}
135+
136+
//Initializes M[0] and M[1]
137+
reducedSqueezeRow0(state, memMatrix[0]); //The locally copied password is most likely overwritten here
138+
reducedDuplexRow1(state, memMatrix[0], memMatrix[1]);
139+
140+
do {
141+
//M[row] = rand; //M[row*] = M[row*] XOR rotW(rand)
142+
reducedDuplexRowSetup(state, memMatrix[prev], memMatrix[rowa], memMatrix[row]);
143+
144+
145+
//updates the value of row* (deterministically picked during Setup))
146+
rowa = (rowa + step) & (window - 1);
147+
//update prev: it now points to the last row ever computed
148+
prev = row;
149+
//updates row: goes to the next row to be computed
150+
row++;
151+
152+
//Checks if all rows in the window where visited.
153+
if (rowa == 0) {
154+
step = window + gap; //changes the step: approximately doubles its value
155+
window *= 2; //doubles the size of the re-visitation window
156+
gap = -gap; //inverts the modifier to the step
157+
}
158+
159+
} while (row < nRows);
160+
//==========================================================================/
161+
162+
//============================ Wandering Phase =============================//
163+
row = 0; //Resets the visitation to the first row of the memory matrix
164+
for (tau = 1; tau <= timeCost; tau++) {
165+
//Step is approximately half the number of all rows of the memory matrix for an odd tau; otherwise, it is -1
166+
step = (tau % 2 == 0) ? -1 : nRows / 2 - 1;
167+
do {
168+
//Selects a pseudorandom index row*
169+
//------------------------------------------------------------------------------------------
170+
//rowa = ((unsigned int)state[0]) & (nRows-1); //(USE THIS IF nRows IS A POWER OF 2)
171+
rowa = ((uint64_t) (state[0])) % nRows; //(USE THIS FOR THE "GENERIC" CASE)
172+
//------------------------------------------------------------------------------------------
173+
174+
//Performs a reduced-round duplexing operation over M[row*] XOR M[prev], updating both M[row*] and M[row]
175+
reducedDuplexRow(state, memMatrix[prev], memMatrix[rowa], memMatrix[row]);
176+
177+
//update prev: it now points to the last row ever computed
178+
prev = row;
179+
180+
//updates row: goes to the next row to be computed
181+
//------------------------------------------------------------------------------------------
182+
//row = (row + step) & (nRows-1); //(USE THIS IF nRows IS A POWER OF 2)
183+
row = (row + step) % nRows; //(USE THIS FOR THE "GENERIC" CASE)
184+
//------------------------------------------------------------------------------------------
185+
186+
} while (row != 0);
187+
}
188+
//==========================================================================/
189+
190+
//============================ Wrap-up Phase ===============================//
191+
//Absorbs the last block of the memory matrix
192+
absorbBlock(state, memMatrix[rowa]);
193+
194+
//Squeezes the key
195+
squeeze(state, (unsigned char*)K, kLen);
196+
//==========================================================================/
197+
198+
//========================= Freeing the memory =============================//
199+
free(memMatrix);
200+
free(wholeMatrix);
201+
202+
//Wiping out the sponge's internal state before freeing it
203+
memset(state, 0, 16 * sizeof (uint64_t));
204+
free(state);
205+
//==========================================================================/
206+
207+
return 0;
208+
}

algorithm/lyra2.h

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/**
2+
* Header file for the Lyra2 Password Hashing Scheme (PHS).
3+
*
4+
* Author: The Lyra PHC team (http://www.lyra-kdf.net/) -- 2014.
5+
*
6+
* This software is hereby placed in the public domain.
7+
*
8+
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
9+
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
11+
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
12+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
13+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
14+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
15+
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
16+
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
17+
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
18+
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19+
*/
20+
#ifndef LYRA2_H_
21+
#define LYRA2_H_
22+
23+
#include <stdint.h>
24+
25+
typedef unsigned char byte;
26+
27+
//Block length required so Blake2's Initialization Vector (IV) is not overwritten (THIS SHOULD NOT BE MODIFIED)
28+
#define BLOCK_LEN_BLAKE2_SAFE_INT64 8 //512 bits (=64 bytes, =8 uint64_t)
29+
#define BLOCK_LEN_BLAKE2_SAFE_BYTES (BLOCK_LEN_BLAKE2_SAFE_INT64 * 8) //same as above, in bytes
30+
31+
32+
#ifdef BLOCK_LEN_BITS
33+
#define BLOCK_LEN_INT64 (BLOCK_LEN_BITS/64) //Block length: 768 bits (=96 bytes, =12 uint64_t)
34+
#define BLOCK_LEN_BYTES (BLOCK_LEN_BITS/8) //Block length, in bytes
35+
#else //default block lenght: 768 bits
36+
#define BLOCK_LEN_INT64 12 //Block length: 768 bits (=96 bytes, =12 uint64_t)
37+
#define BLOCK_LEN_BYTES (BLOCK_LEN_INT64 * 8) //Block length, in bytes
38+
#endif
39+
40+
#ifndef N_COLS
41+
#define N_COLS 8 //Number of columns in the memory matrix: fixed to 64 by default
42+
#endif
43+
44+
#define ROW_LEN_INT64 (BLOCK_LEN_INT64 * N_COLS) //Total length of a row: N_COLS blocks
45+
#define ROW_LEN_BYTES (ROW_LEN_INT64 * 8) //Number of bytes per row
46+
47+
48+
int LYRA2(void *K, uint64_t kLen, const void *pwd, uint64_t pwdlen, const void *salt, uint64_t saltlen, uint64_t timeCost, uint64_t nRows, uint64_t nCols);
49+
50+
#endif /* LYRA2_H_ */

0 commit comments

Comments
 (0)