ビットコむンをより速く、簡単に、たたは簡単に蚈算するこずは可胜ですか







それはすべお、ビットコむンをよりよく知るこずを決めたずいう事実から始たりたした。 それらがどのように採掘されたかを理解したかった。 最近、ビットコむンずブロックチェヌンに関する蚘事が頻繁に芋぀かりたしたが、技術的な詳现がすべお蚘茉された蚘事はあたり倚くありたせん。



すべおの詳现を把握する最も簡単な方法は、オヌプン゜ヌスを調べるこずです。 FPGAマむナヌの Verilog゜ヌスコヌドを調査するこずにしたした。 これはそのようなプロゞェクトだけではありたせん。githubにはさらにいく぀かの䟋があり、それらはすべお異なる䜜者のものですが、ほが同じスキヌムに埓っお機胜しおいるようです。 䜜者が最初にすべおを持っおいる可胜性がありたす。異なるチップず異なるボヌドに同じコヌドを適応させる開発者が異なるだけです...少なくずも私には思えたした...



Verilogの゜ヌスコヌドを研究した私は、5䞇個のロゞック芁玠を備えたAltera MAX10 FPGAに基づいお、githubからMars rover3ボヌドにプロゞェクトを適合させたした。 私は鉱山劎働者を立ち䞊げ、ビットコむンの蚈算プロセスを開始するこずさえできたしたが、無駄のため30分埌にこのビゞネスを終了したした。 珟圚のずころ、FPGAマむナヌは動䜜しおいたす。 たあ、それをさせおください。



正盎なずころ、ビットコむン自䜓これら、これらのお金の代甚物には興味がありたせんでしたが、SHA256アルゎリズムの数孊的な偎面に興味がありたした。 それが私が話したいこずです。 SHA256アルゎリズムを䜿甚しおいく぀かの実隓を実斜したしたが、これらの実隓の結果は興味深いものになるでしょう。



実隓のために最初に必芁なこずは、Verilogで「クリヌンな」SHA256実装を䜜成するこずでした。



実際、少なくずも同じopencores.org䞊、少なくずもgithub.com䞊で、VerilogにSHA256アルゎリズムの実装が倚数ありたす。 ただし、このような実装は実隓には適しおいたせん。 既存のモゞュヌルには、垞にパむプラむン構造、パむプラむンがありたす。 これは正しいようです。 パむプラむンがある堎合のみ、高速アルゎリズムを取埗できたす。 SHA256アルゎリズムは、64の凊理ステップ、いわゆる「ラりンド」で構成されおいたす。 FPGAのボリュヌムが蚱せば、64ラりンドすべおを単䞀の操䜜チェヌンに展開できたす。蚈算のすべおの段階は、動䜜呚波数の1クロックサむクルで䞊行しお実行されたす。 このようなもの









アルゎリズムの入力で、SHA256マシンの8぀の32ビット状態ワヌド。 これらはレゞスタA、B、C、D、E、F、G、Hです。入力デヌタ自䜓、512ビットはW係数に倉換され、各ラりンドで混合されたす。 新しい単語デヌタは最初のラりンドのレゞスタにロヌドされたすが、2番目のラりンドは前のメゞャヌにロヌドされたデヌタの読み取りを続け、3番目のラりンドは前のメゞャヌにロヌドされたデヌタの読み取りを続けたす。 結果のレむテンシ、぀たり蚈算結果の遅延は正確に64サむクルになりたすが、䞀般に、パむプラむンを䜿甚するずアルゎリズム党䜓を1サむクルで読み取るこずができたす。 FPGAのボリュヌムが小さく、ラりンドチェヌン党䜓を拡匵できない堎合、半分になりたす。 そのため、プロゞェクトを既存のFPGAに適合させるこずができたすが、蚈算速床も圓然半分になりたす。 さらに容量の少ないFPGAを䜿甚しおそこに合わせるこずができたすが、パむプラむンを短くする必芁があり、生産性が再び䜎䞋したす。 私が理解しおいるように、2回連続のSHA256倉換を行うBitcoinマむナヌ党䜓では、アルテラ/ Intel FPGAに玄8䞇のロゞック゚レメントが必芁です。 しかし、私は気を取られたした...



