2023年12月3日日曜日

DockerとPodman

DockerとかPodman とか仮想っぽいものをつついてみる。

Linuxのカーネルの機能で複数環境を切り盛りする系のいろいろ

Dockerさん入れてみた

Docker Compose 2種類あるよ

というわけで進化も速いとドキュメントも古いぞ、ということになったり。

継ぎ接ぎだらけで調べてみたりしている。

どのツールが残ってるのかわからんな。Machineってなに、どこに機能移行したの。

RaspberryPi に入れてみたり、Windows に Docker Desktop 入れてみたり。

Minecraft の バニラとかPaperMeのとか入れてみたらそれなりに動いたり動かなかったり癖ありな感じはする。

最近のJREの作り方も把握した。 これでイメージファイル小さくはできるけどそこそこ大きいのは大きい。ディスクがあればメモリー消費するのでもないからいいか。

Podmanの本が出ていた? ようなので半額ポイントバック買い。Dockerよりいろいろできそう。Podman Desktopの1.5も出てるっぽいので入れてみるとDockerと併用できる。どっちが走ってるんだかわからない状態。

Podman Desktop (Windows, Mac, Linux)

Podman イン・アクション (電子書籍版)

Docker 互換な上でGoogleのKubeなんとか寄りのことなどもできるとか。

RaspberryPiにもDockerを消し去って入れてみる。v3.0系しか入らなかったのでdocker compose 互換がない。

test版でバージョンあげてみようとして失敗。RaspberryPi OS を最新版で入れ直し。Podman v4.3.1 くらいがそのまま入ったよ。

podman-compose が使えるようになっていた。docker.io が省略できない以外はだいたい同じでも動くのかな。imageの残り方がなんか違う気もする。

dockerでbuild するのとdocker composeでbuildするのと環境変数の指定が違うのかどうなのか。パラメータの多いdocker / podman 単体で使いたくないので苦戦。

dockerとpodman、基本は同じなのでそれ以降行かないならどっち使ってもいい気がした。 古い環境はdockerの方が入れやすそう。Kubeなんとかなど拡張していくならPodmanの方がいい気がした。

ディストリビューションのimageを指定してrpmなどパッケージ突っ込んで使うのが公式イメージ使うより簡単かどうかというところな感じが。

作る側は大変、使う方は簡単、というところかもしれない。


2023年10月4日水曜日

Lenovo Tablet P11 Pro (2nd) でサブディスプレイ

製品案内ではMiracastでサブディスプレイにできる、とか書かれていたLenovo Tablet P11 Pro (2nd) だが、方法がわからず。

設定のどこかでできるっぽい記述もあるが、今はそんな項目もなく。

結局Lenovo Freestyle というアプリでサブディスプレイ化することが判明。

同じアカウントで設定して共有、あっさりできたが何か違わないか?

2023年6月10日土曜日

AES高速化をもう少し

割と最速だったJavaで作ったAES実装もJDKのAESがOpenSSLかなにかのハードウェア実装を使うようになったおかげで数倍の差がついてしまった。KCyper-2がまだよくわからないのでAESをつついてみたりPKIの方を見たり。

Intel CPU にはAES NI というAESの計算補助的なものがあり、AMD Ryzen 2600X でも使えるようになっていて速くなる。OpenSSLが対応しているのでJavaでもOpenSSL経由でいつのまにか使えるようになっていて、高速処理ができている。

AES NIもたぶん途中の計算をまとめられるだけまとめてあらかじめ計算しておき配列に押し込んで高速化をする手法。

ソフト的にも高速化していくと同じような実装になって普通に解説されているような実装の数十倍はやくなる。

特に競ってみようというわけではないが、いろいろなハッシュや暗号を実装してみるなかでAESも乗せてみたついでに高速化もしてみたというのが前回くらい。32bitまとめるところで高速化ができたが、64bitにしてみたらもう少し速くなった気がするのでそのあたりで止めておいた。

decode側は最適化をどうやればいいのかと思っていたら、計算順を変えることでencodeと同じように最適化できることもわかったので割と高速な方にすることはできた。encodeと同じように64bit化したらencode以上に速くなった。 

AES-CBC Ryzen 7 5800X で 初期値 1400Mbps、JavaのJITが効いてくると1650Mbpsくらいまで速くなる印象。AES-NIだと初期値2500Mbpsくらいなのでかなり追いついている。AES単体だとまだまだ差は大きいが今は未計測。

元になるAESのコードが跡形もなくなってきているので、原型を留めたコードを別に残しておかないと何の参考にもならないなと。

速度比較、AES単体ではなく若干実用的なAES-CBCで比較してみることにして、JDKのコードと2倍くらいの差まで迫ることができる。ということはJDKのCBCが遅いのか。CBCで64bit演算してそのままAESに持っていくことで高速化できている感じ。JDKはそのあたりが遅い印象。

最近の主流はCBCからGCMかなんかになってきているようなので、そっちも実装したいが仕様だけ見てコード自体は見たことがなくまだよくわからず少しずつ進行中。試行錯誤中で8割くらいであとは細かい回数のテストと調整くらいかな。マルチスレッド化もJavaですぐにできる簡単なところは対応したつもりなので他はそのうち。

