Updates to SHA256 core and a difficulty module
This commit is contained in:
parent
547a557a14
commit
e8b6d4b19c
|
@ -37,4 +37,47 @@ package sha256_pkg;
|
|||
32'ha54ff53a, 32'h3c6ef372, 32'hbb67ae85, 32'h6a09e667
|
||||
};
|
||||
|
||||
// Functions used in bit manipulations
|
||||
function [31:0] little_sig0(input logic [31:0] in);
|
||||
little_sig0 = {rotr(in, 7)} ^ {rotr(in, 18)} ^ {shr(in, 3)};
|
||||
endfunction
|
||||
|
||||
function [31:0] little_sig1(input logic [31:0] in);
|
||||
little_sig1 = {rotr(in, 17)} ^ {rotr(in, 19)} ^ {shr(in, 10)};
|
||||
endfunction
|
||||
|
||||
function [31:0] big_sig0(input logic [31:0] in);
|
||||
big_sig0 = {rotr(in, 2)} ^ {rotr(in, 13)} ^ {rotr(in, 22)};
|
||||
endfunction
|
||||
|
||||
function [31:0] big_sig1(input logic [31:0] in);
|
||||
big_sig1 = {rotr(in, 6)} ^ {rotr(in, 11)} ^ {rotr(in, 25)};
|
||||
endfunction
|
||||
|
||||
function [31:0] ch(input logic [31:0] x, y, z);
|
||||
ch = (x & y) ^ (~x & z);
|
||||
endfunction
|
||||
|
||||
function [31:0] maj(input logic [31:0] x, y, z);
|
||||
maj = (x & y) ^ (x & z) ^ (y & z);
|
||||
endfunction
|
||||
|
||||
function [31:0] rotr(input logic [31:0] in, input int bits);
|
||||
for (int i = 0; i < 32; i++) rotr[i] = in[(i+bits) % 32];
|
||||
endfunction
|
||||
|
||||
function [31:0] shr(input logic [31:0] in, input int bits);
|
||||
shr = 0;
|
||||
shr = in >> bits;
|
||||
endfunction
|
||||
|
||||
// Swap bytes (used to convert between little and big endian)
|
||||
function [31:0] bs32(input logic [31:0] in);
|
||||
for (int i = 0; i < 4; i++) bs32[i*8 +: 8] = in[(4-1-i)*8 +: 8];
|
||||
endfunction
|
||||
|
||||
function [63:0] bs64(input logic [63:0] in);
|
||||
for (int i = 0; i < 8; i++) bs64[i*8 +: 8] = in[(8-1-i)*8 +: 8];
|
||||
endfunction
|
||||
|
||||
endpackage
|
|
@ -31,14 +31,16 @@ module sha256_top
|
|||
|
||||
localparam DAT_BYTS = 64;
|
||||
localparam DAT_BITS = DAT_BYTS*8; // Must be 512
|
||||
localparam ROUNDS = 64;
|
||||
|
||||
logic [7:0][31:0] V; // Internal state, V[0] == A, V[7] == H
|
||||
logic [31:0] T1, T2;
|
||||
logic [15:0][31:0] W;
|
||||
logic [15:0] W_nxt;
|
||||
logic eop_l, padding_only, final_block;
|
||||
logic [7:0][0:31] V, H; // Internal states, V[0] == A, V[7] == H (in big endian)
|
||||
logic [0:31] T1, T2;
|
||||
logic [15:0][0:31] W;
|
||||
logic [0:31] W_nxt;
|
||||
logic padding_only, final_block;
|
||||
logic [63:0] bit_len;
|
||||
logic [$clog2(64)-1:0] rnd_cntr;
|
||||
logic [$clog2(ROUNDS)-1:0] rnd_cntr;
|
||||
logic [1:0][0:31] bit_len_c;
|
||||
|
||||
enum {SHA_IDLE = 0,
|
||||
SHA_ROUNDS = 1,
|
||||
|
@ -46,14 +48,14 @@ enum {SHA_IDLE = 0,
|
|||
SHA_FINAL = 3} sha_state;
|
||||
|
||||
// Used to make compression function easier to read
|
||||
localparam A = 0;
|
||||
localparam B = 1;
|
||||
localparam C = 2;
|
||||
localparam D = 3;
|
||||
localparam E = 4;
|
||||
localparam F = 5;
|
||||
localparam G = 6;
|
||||
localparam H = 7;
|
||||
localparam VAR_A = 0;
|
||||
localparam VAR_B = 1;
|
||||
localparam VAR_C = 2;
|
||||
localparam VAR_D = 3;
|
||||
localparam VAR_E = 4;
|
||||
localparam VAR_F = 5;
|
||||
localparam VAR_G = 6;
|
||||
localparam VAR_H = 7;
|
||||
|
||||
|
||||
always_ff @ (posedge i_clk) begin
|
||||
|
@ -64,7 +66,6 @@ always_ff @ (posedge i_clk) begin
|
|||
i_block.rdy <= 0;
|
||||
bit_len <= 0;
|
||||
W <= 0;
|
||||
eop_l <= 0;
|
||||
padding_only <= 0;
|
||||
final_block <= 0;
|
||||
end else begin
|
||||
|
@ -75,7 +76,6 @@ always_ff @ (posedge i_clk) begin
|
|||
update_HV(1);
|
||||
rnd_cntr <= 0;
|
||||
final_block <= 0;
|
||||
eop_l <= 0;
|
||||
padding_only <= 0;
|
||||
i_block.rdy <= 1;
|
||||
// As soon as we have one write on the input we can start
|
||||
|
@ -89,26 +89,29 @@ always_ff @ (posedge i_clk) begin
|
|||
end
|
||||
end
|
||||
SHA_ROUNDS: begin
|
||||
for (int i = 0; i < 16; i++) W[i] <= W[i+i];
|
||||
for (int i = 0; i < 15; i++)
|
||||
W[i] <= W[i+1];
|
||||
W[15] <= W_nxt;
|
||||
compress();
|
||||
rnd_cntr <= rnd_cntr + 1;
|
||||
if (rnd_cntr == 62) begin
|
||||
if (rnd_cntr == ROUNDS - 1) begin
|
||||
rnd_cntr <= 0;
|
||||
i_block.rdy <= ~(final_block || padding_only);
|
||||
sha_state <= SHA_UPDATE_HV;
|
||||
end
|
||||
end
|
||||
SHA_UPDATE_HV: begin
|
||||
update_H(0);
|
||||
update_HV(0);
|
||||
if (final_block) begin
|
||||
sha_state <= SHA_FINAL;
|
||||
i_block.rdy <= 0;
|
||||
end else if (padding_only) begin
|
||||
final_block <= 1;
|
||||
W <= 0;
|
||||
W[(64-8)*8 +: 64] <= bit_len;
|
||||
W[(bit_len/8) % 64 +: 8] <= 1;
|
||||
W[15:14] <= {bit_len_c[0], bit_len_c[1]};
|
||||
if (bit_len % 512 == 0)
|
||||
W[0] <= sha256_pkg::bs32(32'd1);
|
||||
sha_state <= SHA_ROUNDS;
|
||||
end else if (i_block.rdy && i_block.val) begin
|
||||
W <= i_block.dat;
|
||||
bit_len <= bit_len + DAT_BITS;
|
||||
|
@ -121,9 +124,15 @@ always_ff @ (posedge i_clk) begin
|
|||
end
|
||||
SHA_FINAL: begin
|
||||
o_hash.val <= 1;
|
||||
o_hash.dat <= H;
|
||||
for (int i = 0; i < 8; i++)
|
||||
o_hash.dat[i*32 +: 32] <= sha256_pkg::bs32(H[i]); // Shift back to little endian
|
||||
if (o_hash.val && o_hash.rdy) begin
|
||||
o_hash.val <= 0;
|
||||
rnd_cntr <= 0;
|
||||
bit_len <= 0;
|
||||
W <= 0;
|
||||
padding_only <= 0;
|
||||
final_block <= 0;
|
||||
sha_state <= SHA_IDLE;
|
||||
end
|
||||
end
|
||||
|
@ -135,7 +144,6 @@ end
|
|||
// wise set a flag so next time we call we only add the padding block
|
||||
task msg_eop();
|
||||
|
||||
eop_l <= 1;
|
||||
bit_len <= bit_len + (i_block.mod == 0 ? DAT_BITS : i_block.mod*8);
|
||||
if (i_block.mod == 0 || i_block.mod > 64-9) begin
|
||||
padding_only <= 1; // Means we need one block extra with only len (and possibly the terminating 0x1)
|
||||
|
@ -143,41 +151,52 @@ task msg_eop();
|
|||
final_block <= 1; // This is the final block and includes padding
|
||||
end
|
||||
|
||||
for (int i = 0; i < 64; i++)
|
||||
M[i*8 +: 8] <= (i_block.mod == 0 || i < i_block.mod) ? i_block.dat[i*8 +: 8] : 0;
|
||||
// Every 32 bit word needs to be swapped to big endian
|
||||
for (int i = 0; i < 16; i++)
|
||||
W[i] <= (i_block.mod == 0 || i < i_block.mod) ? sha256_pkg::bs32(i_block.dat[i*32 +: 32]) : 0;
|
||||
|
||||
if (i_block.mod != 0)
|
||||
M[i_block.mod*8 +: 8] <= 1;
|
||||
W[i_block.mod/4][8*(i_block.mod % 4) +: 8] <= 8'h80; // Since we operate in big endian
|
||||
|
||||
if (i_block.mod < 64-9)
|
||||
M[(64-8)*8 +: 64] <= bit_len + i_block.mod*8;
|
||||
W[15:14] <= {bit_len_c[0], bit_len_c[1]};
|
||||
|
||||
endtask
|
||||
|
||||
always_comb begin
|
||||
W_nxt = little_sig1(W[14]) + W[9] + little_sig0(W[1]) + W[0];
|
||||
end
|
||||
always_comb begin
|
||||
T1 = V[H] + big_sig1(V[E]) + ch(V[E], V[F], V[G]) + sha256_pkg::K[rnd_cntr] + W[0];
|
||||
T2 = big_sig0(V[A]) + maj(V[A], V[B], V[C]);
|
||||
bit_len_c = (bit_len + i_block.mod*8);
|
||||
|
||||
W_nxt = sha256_pkg::little_sig1(W[14]) +
|
||||
W[9] +
|
||||
sha256_pkg::little_sig0(W[1]) +
|
||||
W[0];
|
||||
|
||||
T1 = V[VAR_H] +
|
||||
sha256_pkg::big_sig1(V[VAR_E]) +
|
||||
sha256_pkg::ch(V[VAR_E], V[VAR_F], V[VAR_G]) +
|
||||
sha256_pkg::K[rnd_cntr] +
|
||||
W[0];
|
||||
|
||||
T2 = sha256_pkg::big_sig0(V[VAR_A]) +
|
||||
sha256_pkg::maj(V[VAR_A], V[VAR_B], V[VAR_C]);
|
||||
end
|
||||
|
||||
task compress();
|
||||
V[H] <= V[G];
|
||||
V[G] <= V[F];
|
||||
V[F] <= V[E];
|
||||
V[E] <= V[D] + T1;
|
||||
V[D] <= V[C];
|
||||
V[C] <= V[B];
|
||||
V[B] <= V[A];
|
||||
V[A] <= T1 + T2;
|
||||
V[VAR_H] <= V[VAR_G];
|
||||
V[VAR_G] <= V[VAR_F];
|
||||
V[VAR_F] <= V[VAR_E];
|
||||
V[VAR_E] <= V[VAR_D] + T1;
|
||||
V[VAR_D] <= V[VAR_C];
|
||||
V[VAR_C] <= V[VAR_B];
|
||||
V[VAR_B] <= V[VAR_A];
|
||||
V[VAR_A] <= T1 + T2;
|
||||
endtask
|
||||
|
||||
task update_HV(logic init);
|
||||
task update_HV(input logic init);
|
||||
if (init) begin
|
||||
for (int i = 0; i < 8; i++) begin
|
||||
H[i] <= sha256_pkg::IV[i];
|
||||
V[i] <= sha256_pkg::IV[i];
|
||||
H[i] <= (sha256_pkg::IV[i]);
|
||||
V[i] <= (sha256_pkg::IV[i]);
|
||||
end
|
||||
end else begin
|
||||
for (int i = 0; i < 8; i++) begin
|
||||
|
@ -187,38 +206,10 @@ task update_HV(logic init);
|
|||
end
|
||||
endtask
|
||||
|
||||
function [31:0] litte_sig0(input logic [31:0] in);
|
||||
litte_sig0 = {rotr(in, 7)} ^ {rotr(in, 18)} ^ {shr(in, 3)};
|
||||
endfunction
|
||||
|
||||
function [31:0] litte_sig1(input logic [31:0] in);
|
||||
litte_sig1 = {rotr(in, 17)} ^ {rotr(in, 19)} ^ {shr(in, 10)};
|
||||
endfunction
|
||||
|
||||
function [31:0] big_sig0(input logic [31:0] in);
|
||||
big_sig0 = {rotr(in, 2)} ^ {rotr(in, 13)} ^ {rotr(in, 22)};
|
||||
endfunction
|
||||
|
||||
function [31:0] big_sig1(input logic [31:0] in);
|
||||
big_sig1 = {rotr(in, 6)} ^ {rotr(in, 11)} ^ {rotr(in, 25)};
|
||||
endfunction
|
||||
|
||||
function [31:0] ch(input logic [31:0] x, y, z);
|
||||
ch = (x & y) ^ (~x & z);
|
||||
endfunction
|
||||
|
||||
function [31:0] maj(input logic [31:0] x, y, z);
|
||||
maj = (x & y) ^ (x & z) ^ (y & z);
|
||||
endfunction
|
||||
|
||||
function [31:0] rotr(input logic [31:0] in, input int bits);
|
||||
for (int i = 0; i < 32; i++) rotr[i] = in[(i+bits) % 32];
|
||||
endfunction
|
||||
|
||||
function [31:0] shr(input logic [31:0] in, input int bits);
|
||||
shr = 0;
|
||||
shr = in >> bits;
|
||||
endfunction
|
||||
// Check that input size is correct
|
||||
initial begin
|
||||
assert ($bits(i_block.dat) == DAT_BITS) else $fatal(1, "%m %t ERROR: sha256_top DAT_BITS (%d) does not match interface .dat (%d)", $time, DAT_BITS, $bits(i_block.dat));
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
|
@ -22,7 +22,7 @@ module sha256_top_tb();
|
|||
import common_pkg::*;
|
||||
|
||||
logic clk, rst;
|
||||
|
||||
logic [255:0] expected;
|
||||
if_axi_stream #(.DAT_BYTS(64)) i_block(clk);
|
||||
if_axi_stream #(.DAT_BYTS(32)) out_hash(clk);
|
||||
|
||||
|
@ -45,17 +45,31 @@ sha256_top DUT (
|
|||
);
|
||||
|
||||
|
||||
// This test runs the hash which is shown in the RFC, for "abc"
|
||||
task rfc_test();
|
||||
// NIST testcase for single 512 bit block "abc"
|
||||
task nist_single_block_test();
|
||||
begin
|
||||
integer signed get_len;
|
||||
logic [common_pkg::MAX_SIM_BYTS*8-1:0] get_dat;
|
||||
$display("Running rfc_test...\n");
|
||||
expected = 'h239900d4ed8623b95a92f1dba88ad31895cc3345ded552c22d79ab2a39c5877dd1a2ffdb6fbb124bb7c45a68142f214ce9f6129fb697276a0d4d1c983fa580ba;
|
||||
i_block.put_stream("cba", 3);
|
||||
$display("Running nist_single_block_test...\n");
|
||||
expected = 'had1500f261ff10b49c7a1796a36103b02322ae5dde404141eacf018fbf1678ba; // Both in little endian
|
||||
i_block.put_stream("cba", 3); // abc in little endian
|
||||
out_hash.get_stream(get_dat, get_len);
|
||||
common_pkg::compare_and_print(get_dat, expected);
|
||||
$display("rfc_test PASSED");
|
||||
$display("nist_single_block_test PASSED");
|
||||
end
|
||||
endtask
|
||||
|
||||
// NIST testcase for double 512 bit block "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
|
||||
task nist_double_block_test();
|
||||
begin
|
||||
integer signed get_len;
|
||||
logic [common_pkg::MAX_SIM_BYTS*8-1:0] get_dat;
|
||||
$display("Running nist_double_block_test...\n");
|
||||
expected = 'hc106db19d4edecf66721ff6459e43ca339603e0c9326c0e5b83806d2616a8d24; // Both in little endian
|
||||
i_block.put_stream("qponponmonmlnmlkmlkjlkjikjihjihgihgfhgfegfedfedcedcbdcba", 56);
|
||||
out_hash.get_stream(get_dat, get_len);
|
||||
common_pkg::compare_and_print(get_dat, expected);
|
||||
$display("nist_double_block_test PASSED");
|
||||
end
|
||||
endtask
|
||||
|
||||
|
@ -67,7 +81,8 @@ initial begin
|
|||
|
||||
#200ns;
|
||||
|
||||
rfc_test();
|
||||
nist_single_block_test();
|
||||
nist_double_block_test();
|
||||
|
||||
#10us $finish();
|
||||
|
||||
|
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
This verifies that a Zcash equihash solution has the correct difficulty.
|
||||
|
||||
Take input stream of entire block header (including equihash solution and size) and
|
||||
calculate the SHA256d (double SHA256)
|
||||
|
||||
We take in the stream in DAT_BYTS in a FIFO, and load the output into 512 bit words
|
||||
for the SHA256 block. Then the 256 bit output it inputted into the same SHA256 block.
|
||||
|
||||
Copyright (C) 2019 Benjamin Devlin and Zcash Foundation
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
module zcash_verif_equihash_difficulty
|
||||
import zcash_verif_pkg::*;
|
||||
#(
|
||||
parameter DAT_BYTS = 8,
|
||||
)(
|
||||
input i_clk, i_rst,
|
||||
|
||||
if_axi_stream.sink i_axi,
|
||||
input logic [31:0] i_difficulty, // Must be valid on .sop && .val
|
||||
output logic o_difficulty_fail,
|
||||
output logic o_val
|
||||
);
|
||||
|
||||
|
||||
logic [$clog2($bits(cblockheader_sol_t)/8)-1:0] byt_cnt;
|
||||
logic o_fifo_full, o_fifo_emp;
|
||||
logic [31:0] difficulty;
|
||||
|
||||
if_axi_stream #(.DAT_BYTS(DAT_BYTS)) o_fifo(clk);
|
||||
if_axi_stream #(.DAT_BYTS(64)) i_block(clk);
|
||||
if_axi_stream #(.DAT_BYTS(32)) o_hash(clk);
|
||||
|
||||
enum {IDLE = 0,
|
||||
SHA256_0 = 1,
|
||||
SHA256_1 = 2,
|
||||
FINISHED = 3} state;
|
||||
|
||||
always_ff @ (posedge i_clk) begin
|
||||
if (i_rst) begin
|
||||
o_difficulty_fail <= 0;
|
||||
o_val <= 0;
|
||||
byt_cnt <= 0;
|
||||
i_block.reset_source();
|
||||
o_hash.rdy <= 0;
|
||||
o_fifo.rdy <= 0;
|
||||
difficulty <= 0;
|
||||
state <= IDLE;
|
||||
end else begin
|
||||
o_val <= 0;
|
||||
o_hash.rdy <= 1;
|
||||
|
||||
case(state)
|
||||
IDLE: begin
|
||||
i_block.reset_source();
|
||||
o_fifo.rdy <= 0;
|
||||
byt_cnt <= 0;
|
||||
if (i_axi.rdy && i_axi.val && i_axi.sop) begin
|
||||
difficulty <= i_difficulty;
|
||||
state <= SHA256_0;
|
||||
o_fifo.rdy <= 1;
|
||||
end
|
||||
end
|
||||
// Convert data to 512 bit wide
|
||||
SHA256_0: begin
|
||||
|
||||
if (o_fifo.rdy && o_fifo.val) begin
|
||||
i_block.val <= 0;
|
||||
byt_cnt <= byt_cnt + DAT_BYTS;
|
||||
i_block.dat[byt_cnt +: DAT_BYTS] <= o_fifo.dat;
|
||||
end
|
||||
|
||||
if (((byt_cnt + DAT_BYTS) % 64 == 0) ||
|
||||
(byt_cnt + DAT_BYTS) == $bits(cblockheader_sol_t)/8) begin
|
||||
i_block.val <= 1;
|
||||
i_block.sop <= (byt_cnt + DAT_BYTS)/64 == 1;
|
||||
i_block.eop <= 0;
|
||||
i_block.mod <= (byt_cnt + DAT_BYTS);
|
||||
o_fifo.rdy <= i_block.rdy;
|
||||
if ((byt_cnt + DAT_BYTS) == $bits(cblockheader_sol_t)/8) begin
|
||||
i_block.eop <= 1;
|
||||
state <= SHA256_1;
|
||||
end
|
||||
end else begin
|
||||
o_fifo.rdy <= 1;
|
||||
end
|
||||
|
||||
end
|
||||
SHA256_1: begin
|
||||
if (i_block.val && i_block.rdy) begin
|
||||
i_block.val <= 0;
|
||||
end
|
||||
|
||||
if (o_hash.val && o_hash.rdy) begin
|
||||
i_block.val <= 1;
|
||||
i_block.dat <= o_hash.dat;
|
||||
i_block.sop <= 1;
|
||||
i_block.eop <= 1;
|
||||
i_block.mod <= 32;
|
||||
state <= FINISHED;
|
||||
end
|
||||
end
|
||||
FINISHED: begin
|
||||
if (i_block.val && i_block.rdy) begin
|
||||
i_block.val <= 0;
|
||||
end
|
||||
|
||||
if (o_hash.val && o_hash.rdy) begin
|
||||
o_difficulty_fail <= check_difficulty(o_hash.dat, difficulty);
|
||||
o_val <= 1;
|
||||
state <= IDLE;
|
||||
end
|
||||
|
||||
end
|
||||
endcase
|
||||
|
||||
if ( o_fifo_full ) begin
|
||||
o_difficulty_fail <= 1;
|
||||
o_val <= 1;
|
||||
o_hash.rdy <= 1;
|
||||
o_fifo.rdy <= 1;
|
||||
i_block.reset_source();
|
||||
if ( o_fifo_emp )
|
||||
state <= IDLE;
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
// Function to check if difficulty passes - bits is the number of 0s we
|
||||
// need
|
||||
// TODO target function
|
||||
function check_difficulty(input logic [255:0] hash, logic [31:0] bits);
|
||||
check_difficulty = 0;
|
||||
for (int i = 0; i < 64; i++)
|
||||
if (i > bits && hash[(64-1-i)*8 +: 8] != 0)
|
||||
check_difficulty = 1;
|
||||
endfunction
|
||||
|
||||
// FIFO for storing input stream
|
||||
axi_stream_fifo #(
|
||||
.SIZE ( ($bits(cblockheader_sol_t)/8)/DAT_BYTS ),
|
||||
.DAT_BITS ( DAT_BYTS/8 ),
|
||||
.USE_BRAM ( 1 )
|
||||
)
|
||||
axi_stream_fifo (
|
||||
.i_clk ( i_clk ),
|
||||
.i_rst ( i_rst ),
|
||||
.i_axi ( i_axi ),
|
||||
.o_axi ( o_fifo ),
|
||||
.o_full ( o_fifo_full ),
|
||||
.o_emp ( o_fifo_emp )
|
||||
);
|
||||
|
||||
// SHA256 block
|
||||
sha256_top sha256_top (
|
||||
.i_clk ( i_clk ),
|
||||
.i_rst ( i_rst ),
|
||||
.i_block ( i_block ),
|
||||
.o_hash ( o_hash )
|
||||
);
|
||||
|
||||
endmodule
|
|
@ -37,6 +37,7 @@ package zcash_verif_pkg;
|
|||
logic BAD_ZERO_ORDER;
|
||||
logic BAD_IDX_ORDER;
|
||||
logic XOR_NON_ZERO;
|
||||
logic DIFFICULTY_FAIL;
|
||||
} equihash_bm_t;
|
||||
|
||||
// Format for equihash input - should be 144 bytes
|
||||
|
|
Loading…
Reference in New Issue