【IPFS】対応ハッシュ・アルゴリズム一覧【Kubo】

# Kubo で対応しているハッシュ・アルゴリズム一覧

> IPFS コマンド（`ipfs`）の Go 版実装である [Kubo](https://github.com/ipfs/kubo)（旧 `go-ipfs`）がサポートしている、`CID` に使えるハッシュ・アルゴリズムが知りたい。

- ハッシュ？CID？という方は、以下を参照
    - [hashアルゴリズムとハッシュ値の長さ一覧（＋ハッシュ関数の基本と応用）](https://qiita.com/KEINOS/items/c92268386d265042ea16) @ Qiita

## TL; DR <sub><sup>（今北産業）</sup></sub>

1. `--hash` オプションでアルゴリズムを指定できます。
    - 例） `ipfs add ../hoge.md --hash=sha3-224`
    - 注意）この場合、`CID` のバージョンは `CID v1` が使われます。また、実験版のオプションであるため、利用可能なアルゴリズムは将来的に変わる可能性があります。
1. サポートされている最新のアルゴリズム。
    - [multihash.go](https://github.com/multiformats/go-multihash/blob/master/multihash.go) | go-multihash | multiformats @ GitHub

1. 2023/04/26 現在、（実験的に）IPFS でサポートされているハッシュ・アルゴリズム（一部未実装） 
    
    | 設定値 | 備考 |
    | :--: | :-- |
    | `identity` | ハッシュ化しない（極小さなデータの場合に使われ、入力と同じバイトを示す）[^identity] |
    | `sha1` | 20 年前に定番だったアルゴリズム（現在は非推奨）|
    | `sha2-256` | 指定がない場合のデフォルトのアルゴリズム。<br>20 年前に生まれた、現在では定番のアルゴリズム [SHA2](https://ja.wikipedia.org/wiki/SHA-2) の 256 ビット版（返り値が 256 ビットのハッシュ・アルゴリズム）。現在は SHA3 の利用が推奨されている。 |
    | `sha2-512` | 上記の 512 ビット版 |
    | `sha3`     | NIST 推奨のアルゴリズム（SHA3-512 の<ruby>エイリアス<rt>別名</rt></ruby>）。後述の KECCAK をベースに NIST が制定した [SHA](https://ja.wikipedia.org/wiki/Secure_Hash_Algorithm) の最新アルゴリズム。 |
    | `sha3-224` | SHA3 の 224 ビット版 |
    | `sha3-256` | SHA3 の 256 ビット版 |
    | `sha3-384` | SHA3 の 384 ビット版 |
    | `sha3-512` | SHA3 の 512 ビット版（上記 `sha3` と同じもの） |
    | `dbl-sha2-256` | Double SHA256（SHA256D）と呼ばれる、SHA2-256 を 2 回ストレッチングしたもの。つまり、SHA2 の 256 ビット版のハッシュ関数に通したものを、さらに通したもの。ビットコインなどでも使われてる。[^sha256d] |
    | `murmur3-x64-64` | MurmurHash3 の 128 ビット版で x64 プロセッサ向けバージョン [^murmur]。 強度・速度では BLAKE3 には敵わないものの、非暗号学的ハッシュ（セキュリティ目的ではないハッシュアルゴリズム）では比較的高速な部類に入る。 |
    | `keccak-224` | SHA-3 の原型となった KECCAK の 224 ビット版。依存パッケージの問題で廃止[^notimplemented]。 |
    | `keccak-256` | KECCAK の 256 ビット版 |
    | `keccak-384` | KECCAK の 384 ビット版。依存パッケージの問題で廃止[^notimplemented]。 |
    | `keccak-512` | KECCAK の 512 ビット版 |
    | `blake3`     | NIST の SHA3 制定にあたり、KECCAK と最後まで争った BLAKE2 の後継。爆速。 |
    | `shake-128`  | SHA3 の可変長（最大 128 ビット）版。パディングしないぶん、SHA3 より若干速い |
    | `shake-256`  | SHA3 の可変長（最大 256 ビット）版 |
    | `sha2-256-trunc254-padded` | SHA2 の可変長（最大 256 ビット）版 |
    | `x11`        | ブロックチェーンのマイニングなどで使われるストレッチングのアルゴリズム。ストレッチングを行う（複数回ハッシュ関数を通す）際に、ラウンドロビン方式で 11 個の異なるアルゴリズムに通すアルゴリズム。`BLAKE`、`BMW`、`Grostl`、`JH`、`Keccak`、`Skin`、`Loofah`、`CubeHash`、`SHavite-3`、`SIMD`、`ECHOP` が順番に使われる[^x11]。依存パッケージが多いため、実装はペンディング（保留）されている[^notimplemented]。
    | `md5`        | SHA1 と並ぶ、20 年前では定番だった 128 ビットのハッシュ・アルゴリズム（現在は非推奨）。|
    | `poseidon-bls12_381-a2-fc1` | Etherium や Polygon などの、ブロックチェーンの[ゼロ知識証明](https://ja.wikipedia.org/wiki/%E3%82%BC%E3%83%AD%E7%9F%A5%E8%AD%98%E8%A8%BC%E6%98%8E)でも使われるハッシュ・アルゴリズム。[楕円曲線暗号](https://ja.wikipedia.org/wiki/%E6%A5%95%E5%86%86%E6%9B%B2%E7%B7%9A%E6%9A%97%E5%8F%B7)と同じ考え方で算出しているのが特徴。[^poseidon] |

    （出典: [multihash.go のソースコード](https://github.com/multiformats/go-multihash/blob/dc3bd6897fcd17f6acd8d4d6ffd2cea3d4d3ebeb/multihash.go#L97-L120)より）

[^notimplemented]: https://github.com/multiformats/go-multihash/issues/120

```shell-session:使用例
$ echo 'Hello, Qiita!' > hello_qiita.txt

$ # アルゴリズム無指定
$ ipfs add ./hello_qiita.txt
added QmSuyo747aBeA4yzXy354VUH3Z3pUBC3rULAQ5oF62fy5B hello_qiita.txt
 14 B / 14 B [================================================================] 100.00%

$ # デフォルトのアルゴリズム（上記と比較）
$ ipfs add ./hello_qiita.txt --hash=sha2-256
added QmSuyo747aBeA4yzXy354VUH3Z3pUBC3rULAQ5oF62fy5B hello_qiita.txt
 14 B / 14 B [================================================================] 100.00%

$ # 爆速アルゴリズムを指定
$ ipfs add ./hello_qiita.txt --hash=blake3
added bafkr4ifqg6zutkurq7ctgfrjaqxroevcihgl62atnrfgrwwhxjoqgjzmwu hello_qiita.txt
 14 B / ? [-----------------------------------------------------=-------------]

$ # 最強のアルゴリズムを指定
$ ipfs add ./hello_qiita.txt --hash=sha3
added bafkriqa3kk2tr6i6zcp7snuepiexsfm4h7ujgsdijzqzipgeovpsy6ujilfm7ozg2g5a76vysvffzb2nkcvkvk7nuemau6xksqgerp4vxkxh4 hello_qiita.txt
 14 B / ? [-----------------------------------------------------=-------------]
```

:::note warn
Web Gateway 経由でコンテンツを取得する場合、（古いバージョンや `experimental` が有効になっていないため）63 文字以上の `CID` は受け付けないことが多いです。`SHA3` などの 512 ビット系アルゴリズムを使った `CID` を発行する場合は注意します。
:::

[^identity]: [Remarks](https://richardschneider.github.io/net-ipfs-core/api/Ipfs.Registry.HashingAlgorithm.html#Ipfs_Registry_HashingAlgorithm_remarks) | Class HashingAlgorithm | HashingAlgorithm | API Documentation @ richardschneider.github.io
[^sha256d]: https://en.bitcoin.it/wiki/Protocol_documentation#Merkle_Trees
[^murmur]: https://en.wikipedia.org/wiki/MurmurHash
[^x11]: https://academy.bit2me.com/en/what-is-x11-mining-algorithm/
[^poseidon]: [POSEIDON: A New Hash Function for Zero-Knowledge Proof Systems](https://eprint.iacr.org/2019/458.pdf) @ IACR

## TS; DR <sub><sup>（コマンドのヘルプが助けにならないのでソースを確認した）</sup></sub>

ローカルの IPFS リポジトリにコンテンツを追加して `CID`（コンテンツ ID）を発行したい場合、通常は以下のように `ipfs add` コマンドを実行します。

```shell-session
$ ipfs add ./hoge.md
added QmSuyo747aBeA4yzXy354VUH3Z3pUBC3rULAQ5oF62fy5B hoge.md
 14 B / 14 B [================================================================] 100.00%
```

この場合、（`Qm...` から始まる `CID`）の CID バージョンは `v0` で、使われるハッシュ・アルゴリズムはデフォルトの `SHA2-256` です（2023/04/26 現在）。

複数のラズパイ Zero で IPFS ノードを立ち上げているのですが、コンテンツの同一性を高めるために、ノードごとに **`CID` 発行時に利用するハッシュ・アルゴリズムを変えたい**と思いました。

つまり、`SHA-1` はもってのほか、20 年選手の `SHA-2` でもはなく、`SHA-3` などの新しいハッシュ・アルゴリズムの `CID` でも提供したかったのです。

`ipfs help add` を見ると、`ipfs add ./hoge.md --hash=sha3-224` のように、**実験的（`experimental`）ではあるものの`--hash` オプションでアルゴリズムを指定できる**ことはわかりました。

しかし、ヘルプには「デフォルトは `sha2-256`」としか情報がなく、指定できるアルゴリズムがわかりません。[調べてみた](https://github.com/multiformats/go-multihash/blob/dc3bd6897fcd17f6acd8d4d6ffd2cea3d4d3ebeb/multihash.go#L97-L120)ところ、`BLAKE3` などの爆速アルゴリズムもサポートしていたので、正式サポートまでの、自分のググラビリティとして。

## 参考文献

- [The Multihash Data Format](https://www.ietf.org/id/draft-multiformats-multihash-06.html) @ IETF
- [Issue #4207 コメント](https://github.com/ipfs/kubo/issues/4207#issuecomment-327368371) | "[sha3 hash functions unrecognised](https://github.com/ipfs/kubo/issues/4207)" | Kubo | IPFS @ GitHub