Testing AES with dynamic S-Boxes #336
-
|
Hello, I want to apply NIST statistical tests on AES algorithm but with dynamic S-Boxes i.e depending on the input plain text the algorithm chooses an S-Box from a set of pre-generated S-Boxes, So as far I understand we need first to implement that as a component graph, But I do not know if that can be done or not, As if it was just testing with another S-Box it would be just replacing the new S-Box with the one exists in the AES model code provided but as I mentioned it is dynamic, So is this some thing can be done ? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
|
Hi @Moh-Gebril, thanks for your question! Let me share a minimal code that implements a toy cipher that takes a 3-bit plaintext and a 1-bit selector as inputs (note that I need to assign 3 bits to the selector to make it compatible with the modular subtraction). The cipher applies S-box1 if the selector is 0b000, and S-box2 if the selector is 0b001. from claasp.cipher import Cipher
class ToyDynamicSbox(Cipher):
def __init__(self):
super().__init__(
family_name="toydynamicsbox",
cipher_type="permutation",
cipher_inputs=["plaintext", "selector"],
cipher_inputs_bit_size=[3, 3],
cipher_output_bit_size=3
)
sbox1 = [0, 5, 3, 2, 6, 1, 4, 7]
sbox2 = [7, 0, 5, 3, 2, 6, 1, 4]
self.add_round()
# mask = 000 - selector modulo 8
# If selector == 0 then mask is 000
# If selector == 1 then mask is 111
# (sbox1 AND NOT mask) XOR (sbox2 AND mask)
# If selector bit is 0 => mask is 000 => sbox1 is selected
# If selector bit is 1 => mask is 111 => sbox2 is selected
const_zero = self.add_constant_component(3, 0b000)
mask = self.add_MODSUB_component([const_zero.id, "selector"], [[0,1,2],[0,1,2]], 3)
not_mask = self.add_NOT_component([mask.id], [[0,1,2]], 3)
self.add_round_output_component([mask.id], [[0, 1, 2]], 3)
sbox1 = self.add_SBOX_component(["plaintext"], [[0, 1, 2]], 3, sbox1)
sbox2 = self.add_SBOX_component(["plaintext"], [[0, 1, 2]], 3, sbox2)
sbox1_masked = self.add_AND_component([sbox1.id, not_mask.id], [[0,1,2], [0,1,2]], 3)
sbox2_masked = self.add_AND_component([sbox2.id, mask.id], [[0,1,2], [0,1,2]], 3)
xor = self.add_XOR_component([sbox1_masked.id, sbox2_masked.id], [[0,1,2], [0,1,2]], 3)
self.add_cipher_output_component([xor.id], [[0, 1, 2]], 3)
cipher = ToyDynamicSbox()
for i in range(8):
plaintext = i
print(f'{plaintext = } ; {cipher.evaluate([plaintext, 0b0]) = }')
print(f'{plaintext = } ; {cipher.evaluate([plaintext, 0b1]) = }')Feel free to use: cipher.evaluate([plaintext, selector], verbosity=True)to print the intermediate values during the execution of evaluate. Hope this helps. |
Beta Was this translation helpful? Give feedback.
Hi @Moh-Gebril, thanks for your question!
Unfortunately, CLAASP does not support the feature you are requesting directly. In CLAASP, the S-box component is defined by a list of integers (in the case of AES, 256 integers) representing the S-box permutation. Each S-box takes one input (the input to the S-box) and returns its output. To perform what you are asking, the S-box should also take a second input, depending on the plaintext (or something else), that selects the desired S-box.
To implement a dynamic S-box selection, you need to build the "selector" circuit that selects the S-box. This can be done in multiple ways, and, ultimately, it depends on how you would like to implement the de…