公開鍵暗号の仕組み

久しぶりにブログを書いてみようと思って書いています。
ハローハロー🌞

今日は暗号技術について紹介しようと思います。

f:id:ingentity:20190920180920j:plain

暗号技術とは

暗号技術はその名の通り、文章を暗号化するための技術です。

例えば、アリスさんがインターネットチャットでボブさんに次のようなメッセージを送ることを考えます。

「ハロー、私アリス。電話番号は090xxxxxxだよ。プリーズコールミー」

アリスはボブにだけ自分の電話番号を教えているつもりですが、もしこのメッセージが暗号化されていなかった場合、メッセージを盗聴され、電話番号がボブ以外の人に知られてしまう可能性があります。
f:id:ingentity:20190920181657j:plain

それを防ぐためにはアリスはメッセージを暗号化する必要があります。
実際に暗号化するとメッセージは次のようになりました。

「91Mk8XDdkGm4ze2mih7yW16+REDBoS7FCqHVnQACvUGc45AfqGuUYeoRWFs+4i4Tc083rvN1HAVhj9OglxPCVRuLMQ4M6hWgK3oDEnFqR2qYazfF3R9kwA0B53xGoez0」

メッセージが暗号化されていれば、もし誰かに盗聴されてもその内容を知られることはありません。

しかし、このままではメッセージを受け取ったボブすらもこのメッセージの内容を理解することができません。
f:id:ingentity:20190920182928j:plain

暗号鍵

暗号文を解読するのに必要になるのは、次のような暗号鍵と呼ばれる文字列です。

401B09EAB3C013D4CA54922BB802BEC8FD5318192B0A75F201D8B3727429080FB337591ABD3E44453B954555B7A0812E1081C39B740293F765EAE731F5A65ED1

暗号鍵はまさに鍵のような役割を持っており、暗号化する時と暗号解読(復号化)する時に使われます。

暗号化する際に暗号鍵を用意し、暗号文を生成します。
f:id:ingentity:20190920192142p:plain

ある暗号文を解読したい場合は、暗号化に使われた時と同じ暗号鍵を使うことで解読が可能です。
f:id:ingentity:20190920192318p:plain

鍵配送問題

再びアリスがボブにメッセージを送る話に戻りましょう。

アリスはメッセージが盗聴されないように、メッセージを暗号化しました。
この時アリスが用意した暗号鍵をここでは”abcd123”とします。(本来の暗号鍵はもっと長く複雑な文字列でなければなりません)

アリスは暗号化したメッセージをボブに送信しました。
しかしその後、ボブから連絡がきました。

「メッセージが読めないので、暗号鍵を送ってください」

このような場合、どう対応すればいいのでしょう。

もしアリスが暗号鍵”abcd123”をボブに送信してしまうと、盗聴されて暗号鍵を盗まれてしまう危険性があります。
暗号鍵を使えば誰でも暗号文を解読できるので、先ほど送信したアリスのメッセージが盗み見られてしまうことになります。

では暗号鍵を暗号化して送信する場合を考えましょう。
暗号鍵"abcd123"を新たな暗号鍵"efgh456"で暗号化してボブに送信します。

すると、またボブからメッセージがきました。
「暗号鍵が暗号化されていて読めないので、暗号鍵の暗号鍵を送ってください」

このように、暗号鍵を暗号化したとしても、その暗号鍵の暗号鍵を送る必要があり結局堂々巡りになってしまうのです。

f:id:ingentity:20190920194553j:plain

公開鍵暗号

暗号鍵の配送問題を解決することができる公開鍵暗号という技術が存在します。

公開鍵暗号とは簡単に言うと、暗号化するための鍵と暗号解読するための鍵を分ける技術です。
f:id:ingentity:20190920202150j:plain
暗号化するための鍵を公開鍵、解読するための鍵を秘密鍵といいます。
公開鍵暗号を理解するために次の3つを覚えておいてください。

  • 公開鍵では暗号化することはできますが、暗号を解読することはできません。
  • 秘密鍵では暗号解読はできますが、暗号文を作ることはできません。
  • 2つの鍵はペアになっているので、別々に作ることはできず、同時に生成されます。

再びアリスとボブの話に戻りましょう。

アリスはボブにメッセージを送ります。このメッセージは暗号化しません。