ガロア体の方も8ビット実装と128ビットな多バイト実装と両方作れたのでそろそろKCyper-2に手を出してもいいのかな。

PKCSとかAES.1とかABNFとかJSONとかOAuth 2.0とかJWSとかOpenID ConnectとかWeb Serverとか上から下までじわじわとフルで作っていると。

2023年1月24日火曜日

RSA鍵を作る

最近暗号系をいろいろ実装してみている中で PKCS #1 の RSA も必要になってきたので実装してみた。中身がわからないと使いにくいタイプ。

RSA は公開鍵暗号という形で秘密鍵、公開鍵の2つの鍵を使う。AESなどの共通鍵暗号とは違うところ。

公開鍵で暗号化、秘密鍵で復号ができるのがひとつめ。

秘密鍵で署名。公開鍵で検証。これが2つめ。 

公開鍵暗号共通の特徴ではなくRSAの特徴のようなので注意。

アルゴリズム的にはガロア体と同じようなものを作って2つの状態を行き来してる感じがした。

何に使えるのか。ひととおりバイト列の暗号化などにも使えるが、速さが出ないので署名用途の方が主流で暗号化も一部用途に限定して使う場合が多い。

秘密鍵と公開鍵の中身を見ていく。

RSAは大きい数の因数分解が難しいというところから作られているので2つの素数から鍵を作る。

素数(prime)2つ(pとq)を決める。2048ビットのRSAだと1024ビットくらいの素数を2つ。今なら3072ビットくらいが最低ラインになってきているので1536ビットくらいの素数を2つ。

Java で作るのでいろいろ省略できるところは省略する。

乱数はjava.math.SecureRandom っぽいところから。安全かどうかは不明。他の要素があればいろいろ混ぜるとより安全かも。普通のRandomは安全ではない。

SecureRandom srnd = SecureRandom.getInstanceStorong();

BigInteger p = BigInteger.probablePrime( len / 2, srnd );

BigInteger q = BigInteger.probablePrime( len / 2, srnd );

これで素数2つを作ってくれるのでおまかせ。素数ではない場合もあるらしい。

modulus 素数2つを掛けたもの 変数名は n など。

BigInteger n = p.multiply(q); // n = p * q

nをpとqに素因数分解するのが難しい。

次はeとdという指数(exponent)を決めていく。

eは公開指数(public exponent)、dは秘密指数(private exponent)。

e * d = 1 mod (p - 1)(q - 1) が成り立つ範囲のeとd。

e はほぼ固定値が使われていてフェルマーなんとかの 65537 ( 0x10001 ) が使われることが多い。

eの条件は、3からn-1の値、p,qと互いに素である数である。素数ではなくてもいいが奇数であること(p-1, q-1が偶数なので)。 ( 2^16 + 1 ~ 2^256 - 1 ) ぐらいが最適っぽい。

BigInteger e = BigInteger.probablePrime(17,srnd); ぐらいでいいんじゃないのかな

e が決まると上の式からdも自動的に決まる。成立しない場合は e, p, qを作り直す。

計算する場合はp-1, q-1 の最小公倍数(lambda(n))を出す必要があるらしいのでこんなかんじ。

BigInteger d = e.modInverse(lambda); // e * d = 1 (mod lambda)

lambda は p-1, q-1の最小公倍数 lambda = LCM(p-1, q-1)

最小公倍数は最大公約数から

最小公倍数 LCM(a, b) = ab / GCD(a,b);

最大公約数 GCD(a, b) = a != 0 ? GCD(b % a, a) : b;

こんなかんじ。

n と e が公開鍵、n と d が秘密鍵(最小の場合)として使われる。

OpenSSLで生成される秘密鍵にはp, qなどの要素も保存されている。

  • modulus = n
  • publicExponent = e
  • privateExponent = d
  • prime1 = p
  • prime2 = q
  • exponent1 = e.modInverse(p - 1) = d.mod(p - 1)
  • exponent2 = e.modInverse(q - 1) = d.mod(q - 1)
  • coefficient = q.modInverse(p)

各要素の使い方は省略.

メッセージ M (長さは鍵長 - 数バイトまで)、暗号文 C で簡単な計算方法

公開鍵で暗号化 C = M.modPow(e, n)

秘密鍵で復号 M = C.modPow(d, n)

秘密鍵で署名 S = Hash(M).modPow(d, n)

公開鍵で署名検証 Hash(M) = S.modPow(e, n)

HashはSHAなどJava では MessageDigest系。Paddingなどもあるので実際はちょっと違う。


 


DockerとPodman

DockerとかPodman とか仮想っぽいものをつついてみる。 Linuxのカーネルの機能で複数環境を切り盛りする系のいろいろ Dockerさん入れてみた Docker Compose 2種類あるよ というわけで進化も速いとドキュメントも古いぞ、ということになったり。 継ぎ接ぎ...