コンピューターやネットワークが社会が深く広く使われている現代におけるサイバーセキュリティは、セキュリティの一部ではなく、実生活全般の安全に関わる上位概念として捉える必要があります。

Hana道場の向かい、Hana工房で開催されたサイバーセキュリティー勉強会。来年本格実施予定の中高生向けのサイバーセキュリティコンテスト「CyberSakura」に向け修行中。 参加に名乗りを上げた、中学1年生3人が受講。サイバーセキュリティの入門とコンテストに向けた模擬競技が行われました。

サイバーセキュリティとは、コンピューター、ネットワーク、データを使い続けられるよう保全すること。 社会にとっての普通の状態を持続するためには、オンライン、オフライン問わず発生しうる迷惑なハッキング行為、悪意のないうっかりや、地震まで、さまざまなリスクに備える必要があります。

CyberSakura」は、その知識と実行力を養うコンテストを含む教育プログラム。
エキシビジョンマッチに向け、日本全国の中学1年生から高専高校の2年生までを募集中です。
CyberSakura 〜サイバーセキュリティ教育プログラム〜 | Peatix

誰が作ったか分からないアプリを自分のパソコンで動かすリスクを考えてみましょう。
プログラミングした人には分かりますが、ファイルを消すのも、編集するのも、どこかに送信するのもプログラムを使えば自由自在。 いくら見た目がかわいくても、自分自身をパソコン内部の分かりづらい部分にコピーし、こっそり動かし続け、何かの司令を待つ、そんなこともできてしまいます。

よく知られた、また、よく使われているアプリであっても完全に信用できるわけではありません。 突然そのアプリの所有者が変わって、悪意ある自動更新が起きない保証はありません。

対処する方法のひとつに仮想化技術があります。仮想的なパソコン上でアプリを動かすことで、実際のアプリの動きを手にとるように確認できます。 CyberSakuraは、問題あるOSの状態を仮想化環境上で動かし、対処します。


Zen言語3行でつくるWebAssemblyの続きとして、ZenからDOM操作の実験成功!(src on GitHub)

ブラウザ上で動作する静的型付け言語環境、WebAssemblyも、仮想化技術のひとつとして注目されています。 WASI (The WebAssembly System Interface) により、サーバー上での動作環境が整ってくると、より安心なサーバー運用ができそうです。

発明が、ソフトウェア化、オープン化したことによって、新技術が世界中から続々誕生するエキサイティングな世界は留まることを知りません。 大いに活用していきましょう!

福井県でのサイバーセキュリティ、キックオフ!
サイバーセキュリティフォーラム&交流会in 福井
2020/8/3(月)開催、オンライン開催となっています。

webアプリのサイズ、小さいほど読み込みが早くて快適に!
Zen言語でシンプルな WebAssembly、動かしてみました。(src on GitHub)


C言語以上に細部に手が届く、軽量静的型付け言語の「Zen言語」は、WebAssembly出力にも対応。 下記、たった3行、誰にでも分かりやすい足し算するだけのプログラムを「zen build」でコンパイルするだけ、HTML/JavaScriptから呼び出して、利用できます。(src on GitHub)

export fn add(a: i32, b: i32) i32 { return a + b; }

(プログラム解説)
export → 外部から使うよ
fn → function 関数だよ
add → 関数名はaddにしよう
a: i32 → 符号付き整数32bitのパラーメータaが関数addの引数1つ目
b: i32 → 符号付き整数32bitのパラーメータbが関数addの引数2つ目
i32 → 符号付き整数32bitを関数の値として返すよ
return a + b; → パラメータaとbを足したものを返すプログラム、終端記号は「;」セミコロン

コンパイルしてできあがった、main.wasm ファイルは、たった115byte。
下記のようにHTML内のJavaScriptでつないで、HTTPサーバーを立ててブラウザで開けば動きます!(ローカルファイルからは動きません)