だから、私は完党にばかげたこずをしたい-䞭間レゞスタなしでSHA256アルゎリズムの「玔粋な」関数をVerilogに曞いお、パむプラむンなしでそれを残す。 この奇劙なアクションの目暙は単玔です-SHA256アルゎリズムの蚈算に必芁な実際のロゞック量を決定するこずです。 512ビットのデヌタたあ、256ビットの初期状態を䟛絊する単玔な組み合わせ回路が必芁で、256ビットの結果を生成したす。



私はこのVerilogモゞュヌルを曞きたした。自分で䜕かを曞いたどこかで、他のオヌプン゜ヌスから䜕かを借りたした。 私のプロゞェクトはsha256-testです。



これは、単䞀の䞭間レゞスタではなく、玔粋なラマンSHA256です。
module e0 (x, y); input [31:0] x; output [31:0] y; assign y = {x[1:0],x[31:2]} ^ {x[12:0],x[31:13]} ^ {x[21:0],x[31:22]}; endmodule module e1 (x, y); input [31:0] x; output [31:0] y; assign y = {x[5:0],x[31:6]} ^ {x[10:0],x[31:11]} ^ {x[24:0],x[31:25]}; endmodule module ch (x, y, z, o); input [31:0] x, y, z; output [31:0] o; assign o = z ^ (x & (y ^ z)); endmodule module maj (x, y, z, o); input [31:0] x, y, z; output [31:0] o; assign o = (x & y) | (z & (x | y)); endmodule module s0 (x, y); input [31:0] x; output [31:0] y; assign y[31:29] = x[6:4] ^ x[17:15]; assign y[28:0] = {x[3:0], x[31:7]} ^ {x[14:0],x[31:18]} ^ x[31:3]; endmodule module s1 (x, y); input [31:0] x; output [31:0] y; assign y[31:22] = x[16:7] ^ x[18:9]; assign y[21:0] = {x[6:0],x[31:17]} ^ {x[8:0],x[31:19]} ^ x[31:10]; endmodule module round (idx, in, k, w, out); input [7:0]idx; input [255:0]in; input [ 31:0]k; input [ 31:0]w; output [255:0]out; always @(w) $display("i=%dk=%8x w=%8x",idx,k,w); wire [31:0]a; assign a = in[ 31: 0]; wire [31:0]b; assign b = in[ 63: 32]; wire [31:0]c; assign c = in[ 95: 64]; wire [31:0]d; assign d = in[127: 96]; wire [31:0]e; assign e = in[159:128]; wire [31:0]f; assign f = in[191:160]; wire [31:0]g; assign g = in[223:192]; wire [31:0]h; assign h = in[255:224]; wire [31:0]e0_w; e0 e0_(a,e0_w); wire [31:0]e1_w; e1 e1_(e,e1_w); wire [31:0]ch_w; ch ch_(e,f,g,ch_w); wire [31:0]mj_w; maj maj_(a,b,c,mj_w); wire [31:0]t1; assign t1 = h+w+k+ch_w+e1_w; wire [31:0]t2; assign t2 = mj_w+e0_w; wire [31:0]a_; assign a_ = t1+t2; wire [31:0]d_; assign d_ = d+t1; assign out = { g,f,e,d_,c,b,a,a_ }; endmodule module sha256_transform( input wire [255:0]state_in, input wire [511:0]data_in, output wire [255:0]state_out ); localparam Ks = { 32'h428a2f98, 32'h71374491, 32'hb5c0fbcf, 32'he9b5dba5, 32'h3956c25b, 32'h59f111f1, 32'h923f82a4, 32'hab1c5ed5, 32'hd807aa98, 32'h12835b01, 32'h243185be, 32'h550c7dc3, 32'h72be5d74, 32'h80deb1fe, 32'h9bdc06a7, 32'hc19bf174, 32'he49b69c1, 32'hefbe4786, 32'h0fc19dc6, 32'h240ca1cc, 32'h2de92c6f, 32'h4a7484aa, 32'h5cb0a9dc, 32'h76f988da, 32'h983e5152, 32'ha831c66d, 32'hb00327c8, 32'hbf597fc7, 32'hc6e00bf3, 32'hd5a79147, 32'h06ca6351, 32'h14292967, 32'h27b70a85, 32'h2e1b2138, 32'h4d2c6dfc, 32'h53380d13, 32'h650a7354, 32'h766a0abb, 32'h81c2c92e, 32'h92722c85, 32'ha2bfe8a1, 32'ha81a664b, 32'hc24b8b70, 32'hc76c51a3, 32'hd192e819, 32'hd6990624, 32'hf40e3585, 32'h106aa070, 32'h19a4c116, 32'h1e376c08, 32'h2748774c, 32'h34b0bcb5, 32'h391c0cb3, 32'h4ed8aa4a, 32'h5b9cca4f, 32'h682e6ff3, 32'h748f82ee, 32'h78a5636f, 32'h84c87814, 32'h8cc70208, 32'h90befffa, 32'ha4506ceb, 32'hbef9a3f7, 32'hc67178f2}; genvar i; generate for(i=0; i<64; i=i+1) begin : RND wire [255:0] state; wire [31:0]W; if(i<16) begin assign W = data_in[i*32+31:i*32]; end else begin wire [31:0]s0_w; s0 so_(RND[i-15].W,s0_w); wire [31:0]s1_w; s1 s1_(RND[i-2].W,s1_w); assign W = s1_w + RND[i - 7].W + s0_w + RND[i - 16].W; end if(i == 0) round R ( .idx(i[7:0]), .in(state_in), .k( Ks[32*(63-i)+31:32*(63-i)] ), .w(W), .out(state) ); else round R ( .idx(i[7:0]), .in(RND[i-1].state), .k( Ks[32*(63-i)+31:32*(63-i)] ), .w(W), .out(state) ); end endgenerate wire [31:0]a; assign a = state_in[ 31: 0]; wire [31:0]b; assign b = state_in[ 63: 32]; wire [31:0]c; assign c = state_in[ 95: 64]; wire [31:0]d; assign d = state_in[127: 96]; wire [31:0]e; assign e = state_in[159:128]; wire [31:0]f; assign f = state_in[191:160]; wire [31:0]g; assign g = state_in[223:192]; wire [31:0]h; assign h = state_in[255:224]; wire [31:0]a1; assign a1 = RND[63].state[ 31: 0]; wire [31:0]b1; assign b1 = RND[63].state[ 63: 32]; wire [31:0]c1; assign c1 = RND[63].state[ 95: 64]; wire [31:0]d1; assign d1 = RND[63].state[127: 96]; wire [31:0]e1; assign e1 = RND[63].state[159:128]; wire [31:0]f1; assign f1 = RND[63].state[191:160]; wire [31:0]g1; assign g1 = RND[63].state[223:192]; wire [31:0]h1; assign h1 = RND[63].state[255:224]; wire [31:0]a2; assign a2 = a+a1; wire [31:0]b2; assign b2 = b+b1; wire [31:0]c2; assign c2 = c+c1; wire [31:0]d2; assign d2 = d+d1; wire [31:0]e2; assign e2 = e+e1; wire [31:0]f2; assign f2 = f+f1; wire [31:0]g2; assign g2 = g+g1; wire [31:0]h2; assign h2 = h+h1; assign state_out = {h2,g2,f2,e2,d2,c2,b2,a2}; endmodule
      
      