「いまからメッセージを送るので、公開鍵をください」

ボブはメッセージを受け取り、公開鍵と秘密鍵のペアを生成し、公開鍵のみをアリスに送ります。このメッセージも暗号化されていません。

「公開鍵は"efgh456"です」

アリスは本当に送りたかったメッセージをボブの公開鍵で暗号化します。

「91Mk8XDdkGm4ze2mih7yW16+REDBoS7FCqHVnQACvUGc45AfqGuUYeoRWFs+4i4Tc083rvN1HAVhj9OglxPCVRuLMQ4M6hWgK3oDEnFqR2qYazfF3R9kwA0B53xGoez0」

ボブはアリスから暗号文を受け取って、自分の持っている秘密鍵で暗号を解読します。

「ハロー、私アリス。電話番号は090xxxxxxだよ。プリーズコールミー」

これでアリスは盗聴されることなくメッセージをボブに送ることに成功しました。
途中ボブが、暗号化せずに公開鍵をアリスに送っていましたが、公開鍵をもし盗まれたとしても、その鍵では暗号文を解読することはできないので、アリスのメッセージを読むことはできません。

これが公開鍵暗号であり、この仕組みのおかげで私たちはインターネットを使って友達にメッセージを安全に送ることができるのです。

👏👏👏

以上、公開鍵暗号の仕組みでした。
読んでくれてありがとー

第二回ビットコインの仕組み(送金編)

こんにちは☼

晴れて第二回を迎えることができました。🎉ビットコインの仕組みシリーズ。

前回ビットコインとはいったいどういうものかについて説明しました。(伝わっているとうれしいけど……)

今回は、ブロックチェーンの深みに入っていく前段階として、ブロックチェーンのメインの処理である、送金が一体どのように行われているかを見ていきましょう。

ただ、ビットコインにおいて残高データの中身が一体どのようになっているのか、まだ説明をしていなかったので、まずはそこから話していきましょう〜!⤴️

ビットコインの残高データの正体

前回、ビットコインでは残高のデータベースをネットワークにつながっているサーバー間で共有することで成り立っていると言いました。

前回説明に使った残高のデータベースがこちらf:id:ingentity:20180904004357p:plain

ビットコインにおける実際のデータはこのようにユーザーと残高が直接対応している訳ではありません。

では一体どのように残高を記録しているのでしょう。

f:id:ingentity:20180904181459p:plain

かなり簡単化していますが、これがビットコインにおける残高データベースの大まかな形になります。

ビットコインの残高データはブロックという単位に分けられ、それが鎖状に繋がっているのでブロックチェーンと呼ばれています。

そして、赤い枠で囲まれた部分がトランザクションと呼ばれるデータで、通貨が誰から誰へいくら移動したかを示しています。

緑色の枠で囲まれた部分は通貨の獲得を表していて、これに関しては後ほど詳しく説明しますのでいまは取り合えず、単に通貨を獲得していると考えてください。

このようにビットコインは、通貨の獲得とその後の移動を全て記録し、それを辿ることで最終的に現在誰がいくら持っているのかを把握できるようになっています。

この例での武田さんの残高は、2番目のブロックで90円獲得していますが、田中さんに67円送金し、最後のブロックでも竹下さんに3円送金しているため、

90 - 67 - 3

で20円となります。

同様に他の人のトランザクションに関しても辿っていくことで、残高を把握てきます。

ビットコインにおける送金の仕組み

ビットコインでは、誰でも自分が保持しているお金を他のユーザーに送金することができます。

どのようにして、送金が行われるかと言うと、単にトランザクションを発行するだけです。

例えば、田中さんが武田さんからりんごを買うために120円送金するといった場合を考えます。

まず、田中さんは新しいトランザクションを作ります。

f:id:ingentity:20180906004741p:plain

そのトランザクションを田中さんはビットコインのサーバーに送信します。

f:id:ingentity:20180906004904p:plain

サーバーは田中さんの残高を確認し、本当に120円以上田中さんが持っていれば、正しく処理が可能であると判断し、新規ブロックに田中さんのトランザクションを組み込みます。

f:id:ingentity:20180906005612p:plain

f:id:ingentity:20180906005732p:plain

