# C-KZG-4844 ## Item 1 **Description:** Usage of `m=i+1` in `compute_kzg_proof_impl` is not immediately clear. **Link:** [code](https://github.com/ethereum/c-kzg-4844/blob/9b91f3b8320cfd805b99fc04d96066e613132d12/src/c_kzg_4844.c#L1099) **Suggestion:** The non-intuitive part is mainly due to `m=i+1` instead of `m=i`. This is because if `m==0`, then the [this line](https://github.com/ethereum/c-kzg-4844/blob/9b91f3b8320cfd805b99fc04d96066e613132d12/src/c_kzg_4844.c#L1115) won't trigger. In other languages we do this with an `Optional` type which is capable of checking if `m` was originally set. My suggestion is to use `m=-1` as a sentinel value to denote `m` not being set, then our check becomes `if (m != -1)` **Reason:** The codepath requires you to know about how C handles truthiness of values, ie 0 is false and anything else is true. **George Comment:** Good point. Let's do this improvement! **Gotti Comment:** Considered fixed by #208. It still uses `m==0` to indicate that the evaluation point is not among the roots of unity, but it is clearly documented now. ## Item 2 **Description:** `8 * sizeof(blst_scalar)` is used in both g1_mul and g2_mul. **Link** : [g1_mul](https://github.com/ethereum/c-kzg-4844/blob/9b91f3b8320cfd805b99fc04d96066e613132d12/src/c_kzg_4844.c#L351) and [g2_mul]() **Suggestion:** Create a constant with some documentation explaining why its needed. **Reason:** If you need to change that value, it would need to be changed in both places, so a constant is generally better and it also allows you to document what it is. For example, it is not clear how that value differs from the `BYTES_PER_FIELD_ELEMENT` constant. **George Comment:** Agreed. Let's do it. I think we might also be able to make that [255](https://github.com/ethereum/c-kzg-4844/blob/main/src/c_kzg_4844.c#L799) instead of 256 as we are doing in the pippenger function for a tiny speed boost. But figuring this out properly needs some digging. **Gotti Comment:** With the comment added in #212, it is sufficiently clear, I think. We could replace 8 by the `CHAR_BIT` standard macro, but it's not that we expect anything to work with non-8-bit bytes. ## Item 3 **Description:** `bytes_from_uint64` does not specify the endianness. Link: [code](https://github.com/ethereum/c-kzg-4844/blob/9b91f3b8320cfd805b99fc04d96066e613132d12/src/c_kzg_4844.c#L480) **Suggestion:** Specify an endianness in the comments or function name. **Reason:** Mixing up endianness is a common source of bugs, so being explicit in every place its used goes a long way to avoiding these. **George Comment:** Fixed by Gotti in #208. ## Item 4 **Description:** Extra parameter `n` in doc comments. **Link:** [code](https://github.com/ethereum/c-kzg-4844/blob/549739fcb3aaec6fe5651e1912f05c604b45621b/src/c_kzg_4844.c#L685) **Suggestion:** Remove parameter `n` as its not a parameter. **George Comment:** Fixed by Gotti in #208. ## Item 5 **Description:** `bit_reversal_permutation` takes `n` as a `uint64` **Link:** [code](https://github.com/ethereum/c-kzg-4844/blob/9b91f3b8320cfd805b99fc04d96066e613132d12/src/c_kzg_4844.c#L555) **Suggestion:** It seems that this is because `FFTSettings::MaxWidth` is a `uint64` instead of `uint32`. However note that [this assert](https://github.com/ethereum/c-kzg-4844/blob/9b91f3b8320cfd805b99fc04d96066e613132d12/src/c_kzg_4844.c#L557) forces it to be a `uint32` anyways and the 2-adicity of bls12-381 is 32, so having it as a uint32 should be fine. **Reason:** If we are using a `uint64` and asserting that it is a `uint32`. It makes sense to use a `uint32` from the beginning. **George Comment:** Agreed let's do it. I wonder if `max_width` is uint64 for a reason and we are gonna get lots of type errors if we attempt to do this change. **Gotti Comment:** I started doing this and ran into some robustness issue: Since the 2-adicity of bls12-381 is 32, the natural maximum value of `FFTSettings::MaxWidth` is `1<<32`, which just overflows `uint32_t`. This would mean having to artifically restrict `MaxWidth` to `1<<31`, which is kind-of ugly and error-prone. I would suggest instead to extend `log2_pow2` to work with 64-bits and then change the assertion to `<= (1<<32)`. The 64-bit value is then required for the possible valid value `1<<32` ## Item 6 **Description:** `CHALLENGE_INPUT_SIZE` has constants `32` and `48` but it is not clear why. Link: [code](https://github.com/ethereum/c-kzg-4844/blob/9b91f3b8320cfd805b99fc04d96066e613132d12/src/c_kzg_4844.c#L675) **Suggestion:** Specify what the `32` and `48` are related to. **Note:** I wonder if there is anyway to not need to manually do pointer arithmetic; `offset + 8`. **Reason:** Just a general nit to document constants; for `48` we could probably use `BYTES_PER_COMMITMENT` and for `32` I'm not completely sure why we need `32 byte` alignment. I have just used the `16` as a constant in the golang code. **George Comment:** `CHALLENGE_INPUT_SIZE = 32 + BYTES_PER_BLOB + 48;` It's 32 bytes for the domain separator, then a blob, then a commitment. I agree we should document 32 and 48 with constants instead of magic numbers there. I don't know of a better way to do the pointer stuff there (without implementing a higher-level `buffer` abstraction). **Gotti Comment:** Considered fixed by #212 ## Item 7 (George No Action needed) Description: `max_width+1` is used in the codebase and signifies the fact that some arrays have `4097` roots of unity and not 4096. Link: [code](https://github.com/ethereum/c-kzg-4844/blob/9b91f3b8320cfd805b99fc04d96066e613132d12/src/c_kzg_4844.c#L1639) **Suggestion:** Document why its 4097 elements. If I understand corretly, its so that its easier to reason about the inverse of a particular root of unity when the expanded roots are reversed (since the inverse of 1 is 1) **Gotti Comment:** Addressed by #222 ## Item 8 (Dankrad Confirmed) Description: The `log2_pow2` method is using a lookup table algorithm and `register` keyword. Link: [code](https://github.com/ethereum/c-kzg-4844/blob/549739fcb3aaec6fe5651e1912f05c604b45621b/src/c_kzg_4844.c#L443) Suggestion: Two suggestions are noted: - One could use `log2l` or `log2` from `math.h` - One could use a *simpler* algorithm: ```c static int log2_pow2_(uint32_t n) { int result = 0; while (n >>= 1) ++result; return result; } ``` **Gotti Comment:** Note that C23 will have a count-trailing-zeros in the standard library. ## Item 9 (George Confirmed) Level: Informational Description: doc comment uses `@p x` however there is no `x` parameter. Link: [code](https://github.com/ethereum/c-kzg-4844/blob/9b91f3b8320cfd805b99fc04d96066e613132d12/src/c_kzg_4844.c#L989) **Suggestion:** Change to `@p z` **Gotti Comment:** Addressed in #227 ## Item 10 (George Confirmed) Description: the use of the phrase "trusted and validated" in the same sentence is a bit ambiguous as to how they differ. Link: [code](https://github.com/ethereum/c-kzg-4844/blob/549739fcb3aaec6fe5651e1912f05c604b45621b/src/c_kzg_4844.c#L596) **Suggestion:** We can remove the word `trusted` and specify what validation is happening. ## Item 11 (George Confirmed) **Description:** Before using the pairings function, it is assumed that the inputs have been subgroup checked. Link: [code](https://github.com/ethereum/c-kzg-4844/blob/549739fcb3aaec6fe5651e1912f05c604b45621b/src/c_kzg_4844.c#L406) **Suggestion:** It would be good to specify this in the comments, since I don't think its specified in the blst code either. **Note:** The go-kzg code does not have this comment either, but the gnark library has a comment on top of the pairings method.