tag:crieit.net,2005:https://crieit.net/users/__canal/feed spinlockの投稿 - Crieit Crieitでユーザーspinlockによる最近の投稿 2023-01-21T00:14:05+09:00 https://crieit.net/users/__canal/feed tag:crieit.net,2005:PublicArticle/18372 2023-01-20T18:45:37+09:00 2023-01-21T00:14:05+09:00 https://crieit.net/posts/rsa7680 RSAは終わらない - RSA 7680bitのICカードの実現可能性 <h2 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h2> <p>RSAは終わらないというタイトルですが筆者(Naoki Hirayama)がRSAが安全であることを保証するのではなくて既に量子コンピュータによって解読が懸念されているECDSAに移行するつもりがあるならRSAは終わらないということです。</p> <p>暗号移行を促すQiita投稿 : <a target="_blank" rel="nofollow noopener" href="https://qiita.com/lemiyachi/items/c20a18b172c6f192a262">「RSAの終わりの始まり - 暗号移行再び」</a><br /> 投稿者のラング・エッジ 宮地さんは、ネット上では有名な方のようです</p> <p>上記、Qiita投稿ではRSA 7680bitのICカードは非実用的という評価によってECDSA(楕円曲線暗号)に移行すべきかを検討しましょうという流れになっているようなのでRSA 7680bitのICカードの実現可能性について考えてみます。</p> <h2 id="FPGAによるRSA 2048bitの実装結果"><a href="#FPGA%E3%81%AB%E3%82%88%E3%82%8BRSA+2048bit%E3%81%AE%E5%AE%9F%E8%A3%85%E7%B5%90%E6%9E%9C">FPGAによるRSA 2048bitの実装結果</a></h2> <p><a target="_blank" rel="nofollow noopener" href="https://snakecube.idletime.tokyo/">暗号プロセッサSnakeCubeのWebサイト</a>に詳しく書かれていますがRSA 2048bitの復号化1回の性能が1.74[ms]です。これは概ねRSA署名1回の時間と同じです。</p> <p><strong>この実装結果で使われたFPGAはXilinxのコスト重視のFPGA(Artix-7)です。さらにスピードグレードの一番遅いものなのでICカードへの実装可能性を考えるには良さそうです。</strong> このXilinxのArtix-7シリーズは28nmの半導体です。28nmと言えば国が作ったTSMCの熊本工場の半導体と同じ。ハードをソフトウェアのように書き込めるFPGAで1.74[ms]の性能が出るのでASICで開発すれば、さらに高速に動作します。</p> <h2 id="NAOKIの法則を使って7680bitの性能を予想"><a href="#NAOKI%E3%81%AE%E6%B3%95%E5%89%87%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A67680bit%E3%81%AE%E6%80%A7%E8%83%BD%E3%82%92%E4%BA%88%E6%83%B3">NAOKIの法則を使って7680bitの性能を予想</a></h2> <p>SnakeCubeは演算器ブロックを一筆書きで並べていくことで大きな鍵長に対応できて容易に開発可能です。<a href="https://crieit.net/posts/naokislaw">NAOKIの法則</a>は、僕が作った法則です。自分で言うと馬鹿っぽいですけど(笑)。<strong>法則と言っていますけど保証できるくらいの精度です。</strong></p> <p>このXilinx FPGA(Artix-7)に実装されたSnakeCubeでは中国人剰余定理(CRT)を使っています。しかしICカードでは中国人剰余定理の脆弱性の対策が難しいので中国人剰余定理を使わないことを考えます。<br /> 中国人剰余定理が無い場合、おおよそRSA 1024bit復号化 1.74[ms]になります</p> <p><a href="https://crieit.net/posts/naokislaw">NAOKIの法則</a>から鍵長を8倍の8192bitにすると演算時間は64倍になるので<br /> 1.74[ms] × 64 = 111.36[ms]</p> <p>8192bitの演算器ですが7680bitの演算ではループ数が少なくて良いので<br /> 111.36[ms] × 7680 ÷ 8192 = 104.4 ≒ 105[ms]</p> <h2 id="結論"><a href="#%E7%B5%90%E8%AB%96">結論</a></h2> <p>FPGAによる実機の実測値を使ってRSA 7680bit署名1回の演算時間を予想すると105[ms]の性能が出ます。ICカードはFPGAより楽なASICで実装するためRSA 7680bit署名1回の演算時間 0.1~0.2秒のICカードは実現可能であるように思われます。<br /> <a target="_blank" rel="nofollow noopener" href="https://snakecube.idletime.tokyo/">SnakeCube</a>はゲート間の配線が局所化しているので高性能プロセッサにありがちな高価な配線材料は不要です。ICカード向けの安価な実装ができるように思われます。</p> <p>筆者はRSA暗号の高速な演算の実装方法、つまり筆者の発明<a target="_blank" rel="nofollow noopener" href="https://snakecube.idletime.tokyo/">SnakeCube</a>を提案していますが、RSA暗号が解読されないということについては一切保証しないことを予めご了承下さい。</p> <p>暗号プロセッサSnakeCubeはRSAほど効率良く演算できませんがECDSAも演算可能です。また巨大整数の四則演算が高速なので困難性の異なる新しい公開鍵暗号を促したり、新しいアプリでも利用できることを考えるなら暗号プロセッサSnakeCubeを、ここで開発しておくことは、良いことだと思っています。</p> <h5 id="参考URL"><a href="#%E5%8F%82%E8%80%83URL">参考URL</a></h5> <p>FPGAによる実機で2048bit RSA復号化1回、1.74[ms]を記録した動画<br /> <a target="_blank" rel="nofollow noopener" href="https://www.youtube.com/watch?v=beaFg0x8Qj8">https://www.youtube.com/watch?v=beaFg0x8Qj8</a></p> <p>プレスリリース、暗号プロセッサSnakeCubeをマイコンに接続できる ソフトウェア「WZeta BIOS」を5月28日に提供開始<br /> <a target="_blank" rel="nofollow noopener" href="https://www.atpress.ne.jp/news/310208">https://www.atpress.ne.jp/news/310208</a></p> spinlock tag:crieit.net,2005:PublicArticle/18199 2022-05-27T07:07:11+09:00 2022-06-14T11:43:00+09:00 https://crieit.net/posts/wzpowmod 乗算器のない8bit CPUで高速にべき乗剰余演算するコード <h1 id="目的"><a href="#%E7%9B%AE%E7%9A%84">目的</a></h1> <p>軽量で非常に良くできた<a target="_blank" rel="nofollow noopener" href="https://wzeta.idletime.tokyo/">8bit CPUのオープンソースWZeta</a>を普及させるためにRSA暗号や楕円暗号などの公開鍵暗号で使われるべき乗剰余演算のアセンブラコードをCC0ライセンス(パブリックドメインと同じ)で公開したことのお知らせ。</p> <p><strong>注意!!! CC0であるのは、べき乗剰余演算のWZetaのアセンブラコードのみ</strong></p> <h1 id="WZetaとは"><a href="#WZeta%E3%81%A8%E3%81%AF">WZetaとは</a></h1> <p>WZetaは<strong>トランジスタ数当たりの性能</strong>、命令セット内パリティ、ハードマクロ命令など8bit CPUにして新技術を多数持ち、常識を破る変則的な命令セットですが、高い効率であることが確認されつつあるCPU。</p> <h1 id="1024bitのべき乗剰余演算(事前定数有版)"><a href="#1024bit%E3%81%AE%E3%81%B9%E3%81%8D%E4%B9%97%E5%89%B0%E4%BD%99%E6%BC%94%E7%AE%97%28%E4%BA%8B%E5%89%8D%E5%AE%9A%E6%95%B0%E6%9C%89%E7%89%88%29">1024bitのべき乗剰余演算(事前定数有版)</a></h1> <pre><code>################################################################### ### WZeta powmod 1024bit 2022/05/27 by Naoki Hirayama ### ### These codes are licensed under CC0.(Public Domain) ### http://creativecommons.org/publicdomain/zero/1.0/deed.ja ### ### Montgomery multiplication method with radix 2, ### which is famous for being used in ICF3(1999). ### ### This code is for Open source 8bit CPU WZeta. ### https://wzeta.idletime.tokyo/ ### ### download WZeta simulator ### https://subnote.icf3.net/wz660/download/ ### ### How to do simulation. ### &gt; wzsim (this file) ### ################################################################### ### --------------------------------------------------------------- ### Subroutine powmod1024 y = g^x mod p ### INOUT g,r(=y) 128,128 !0x100 ### IN x,p 128,128 !0x100 ### r = R^2 mod p ### --------------------------------------------------------------- MEMORY 4 MODEL TINY ### MEMORY 8 ### MODEL HALF .PROG LD A,&powmod_gr.H ST %_b_powmod_gr,A LD A,&powmod_px.H ST %_b_powmod_px,A LD A, ^_b_powmod1024.H LD B, ^_b_powmod1024.L BAL A:B LD A,32 ST %_b_powmod_i,A LD A, &ANS.H LD B,0x80 LD C,0x00 copy_ans: # ans <- powmod_y STACP [&powmod_y:B] STACP [&powmod_y:B] STACP [&powmod_y:B] STACP [&powmod_y:B] DEC %_b_powmod_i JRZ0 ^copy_ans $PRINT &ANS 128 NOP $PRINT &powmod_exp 128 EXIT ### --------------------------------------------------------------- ### [%h:%l] =[%h:%l] * g R-1mod p ### IN %h:%l : pointer ### CONST p,g ### --------------------------------------------------------------- _b_powmod1024_mm: ST %_b_powmod_retA,A ST %_b_powmod_retB,B LD A,&_b_powmod_a.H # a = 0 LD B,&_b_powmod_a.L LD C,128 # repeat 129 LOOPZERO ZERO %_b_powmod_m _b_powmod1024_mm_loop_m: # for m=0 to 127 LD A,8 ST %_b_powmod_n,A LD A, %_b_powmod_m ADD A, %_b_powmod_l LD B,A LD A, %_b_powmod_h LD A,[A:B] ST %_b_powmod_x,A _b_powmod1024_mm_loop_n: # for n=0 to 7 ### loop body start -------------------------- LD A, %_b_powmod_x LD B, 0 AND A,[&powmod_g:B] XOR A,[&_b_powmod_a:B] ST %_b_powmod_u,A SHRC %_b_powmod_x JRC0 ^_b_powmod1024_mm2 # yi = 0 skip a += g LD B,0 # a += g CLC LD C,15 _b_powmod1024_mm1: LD A,[&powmod_g:B] !ADDC [&_b_powmod_a:B],A LD A,[&powmod_g:B] !ADDC [&_b_powmod_a:B],A LD A,[&powmod_g:B] !ADDC [&_b_powmod_a:B],A LD A,[&powmod_g:B] !ADDC [&_b_powmod_a:B],A LD A,[&powmod_g:B] !ADDC [&_b_powmod_a:B],A LD A,[&powmod_g:B] !ADDC [&_b_powmod_a:B],A LD A,[&powmod_g:B] !ADDC [&_b_powmod_a:B],A LD A,[&powmod_g:B] ADDC [&_b_powmod_a:B],A LOOPINC ^_b_powmod1024_mm1 INCC [&_b_powmod_a:B] _b_powmod1024_mm2: SHRC %_b_powmod_u JRC0 ^_b_powmod1024_mm4 # u=0 skip +p LD B,0 # a += p CLC LD C,15 _b_powmod1024_mm3: LD A,[&powmod_p:B] !ADDC [&_b_powmod_a:B],A LD A,[&powmod_p:B] !ADDC [&_b_powmod_a:B],A LD A,[&powmod_p:B] !ADDC [&_b_powmod_a:B],A LD A,[&powmod_p:B] !ADDC [&_b_powmod_a:B],A LD A,[&powmod_p:B] !ADDC [&_b_powmod_a:B],A LD A,[&powmod_p:B] !ADDC [&_b_powmod_a:B],A LD A,[&powmod_p:B] !ADDC [&_b_powmod_a:B],A LD A,[&powmod_p:B] ADDC [&_b_powmod_a:B],A LOOPINC ^_b_powmod1024_mm3 INCC [&_b_powmod_a:B] _b_powmod1024_mm4: # a >>= 1 LD A, &_b_powmod_a.H LD B,128 LD C,128 CLC LOOPSHRC ### loop body end -------------------------- DEC %_b_powmod_n JRZ0 ^_b_powmod1024_mm_loop_n INCX %_b_powmod_m # A=m++ XOR A,0x7F JRZ0 ^_b_powmod1024_mm_loop_m ### Final Substruct INC %_b_powmod_n # n=1 _b_powmod1024_mm5: LD A,32 # y=a(before sub) ST %_b_powmod_m,A # 32 = 128 / 4 LD A,%_b_powmod_h LD C,%_b_powmod_l LD B,0 _b_powmod1024_mm6: STACP [&_b_powmod_a:B] STACP [&_b_powmod_a:B] STACP [&_b_powmod_a:B] STACP [&_b_powmod_a:B] DEC %_b_powmod_m JRZ0 ^_b_powmod1024_mm6 LD C,%_b_powmod_n LOOPINC ^_b_powmod1024_mm8 # if C!=0 jump _b_powmod1024_mm7: # return LD A,%_b_powmod_retA LD B,%_b_powmod_retB JMP A:B _b_powmod1024_mm8: LD B,0 # a -= p LD A,0 SUB A,C # CF=1 LD C,31 _b_powmod1024_mm9: LD A,[&powmod_p:B] !SUBC [&_b_powmod_a:B],A LD A,[&powmod_p:B] !SUBC [&_b_powmod_a:B],A LD A,[&powmod_p:B] !SUBC [&_b_powmod_a:B],A LD A,[&powmod_p:B] SUBC [&_b_powmod_a:B],A LOOPINC ^_b_powmod1024_mm9 DECC [&_b_powmod_a:B] JRC0 ^_b_powmod1024_mm7 ZERO %_b_powmod_n JR ^_b_powmod1024_mm5 ### --------------------------------------------------------------- ### --------------------------------------------------------------- ### Subroutine powmod1024 ### INOUT g,r(=y) 128,128 !0x100 ### const IN x,p 128,128 !0x100 ### work _b_powmod_a 129 !0x100 ### r : R2modP ### --------------------------------------------------------------- _b_powmod1024: ST %_b_powmod_RETA,A ST %_b_powmod_RETB,B ### CALL powmod_1024mm LD A, %_b_powmod_gr # y = y(r) * g R-1mod p ST %_b_powmod_h , A LD A, 0x80 ST %_b_powmod_l , A BR ^_b_powmod1024_mm ### COPY y -&gt; g LD A, %_b_powmod_gr LD C,0x7F LD B,0xFF copy_y_g: STAC [A:B] LOOPDEC ^copy_y_g # if c--==0 jump -1 # powmod_y = 1 start LD A, %_b_powmod_gr LD B,0x80 # y LD C, 1 !ST [A:B],C # y[0] = 1 LD C,126 # repeat 127 LOOPZERO ZERO %_b_powmod_i # for i=0 to 127 powmod_loop_i: LD A,8 ST %_b_powmod_j,A # for j=0 to 7 LD A, &powmod_x.L ADD A, %_b_powmod_i LD B,A LD A,[&powmod_x:B] ST %_b_powmod_y,A powmod_loop_j: ### ### loop main ### SHRC %_b_powmod_y JRC0 ^powmod1024_lbl3 # skip yi=0 ### CALL powmod_1024mm (y*g) LD A, &powmod_y.H ST %_b_powmod_h , A LD A, &powmod_y.L ST %_b_powmod_l , A LD B, ^_b_powmod1024_mm.L BAL ^_b_powmod1024_mm:B powmod1024_lbl3: ### CALL powmod_1024mm (g*g) LD A, &powmod_g.H ST %_b_powmod_h , A LD A, &powmod_g.L ST %_b_powmod_l , A LD B, ^_b_powmod1024_mm.L BAL ^_b_powmod1024_mm:B DEC %_b_powmod_j JRZ0 ^powmod_loop_j INCX %_b_powmod_i # A=[i++] XOR A,0x7F JRZ0 ^powmod_loop_i LD A,%_b_powmod_RETA LD B,%_b_powmod_RETB JMP A:B .DATA REG 16 _reg02 ALIAS _b_powmod_gr _reg02 0 ALIAS _b_powmod_px _reg02 1 ALIAS _b_powmod_x _reg02 2 ALIAS _b_powmod_y _reg02 3 ALIAS _b_powmod_i _reg02 4 ALIAS _b_powmod_j _reg02 5 ALIAS _b_powmod_m _reg02 6 ALIAS _b_powmod_n _reg02 7 ALIAS _b_powmod_h _reg02 8 ALIAS _b_powmod_l _reg02 9 ALIAS _b_powmod_u _reg02 10 ALIAS _b_powmod_retA _reg02 11 # child sub ALIAS _b_powmod_retB _reg02 12 # child sub ALIAS _b_powmod_RETA _reg02 13 ALIAS _b_powmod_RETB _reg02 14 MEM 129 _system_work !0x100 ALIAS _b_powmod_a _system_work 0 MEM 256 powmod_gr !0x100 \ 0x3A 0x43 0xCE 0xEB 0xEC 0x52 0x88 0x94 0x4B 0x42 0x09 0xF6 0x91 0x70 0x7B 0x7F 0x25 0x1F 0xB8 0x44 0x32 0x0F 0x05 0x7F 0xF9 0xDD 0xA5 0x94 0x58 0x32 0x70 0x1E 0xCD 0x91 0x16 0xAC 0x21 0x16 0x90 0x79 0xCC 0xC2 0x66 0xC1 0x88 0x85 0x06 0x3B 0xF5 0x66 0xF2 0x31 0x89 0x74 0x2C 0x87 0x1D 0xBF 0x93 0x85 0x80 0x40 0x20 0xD3 0x18 0x47 0x16 0xE1 0xC5 0xB7 0xEB 0x70 0xF6 0xF0 0x2C 0x34 0x1A 0xBA 0xD5 0x9C 0x8C 0xA4 0xEE 0xDD 0x3C 0xD8 0xD9 0x7B 0xC4 0xA6 0x15 0xB3 0xAC 0x26 0x3D 0x45 0x21 0x7B 0x67 0x43 0xA7 0x63 0x16 0x7B 0x83 0x3C 0x1B 0xAE 0x6A 0x8F 0x9E 0x49 0xBE 0x99 0x01 0x92 0x1A 0xDE 0x6A 0xC5 0x7B 0x48 0xBA 0xF9 0x0A 0x29 0x82 0x46 0x3E 0x9C 0xD5 0x81 0xDB 0xC7 0x70 0xFD 0xEB 0x6C 0x52 0x37 0x07 0xF8 0x61 0x3F 0x79 0x31 0x57 0x32 0xC4 0x44 0x51 0x54 0x10 0x14 0x98 0x82 0x6B 0x0D 0xE5 0x50 0xA8 0xC0 0xC2 0x11 0x48 0xF1 0x38 0x4B 0x86 0xAC 0xF0 0xA5 0x34 0x37 0x52 0x67 0x89 0x88 0x93 0x4A 0x08 0x1E 0x92 0x17 0xE5 0x15 0xE5 0x14 0xB9 0x0C 0xCE 0x89 0xC7 0x0F 0x92 0xC5 0x1C 0xA3 0xF6 0x77 0xB8 0x88 0x50 0xF0 0x57 0xC8 0x62 0xED 0x34 0x89 0xE8 0x33 0xD2 0x22 0x6D 0x1B 0x45 0xC7 0xEB 0x84 0x32 0x13 0x18 0x84 0x84 0x69 0x24 0xD5 0x87 0xC0 0x5D 0x82 0xE8 0x55 0x2A 0x1A 0x77 0xEC 0x04 0xA5 0x21 0x86 0x16 0x04 0x25 0x9D 0x6D 0x66 0x11 0x9A 0x0E 0xBD 0xA9 0xB1 0xD1 0x4A ALIAS powmod_g powmod_gr 0x00 ALIAS powmod_y powmod_gr 0x80 # = R2modP MEM 256 powmod_px !0x100 \ 0xA1 0x63 0xD2 0x90 0x0B 0xD0 0x3A 0xAC 0xB4 0x15 0x75 0xEA 0x5E 0x05 0x57 0x86 0x55 0x12 0x36 0xE2 0xF8 0x07 0xCD 0x3E 0xE5 0x65 0x6E 0x70 0xE0 0x57 0xAE 0x5E 0x2D 0x21 0x53 0xE1 0xF0 0xC4 0xE5 0x96 0xB9 0x83 0xB3 0x5C 0x37 0xE2 0x3C 0x54 0xBF 0xF7 0x0F 0x4A 0xD8 0x19 0x2C 0xCA 0x3C 0xCA 0xD9 0x28 0xC3 0x76 0x75 0x5B 0x13 0x93 0xA3 0xC4 0x98 0x4E 0x6B 0x99 0x33 0x79 0xDC 0xCE 0x9C 0xB0 0xE8 0xBA 0x71 0xCD 0x27 0x5E 0xFA 0x8D 0xB0 0x7C 0x08 0xCF 0xF6 0x24 0x1B 0xD4 0xDA 0xCC 0x09 0x27 0x72 0x9C 0x5F 0x8D 0x08 0x6D 0x95 0x33 0x28 0xEE 0xAF 0x5D 0xED 0xB2 0x6E 0xB0 0xC3 0xE4 0xA3 0x70 0x4E 0x6B 0xF2 0xF9 0x6E 0x9C 0x4F 0xAB 0xFB 0xD8 0xC0 0xFA 0x69 0x4E 0x7C 0xBF 0x6D 0x94 0x18 0xE7 0x5C 0xB7 0xE8 0xE2 0xF4 0xCB 0x4B 0x75 0x3B 0x93 0x78 0x55 0xFC 0x0A 0x0D 0x00 0xEE 0xFE 0x16 0x0A 0x1D 0xAF 0x28 0xD0 0x9B 0xF2 0x09 0x4B 0x31 0xDE 0xF5 0x54 0x0E 0xCD 0xFE 0x4E 0x98 0x73 0x31 0x07 0x7E 0x90 0x1E 0xC6 0x98 0xD0 0xD8 0x1F 0xE8 0x0B 0x34 0xB7 0xFF 0x73 0x4A 0x86 0x82 0x48 0x20 0x52 0x9C 0x57 0xD4 0x38 0x5F 0x8F 0x43 0x33 0xB6 0x91 0xC1 0x14 0x5D 0xA6 0xAF 0x7B 0x13 0xA8 0xFB 0x89 0xAC 0xC8 0xFA 0x40 0x1F 0x21 0x14 0x7C 0xE7 0x64 0xCE 0xFF 0x48 0x49 0x7F 0xFD 0x9B 0x1A 0xA5 0x97 0x42 0x4A 0x94 0xB9 0xD6 0x70 0x83 0x38 0xAE 0xB3 0x78 0xBF 0xA6 0x48 0x24 0x4D 0x81 0x8C ALIAS powmod_p powmod_px 0x00 ALIAS powmod_x powmod_px 0x80 MEM 128 ANS &0xF00 MEM 128 powmod_exp \ 0xB4 0xBB 0x5B 0xB6 0x58 0x7A 0x9D 0x7A 0xEB 0x1C 0xE9 0x79 0xBF 0x94 0xF6 0x60 0x57 0x37 0x87 0x60 0x20 0x85 0xB3 0xB6 0xDD 0x9B 0xF4 0xA5 0xD8 0xFA 0x4C 0xC6 0xAD 0x84 0x39 0xCC 0xEC 0xD3 0xDD 0x23 0x86 0x4A 0x2C 0x50 0x93 0xEC 0xD6 0xAD 0x0D 0xD6 0xC4 0xBC 0xA1 0xD7 0x36 0x4F 0x2A 0x80 0x3F 0xC3 0x0C 0x0F 0xCD 0x4F 0x6C 0x6D 0xF1 0x5F 0x3D 0x58 0xAF 0xB5 0x1A 0x5B 0x85 0xF4 0xB8 0x77 0x11 0xD0 0x48 0x94 0xD7 0xC4 0xFF 0xFD 0x21 0xC1 0x41 0xA4 0x34 0xBB 0xC3 0x01 0x3A 0x36 0x4A 0x30 0xC3 0x3E 0x91 0xB2 0x86 0x2E 0x82 0xB0 0x87 0x63 0x81 0xCF 0x9E 0x33 0xC0 0x22 0x73 0x3B 0x05 0x95 0x8D 0xEA 0x80 0xA1 0xEE 0x33 0x47 0xD7 0xF2 0x84 </code></pre> <h1 id="解説(事前定数有版)"><a href="#%E8%A7%A3%E8%AA%AC%28%E4%BA%8B%E5%89%8D%E5%AE%9A%E6%95%B0%E6%9C%89%E7%89%88%29">解説(事前定数有版)</a></h1> <pre><code>y = g ^ x mod p ( r: R^2 mod p ) </code></pre> <p>rはpの値によって決まるモンゴメリ乗算の事前定数。モンゴメリ乗算の基数2は<a target="_blank" rel="nofollow noopener" href="https://openicf3.idletime.tokyo/">ICF3(1999年)</a>でも使われていました。1024bitべき乗剰余演算のサブルーチンの入力パラメータは256バイトのブロック2個。powmod_grとpowmod_pxです。grは前半128バイトがg、後半128バイトがr。 pxは前半128バイトがp(奇数)、後半128バイトがx。サブルーチンが終了するとrの場所に演算結果yが入っています。</p> <h1 id="1024bitのべき乗剰余演算(事前定数無版)"><a href="#1024bit%E3%81%AE%E3%81%B9%E3%81%8D%E4%B9%97%E5%89%B0%E4%BD%99%E6%BC%94%E7%AE%97%28%E4%BA%8B%E5%89%8D%E5%AE%9A%E6%95%B0%E7%84%A1%E7%89%88%29">1024bitのべき乗剰余演算(事前定数無版)</a></h1> <pre><code>################################################################### ### WZeta powmod 1024bit 2022/06/10 by Naoki Hirayama ### ### These codes are licensed under CC0.(Public Domain) ### http://creativecommons.org/publicdomain/zero/1.0/deed.ja ### ### Montgomery multiplication method with radix 2, ### which is famous for being used in ICF3(1999). ### ### This code is for Open source 8bit CPU WZeta. ### https://wzeta.idletime.tokyo/ ### ### download WZeta simulator ### https://subnote.icf3.net/wz660/download/ ### ### How to do simulation. ### &gt; wzsim (this file) ### ################################################################### ### --------------------------------------------------------------- ### Subroutine powmod1024 y = g^x mod p ### INOUT g,y 128,128 !0x100 ### IN x,p 128,128 !0x100 ### --------------------------------------------------------------- MEMORY 4 MODEL TINY ### MEMORY 8 ### MODEL HALF .PROG LD A,&powmod_gy.H ST %_b_powmod_gy,A LD A,&powmod_px.H ST %_b_powmod_px,A LD A, ^_b_powmod1024.H LD B, ^_b_powmod1024.L BAL A:B LD A,32 ST %_b_powmod_i,A LD A, &ANS.H LD B,0x80 LD C,0x00 copy_ans: # ans <- powmod_y STACP [&powmod_y:B] STACP [&powmod_y:B] STACP [&powmod_y:B] STACP [&powmod_y:B] DEC %_b_powmod_i JRZ0 ^copy_ans $PRINT &ANS 128 NOP $PRINT &powmod_exp 128 EXIT ### --------------------------------------------------------------- ### [%h:%l] =[%h:%l] * g R-1mod p ### IN %h:%l : pointer ### CONST p,g ### --------------------------------------------------------------- _b_powmod1024_mm: ST %_b_powmod_retA,A ST %_b_powmod_retB,B LD A,&_b_powmod_a.H # a = 0 LD B,&_b_powmod_a.L LD C,128 # repeat 129 LOOPZERO ZERO %_b_powmod_m _b_powmod1024_mm_loop_m: # for m=0 to 127 LD A,8 ST %_b_powmod_n,A LD A, %_b_powmod_m ADD A, %_b_powmod_l LD B,A LD A, %_b_powmod_h LD A,[A:B] ST %_b_powmod_x,A _b_powmod1024_mm_loop_n: # for n=0 to 7 ### loop body start -------------------------- LD A, %_b_powmod_x LD B, 0 AND A,[&powmod_g:B] XOR A,[&_b_powmod_a:B] ST %_b_powmod_u,A SHRC %_b_powmod_x JRC0 ^_b_powmod1024_mm2 # yi = 0 skip a += g LD B,0 # a += g CLC LD C,15 _b_powmod1024_mm1: LD A,[&powmod_g:B] !ADDC [&_b_powmod_a:B],A LD A,[&powmod_g:B] !ADDC [&_b_powmod_a:B],A LD A,[&powmod_g:B] !ADDC [&_b_powmod_a:B],A LD A,[&powmod_g:B] !ADDC [&_b_powmod_a:B],A LD A,[&powmod_g:B] !ADDC [&_b_powmod_a:B],A LD A,[&powmod_g:B] !ADDC [&_b_powmod_a:B],A LD A,[&powmod_g:B] !ADDC [&_b_powmod_a:B],A LD A,[&powmod_g:B] ADDC [&_b_powmod_a:B],A LOOPINC ^_b_powmod1024_mm1 INCC [&_b_powmod_a:B] _b_powmod1024_mm2: SHRC %_b_powmod_u JRC0 ^_b_powmod1024_mm4 # u=0 skip +p LD B,0 # a += p CLC LD C,15 _b_powmod1024_mm3: LD A,[&powmod_p:B] !ADDC [&_b_powmod_a:B],A LD A,[&powmod_p:B] !ADDC [&_b_powmod_a:B],A LD A,[&powmod_p:B] !ADDC [&_b_powmod_a:B],A LD A,[&powmod_p:B] !ADDC [&_b_powmod_a:B],A LD A,[&powmod_p:B] !ADDC [&_b_powmod_a:B],A LD A,[&powmod_p:B] !ADDC [&_b_powmod_a:B],A LD A,[&powmod_p:B] !ADDC [&_b_powmod_a:B],A LD A,[&powmod_p:B] ADDC [&_b_powmod_a:B],A LOOPINC ^_b_powmod1024_mm3 INCC [&_b_powmod_a:B] _b_powmod1024_mm4: # a >>= 1 LD A, &_b_powmod_a.H LD B,128 LD C,128 CLC LOOPSHRC ### loop body end -------------------------- DEC %_b_powmod_n JRZ0 ^_b_powmod1024_mm_loop_n INCX %_b_powmod_m # A=m++ XOR A,0x7F JRZ0 ^_b_powmod1024_mm_loop_m ### Final Substruct INC %_b_powmod_n # n=1 _b_powmod1024_mm5: LD A,32 # y=a(before sub) ST %_b_powmod_m,A # 32 = 128 / 4 LD A,%_b_powmod_h LD C,%_b_powmod_l LD B,0 _b_powmod1024_mm6: STACP [&_b_powmod_a:B] STACP [&_b_powmod_a:B] STACP [&_b_powmod_a:B] STACP [&_b_powmod_a:B] DEC %_b_powmod_m JRZ0 ^_b_powmod1024_mm6 LD C,%_b_powmod_n LOOPINC ^_b_powmod1024_mm8 # if C!=0 jump _b_powmod1024_mm7: # return LD A,%_b_powmod_retA LD B,%_b_powmod_retB JMP A:B _b_powmod1024_mm8: LD B,0 # a -= p LD A,0 SUB A,C # CF=1 LD C,31 _b_powmod1024_mm9: LD A,[&powmod_p:B] !SUBC [&_b_powmod_a:B],A LD A,[&powmod_p:B] !SUBC [&_b_powmod_a:B],A LD A,[&powmod_p:B] !SUBC [&_b_powmod_a:B],A LD A,[&powmod_p:B] SUBC [&_b_powmod_a:B],A LOOPINC ^_b_powmod1024_mm9 DECC [&_b_powmod_a:B] JRC0 ^_b_powmod1024_mm7 ZERO %_b_powmod_n JR ^_b_powmod1024_mm5 ### --------------------------------------------------------------- ### --------------------------------------------------------------- ### Subroutine powmod1024 ### INOUT g,y 128,128 !0x100 ### const IN x,p 128,128 !0x100 ### work _b_powmod_a 129 !0x100 ### --------------------------------------------------------------- _b_powmod1024: ST %_b_powmod_RETA,A ST %_b_powmod_RETB,B ### g = gR mod p LD A,4 ST %_b_powmod_i,A # for i=4 to 1 ZERO %_b_powmod_j # for j=0 to 255 powmod_loop_gi: ### always %_b_powmod_j = 0 powmod_loop_gj: LD A,&powmod_g.H # g<<=1 LD B,0 LD C,0x7F CLC LOOPSHLC GETFLAG [0] JRC1 ^_b_powmod1024_lbl1 # skip copy LD A,&_b_powmod_a.H # copy a <- g LD B,0 LD C,0x7F _b_powmod1024_loop1: STAB [&powmod_g:B] LOOPINC ^_b_powmod1024_loop1 _b_powmod1024_lbl1: LD B,0 LD A,[&powmod_p:B] SUB [&powmod_g:B],A !LD C,126 _b_powmod1024_loop2: LD A,[&powmod_p:B] SUBC [&powmod_g:B],A LOOPINC ^_b_powmod1024_loop2 JRC1 ^_b_powmod1024_lbl2 SHL [0] JRC1 ^_b_powmod1024_lbl2 LD A,&powmod_g.H # copy g <- a LD B,0 LD C,0x7F _b_powmod1024_loop3: STAB [&_b_powmod_a:B] LOOPINC ^_b_powmod1024_loop3 _b_powmod1024_lbl2: DEC %_b_powmod_j JRZ0 ^powmod_loop_gj DEC %_b_powmod_i JRZ0 ^powmod_loop_gi # powmod_y = 1 start LD A, %_b_powmod_gy LD B,0x80 # y LD C, 1 !ST [A:B],C # y[0] = 1 LD C,126 # repeat 127 LOOPZERO ZERO %_b_powmod_i # for i=0 to 127 powmod_loop_i: LD A,8 ST %_b_powmod_j,A # for j=0 to 7 LD A, &powmod_x.L ADD A, %_b_powmod_i LD B,A LD A,[&powmod_x:B] ST %_b_powmod_y,A powmod_loop_j: ### ### loop main ### SHRC %_b_powmod_y JRC0 ^powmod1024_lbl3 # skip yi=0 ### CALL powmod_1024mm (y*g) LD A, &powmod_y.H ST %_b_powmod_h , A LD A, &powmod_y.L ST %_b_powmod_l , A LD B, ^_b_powmod1024_mm.L BAL ^_b_powmod1024_mm:B powmod1024_lbl3: ### CALL powmod_1024mm (g*g) LD A, &powmod_g.H ST %_b_powmod_h , A LD A, &powmod_g.L ST %_b_powmod_l , A LD B, ^_b_powmod1024_mm.L BAL ^_b_powmod1024_mm:B DEC %_b_powmod_j JRZ0 ^powmod_loop_j INCX %_b_powmod_i # A=[i++] XOR A,0x7F JRZ0 ^powmod_loop_i LD A,%_b_powmod_RETA LD B,%_b_powmod_RETB JMP A:B .DATA REG 16 _reg02 ALIAS _b_powmod_gy _reg02 0 ALIAS _b_powmod_px _reg02 1 ALIAS _b_powmod_x _reg02 2 ALIAS _b_powmod_y _reg02 3 ALIAS _b_powmod_i _reg02 4 ALIAS _b_powmod_j _reg02 5 ALIAS _b_powmod_m _reg02 6 ALIAS _b_powmod_n _reg02 7 ALIAS _b_powmod_h _reg02 8 ALIAS _b_powmod_l _reg02 9 ALIAS _b_powmod_u _reg02 10 ALIAS _b_powmod_retA _reg02 11 # child sub ALIAS _b_powmod_retB _reg02 12 # child sub ALIAS _b_powmod_RETA _reg02 13 ALIAS _b_powmod_RETB _reg02 14 MEM 129 _system_work !0x100 ALIAS _b_powmod_a _system_work 0 MEM 256 powmod_gy &0xE00 \ 0x3A 0x43 0xCE 0xEB 0xEC 0x52 0x88 0x94 0x4B 0x42 0x09 0xF6 0x91 0x70 0x7B 0x7F 0x25 0x1F 0xB8 0x44 0x32 0x0F 0x05 0x7F 0xF9 0xDD 0xA5 0x94 0x58 0x32 0x70 0x1E 0xCD 0x91 0x16 0xAC 0x21 0x16 0x90 0x79 0xCC 0xC2 0x66 0xC1 0x88 0x85 0x06 0x3B 0xF5 0x66 0xF2 0x31 0x89 0x74 0x2C 0x87 0x1D 0xBF 0x93 0x85 0x80 0x40 0x20 0xD3 0x18 0x47 0x16 0xE1 0xC5 0xB7 0xEB 0x70 0xF6 0xF0 0x2C 0x34 0x1A 0xBA 0xD5 0x9C 0x8C 0xA4 0xEE 0xDD 0x3C 0xD8 0xD9 0x7B 0xC4 0xA6 0x15 0xB3 0xAC 0x26 0x3D 0x45 0x21 0x7B 0x67 0x43 0xA7 0x63 0x16 0x7B 0x83 0x3C 0x1B 0xAE 0x6A 0x8F 0x9E 0x49 0xBE 0x99 0x01 0x92 0x1A 0xDE 0x6A 0xC5 0x7B 0x48 0xBA 0xF9 0x0A 0x29 0x82 0x46 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 ALIAS powmod_g powmod_gy 0x00 ALIAS powmod_y powmod_gy 0x80 MEM 256 powmod_px &0xD00 \ 0xA1 0x63 0xD2 0x90 0x0B 0xD0 0x3A 0xAC 0xB4 0x15 0x75 0xEA 0x5E 0x05 0x57 0x86 0x55 0x12 0x36 0xE2 0xF8 0x07 0xCD 0x3E 0xE5 0x65 0x6E 0x70 0xE0 0x57 0xAE 0x5E 0x2D 0x21 0x53 0xE1 0xF0 0xC4 0xE5 0x96 0xB9 0x83 0xB3 0x5C 0x37 0xE2 0x3C 0x54 0xBF 0xF7 0x0F 0x4A 0xD8 0x19 0x2C 0xCA 0x3C 0xCA 0xD9 0x28 0xC3 0x76 0x75 0x5B 0x13 0x93 0xA3 0xC4 0x98 0x4E 0x6B 0x99 0x33 0x79 0xDC 0xCE 0x9C 0xB0 0xE8 0xBA 0x71 0xCD 0x27 0x5E 0xFA 0x8D 0xB0 0x7C 0x08 0xCF 0xF6 0x24 0x1B 0xD4 0xDA 0xCC 0x09 0x27 0x72 0x9C 0x5F 0x8D 0x08 0x6D 0x95 0x33 0x28 0xEE 0xAF 0x5D 0xED 0xB2 0x6E 0xB0 0xC3 0xE4 0xA3 0x70 0x4E 0x6B 0xF2 0xF9 0x6E 0x9C 0x4F 0xAB 0xFB 0xD8 0xC0 0xFA 0x69 0x4E 0x7C 0xBF 0x6D 0x94 0x18 0xE7 0x5C 0xB7 0xE8 0xE2 0xF4 0xCB 0x4B 0x75 0x3B 0x93 0x78 0x55 0xFC 0x0A 0x0D 0x00 0xEE 0xFE 0x16 0x0A 0x1D 0xAF 0x28 0xD0 0x9B 0xF2 0x09 0x4B 0x31 0xDE 0xF5 0x54 0x0E 0xCD 0xFE 0x4E 0x98 0x73 0x31 0x07 0x7E 0x90 0x1E 0xC6 0x98 0xD0 0xD8 0x1F 0xE8 0x0B 0x34 0xB7 0xFF 0x73 0x4A 0x86 0x82 0x48 0x20 0x52 0x9C 0x57 0xD4 0x38 0x5F 0x8F 0x43 0x33 0xB6 0x91 0xC1 0x14 0x5D 0xA6 0xAF 0x7B 0x13 0xA8 0xFB 0x89 0xAC 0xC8 0xFA 0x40 0x1F 0x21 0x14 0x7C 0xE7 0x64 0xCE 0xFF 0x48 0x49 0x7F 0xFD 0x9B 0x1A 0xA5 0x97 0x42 0x4A 0x94 0xB9 0xD6 0x70 0x83 0x38 0xAE 0xB3 0x78 0xBF 0xA6 0x48 0x24 0x4D 0x81 0x8C ALIAS powmod_p powmod_px 0x00 ALIAS powmod_x powmod_px 0x80 MEM 128 ANS &0xF00 MEM 128 powmod_exp \ 0xB4 0xBB 0x5B 0xB6 0x58 0x7A 0x9D 0x7A 0xEB 0x1C 0xE9 0x79 0xBF 0x94 0xF6 0x60 0x57 0x37 0x87 0x60 0x20 0x85 0xB3 0xB6 0xDD 0x9B 0xF4 0xA5 0xD8 0xFA 0x4C 0xC6 0xAD 0x84 0x39 0xCC 0xEC 0xD3 0xDD 0x23 0x86 0x4A 0x2C 0x50 0x93 0xEC 0xD6 0xAD 0x0D 0xD6 0xC4 0xBC 0xA1 0xD7 0x36 0x4F 0x2A 0x80 0x3F 0xC3 0x0C 0x0F 0xCD 0x4F 0x6C 0x6D 0xF1 0x5F 0x3D 0x58 0xAF 0xB5 0x1A 0x5B 0x85 0xF4 0xB8 0x77 0x11 0xD0 0x48 0x94 0xD7 0xC4 0xFF 0xFD 0x21 0xC1 0x41 0xA4 0x34 0xBB 0xC3 0x01 0x3A 0x36 0x4A 0x30 0xC3 0x3E 0x91 0xB2 0x86 0x2E 0x82 0xB0 0x87 0x63 0x81 0xCF 0x9E 0x33 0xC0 0x22 0x73 0x3B 0x05 0x95 0x8D 0xEA 0x80 0xA1 0xEE 0x33 0x47 0xD7 0xF2 0x84 </code></pre> <h1 id="解説(事前定数無版)"><a href="#%E8%A7%A3%E8%AA%AC%28%E4%BA%8B%E5%89%8D%E5%AE%9A%E6%95%B0%E7%84%A1%E7%89%88%29">解説(事前定数無版)</a></h1> <pre><code>y = g ^ x mod p </code></pre> <p>モンゴメリ乗算の基数2は<a target="_blank" rel="nofollow noopener" href="https://openicf3.idletime.tokyo/">ICF3(1999年)</a>でも使われていました。1024bitべき乗剰余演算のサブルーチンの入力パラメータは256バイトのブロック2個。powmod_gyとpowmod_pxです。gyは前半128バイトがg、後半128バイトは演算結果。 pxは前半128バイトがp(奇数)、後半128バイトがx。</p> <h1 id="実行環境"><a href="#%E5%AE%9F%E8%A1%8C%E7%92%B0%E5%A2%83">実行環境</a></h1> <p><a target="_blank" rel="nofollow noopener" href="https://subnote.icf3.net/wz660/download.html">WZetaシミュレータ</a>で実際に演算させてみることが可能です。</p> <pre><code>> wzsim (アセンブラのファイル) </code></pre> <p><strong>注意 シミュレータにはC言語実装のシミュレータとverilogのバイナリがあります。verilogでは1024bitのべき乗剰余演算に1週間以上かかることもあるので、ご注意ください。</strong></p> <h1 id="実行結果"><a href="#%E5%AE%9F%E8%A1%8C%E7%B5%90%E6%9E%9C">実行結果</a></h1> <p>実行後、演算が終了すると演算結果に続いて期待値が表示されます。期待値はコードの最後にあるpowmod_expの値が、そのまま表示されます。</p> <h1 id="性能について"><a href="#%E6%80%A7%E8%83%BD%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6">性能について</a></h1> <p>乗算命令が無いため8bitの加算器1個で演算しています。絶対時間では非常に遅いため軽量な楕円暗号か、数時間の演算時間が許容されるIoTシステムなどでの利用に向いています。BIOSを通してアプリを作成すればアプリを改変することなく超高速な<a target="_blank" rel="nofollow noopener" href="https://snakecube.idletime.tokyo/">暗号プロセッサSnakeCube</a>に置き換えられることを考えているため、性能が必要になったところで、暗号プロセッサSnakeCubeに置き換えることが可能になる予想です。シミュレータの実行終了後、命令数が表示されます。WZetaのSDogコアでは1命令4サイクルなので命令数を4倍して周波数を計算すると1024bitのべき乗剰余演算1回の時間が求まります。値に依存しますが、上記、サンプルコードでは666530315命令。CPUの周波数に8MHzを想定した場合、1サイクル125[ns]なので<br /> 666530315 × 4 × 125 ÷ 10^9 ≒ 333秒 ( 512bitのべき乗剰余演算だと約42秒 )</p> <h1 id="脆弱性対策"><a href="#%E8%84%86%E5%BC%B1%E6%80%A7%E5%AF%BE%E7%AD%96">脆弱性対策</a></h1> <p>今回のコードは脆弱性対策の無い単純に最も高速なプログラムになっています。また最上位ビットを高速モードとして使っています。サイドチャネル攻撃を対策をするには値に依存しないようにダミーの計算時間を入れます。WZetaの命令セットはオペコードに依存せずメモリアクセスをするという低消費電力でない特性がありますが、これが電力解析などのサイドチャネル攻撃への耐性を高めることにもなっています。トランジスタ数が少ないのでオペコードに依存しない動作で0、1の切り替えが多くなったとしても、全体としての消費電力は少ないという予想です。</p> spinlock tag:crieit.net,2005:PublicArticle/17956 2022-01-27T07:50:41+09:00 2022-01-27T08:21:13+09:00 https://crieit.net/posts/naokislaw 暗号半導体チップにおける『ナオキの法則』 <p><a href="https://crieit.now.sh/upload_images/a8228c3f8fb4b5ea19b4961beb6bd1f061f1d76540194.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/a8228c3f8fb4b5ea19b4961beb6bd1f061f1d76540194.png?mw=700" alt="暗号プロセッサSnakeCube" /></a></p> <h3 id="背景"><a href="#%E8%83%8C%E6%99%AF">背景</a></h3> <p>半導体業界ではムーアの法則が有名ですが、ムーアの法則は集積回路上のトランジスタ数は「2年ごとに倍になる」という指標のような経験則です。似たような法則として平山 直紀(Naoki Hirayama)が2018年に発明したSnakeCubeから、後世の人に役立つ指標になる<strong>ナオキの法則(Naoki's law)</strong>を提案します。発明直後に、この法則が言えることを確信していたのですが<a target="_blank" rel="nofollow noopener" href="https://snakecube.idletime.tokyo/">SnakeCube</a>の実装に奔走していたため、後回しにしてきました。この法則が学会、産業界で、大いに活用してもらえるように、ここで発表します。</p> <h3 id="概略"><a href="#%E6%A6%82%E7%95%A5">概略</a></h3> <p>SnakeCubeはRSAなどの公開鍵暗号の演算で良く使われるモンゴメリ乗算器とプロセッサの構成法のことです。デバイスに依存しない数学のアルゴリズムに近いものです。ざっくり言うと演算器、単体で3倍以上、性能を4倍にできる中国人剰余定理も併用可能なため、従来研究の3×4=12倍の高速化を達成しました。演算器単体でも10倍あるかもしれないデータもあるため革命的な発明ではないかと思われます。モンゴメリ乗算を使わないアルゴリズムにはSnakeCubeよりも高速なサバンジュ大学の論文があります。ただ量子コンピュータによる解読問題を緩和するためには、鍵長を長くする必要があるのですが、その方法は鍵長を大きくすることが実装上非常に困難であるため、僕はSnakeCubeが世界最高の暗号プロセッサであると考えています。移植の容易性や、鍵長を長くするのが、とても容易なこと。鍵長を長くしても効率が落ちない。マルチチップに実装することが容易であること、IPにしやすいなど、SnakeCubeは良い点が多いのです。</p> <h3 id="トルコにあるサバンジュ大学の論文"><a href="#%E3%83%88%E3%83%AB%E3%82%B3%E3%81%AB%E3%81%82%E3%82%8B%E3%82%B5%E3%83%90%E3%83%B3%E3%82%B8%E3%83%A5%E5%A4%A7%E5%AD%A6%E3%81%AE%E8%AB%96%E6%96%87">トルコにあるサバンジュ大学の論文</a></h3> <p>次の論文は「鍵長2倍で計算時間2倍」を理論的に説明した論文。米アマゾンとイーサリアム財団ら、<a target="_blank" rel="nofollow noopener" href="https://crypto.watch.impress.co.jp/docs/news/1200097.html">賞金10万ドルのFPGAデザインコンテスト</a>を優勝した論文です。</p> <p><a href="https://crieit.now.sh/upload_images/59546e984c704859bcdffa3eaadfed2261f1d23a8488e.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/59546e984c704859bcdffa3eaadfed2261f1d23a8488e.png?mw=700" alt="サバンジュ大学の論文" /></a></p> <p>理論的に美しい論文ですが、鍵長が長くなるにしたがって、効率が下がり、実装が急激に(経済的にも)困難になっていくため、量子コンピュータの暗号解読が懸念される、現在では、論文の成果が薄れています。</p> <h3 id="暗号プロセッサSnakeCube"><a href="#%E6%9A%97%E5%8F%B7%E3%83%97%E3%83%AD%E3%82%BB%E3%83%83%E3%82%B5SnakeCube">暗号プロセッサSnakeCube</a></h3> <p><a target="_blank" rel="nofollow noopener" href="https://snakecube.idletime.tokyo/">SnakeCube</a>は、平山 直紀(Naoki Hirayama)が2018年に発明した暗号プロセッサ。<br /> 次のURLにある説明を読むとわかるかも。</p> <p><a target="_blank" rel="nofollow noopener" href="https://snakecube.idletime.tokyo/">暗号プロセッサSnakeCube</a></p> <p><a target="_blank" rel="nofollow noopener" href="https://icf.hatenablog.com/entry/2020/04/05/143527">巨大整数用四則演算プロセッサSnakeCubeが高速である秘密</a></p> <p>[<a target="_blank" rel="nofollow noopener" href="https://icf.hatenablog.com/entry/2019/11/06/210448">大きなモンゴメリ乗算器は実装できるのか?</a></p> <h3 id="ナオキの法則 (Naoki's law)"><a href="#%E3%83%8A%E3%82%AA%E3%82%AD%E3%81%AE%E6%B3%95%E5%89%87+%28Naoki%27s+law%29">ナオキの法則 (Naoki's law)</a></h3> <p>RSA暗号は鍵長が2倍になると計算量が8倍になるのです。<br /> サバンジュ大学の論文は、わかりやすく説明すると、理論的に<strong>RSA暗号性能が</strong>「鍵長2倍で計算時間2倍」を説明した論文ですが、ナオキの法則は「鍵長2倍で計算時間4倍」です。<br /> サバンジュ大学の論文のほうが勝っていますが、これは鍵長を2倍にした場合、トランジスタ数を4倍にして計算時間2倍を成り立たせています。ただし前述のように実際の製品にしていくには鍵長が大きくなるしたがって、劇的に困難になります。一方、ナオキの法則はSnakeCubeによって、だいたい保証されそうだということが、わかってきています。つまり、あるプロセスのデバイスでデータを取るとナオキの法則を使って、そのデバイスで鍵長を大きくした場合の精密な性能が予測できるのです。</p> <h3 id="SnakeCubeは世界最高の暗号プロセッサ"><a href="#SnakeCube%E3%81%AF%E4%B8%96%E7%95%8C%E6%9C%80%E9%AB%98%E3%81%AE%E6%9A%97%E5%8F%B7%E3%83%97%E3%83%AD%E3%82%BB%E3%83%83%E3%82%B5">SnakeCubeは世界最高の暗号プロセッサ</a></h3> <p>SnakeCubeよりもレイテンシ性能の高いプロセッサを開発することは可能だと思います。しかしデバイス毎に大きな設計コストが要求されると予想されるため、SnakeCubeが世界最高の暗号プロセッサであり続けると考えています。これは、これまで設計にお金をかけるよりデバイスにお金をかけて性能を向上することを優先する場合が多かったこと。概略で書いたとおりSnakeCubeの良い点が、多数あるため。</p> <h3 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h3> <p>今後、世界でSnakeCubeよりも高速な暗号プロセッサの開発を考えることはあると思います。ナオキの法則は、それを評価する上で便利な指標となるため、広く利用されるように考えます。量子コンピュータの進歩によりRSA暗号の安全性が危ぶまれている状況ですが、2048bitの鍵長を、いっきに大きくして、量子ビットを同時に多数安定化する技術が限界に達するところまで、もっていけば、RSAも、まだしばらくは安全だと楽観的に考えることもできるように思います。またSnakeCubeはRSA暗号専用のプロセッサではなくて、巨大な整数の四則演算器なので、今後、新しい公開暗号を高速化するためにも役に立ちます。</p> <p>ナオキの法則は、人類史に残る法則となるかもしれない。</p> spinlock tag:crieit.net,2005:PublicArticle/15817 2020-04-10T21:22:29+09:00 2020-04-10T21:47:22+09:00 https://crieit.net/posts/IC クレジットカードのICチップの高速化 <p>クレジットカードにICチップが義務化され、量子コンピュータが進歩したためクレジットカードのICチップに搭載されるRSA暗号の高速化に関心を持つ人が増えたように思います。</p> <p>クレジットカードではRSA/ECC暗号の鍵長を長くする以外の方法で対策することも考えられますが、僕が発明した暗号プロセッサSnakeCubeは高速、高効率に演算可能なので、RSA/ECC暗号の鍵長を長くする方法が、世の中の多くの人にとって幸せ、ということにならないだろうか。</p> <p>SnakeCubeは、これまでICF3-Fと呼んできたものです。1999年にRSA暗号の性能で世界一だったICF3をベースに高速、高効率なモンゴメリ乗算器を搭載しています。</p> <p><strong>重要なのはSnakeCubeがICチップに向いているアーキテクチャ</strong>だろうと予想できること。配線の局所性が高いためICチップの配線層を少なくできて<strong>製造コストを抑えることができると考えているため。</strong> 配線層が増えればチップの製造コストは上がるのでICチップのように製造コストが重要なものでは、有効な特長であるように思っています。</p> <p>以下は、SnakeCubeのアーキテクチャが、わかるブログです。</p> <p><a target="_blank" rel="nofollow noopener" href="https://icf.hatenablog.com/entry/2020/04/05/143527">「巨大整数用四則演算プロセッサSnakeCubeが高速である秘密」</a></p> <p>以下、配線の局所性について、わかるかもしれないブログ</p> <p><a target="_blank" rel="nofollow noopener" href="https://icf.hatenablog.com/entry/2019/08/12/230403">「わかりやすいICF3-Fのモンゴメリ乗算器の説明」</a></p> spinlock tag:crieit.net,2005:PublicArticle/15772 2020-03-19T20:19:01+09:00 2021-02-09T20:50:42+09:00 https://crieit.net/posts/CPU-RISC-V-vs-ICF3-Z オープンソースのCPUの除算性能 RISC-V vs ICF3-Z <h2 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h2> <p>2020年1月15日に<a target="_blank" rel="nofollow noopener" href="https://icf3z.idletime.tokyo/">8bit CPU ICF3-Z</a>を制限の緩いオープンソースのライセンスで公開しました。</p> <p>CPUのようなハードウェアもオープンソースな時代になってきました。CPUのオープンソースで最も有名なのはRISC-Vです。RISC-Vを見てみるとオープンソースによるメリットを見つけることができます。RISC-Vは、とても広い範囲をカバーする32bit(64bit)のCPUですが低性能な領域でも万能というわけではないように思います。</p> <p>例えば通信系のハードウェアでは8bit単位で処理するものもあり32bitが無駄になる場合もあります。無駄になるだけなら問題はありませんが消費電力で不利です。</p> <p>一方、8bit CPUは除算命令がなかったり、除算命令があっても8bit÷8bitで、使える範囲が狭いということがありました。8bit CPUのオープンソースも既に複数、存在していますが、高性能な除算を持ったものは、あまりないように思います。ICF3-Zはオープンソースで、少ないトランジスタ数であるにもかかわらず高速な除算が可能です。</p> <h2 id="除算性能の比較"><a href="#%E9%99%A4%E7%AE%97%E6%80%A7%E8%83%BD%E3%81%AE%E6%AF%94%E8%BC%83">除算性能の比較</a></h2> <p><strong>実際に比較しないと、わからない人が多いと思っています。</strong> ICF3-ZのZeviosを小型のRISC-VコアであるlowRISCのibexと比較してみました。 ICF3-ZのZeviosは8bit CPUですが、lowRISCのibexは<strong>除算器を持った32bit CPU</strong>です。</p> <p>lowRISCの<a target="_blank" rel="nofollow noopener" href="https://www.lowrisc.org/blog/2019/06/an-update-on-ibex-our-microcontroller-class-cpu-core/">Webページ</a>にXilinxのローエンドのFPGA(7シリーズ)に実装した場合の周波数が50MHz、面積2500LUTと書かれてありました。 除算のサイクル数は<a target="_blank" rel="nofollow noopener" href="https://ibex-core.readthedocs.io/en/latest/instruction_decode_execute.html#multiplier-divider-block-mult-div">別のページ</a>に37サイクルと記述されています。</p> <p>Zeviosは同じくXilinxのローエンドのFPGA(Artix-7)に実装した場合、周波数は150MHzになります。つまりibexの3倍の周波数で動作します。ibexが1命令を実行するのにZeviosは3命令を実行できる。</p> <div class="table-responsive"><table> <thead> <tr> <th>除算</th> <th>ibexRISC-V[サイクル]</th> <th>ZeviosICF3-Z[サイクル]</th> <th>ibexを1とした倍率</th> <th>周波数を考慮した倍率</th> </tr> </thead> <tbody> <tr> <td>16bit÷8bit</td> <td>37</td> <td>20</td> <td>1.85</td> <td>5.55</td> </tr> <tr> <td>24bit÷8bit条件付き</td> <td>37</td> <td>21</td> <td>1.76</td> <td>5.29</td> </tr> <tr> <td>32bit÷8bit</td> <td>37</td> <td>55</td> <td>0.67</td> <td>2.02</td> </tr> <tr> <td>32bit÷16bit</td> <td>37</td> <td>約350</td> <td>0.11</td> <td>0.32</td> </tr> </tbody> </table></div> <p>0除算などのチェックや演算レジスタへのロード、ストアの補正として3~6サイクル追加しています。<br /> ZeviosはXilinxのFPGA XC7A35TICSG324-1Lに実装した場合です。</p> <h2 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h2> <p>ibexは2500LUTの面積ですが、Zeviosは400LUTの面積です。 外部I/OなどZeviosに不足しているものがあるかもしれませんが<strong>5分の一の面積で5倍以上の性能が出る</strong>ことは、考えるべき点ではないでしょうか。16bit÷8bitは32bit CPUであるRISC-Vに不利ということはありますが、制御など32bitの精度が必ずしも必要ない場合もあるように思います。</p> <p>ICF3-Zは海外のパクリな構造ではなく僕の考えた独自アーキテクチャです。疑似パイプラインによって高周波数で動作することも、この圧倒的な面積当たりの性能(25倍)に貢献しています。</p> <p>このオープンソースな8bit CPU ICF3-Zが、期待を含めれば2020年代に大きく産業に貢献していくかもしれません。</p> <h2 id="参考リンク"><a href="#%E5%8F%82%E8%80%83%E3%83%AA%E3%83%B3%E3%82%AF">参考リンク</a></h2> <p><a target="_blank" rel="nofollow noopener" href="https://qiita.com/izuna/items/49ad4eef53c65c591d61">8bit CPU ICF3-ZのZeviosの除算性能のメモ</a></p> <p><a target="_blank" rel="nofollow noopener" href="https://qiita.com/izuna/items/38a04fbedf531f193a7d">8bit CPU ATmega328の除算性能を測定してみた</a></p> <p><a target="_blank" rel="nofollow noopener" href="https://icf.hatenablog.com/entry/2019/04/16/181417">仮想マシンの加速支援機構つきの新型8bit CPU</a></p> spinlock tag:crieit.net,2005:PublicArticle/15684 2020-01-16T06:22:14+09:00 2020-01-16T06:22:14+09:00 https://crieit.net/posts/8bit-CPU-ICF3-Z-Zevios 8bit CPU ICF3-ZのZeviosの除算性能のメモ <h2 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h2> <p>8bit CPU ICF3-Zのオリジナルのコア、<a target="_blank" rel="nofollow noopener" href="https://icf3z.idletime.tokyo/download.html">Zevios</a>の除算性能について解説します。Zeviosは2020年1月15日に緩いオープンソースライセンスであるApache License 2.0で公開されました。FPGAに実装できるverilogファイルがあるので、いろいろ性能を測定することができます。</p> <h2 id="Zeviosの除算器について"><a href="#Zevios%E3%81%AE%E9%99%A4%E7%AE%97%E5%99%A8%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6">Zeviosの除算器について</a></h2> <p>正しくは除算器というものはなくて8bitの加算器を効率的に動作させることで1サイクルに1bitの商を演算するアーキテクチャです。除算器の性能としては低いのですが、マイコン向けのCPUでは除算器がないものも多く、小さい面積なのに高速に除算ができるものになっています。(除算器としての面積がほとんどない) その除算向けのアーキテクチャを使って8bitより大きい除算をソフトウェアで実装できます。一般の8bit CPUによる実装よりも高速に演算できます。</p> <h2 id="16bit÷8bitの除算"><a href="#16bit%C3%B78bit%E3%81%AE%E9%99%A4%E7%AE%97">16bit÷8bitの除算</a></h2> <p>ICF3-Zでは加算器を使って効率的に演算できるようになっています。17サイクルで演算ができます。</p> <h2 id="24bit÷8bitの除算"><a href="#24bit%C3%B78bit%E3%81%AE%E9%99%A4%E7%AE%97">24bit÷8bitの除算</a></h2> <p>ICF3-Zでは加算器を使って効率的に演算できるようになっています。17サイクルで演算ができます。<br /> ただし被除数の最上位8bitが除数8bitよりも小さい場合に限ります。</p> <h2 id="32bit÷8bitの除算"><a href="#32bit%C3%B78bit%E3%81%AE%E9%99%A4%E7%AE%97">32bit÷8bitの除算</a></h2> <p>16bit÷8bitの除算方法を応用したサンプルコードによる性能は50サイクルです。サンプルコードはgithubで公開されています。<br /> sim2フォルダのpmem.asmzが32bit÷8bitのコードです。</p> <h2 id="32bit÷16bitの除算"><a href="#32bit%C3%B716bit%E3%81%AE%E9%99%A4%E7%AE%97">32bit÷16bitの除算</a></h2> <p>ICF3-Zのアーキテクチャを駆使したサンプルコードによる性能は約350サイクルです。サンプルコードはgithubで公開されています。<br /> sim1フォルダのpmem.asmzが32bit÷16bitのコードです。<br /> ソフトウェアの実装によって性能は違ってくると思われます。もっと高速な方法もあるかもしれません。<br /> 除数が8bit × 8bitの因数に分解できるものなら32bit ÷ 8bitを2回演算したほうが高速です。</p> <p>32bit÷15bitを230サイクルで演算するコードも作ったのですが、まだ十分に検証できていないため、今回は見送りました。</p> <h2 id="おわりに"><a href="#%E3%81%8A%E3%82%8F%E3%82%8A%E3%81%AB">おわりに</a></h2> <p>ICF3-Z Zeviosは、とても少ないトランジスタ数(面積)で実装できるのに高速です。16bit÷8bit、24bit÷8bitの除算が有効につかえるアプリでは低消費電力が期待できるように思われます。</p> spinlock tag:crieit.net,2005:PublicArticle/15676 2020-01-12T04:51:56+09:00 2020-06-03T01:49:25+09:00 https://crieit.net/posts/8bit-CPU-ATmega328 8bit CPU ATmega328の除算性能を測定してみた <h2 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h2> <p>ATmega328は Microchipの8bit CPU AVRの1種です。AVRは除算命令がなくArduinoで除算をするコードを書いた場合、どのくらいの性能になるのか測定しました。測定条件でソフトウェア処理が最適化されていないのでAVRのアセンブラを使って最適化をすれば、もっと高速になるはずですが、これはソフト開発環境Arduinoのソフトウエア除算性能の測定です。</p> <h2 id="測定条件"><a href="#%E6%B8%AC%E5%AE%9A%E6%9D%A1%E4%BB%B6">測定条件</a></h2> <p>CPU : ATmega328 クロック 16MHz<br /> ボード: Arduino<br /> ソフト開発環境 : Arduino 1.8.10<br /> 性能を測定する除算 : 16bit ÷ 8bit / 24bit ÷ 8bit</p> <h2 id="測定コード(16bit÷8bit)"><a href="#%E6%B8%AC%E5%AE%9A%E3%82%B3%E3%83%BC%E3%83%89%2816bit%C3%B78bit%29">測定コード(16bit÷8bit)</a></h2> <p>除算を1万回実行して、加算のみの場合との差分を除算1万回の実行時間とします。</p> <pre><code>void setup() { Serial.begin(9600); randomSeed(analogRead(0)); } void loop() { unsigned long s, e, t; unsigned int i; unsigned short x,z; unsigned char y; t = millis(); /* dummy */ s = millis(); for(i=0 ; i<10000 ; i++) { x = random(0,0xffff); y = random(2,0xff); z += x + y; } e = millis(); t = e - s; Serial.print("x="); Serial.print(x); Serial.print(" y="); Serial.print(y); Serial.print(" time1="); Serial.print(t); Serial.print("\n"); s = millis(); for(i=0 ; i<10000 ; i++) { x = random(0,0xffff); y = random(2,0xff); z += x / y; } e = millis(); t = e - s; Serial.print("x="); Serial.print(x); Serial.print(" y="); Serial.print(y); Serial.print(" z="); Serial.print(z); Serial.print(" time2="); Serial.print(t); Serial.print("\n\n"); } </code></pre> <h2 id="測定コード(24bit÷8bit)"><a href="#%E6%B8%AC%E5%AE%9A%E3%82%B3%E3%83%BC%E3%83%89%2824bit%C3%B78bit%29">測定コード(24bit÷8bit)</a></h2> <p>除算を1万回実行して、加算のみの場合との差分を除算1万回の実行時間とします。</p> <pre><code>void setup() { Serial.begin(9600); randomSeed(analogRead(0)); } void loop() { unsigned long s, e, t; unsigned int i; unsigned long x,z; unsigned char y; t = millis(); /* dummy */ s = millis(); for(i=0 ; i<10000 ; i++) { x = random(0,0x7effff); y = random(0x7f,0xff); z += x + y; } e = millis(); t = e - s; Serial.print("x="); Serial.print(x); Serial.print(" y="); Serial.print(y); Serial.print(" time1="); Serial.print(t); Serial.print("\n"); s = millis(); for(i=0 ; i<10000 ; i++) { x = random(0,0x7effff); y = random(0x7f,0xff); z += x / y; } e = millis(); t = e - s; Serial.print("x="); Serial.print(x); Serial.print(" y="); Serial.print(y); Serial.print(" z="); Serial.print(z); Serial.print(" time2="); Serial.print(t); Serial.print("\n\n"); } </code></pre> <h2 id="結果(16bit÷8bit)"><a href="#%E7%B5%90%E6%9E%9C%2816bit%C3%B78bit%29">結果(16bit÷8bit)</a></h2> <p>除算1万回の実行時間は約128 [mS] 16MHzで動作しているのでサイクル数は2048000 cyc<br /> 除算1回のサイクル数は204.8 cyc<br /> 比較用の加算2サイクルの補正を追加すると<br /> <strong>16bit÷8bit 除算1回のサイクル数は207 cyc</strong></p> <h2 id="結果(24bit÷8bit)"><a href="#%E7%B5%90%E6%9E%9C%2824bit%C3%B78bit%29">結果(24bit÷8bit)</a></h2> <p>除算1万回の実行時間は約373 [mS] 16MHzで動作しているのでサイクル数は5968000 cyc<br /> 除算1回のサイクル数は596.8 cyc<br /> 比較用の加算2サイクルの補正を追加すると<br /> <strong>24bit÷8bit 除算1回のサイクル数は599 cyc</strong><br /> 32bit÷16bitの性能と、ほとんど同じなので、24bit÷8bit用に除算ルーチンを作り直せば性能は向上するのではないだろうか。</p> spinlock tag:crieit.net,2005:PublicArticle/15672 2020-01-09T13:37:32+09:00 2020-01-09T13:37:32+09:00 https://crieit.net/posts/8bit-CPU 仮想マシンの加速支援機構つきの新型8bit CPU <h2 id="概要"><a href="#%E6%A6%82%E8%A6%81">概要</a></h2> <p><a target="_blank" rel="nofollow noopener" href="https://icf3z.idletime.tokyo/">新型の8bit CPU(ICF3-Z)</a>を設計してFPGAに実装。仮想マシンの加速支援機構を使った、簡単なスタックマシンで、サンプルプログラムがXilinx FPGA Artix-7(-1)の実機上で動作した。たった約400LUTの小さいCPUで。Intel 8051マイコンのFREEな実装に<a target="_blank" rel="nofollow noopener" href="https://github.com/jaruiz/light52">light52</a>があります。軽量なマイコンですがCPU部だけで約800LUTあるようです。light52は1命令、6サイクルですが、このICF3-Zは1命令、1サイクルが基本で、時に1サイクルに複数命令の実行ができます。周波数比較もICF3-Zが、おおよそ2倍のようで、<strong>圧倒的に勝った</strong>のかも。他にあまり比較できるものがなかったという話もありますが。</p> <h2 id="仮想マシンの加速支援機構とは"><a href="#%E4%BB%AE%E6%83%B3%E3%83%9E%E3%82%B7%E3%83%B3%E3%81%AE%E5%8A%A0%E9%80%9F%E6%94%AF%E6%8F%B4%E6%A9%9F%E6%A7%8B%E3%81%A8%E3%81%AF">仮想マシンの加速支援機構とは</a></h2> <p>新型8bit CPU(ICF3-Z)なのですが命令コードが32bitで、一般的な8bit CPUと比べてメモリ効率が悪い。そこで16bitの圧縮命令の機能を追加した。この機能が仮想マシンの加速支援機構なのです。<br /> 圧縮命令のために作られたもので、加速支援機構として、最終的に成立するのかは、わからないですが、需要があって無理がなければ、加速支援機構として考えていく方向です。</p> <h2 id="加速支援機構が何の役に立つのか?"><a href="#%E5%8A%A0%E9%80%9F%E6%94%AF%E6%8F%B4%E6%A9%9F%E6%A7%8B%E3%81%8C%E4%BD%95%E3%81%AE%E5%BD%B9%E3%81%AB%E7%AB%8B%E3%81%A4%E3%81%AE%E3%81%8B%EF%BC%9F">加速支援機構が何の役に立つのか?</a></h2> <p>超低スペックなCPUでは、ソフトウエアで仮想マシンを実装しても性能的な問題で用途が狭められることがあります。この加速支援機構があれば実用の範囲が広がります。</p> <p><strong>2019年11月23日 追記</strong><br /> 仮想マシンの命令列を大容量の安価なプログラムメモリに置けるので、容量の少ない高価なデータメモリを圧迫しないということも利点です。</p> <h2 id="なぜ低スペックなCPUで仮想マシンなのか?"><a href="#%E3%81%AA%E3%81%9C%E4%BD%8E%E3%82%B9%E3%83%9A%E3%83%83%E3%82%AF%E3%81%AACPU%E3%81%A7%E4%BB%AE%E6%83%B3%E3%83%9E%E3%82%B7%E3%83%B3%E3%81%AA%E3%81%AE%E3%81%8B%3F">なぜ低スペックなCPUで仮想マシンなのか?</a></h2> <p>仮想マシンをJavaのようなスタックマシンにしたり、レジスタ1個のマシンにしたりできます。<br /> CPUのアーキテクチャの違いを吸収して、いろいろな言語のコンパイラの開発を容易にします。<br /> 非C言語が利用できるようになることで、より多くの人がIoTデバイスなどを開発できるようになります。</p> <h2 id="試作プログラム"><a href="#%E8%A9%A6%E4%BD%9C%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0">試作プログラム</a></h2> <p>プログラムの上部で簡単なスタックマシンの命令を実装して、仮想マシンの命令列をFPGAの実機で動作させたものです。独自のアセンブラなので多少、わかりにくかもしれません。自作したアセンブラでバイナリを生成して、FPGAのプログラムメモリに、置きます。<br /> 即値の5をPUSH、メモリの0番の値をPUSH、メモリの1番の値をPUSH、乗算、加算、LEDに結果を出力。<br /> メモリ0番には、最初のところで2を書き込んでいます。メモリ1番には3。つまり3*2+5 = 11がLEDに出力されます。(確認しました)</p> <pre><code>######################################################## # vm (Virtual Machie) # # C Register : SP(Stack Pointer) # D Register : PRINT (LED x 8) # MEM[0-255] : Memory # # PUSHI: SP=SP-1 , MEM[SP]=nn (5cyc) # PUSHR: SP=SP-1 , MEM[SP]=MEM[nn] (5cyc) # POP : MEM[nn]=MEM[SP] , SP=SP+1 (4cyc) # ADD : MEM[SP+1]=MEM[SP]+MEM[SP+1] , SP=SP+1 (7cyc) # MUL : MEM[SP+1]=MEM[SP]*MEM[SP+1] , SP=SP+1 (16cyc) # PRINT: PRINT MEM[SP] ######################################################## # Initial MEM[0]=0x02 , MEM[1]=0x03 ######################################################## ADDL=N;N=0x02;A=ANS STORE;Z=0 ADDL=N;N=0x03;A=ANS B(START) STORE;Z=1;C=ANS;D=ANS ######################################################## %NOP: JRETURN %PUSHI: ADDR=C;ADDL=N;N=0xFF;C=ANS RETURN;COPR;ADDL=N;A=ANS ADDR=C;R(ADDR);STORE %PUSHR: ADDR=C;ADDL=N;N=0xFF;C=ANS RETURN;R(N);COPR MOV;ADDR=C;R(ADDR);STORE %POP: RETURN;R(ADDR);ADDR=C;ONE;C=ANS MOV;COPR;R(N);STORE %ADD: R(ADDR);ADDR=C;ONE;C=ANS B=REG;R(ADDR);ADDR=C B=REG;ADDR=B;A=ANS RETURN;ADDL=A;ADDR=B;A=ANS R(ADDR);ADDR=C;STORE %MUL: R(ADDR);ADDR=C;ONE;C=ANS;D=ANS C=REG;R(ADDR);ADDR=C C=REG;ADDR=C;A=ANS B=ANS;I=X;X=7 MUL;ADDL=A;ADDR=B;B=RSH;C=RSH;WAIT RETURN;ADDR=C;A=ANS R(ADDR);ADDR=D;STORE;C=ANS %PRINT: RETURN;R(ADDR);ADDR=C D=REG START: _%PUSHI,0x05,%PUSHR,0x00 _%PUSHR,0x01,%MUL,0x00 _%ADD,0x00,%PRINT,0x00 EXIT(0);@D END: B(END) NOP </code></pre> <h2 id="ちなみに"><a href="#%E3%81%A1%E3%81%AA%E3%81%BF%E3%81%AB">ちなみに</a></h2> <p>割込みの実装もついていて約400LUTです。2つの割込みを受けられます。</p> <h2 id="2019年12月29日更新"><a href="#2019%E5%B9%B412%E6%9C%8829%E6%97%A5%E6%9B%B4%E6%96%B0">2019年12月29日更新</a></h2> <p>XilinxのFPGA(XC7A35TICSG324-1L)に搭載した<a target="_blank" rel="nofollow noopener" href="http://akizukidenshi.com/catalog/g/gM-14484/">Arty</a>に実装して面積を確認しています。 論理合成のオプションで結果が違うので、面積重視、性能重視の結果です。</p> <div class="table-responsive"><table> <thead> <tr> <th align="left">合成方針</th> <th align="center">LUT数</th> <th align="center">FF数</th> <th align="center">BRAM数</th> <th align="center">LUT-RAM</th> <th align="center">周波数</th> </tr> </thead> <tbody> <tr> <td align="left">面積重視</td> <td align="center">390</td> <td align="center">197</td> <td align="center">1.5</td> <td align="center">10</td> <td align="center">150MHz</td> </tr> <tr> <td align="left">面積重視</td> <td align="center">406</td> <td align="center">197</td> <td align="center">1.5</td> <td align="center">10</td> <td align="center">160MHz</td> </tr> <tr> <td align="left">性能重視</td> <td align="center">481</td> <td align="center">197</td> <td align="center">1.5</td> <td align="center">10</td> <td align="center">175MHz</td> </tr> </tbody> </table></div> <p>BRAM 1.5の内訳はプログラムメモリ 4KBとデータメモリ 2KB</p> <p>データメモリの先頭32バイトがレジスタ、先頭256バイトがスクラッチパッドメモリ。この合成結果はデータのアドレス線を8bitにしたものです。11bitにすればBRAMを消費することなく2KBのデータメモリをすべて使えます。データのアドレス線を16bitまで設定可能ですがBRAMを消費します。圧縮命令(仮想マシン)を利用する場合はプログラムメモリの先頭の領域を消費します。圧縮命令の命令数によって消費する領域が変化します。</p> <p>割込みを使ったデバッグ機能の検証をしました。 プログラムのコード中に、ブレークポイントを設定して、そこに、たどり着いた回数を計算して、設定した値(パスカウント)のとき、ブレークさせるみたいな機能が実現できます。 具体的には毎サイクル割込みを入れて、アドレスを確認して、設定されたアドレスなら、指定された回数に到達したかをチェック。 指定された回数の場合は、LEDを点灯させるというプログラムを作成して、FPGAの実機でテストしました。ちゃんと動いているようです。 ただプログラムコード中の一部の命令ではパスカウントを正しく計算できません。遅延分岐で遅延スロットをキャンセルする命令などです。 分岐命令の直後の命令にブレークポイントを設定した場合は、パスカウントは正しくありませんという仕様にしようかと考えています。 割込み処理中でキャンセル信号をチェックしてもいいのですが、 デバッグ機能のためにキャンセル信号をチェックする論理を追加するのは面積最小を追求するプロセッサでは、あまり良くないと考えてのことです。 (面倒とかではなくて)</p> <p>約400 LUTの面積の小さいCPUで、追加のデバッグモジュールなしにパスカウントを 使ったブレークポイントを設定できるのは、良くできるほうなんだろうと思うが、 他のCPUの面積とかわからないから、なんとも。</p> spinlock