このブロックが正しくブロックチェーンに組み込まれた時点で送金が完了となります。

f:id:ingentity:20180906005958p:plain

武田さんはブロックチェーン情報をダウンロードして、正しく送金が行われていることを確認すると、田中さんにりんごを受け渡します。

f:id:ingentity:20180906010307p:plain

これが送金の大まかな流れになります。

ただし、この説明でシステムが成り立つには大きな前提が三つあります。

1つは、田中さんのお金を引き出すようなトランザクションは田中さんにしか作れないこと。

2つ目は、誰も田中さんの作ったトランザクションを書き換えることができないこと。

そして3つ目は、ビットコインのサーバーは正しいトランザクションのみを集めた正しいブロックを作り、正しくブロックチェーンに接続すること

ビットコインではこれら3つの条件を全て満たしています。
次回以降、これらの条件が一体どのようにして保証されるのかというところを見ていきたいと思います。(ほんとは今回説明するはずだったんですが…‥)


長くなってしまったのでここまで!

それでは、さよなら〜👋

第一回ビットコインの仕組み(概要編)

ブログ何かこうか思いつかなかったので、今興味持っているブロックチェーンについて書いていこうかなって思います。

第一回はビットコインについてです!👏

ビットコインってなんか聞いたことあるよね

ビットコインっていう名前は多くの人が聞いたことがあると思います。去年すごく流行って、ニュースなんかでも頻繁に取り上げられましたね。いまでは、落ち着いてきたような感じはしますが、価格で見れば上がったり下がったり大忙しです。

仮想通貨関連で一番大きいニュースになったのは、コインチェックNEM流出騒動ですが、ビットコインNEMブロックチェーンと呼ばれる技術を使った仮想通貨の一種です。

ビットコインにはなぜ価値があるのか

ビットコインは2018年9月4日現在1BTCあたり80万円もの高値で取引されています。

仮想通貨という名の通りビットコインに実態は無く、単なるシステム上のデータに過ぎません。

それなのに何故このような価格が付けらているかというと、基本的にはビットコインの決済システムに対する信頼からです。

ビットコインは稼働開始から現在に至るまで、致命的なエラーや、悪質な攻撃によって崩壊することなく稼働し続けており、その信頼性は高く評価されています。

ビットコインに価値が付いている理由は、そこにあります。

今回はそのビットコインが一体どのようなシステムなのか、まずは電子マネーの例と比較しながら話していきたいと思います。

ビットコイン電子マネーの違い

ビットコインのようなブロックチェーンの大きな特徴というのは、中央集権機関がないことです。

ビットコインと違い、現在一般的に普及している電子マネーと呼ばれるものは、すべて電子マネーを提供している企業のサーバーで顧客の残高が管理されます。

f:id:ingentity:20180901230451p:plain

例えば、田中さんが1000円電子マネーにチャージしたとしましょう。

1000円チャージされたという情報は、企業のサーバーに送信されます。

f:id:ingentity:20180901231559p:plain

サーバーには顧客の残高の情報が入っているデータベースがあるので、その中から田中さんを探し出し、残高を1000円増やします。

f:id:ingentity:20180901231819p:plain

電子マネーの仕組みとしてはこれだけです。

支払いの場合はこの逆で残高を減らすだけです。

ただし、ビットコインの場合はこの場合の企業にあたる中央集権機関がありません。

つまり、運営機関がないということです。

ではどのようにして残高を管理するのでしょう。

運営機関がなくても動くよビットコイン

運営機関がないならどこに残高情報を記録するんだ、と思った方もいるでしょう。ビットコインビットコインを使いたい人によって建てられたサーバー同士がネットワークで接続されることにより、成り立っています。

じゃあ、誰が残高情報を管理するのかというと、基本的には全員です。

ビットコインに参加しているサーバー全員が残高データのコピーを共有します。

f:id:ingentity:20180902005117p:plain

常にみんなが同じかつ正しいデータを持っていれば、それを残高情報として処理が行えますよね。

ビットコインはこの残高情報を正しく、また皆が同じになるように同期をとるためのシステムです。

残高の変動があってもビットコインでは、それを正しく同期することができます。

例えば、サーバーAにおいて田中さんが50円使ってしまい、残高が50円減ったと分かったとき、