<script type="module"> (async () => { const bin = await (await fetch("./main.wasm")).arrayBuffer(); const wasm = await WebAssembly.instantiate(bin); const ex = wasm.instance.exports; const add = ex.add; document.body.textContent = "WebAssembly in Zen, add(1,2) = " + add(1, 2); })(); </script>

簡単ですね!

別途 wasm-strip を使ったビルドコマンド「zen build strip」を使うと、72byteまで縮みます。

ランタイムがなく、追加容量なしでプログラムを分かりやすく整理できる(抽象化)Zen言語。
大規模Webアプリ開発にも使える予感!何かのアプリで実証してみたくなりますね!

links
- Zen言語で LPC810 Arm組み込み開発、Zenbedded!
- 言語づくりという解決手段、高速安全コンパクトなZen言語で簡単組み込み開発 on IchigoJam with zen4ij
- RustではじめるWebAssemblyはじめのいっぽ、足し算するwasmファイルは116byte
- IchigoJam BASIC on the web by WebAssembly

気持ちよく大規模webアプリを開発するために、静的型付け言語を使用するのも有効です。 APIを使用する際、間違ったパラメータを渡してハマることを防いでくれ、エディタの支援も受けやすいのが特徴です。

ブラウザで動作するクライアント側がサポートする2つの言語、JavaScriptとWebAssembly。 最近のお気に入り、静的型付け言語 Rust は WebAssembly のバイトコードを生成してくれます。 (もう一つの人気の静的型付け言語TypeScriptは、動的型付け言語JavaScriptへと変換するトランスパイラGLSLを含めると3つ?)


早速実験してみましょう。

まず準備、Rustをインストールし、WebAssembly用にコンパイルするために、targetを追加します(一度だけでok)

$ rustup target add wasm32-unknown-unknown 次のコードは、超コンパクトな、足し算するだけのRustのプログラム add.rs です。

#![no_main] #![no_std] #[panic_handler] fn panic(_info: &core::panic::PanicInfo) -> ! { loop {} } #[no_mangle] pub fn add(a: i32, b: i32) -> i32 { a + b }

mainがなく、標準ライブラリを使わないための設定をするのは、IchigoJam用のRust「rust4ij」と同様です。 no_mangleで、最適化して行方不明になってしまわないよう設定します。

コンパイルはこのように

$ rustc --target wasm32-unknown-unknown add.rs -C opt-level=1

131byte、小さな add.wasm ファイルができました!
(wasm-strip add.wasm で116byteに!opt-level=1 を付けないとデバッグ情報で1.5MBに!)

wasmをJavaScriptから呼び出すのはこんなコードを書きます。

<script type="module"> (async () => { const bin = await (await fetch("./add.wasm")).arrayBuffer(); const wasm = await WebAssembly.instantiate(bin); const ex = wasm.instance.exports; const add = ex.add; document.body.textContent = "WebAssembly in Rust, add(1,2) = " + add(1, 2); })(); </script>

* ブラウザがトップレベルawaitに対応してくれると、async関数で囲む必要がなくなります
* SafariがWebAssembly.instantiateStreaming対応したらもっと短くかけます

wasmの読み込みはファイル上ではだめなので、live-serverなど、何かHTTPサーバーをローカルに立てて、http://127.0.0.1:8080/ などでアクセスするか、手持ちのサーバーにアップして試してみましょう!

$ live-server

コンパクトで簡単ですね!

JavaScriptやブラウザとの相互やり取りには共有メモリを使うイメージで連携します。
本格的なwebアプリ、RustとJavaScriptの連携で一度作ってみたいと思います。

DenoやNode.jsでもwasmは動きます。

$ deno run -A test-file.mjs $ node test-node.mjs

src on GitHub、いろいろ遊んでみてください!

links
- マシン語で検証、RustはC言語の代わりになりうるか? IchigoJamでライトに楽しむ組み込み開発 panic編と情報処理
- IchigoJamでかんたん組み込みRust開発 - rust4ij x IchigoJam API