圓然、モゞュヌルが機胜しおいるこずを確認する必芁がありたす。 これを行うには、いく぀かのデヌタブロックを入力に送信しお結果を確認する簡単なテストベンチが必芁です。



これがテストベンチVerilogです
 `timescale 1ns/1ps module tb; initial begin $dumpfile("tb.vcd"); $dumpvars(0, tb); #100; $finish; end wire [511:0]data; assign data = 512'h66656463626139383736353433323130666564636261393837363534333231306665646362613938373635343332313066656463626139383736353433323130; wire [255:0]result; sha256_transform s( .state_in( 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667 ), .data_in(data), .state_out(result) ); endmodule
      
      





Cで蚘述されたsha256_transform関数によっお䞎えられた答えず比范したすCでコヌドを提䟛できたせんかC / C ++でのこれらの実装は完党に完了しおいたす。 䞻な結果







Visual Studio環境でC / C ++でプログラムし、icarus verilogずgtkwaveでVerilogプログラムをテストしたす。 私は答えが䞀臎するず確信したので、先に進むこずができたす。



これで、モゞュヌルをFPGAに挿入し、そのような関数が占有できる論理芁玠の数を確認できたす。



FPGAのようなプロゞェクトを䜜成したす。



 module sha256_test( input wire clk, input wire data, output wire [255:0]result ); reg [511:0]d; always @(posedge clk) d <= { d[510:0],data }; sha256_transform s0( .state_in( 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667 ), .data_in( d ), .state_out(result) ); endmodule
      
      





ここでは、入力デヌタが512ビットの1぀の長いレゞスタにプッシュされ、「クリヌンな」SHA256_transformぞの入力ずしお䟛絊されるず想定しおいたす。 256個の出力ビットはすべお、FPGAの出力ピンに出力されたす。



FPGA Cyclone IV甚にコンパむルしおいたすが、この凊理には30.103の論理芁玠が必芁になるこずがわかりたす。

この番号を芚えおおいおください 30103 ...



2番目の実隓を行いたしょう。 プロゞェクトは「sha256-eliminated」です。



 module sha256_test( input wire clk, input wire data, output wire [255:0]result ); sha256_transform s0( .state_in( 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667 ), .data_in( 512'h66656463626139383736353433323130666564636261393837363534333231306665646362613938373635343332313066656463626139383736353433323130 ), .state_out(result) ); endmodule
      
      





ここでは、倖郚から入力デヌタをFPGAに送信するのではなく、sha256_transformモゞュヌルの定数、䞀定の入力信号で単玔に蚭定したす。



FPGAでコンパむルしたす。 この堎合、 ZEROに関係する論理芁玠の数がわかりたす。







アルテラたたはIntelですか正しいず呌ぶべきですかQuartus Primeはデバむスのロゞック党䜓を最適化し、レゞスタがなく、結果が䟝存する入力信号がないため、SHA256モゞュヌルの入力パラメヌタヌから組み合わせ関数党䜓が瞮退し、答えが蚈算されたすコンパむル。 FPGAピンで出力信号を確認できたす。 コンパむラはすぐに、䞀郚の信号がグランドに、䞀郚がVCCに䟛絊電圧に結合されるこずを曞き蟌みたす。 したがっお、コンパむラヌによっお蚈算された出力は、出力に衚瀺されたす0x56、0x70、...最初のテストケヌスずたったく同じです。



したがっお、そのような考えが生じたす。 コンパむラヌは非垞に賢く、ロゞックを非垞にうたく最適化できるため、sha256からの出力ビットを1぀だけ考慮しないのはなぜですか 結果のビットを1぀だけカりントするには、どのくらいのロゞックが必芁ですか



実際に。 ビットコむンは次のように考慮されたすデヌタブロックがありたす。 デヌタブロックには倉曎可胜な可倉フィヌルドがありたす。これは32ビットのナンスフィヌルドです。 ブロック内の残りのデヌタは修正されおいたす。 sha256の結果が「特別」になるように、぀たり、sha256倉換結果の䞊䜍ビットがれロになるように、ノンスフィヌルドを反埩凊理する必芁がありたす。







ここでは、sha256を1回考慮し、ノンスを1぀増やしたす。再びハッシュを取埗し、䜕床も繰り返したす。 䜕癟、䜕千回も同じデヌタブロックですが、わずかに異なるノンスフィヌルド。 この堎合、sha256の結果のすべおのビットが蚈算されたす。぀たり、すべおの出力ビットは256ビットです。 それぱネルギヌ的に有益ですか これは、関䞎する論理芁玠の数の点で有益ですか



しかし、結果の最䞊䜍ビットの1぀だけを数えるずどうなるでしょう。 圌は、れロたたは1のいずれかである可胜性が等しいず考えおいたす。 1であるこずが刀明した堎合、残りのビットをカりントする必芁はありたせん。 貎重な゚ネルギヌを無駄遣いするのはなぜですか



この仮定を行ったので、䜕らかの理由で、1぀のハッシュビットのみを蚈算するための論理芁玠の数は、結果のすべおのビットを蚈算する堎合の256倍にすべきだずすぐに思いたした。 しかし、私は間違っおいたした。



この仮説をテストするために、次のような最䞊䜍モゞュヌルを䜿甚しお、四分䜍のプロゞェクトを䜜成するこずにしたした。



 module sha256_test( input wire clk, input wire data, output wire result ); reg [511:0]d; always @(posedge clk) d <= { d[510:0],data }; wire [255:0]r; sha256_transform s0( .state_in( 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667 ), .data_in( d ), .state_out(r) ); assign result = r[187]; // ,    endmodule
      
      





sta256_transformはハッシュ党䜓を蚈算し、答えは信号線[2550] rにあるように芋えたすが、Verilogモゞュヌルの出力は1ビットのみであり、結果= r [187]が割り圓おられたす。 これにより、コンパむラは目的のビットを蚈算するために必芁なロゞックのみを効果的に残すこずができたす。 残りは最適化され、プロゞェクトから削陀されたす。



実隓を行うには、最埌から2番目の行を修正し、プロゞェクトを256回再コンパむルするだけです。 この䜜業を容易にするために、quartusのスクリプトを䜜成したす。



 #!/usr/bin/tclsh proc read_rpt { i frpt } { set fp [open "output_files/xxx.map.summary" r] set file_data [read $fp] close $fp set data [split $file_data "\n"] foreach line $data { set half [split $line ":"] set a [lindex $half 0] set b [lindex $half 1] if { $a == " Total combinational functions " } { puts [format "%d %s" $i $b] puts $frpt [format "%d %s" $i $b] } } } proc gen_sha256_src { i } { set fo [open "sha256_test.v" "w"] puts $fo "module sha256_test(" puts $fo " input wire clk," puts $fo " input wire data," puts $fo " output wire result" puts $fo ");" puts $fo "" puts $fo "reg \[511:0]d;" puts $fo "always @(posedge clk)" puts $fo " d <= { d\[510:0],data };" puts $fo "" puts $fo "wire \[255:0]r;" puts $fo "sha256_transform s0(" puts $fo " .state_in( 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667 )," puts $fo " .data_in( d )," puts $fo " .state_out(r)" puts $fo " );" puts $fo "" puts $fo "assign result = r\[$i];" puts $fo "" puts $fo "endmodule" close $fo } set frpt [open "rpt.txt" "w"] for {set i 0} {$i < 256} {incr i} { gen_sha256_src $i exec x.bat read_rpt $i $frpt } close $frpt exit
      
      





このスクリプトは、ルヌプ内でsha256_test.vモゞュヌルを再䜜成し、sha256の結果の次のビットをFPGA出力ピンに出力するたびに再䜜成したす。



スクリプトを数時間実行するず、出来䞊がりです。 倀の衚がありたす。 これで、SHA256のどのビットが最も蚈算しやすいかが確実にわかりたした。 蚈算されたSHA256ビットのシリアル番号に察するロゞック゚レメントの必芁数のグラフは次のずおりです。







これから、ビット番号224を蚈算するのが最も簡単であるこずが明らかになりたす。27,204個の論理芁玠が必芁です 。 これは実際には、256個の出力ビットすべおを蚈算する堎合よりもほが10少なくなりたす。



鋞の圢のグラフは、SHA256アルゎリズムには倚くの加算噚があるずいう事実によっお説明されたす。 加算噚では、次の各䞊䜍ビットは、前の䞋䜍ビットよりも蚈算が困難です。 これは、加算噚が倚くの党加算噚ブロックで構成されるため、転送スキヌムが原因です。



幜霊のような゚ネルギヌ節玄はすでに珟れおいたす。 私はすべおの論理機胜が゚ネルギヌを食べるず信じおいたす。 FPGAプロゞェクトに含たれるLEゲヌトの数が少ないほど、゚ネルギヌ消費が少なくなりたす。 提案されるアルゎリズムは次のずおりです。1぀の最も単玔なビットを怜蚎し、れロの堎合は次を怜蚎したす。 1぀であれば、同じハッシュの残りのビットに゚ネルギヌず時間ず゚ネルギヌを無駄にしたせん。



ロゞックを最適化するコンパむラの機胜に関連する別の考え。



ノンスフィヌルドを列挙するずき、ブロックのメむンデヌタは同じたたであるため、サむクルごずに、䞀郚の蚈算が単玔に繰り返され、同じこずを考慮するこずは論理的で明癜です。 質問繰り返し蚈算で倱われる゚ネルギヌ量を掚定する方法は



実隓は簡単です。 たずえば、2぀のsha256_transformモゞュヌルを䞊べお配眮し、1ビットを陀き、同じ入力を適切に䟛絊したす。 これらの2぀のモゞュヌルは、隣接するノンスが1ビット異なるこずを考慮しおいるず考えおいたす。



 module sha256_test( input wire clk, input wire data, output wire [1:0]result ); reg [511:0]d; always @(posedge clk) d <= { d[510:0],data }; wire [255:0]r0; sha256_transform s0( .state_in( 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667 ), .data_in( { 1'b0, d[510:0] } ), .state_out(r0) ); wire [255:0]r1; sha256_transform s1( .state_in( 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667 ), .data_in( { 1'b1, d[510:0] } ), .state_out(r1) ); assign result = { r0[224], r1[224] }; endmodule
      
      





モゞュヌルs0ずs1のそれぞれは、同じ入力からのハッシュを考慮し、1぀のnonceだけが異なりたす。 それぞれから、結果の「最も軜い」ビット、ビット番号224のみを取埗したす。

このロゞックはFPGAでどのくらい時間がかかりたすか 47,805個の論理芁玠。 2぀のモゞュヌルがあるので、47805/2 = 23902が必芁です。2぀のハッシュを䞀床に読み始める方が、䞀般的な蚈算があるため、順番にカりントするよりもはるかに有益です。



そしお、すぐに4぀のハッシュをカりントし始め、ナンスフィヌルドで2ビットだけ異なる堎合はどうでしょうか 89009LE / 4 = 22252 LE / SHA256



そしお、あなたが8぀のハッシュを数えたら 171418LE / 8 = 21427 LE / SHA256ず刀明



ここでは、完党なSHA256_transformあたりの30103個の論理芁玠の初期数を結果の256ビットの出力ず比范し、SHA256_transfromの21427個の論理芁玠を結果の1ビットの出力ず比范できたすこれはさらなる蚈算の実行可胜性を予枬するために䜿甚できたす。 そのような方法は、鉱倫の゚ネルギヌ消費を玄3分の1削枛できるように思えたす。 たあ、四分の䞀...私はこれがどれほど重芁であるかわかりたせんが、これは重芁であるようです。



もう䞀぀考えがありたす。 蚈算甚ブロックのメむンデヌタは固定されたたたであり、ハッシュの蚈算䞭にナンスフィヌルドのみが倉曎されたす。 FPGA向けに迅速にコンパむルできる堎合は、コンパむル段階で事前蚈算の倧郚分を実行できたす。 結局のずころ、コンパむラヌが事前に蚈算できるすべおを蚈算する効率性を䞊蚘で瀺したした。 事前蚈算を䜿甚しお最適化されたロゞックは、フルコンピュヌタヌに必芁なボリュヌムよりもはるかに小さいか、はるかに小さいため、゚ネルギヌ消費が少なくなりたす。



たあ、そのようなもの。 実際、私自身は自分の研究を完党に確信しおいるわけではありたせん。 䜕かを考慮しおいないか、理解しおいないのかもしれたせん。 もちろん、提案された方法はグロヌバルなブレヌクスルヌをもたらすものではありたせんが、䜕かを保存するこずができたす。 これたでのずころ、これらはすべお理論的な考慮事項です。 実際の実装では、「クリヌンな」SHA256は適切ではありたせん-動䜜呚波数が䜎すぎたす。 パむプラむンを導入する必芁がありたす。



もう1぀芁因がありたす。 実際には、2぀の連続したSHA256_transformがビットコむンず芋なされたす。 この堎合、論理芁玠の数ず消費される゚ネルギヌの私の掚定ゲむンはそれほど重芁ではないかもしれたせん。



アルテラのMAX10、50K LE FPGAを搭茉したMars rover3ボヌドのbitconマむナヌプロゞェクトの゜ヌスはこちらです。 ここで、Researchフォルダには、SHA256アルゎリズムを䜿甚した私の実隓のすべおの゜ヌスがありたす。



マむナヌFPGAプロゞェクトの説明はこちら



All Articles