f:id:ingentity:20180902005914p:plain

その情報はネットワークを介して、全員に伝えられます。

f:id:ingentity:20180902011155p:plain

サーバーは田中さんの残高に変動があったことを聞くと、自分が持っている残高データベースを修正します。
こうして無事、田中さんの残高は250円から200円になりました。

ただし、これだけでは全く役に立たないシステムです。ビットコインではだれでもサーバーを立てることができます。その中には悪人がいるかもしれません。このままでは悪人は勝手に自分の残高を増やしたり、人の残高を奪ったりやりたい放題です。

もちろん、ビットコインではそのようなことはできないようになっています。

その辺の説明は長くなるのでまたの機会に……しておきます。

それでは、さよなら~

ingentity.hatenablog.com

Unity Multiplayer NetworkLobbyManagerとは

Unity MultiplayerにおいてNetworkManagerとNetworkLobbyManagerというものがある。

 

NetworkManagerはその名の通り、ネットワーク接続に関することを司る。

 

NetworkLobbyManagerはNetworkManagerのロビーを提供するバージョンのようだ。

 

設定項目の違いを見てみましょう👀

f:id:ingentity:20180502014328p:plain

 

設定できるシーンは2つ存在し、Offline SceneとOnline Sceneがある。

 

Offline Sceneでキャラクター選択などのゲームの設定を行い、Online Sceneで実際のゲームを実行するといったことができる。

 

こちらがNetwork Lobby Manager

f:id:ingentity:20180502014824p:plain

 

いろいろ項目が増えてますが、わかりやすいのが、Offline SceneがLobby SceneにOnline SceneがPlay Sceneになったことですね

 

NetworkManagerではOfflineだったシーンがLobby Sceneになってオフラインじゃなくなりました。

つまり、ロビーの状態でネットワークに接続されます。

 

そうすることで、ルーム内のメンバーリストの表示や、オンラインゲームではよくある、全員が準備完了を押してからゲームを始めるようなことが可能になります。

 

Max Playersで参加プレイヤーの最大人数を設定できたり、Minimum Playersではゲーム開始に必要となる準備完了プレイヤーの数を設定できます。

 

あとは、その他もろもろいろんな機能があってなにかと便利なので、NetworkManagerよりNetworkLobbyManagerを使うことが多いのかなと思います。

 

ネットワークロビーのサンプルアセットがあるのでそれを使ってみたり、スクリプトを覗いてみたりするのがいいかと思います。

assetstore.unity.com

Unity キャラクター接地判定(空中ジャンプ禁止)

Unityのキャラクターが空中でジャンプできてしまう問題が意外と解決できなくて、すこし悩みました😱


CharacterControllerを使えばできるらしいのですが、あんまり使いたくなかったのでRigitbodyを使ってキャラクターの接地判定をする方法を考えました😏参考程度に聞いてください

先にアイディアだけを説明すると、キャラクターの下にColliderを敷いてそのColliderの接触判定を使って接地したかどうかを判定させました。

今回は、簡単にplaneとcubeだけ用意しました。planeが地面で、cubeがキャラクターのつもりです。
f:id:ingentity:20180430180152p:plain

cubeにはRigidbodyをつけてあげましょう。キャラクターがずっこけないようにFreez Rotationには三つともチェックを入れましょう。
f:id:ingentity:20180430181850p:plain


今回はジャンプの機能だけを作ります。
ジャンプ用スクリプトはこんなかんじ。

using UnityEngine;

public class TestJump : MonoBehaviour {

    public Rigidbody rb;
    public float JumpPower;

    private void Start()
    {
        OnGround = false;
    }

    //RigitbodyをいじるためFixedUpdateで処理を行う
    private void FixedUpdate()
    {
        if (Input.GetButtonDown("Jump"))
        {
            rb.velocity = transform.up*JumpPower;
        }
    }
}


上のスクリプトをcubeにアタッチして、Rigitbody、JumpPowerの設定をしましょう
f:id:ingentity:20180430180340p:plain


いざ実行!👉
f:id:ingentity:20180430180958g:plain


もちろん接地判定を行っていないので無限にジャンプして画面から消えてしまいました👋


では、接地判定を作っていきましょう!まず、新たなcubeを作成し、元あったcubeの子供にしてください👶
f:id:ingentity:20180430181314p:plain


