Let first look at $$\operatorname{KECCAK}[c] (N || suffix, d) \label{1}\tag{1}$$ It calls
$$\operatorname{KECCAK}[c] (N, d) = \operatorname{SPONGE}[\operatorname{KECCAK-p}[1600, 24], pad10*1, 1600 – c] (N, d).$$
- $c$ is the capacity
- $d$ is the output size
- 1600 is the base $b$
- $pad10*1$ is the multi rate padding.
- 24 is the number of rounds $n_r$
- The sponge in short is the framework for specifying functions on binary data with arbitrary output length.
Let assume that we have a black box SHA3 implementation of any mode
- $\operatorname{SHA3-224}(M) = \operatorname{KECCAK}[448] (M || 01, 224)$
- $\operatorname{SHA3-256}(M) = \operatorname{KECCAK}[512] (M || 01, 256)$
- $\operatorname{SHA3-384}(M) = \operatorname{KECCAK}[768] (M || 01, 384)$
- $\operatorname{SHA3-512}(M) = \operatorname{KECCAK}[1024] (M || 01, 512)$
and black box SHAKEx implementations
$\operatorname{SHAKE128}(M, d) = \operatorname{RawSHAKE128}(M || 11, d)$
$\operatorname{SHAKE256}(M, d) = \operatorname{RawSHAKE256}(M || 11, d)$
where
- $\operatorname{RawSHAKE128}(J, d) = \operatorname{KECCAK}[256] (J || 11, d)$
- $\operatorname{RawSHAKE256}(J, d) = \operatorname{KECCAK}[512] (J || 11, d)$
Now you want to use the above as black box implementation for cSHAKE
cSHAKE128(X, L, N, S):
1. If N = "" and S = "":
return SHAKE128(X, L);
2. Else:
return KECCAK[256](bytepad(encode_string(N) || encode_string(S), 168) || X || 00, L).
- The
if
part is not a problem, since it directly uses the SHAKE128.
- The
else
part is the problematic part. One can externally implement bytepad(encode_string(N) || encode_string(S), 168)
and concatenate it with X
. The domain separation padding 00
is the real issue. If the block box doesn't allow this as input, then there is no way to this.
If the library somehow extendible one may use the \ref{1} to generate all of the above, otherwise no.
The cSHAKE is the base for KMAC, TupleHash, and ParallelHash. If you are going to need those, you may need to implement yourself.