概要
bijou64 は、 Subduction CRDT sync protocol 向けに開発された新しい可変長整数エンコーディング方式。 セキュリティ のための設計が、結果的に パフォーマンス向上 ももたらした。 従来の LEB128 と比較して、 一意的なエンコーディング と高速なデコードを実現。 署名検証やカノニカル化 が重要な用途に適した設計。 Rustライブラリ や Wasm/JavaScriptラッパー も公開中。
bijou64: セキュリティとパフォーマンスを両立する新しいvarintエンコーディング
- bijou64 は、 Subduction CRDT sync protocol のために開発された可変長整数(varint)エンコーディング方式
- 主な目的は、 各整数値に対して一意なバイト列のみを許容 し、署名検証時などのバグや攻撃を防止
- LEB128 や他の一般的なvarint方式は、同じ値を複数のバイト列で表現できる問題点
- 例: 0は0x00、0x80 0x00、0x80 0x80 0x00など、何通りも表現可能
- bijou64 はこの問題を設計段階で排除し、 カノニカル化(canonicalisation) を追加チェックなしで保証
- セキュリティ要件 が高いプロトコル(署名、圧縮、データ重複排除など)で有用
bijou64の設計と動作原理
- 1バイト目の役割分担 :0〜247はそのまま値、248〜255は「タグ」として後続バイト数を示す
- 例: 0x42 → 0x42、0xF8以降は複数バイトモード
- オフセット方式 :タグ+データバイトで値を決定、各長さごとにオフセット値を加算
- 例: 3バイト(タグ+2バイト)の場合、0x1F8を加算
- 各バイト長ごとにオフセットが増加、1バイト目で即座に範囲が決まる
- 最大値制限 :9バイト(u64最大値超え)の場合のみ範囲チェック
- デコード時の効率性 :最初の1バイトで必要なバイト数が分かるため、O(1)でメモリ確保可能
- エンコーディングの一意性 : 全ての値が唯一のバイト列で表現 される
LEB128との比較とベンチマーク
- デコード速度 :bijou64はLEB128より2〜10倍高速
- 小さい値では2倍、大きい値では8〜10倍の差
- 4096個バッチ処理でbijou64は約3µs、LEB128は約30µs
- カノニカルチェックのコスト :bijou64は追加コストゼロ、LEB128は追加チェックが必要
- エンコード速度 :ほぼ同等だが、特定の範囲(248〜65535)ではLEB128が約1.24倍速い
- エンコードサイズ :ほぼ同等、配列境界付近で微差
- CPUフレンドリー設計 :
- ビッグエンディアン連続バイト列 →現代CPUのバイトスワップ命令が活用可能
- 分岐予測が容易 →パターンが安定しやすい
- 算術演算のみで高速 →条件分岐の削減
bijou64の適用場面と注意点
- 新規プロトコル設計 や カノニカル性が重要な用途 で特に有効
- 署名、コンテンツアドレス、複数実装間のバイト列一致が必要な場面
- LEB128の成熟度 には及ばず、十分な実戦テストは未了
- 現状はApple M2 Pro、AMD Zen 5、Zen 3でベンチマーク済み
- Rustライブラリ(crates.ioのbijou64) としてMIT/Apache-2.0で公開
- Wasm/JavaScriptラッパー や bijou32/bijou128 等の拡張も計画
- バグ報告や他方式との比較事例 も歓迎とのこと
まとめ:bijou64の選択基準
- カノニカル性重視 ・ パフォーマンス重視 の用途において、bijou64は有力な選択肢
- LEB128 は引き続き多くの用途で有効、bijou64は新規設計や要件が合致する場合に検討
- 実装・検証・ベンチマークの継続的なフィードバック が今後の発展に重要