名前は、Footとかにしましょう👣
f:id:ingentity:20180430182805p:plain


そして、Transformを下のように設定しましょう。ついでにBox ColliderのIs Triggerにもチェックを入れてください。
f:id:ingentity:20180430181541p:plain


cubeの底に張り付く感じになればOKです👌
f:id:ingentity:20180430182933p:plain


そして新たにスクリプトを作ります。

using UnityEngine;
using UnityEngine.Events;

public class GroundChecker : MonoBehaviour {

    //接地した場合の処理
    public UnityEvent OnEnterGround;
    //地面から離れた場合の処理
    public UnityEvent OnExitGround;
    //接地数
    private int enterNum = 0;

    private void OnTriggerEnter(Collider collision)
    {
        Debug.Log("OnGround!");
        enterNum++;
        OnEnterGround.Invoke();
    }

    private void OnTriggerExit(Collider collision)
    {
        Debug.Log("ExitGround!");
        enterNum--;
        if (enterNum <= 0)
        {
            OnExitGround.Invoke();
        }
    }

}


上のスクリプトをFootにアタッチしましょう。


上のスクリプトでenterNumを増やしたり減らしたりしているのは、複数のオブジェクトがTrigger内にEnterする場合もあるのでこのような処理になりました。


これで、Footが何かColliderを持つオブジェクトに触れたとき、OnEnterGroundが呼ばれ、Footがどのオブジェクトにも触れなくなった時OnExitGroundが呼ばれるはずです。


そこで、もう一度TestJump.csを開いて編集しましょう。

using UnityEngine;

public class TestJump : MonoBehaviour {

    public Rigidbody rb;
    public float JumpPower;
    //接地判定
    public bool OnGround { get; set; }//追記

 //追記
    private void Start()
    {
        OnGround = false;
    }

    //RigitbodyをいじるためFixedUpdateで処理を行う
    private void FixedUpdate()
    {
        //接地していればジャンプできる
        if (Input.GetButtonDown("Jump")&&OnGround)//追記
        {
            rb.velocity = transform.up*JumpPower;
            //ジャンプした瞬間接地判定を解除
            OnGround = false;//追記
        }
    }
}


OnGroundを設置状況に応じて変更するため、GroundCheckerのイベントを登録しましょう。
f:id:ingentity:20180430184542p:plain
f:id:ingentity:20180430184822p:plain
f:id:ingentity:20180430184838p:plain


いざ、実行!👉👉
f:id:ingentity:20180430185139g:plain

うん!よさげ!!


Footの位置やサイズやフィールドの状況次第で不具合は起きる可能性があります😭参考程度でよろしく

おすし天国

お寿司を食べました

 

いや、うんま!🍣

 

なんでお寿司ってあんなに美味しいんでしょうねえ🤔

 

特にサーモンが好き!

 

醤油にちょんとつけて、口に入れれば噛むたびに柔らかくて肉厚なサーモンがとろけて、はぁ〜すき😍

 

もう、サーモンでビンタされたい

 

はい!決めました

 

今決めました

 

僕がお年玉をあげるときは、お年玉袋にサーモン刺しを入れてあげる🐟

 

子どもたちもみんなサーモンが好きでしょう?😋

 

いやもちろん好きだけど、現金のほうがいいに決まってるだろー!😡パシーーン!(サーモン刺しでビンタ)

 

あはん、しあわせ😍🐟

ハッピー新年

こんばんは、真夜中の僕です👻

 

 ていうか、

 

ハッピーニューイヤー!🎉

 

とうとう2018年ですか🐶

 

大晦日は皆さん何してましたか?

 

僕は気分が悪くなるまでお菓子を食べていました

 

オ”ェエ🤢

 

食べ過ぎには注意しましょう☝️

 

そんな僕も、今年の抱負を考えました

 

聞いてください

 

友達を大切にする

 

です!

 

やっぱり友達は大事💪

 

一人は寂しいから……😭

 

友達を大切にすればそこから友達が増えたりしちゃって……

 

エヘヘ😏

 

もしかすると、恋人もできちゃったりなんかしちゃって?

 

グヘヘ😝

 

こりゃ、ワンちゃんあるで!🐶

 

戌年