Can a SHA3 engine be used to construct a Keccak implementation? I am working on a cSHAKE-128 &amp; cSHAKE-256 implementation that takes advantage of a number of hardware accelerators I have at my disposal, specifically for SHA-3 256/384/512 and SHAKE 128/256.
cSHAKE 128 is defined as follows:
1. If N = &quot;&quot; and S = &quot;&quot;:
return SHAKE128(X, L);
2. Else:
return KECCAK[256](bytepad(encode_string(N) || encode_string(S), 168) || X || 00, L).

If condition 1 is met, the solution is trivial, since I do have a SHAKE128 engine available.
However, in the case of condition 2, I don't have a Keccak engine readily available. I'm wondering if SHA3 can be used as primitive to construct Keccak 256.
I have read that SHA3 is directly derived from Keccak (was a result of a contest which Keccak won), but I've also read they're not exactly the same. This very useful on-line hasher does not produce the same hash values for SHA3 256 and Keccak 256.
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 = &quot;&quot; and S = &quot;&quot;:
    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.