Rustの基本的な要素

名前: 半角英字

fn main(){
	let age = 10;
	println!("age={}", age);
}
fn main(){
	let dog1_age = 10;
	println!("dog1_age={}", dog1_age);
}

先頭に「_」を付けたり、「_」だけの名前は使わない変数を表す

fn main(){
	let mut _a = 9;
	let _ = 12;

	println!("表示する値がありません");
}

式は let x = 5; などと表す
関数の場合は printdata(a, b); など。何もしない時は()を使うことがよくある

Rustのプロジェクトとビルド

大規模なプログラムを作成する場合は関連ファイルをプロジェクトと呼ぶ単位で扱うと便利なことがある
プロジェクトを作成するには、作成したいフォルダでcargo newを実行する

$ cargo new helloprj —bin
Created binary (application) `helloprj` package
$ cd helloprj
$ tree
.
├── Cargo.toml
└── src
└── main.rs

main.rs

fn main() {
    println!("Hello, world!");
}

$ cargo build

buildして実行する場合
$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.01s
Running `target/debug/helloprj`
Hello, world!

Rust playground
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021

Rustを始める

従来のプログラミング言語の優れた点を採用し、問題点を排除して作成された

// dispfile.rs
use std::env;
use std::io::BufReader;
use std::io::prelude::*;
use std::fs::File;

fn main() -> std::io::Result<()> {
	let argv: Vec<String> = env::args().collect(); // コマンドライン引数
	if argv.len() < 2 {
		println!("引数にファイル名を指定してください。");
		std::process:exit(1);
	}

	let f = File::open(&argv[1])?;
	let reader = BufReader::new(f);

	for line in reader.lines() {
		println!("{}", line?);
	}
	Ok(())
}

OpenSSLと楕円曲線暗号

$ openssl ecparam -list_curves

ECDSAで署名の生成・検証をする
$ echo abcde > plain.txt
$ openssl ecparam -genkey -name secp112r1 -out key-pair.pem
$ openssl ec -in key-pair.pem -outform PEM -pubout -out public.pem
$ openssl ec -in key-pair.pem -outform PEM -out private.pem
$ openssl dgst -sha1 -sign private.pem plain.txt > signature.dat
$ openssl dgst -sha1 -verify public.pem -signature signature.dat plain.txt
$ openssl asn1parse -inform DER -in signature.dat
0:d=0 hl=2 l= 34 cons: SEQUENCE
2:d=1 hl=2 l= 15 prim: INTEGER :D8BBE81DBD2E3A576952570B88D6
19:d=1 hl=2 l= 15 prim: INTEGER :B655B2C4FB75815E84B67BC4356E

sha256とsha512

SHA–256は入力値ごとに固有のハッシュ値を生成することにより、データの完全性などをチェックするために用いられる

$original_string = "パスワード";
$hashed_string = hash('sha256', $original_string);
print_r($hashed_string);

$ php index.php
d8b076148c939d9d2d6eb60458969c486794a4c0fcf0632be58fa5bf6d15aafa

$original_string = "パスワード";
$hashed_string = hash('sha512', $original_string);
print_r($hashed_string);

e2f8de62a90c1e3039cba62afb7646401ca5fbd97ec4ef3fbada4752aeafd022cfa7eafda320d08b2df6a0a6e55f0d62b5967081792095d7eaafc58d00533283

512にすると倍になってますね。

署名

署名は署名者アリスと受け取ったデータの正当性を確認したいボブの二人の間で使用する

1. 鍵生成: 署名鍵sと検証鍵Sのペアを作成する
2. 署名: アリスは署名したいデータmに足して署名鍵sで検証に使うためのデータΩを作成する これを署名という
3. 検証: データと署名の組み合わせをもらったボブはアリスから受け取った検証鍵Sを用いて検証する

メッセージ認証符号MAC(Message Authentication Code)

MACはデータの完全性を保証するための仕組み

1.初期化:事前に秘密鍵sを決めて共有しておく 
2.MAC生成: データmと秘密鍵sからMAC生成関数を使ってMAC値tと呼ばれる値を作り、データmと一緒にMAC値tをボブに送る
3.検証: 共有しておいた秘密鍵sと受け取ったデータmからMAC生成関数を使ってMAC値tを計算する
       L MAC値tが一致していればデータmを正常に受信できたとして受理(accept)、そうでなければ不正としてreject

ハッシュ関数 SHA-2とSHA-3

ハッシュはあらゆるデータに対して、相違なる識別子を割り振る仕組み
認証や署名などに必須の要素技術

指紋認証などは、その特徴量は容易に複製されないことを前提としている

ハッシュ関数とは、任意のデータから、予め決められた範囲内の値を計算する関数
同じデータを入力すると常に同じ値が得られる
L 出力サイズが一定: SHA256は出力ハッシュ値はいつも256ビット。サイズの大きなデータはデータが欠損している
L 一方向性、衝突困難性: データが一致しているかを調べるにはハッシュ値の値が同一かを確認すれば良い

MD5, SHA-1は衝突する。SHA256, SHA3は今の所安全とされている
予めよく使われる単語を用意したり、パスワードとしてよく使われるパスワードはすぐにバレてしまう。携帯電話も同様。文字数が長くなると計算時間がかかる 8文字の場合は高性能GPUだと8時間で解明されてしまう

### SHA-2(256)とSHA-3
SHA-256が広く使われている
入力データを512ビットごとのブロックに分割する
あまりにデータの収量を示す1ビットの1を追加
0をあまりのサイズが448ビットになるように追加する
最後に64ビット整数の形式で追加して全体が512ビットの倍数になるように調整

paddingと書く

8個の32ビット整数からなる256ビットの内部状態Sを準備する
内部状態SとブロックBを入力して新しい内部状態Sを出力する圧縮関数fを準備する
内部状態Sを初期化IVで初期化し、各ブロックを入力して順次内部状態を更新する
SHA-256の方が高速に処理される

### SHA-3
マークルダンガード構造ではなくスポンジ構造を採用している。吸収フェーズと搾取フェーズがある

楕円曲線暗号(elliptic curve cryptography)

ECDHP:(P, aP, bP)が与えられた時にabPを求めよ
楕円離散対数問題(ECDLP): P, Aが与えられた時にA=aPとなるaを求めよ
ECDHPやECDLPが難しいとされている
楕円曲線を用いたDH鍵共有がECDH鍵共有

### 中間者攻撃
アリスとボブの間に入って、秘密鍵s, 公開鍵Sのうち、公開鍵Sを書き換える
Dec(s, c) = m
Enc(B, m) = c’