bls_ckd 0.2.0

BLS child key derivation
Documentation
# Rust BLS child key derivation (EIP2333, EIP2334)

This library is a forked version of [bls_key_derivation](https://crates.io/crates/bls_key_derivation), containing a straightforward interface to BLS12-381 child key derivation in complete compliance with [EIP2333](https://eips.ethereum.org/EIPS/eip-2333).

Since EIP2333 only proposes the hardened child key derivation, this library has also implemented a method of non-hardened child key derivation inspired by [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) to support the current application scenarios.

## Changes

Differences with the original library (<https://github.com/ChainSafe/rust-bls-derivation>) lie in the following:

1. removing the dependency on the unmaintained-for-over-6-years crate [rust-crypto]https://crates.io/crates/rust-crypto;
2. adding the active crate [curv-kzen]https://crates.io/crates/curv-kzen to support non-hardened BLS child key derivation beyond EIP233;
3. changing the lower limit of the seed entropy from 16 bytes to 32 bytes to be consistent with the current EIP2333 and [draft-irtf-cfrg-bls-signature-05]https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-05;
4. particularly modifying the function `hkdf_mod_r` in the following 5 parts to be in complete compliance with both EIP2333 and KeyGen in [Section 2.3 of draft-irtf-cfrg-bls-signature-05]https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-05#name-keygen:
   1. IKM -> IMK || I20SP(0, 1);
   2. keyinfo -> keyinfo || I20SP(L, 2);
   3. salt -> H(salt);
   4. add a loop with the zero private key check;
   5. add an input parameter `key_info` to support user-customized key info strings instead of fixing as a default empty string "".

## Usage

Defined in the crate [`curv`](https://github.com/ZenGo-X/curv), `FE` is the scalar type in $G_1$ and $G_2$, with `GE1` and `GE2` as point types, respectively. The following generic type `T` should be either `GE1` or `GE2`.

### CKD hardened

private->private hardened child key derivation:

```
pub fn ckd_sk_hardened(parent_sk: &FE, index: u32) -> FE
```

private->private hardened child key derivation from a path:

```
pub fn derive_child_sk(parent_sk: FE, path_str: &str) -> FE
```

master private key derivation from a seed:

```
pub fn derive_master_sk(seed: &[u8]) -> Result<FE, String>
```

Get indexes from a string path following EIP2334 spec:

```
pub fn path_to_node(path_str: &str) -> Result<Vec<u32>, String>
```

### CKD non-hardened

private->private non-hardened child key derivation:

```
pub fn ckd_sk_norma::<T>(parent_sk: &FE, index: u32) -> FE
```

private->private non-hardened child key derivation from a path:

```
pub fn derive_child_sk_normal::<T>(parent_sk: FE, path_str: &str) -> FE
```

public->public non-hardened child key derivation:

```
pub fn ckd_pk_normal(parent_pk: &T, index: u32) -> T
```

public->public non-hardened child key derivation from a path:

```
pub fn derive_child_pk_normal(parent_pk: T, path_str: &str) -> T
```

Compute the scalar tweak added to this key to get a child key:

```
pub fn ckd_tweak_normal(parent_pk: &T, index: u32) -> FE
```

## Testing

run tests with:

```
cargo test
```