ruby4ijを早速使っていただきました!「風船 Ruby 版 (ruby4ij)/Kidspod;

ただ、なかなかにやっかいな開発環境づくり。開発するために必要なツールが多く、それぞれがバージョンアップするので環境構築方法が変わってしまったりして鬼門です。 そこで便利なweb技術。クラウド処理もありですが、IchigoJam web でも使っている、エッジ技術、WebAssemblyを使ったパパっと手元で軽快動作を目指します。

手始めに、こちら学習用ミニCコンパイラ「ci0」を移植して作った「webci0

webci0 - mini C compiler ci0 in WebAssembly
C言語風に書いたプログラムをスタックマシンなVM用マシン語に変換、インタプリタとして実行します。標準関数は文字列表示のputstrと数表示のputnumのみ。メイン部分は500行ちょっとのオープンソース、いろいろ改造して遊んでみましょう!

WebAssembly用に標準ライブラリ系を準備して、clang, llvm-link, llc, s2wasm, wat2wasm の手順でコンパイル。16KBのWebAssembly用バイナリ ci0.wasm ファイルができあがり!(参考、WebAssembly開発環境 WABTコンパイル用シェルスクリプト

printfは「Linuxをはじめよう!:printfを自作してみる」を使わせてもらいましたが、WebAssembly環境で複数の引数の時にうまく動いていないので ci0.c では回避策をとっています。

ブラウザ上のコードエディタとして Ace を使用。快適に動作するので、普段使う標準エディタにしてもいいくらい! カラーテーマも「Ace Kitchen Sink」からC言語のハイライトに合う感じのものを選んでみました。

ci0のスタックマシンはWebAssemblyのマシン語ともよく似ているので、WASMコンパイラとして育てるのもおもしろそう!
Cコンパイラを作ってみたい人、自作言語を作ってみたい人、WebAssemblyでの開発、オススメです!
(WASM、現時点では、goto非対応、例外非対応な点に注意!)

WebAssemblyマシン語入門
- ブラウザだけでOK! 1+1からはじめる、WebAssemblyマシン語入門その1
- プログラミングはプログラミングで楽をする、WebAssemblyマシン語入門その2
- もっと楽するコンパイラ、WebAssemblyマシン語入門その3

IchigoJam web(ブラウザで動くIchigoJam)で使っているお気に入り技術、WebAssembly。
マシン語をバイナリで直接書いてみる第一回、初歩的なアセンブラ体験する第二回に続く第三回のテーマは、コンパイラです。

おさらいとして、前回のアセンブラで、param+10 を計算するプログラムを作ってみましょう。

正解はこちら

get_local $0 i32.const 10 i32.add end

paramが1の時、ちゃんと答は11と出ます。では、param+100 を計算するプログラムに変えてみてください。

おや、おかしいですね!?では、128にすると、今度はコンパイルエラーになってしまいます。

WebAssemblyのマシン語での数値は大きさによって1byteから5byteまで長さを変えて表します。最上位bitが1なら、次のbyteを読んで上位に追加していく仕組みになっています。 つまり、1byteで表せる数は、7bitで表せる-64〜63まで。100(2進数で1100100)はこの範囲を超えているので、上位bitを1にして、残りのbitを次のbyteで表すので、1 1100100 (e4) と 0 0000000 (00) となります。

WebAssemblyのコードを書き換えて試してみましょう。

20 0 41 e4 0 6a b

i32.const を表す 41 の後の 64 (=10進数の100) を、e4 に変えてその後ろに 0 を加えて「RUN」
ちゃんと答がでました!

このような計算をいちいち手でやらなくて済む方法は?・・・そうです、プログラムですね。
命令表から手打ちするのも面倒なので、短く楽にプログラムを書けるようにするソフトをつくりましょう。

コンパイラはじめのいっぽ
「P 3 +」と空白区切りで書いたら対応するアセンブリ言語を出力するものです。
※ P は、パラーメータ0を意味することにします

compilebtn.onclick = function() { var src = srcprg.value.split(" "); var asm = []; for (var i = 0; i < src.length; i++) { var s = src[i]; if (s == "P") { asm.push("get_local 0"); } else if (s == "+") { asm.push("i32.add"); } else if (parseInt(s) == s) { asm.push("i32.const " + s); } } asm.push("end"); srcasm.value = asm.join("\n"); }

簡単ですね。このようなソフトをコンパイラといいます。
掛け算とかいろいろ足したものがこちら「WebAssembly poor compiler」です。

WebAssembly poor compiler

「P 3 +」と入力し「COMPILE」「ASSEMBLE」「RUN」と順に押して、答が出してみましょう。

課題:パラメータを自乗して1を足すプログラムをつくってみよう!

アセンブラも上記、大きな数値にも対応するよう改良してあるので、プログラムを確認してみてください。

次はこのコンパイラをもう一歩進めて、もっと自然な数式で書けるように改良してみます。
待ちきれない人は、どんどん進めちゃってください!

WebAssemblyマシン語入門
- ブラウザだけでOK! 1+1からはじめる、WebAssemblyマシン語入門その1
- プログラミングはプログラミングで楽をする、WebAssemblyマシン語入門その2
- もっと楽するコンパイラ、WebAssemblyマシン語入門その3

- 連載、IchigoJamではじめる、Armマシン語入門
1. はじめてのマシン語
2. ハンドアセンブルで超速計算!
3. マシン語メモリアクセスで画面超速表示!
4. マシン語でLEDを光らせよう!
5. 楽しさ広がるマルチバイトメモリアクセスとスタック
6. マシン語使いこなしTIPS
7. カジュアルに使うインラインマシン語
8. アセンブラを使って楽しよう
9. マシン語で高速SPI
10. マシン語を制するもの時間を制す
11. 画面をイチゴで埋め尽くす12の方法
12. レジスタ不足に上位レジスタとスタック操作
13. コンパイラはじめのいっぽ、EVAL実現法とマシン語生成
14. サイズを取るかスピードを取るか、割り算のアルゴリズムとマシン語実装
15. マシン語化で1万倍速!? セットで学ぶアルゴリズムとコンピューター

links
- WebAssembly Advent Calendar 2017 - Qiita 参加!

前回「ブラウザだけでOK! 1+1からはじめる、WebAssemblyマシン語入門その1」では、マシン語の命令表からひとつずつ選んで数を書いてみました。 プログラムをこのようにマシン語にする作業のことをアセンブル(英語で組み立てを意味する)と言います。

数が多くなってくると、こうして手で変換するのは大変なので、プログラムを作って自動化しましょう。 今使っている環境の範囲だけで動く簡易的なアセンブラ「WebAssembly poor assembler」をJavaScriptで作りました。


WebAssembly poor assembler

こちら、前回はマシン語だった param+1 を計算するプログラムのアセンブリ言語プログラムです。

get_local $0 i32.const 1 i32.add end

「ASSEMBLE」ボタンを押すと、下に数字の並びに変換され、RUNで動かせます。

20 0 41 1 6a b

試しに、i32.add を i32.mul に書き換えて、ASSEMBLE、RUNしてみましょう。
i32.const 1 を i32.const 5 に書き換えて、ASSEMBLE、RUNしてみましょう。
param に、10と入力しなおして、RUNしてみましょう。

ちょっとだけ複雑な計算をさせてみます。

get_local $0 i32.const 5 i32.mul i32.const 1 i32.add end

i32.const 1 と i32.add を書き加えて、n*5+1 を計算するプログラムにしました。
ASSEMBLE、RUNしたり、paramを書き換えてみましょう。

このようにアセンブルを自動化するプログラムのことを、アセンブラといいます。
(手でアセンブルすることをハンドアセンブルといい、アセンブラがない時代の必須テクニックでした)

次はコンパイラを作ってみます。お楽しみに!

WebAssemblyマシン語入門
- ブラウザだけでOK! 1+1からはじめる、WebAssemblyマシン語入門その1
- プログラミングはプログラミングで楽をする、WebAssemblyマシン語入門その2
- もっと楽するコンパイラ、WebAssemblyマシン語入門その3

コンピューターの気持ちに近づけるマシン語。
IchigoJamだけで始めるArmマシン語入門に続き、
ブラウザだけで始めるWebAssemblyマシン語入門その1です。

コンピューターは高速に計算する機械(=マシン)です。

メモリ(=記憶装置)に2つの数があったら足し算する電子回路があるとします。
1と1をメモリに書いたら瞬時に2が得られます。
(参考「なぜコンピューターは計算が速いのか? 電気回路で計算ができる謎を解く」)

足し算だけだと使いみちが限られるので、引き算・掛け算や、計算順序を変える機能などを追加します。
機能を区別する方法は何でもいいのですが、計算が得意なコンピューターのために、それぞれの機能に数を割り当ててあげると効率的です。
やってほしい計算を表す数をずらずらと並べたもの、これがマシン語プログラムとなります。

IchigoJamで使っているのはArmという会社が考えたコンピューターなので、Armマシン語。
今回使うWebAssemblyマシン語は、ブラウザで動くことにした仮想的なコンピューターです。
仮想的とは、マシン(ハードウェア)をソフト(=プログラム)で表現したものを言います。

とりあえず、動かしてみましょう。
WebAssembly testenv」を開き、「RUN」を押すと、2とでます。


WebAssembly testenv」で、1+1=2 をマシン語プログラムでつくり、動かした様子

「param」に1と書いてあるものを、10に変えて、もう一度「RUN」を押してみましょう。
きっと、今度は11と出ます。
(もし動かないならば、きっとお使いのブラウザがWebAssemblyに対応していません!Chrome/FireFox/Safariの最新版をダウンロードしましょう)

20 0 41 1 6a 0b

実はこれがWebAssemblyのマシン語です。(0〜9とa〜fの15種類の文字を使った16進法表記)

右の表を照らし合わせてみると・・・
20 0 ・・・ get_local $0 (渡された数をメモリに書くよ)
41 1 ・・・ i32.const 1 (1をメモリに書くよ)
6a ・・・ i32.add (メモリに書かれた2つの数を足してメモリに書くよ)
0b ・・・ end (プログラムを終わって、メモリに書かれたものを返すよ)

と解読できます。

10-1を計算させるには、i32.add (6a) の代わりに i32.sub (6b) を使います。

20 0 41 1 6b 0b

計算できました!

コードの上に書いてある、WebAssmeblyマシン語であることを表すIDなどと組み合わせて、.wasmファイルを作成すれば、ブラウザ上で高速に動くプログラムができるわけです!

右の表にあるものはもちろん一部です。
興味があればWebAssemblyの仕様書を覗いてみましょう。

ひとつひとつ表から照らし合わせてプログラムを書くのは大変なので、普通はこの作業をプログラムで自動化します。
アセンブラとか、コンパイラなどと呼ばれるソフトで、その数だけプログラミング言語があるわけですね!

マシン語が分かれば自分だけのプログラミング言語を作ることもできちゃいます!
日本生まれで世界に広がるプログラミング言語 Ruby に続こう!

WebAssemblyマシン語入門
- ブラウザだけでOK! 1+1からはじめる、WebAssemblyマシン語入門その1
- プログラミングはプログラミングで楽をする、WebAssemblyマシン語入門その2
- もっと楽するコンパイラ、WebAssemblyマシン語入門その3

Tweet
クリエイティブ・コモンズ・ライセンス
この作品は「Creative Commons — CC BY 4.0」の下に提供されています。
CC BY / @taisukef / アイコン画像 / プロフィール画像 / RSS