Analyse du circuit
C’est une boîte de substitution (S-box) composée de 8 portes logiques interconnectées, dont 4 NOR et 4 XOR. Le circuit prend une entrée x de 4 bits et produit une sortie y de 4 bits.
Architecture :
- Premier niveau (portes NOR 
) - Signal intermédiaire w : 
w(3) = x(3) nor x(2)
w(2) = x(2) nor x(1)
w(1) = x(1) nor y(3)    # Noter la rétroaction avec y(3)
w(0) = y(3) nor y(2)    # Noter la rétroaction avec y(3) et y(2)
- Deuxième niveau (portes XOR 
) - Signal de sortie y : 
y(3) = x(0) xor w(3)
y(2) = x(3) xor w(2)
y(1) = x(2) xor w(1)
y(0) = x(1) xor w(0)
Caractéristiques importantes :
- Il y a une rétroaction car w(1) et w(0) dépendent des sorties y(3) et y(2)
- Le circuit crée une transformation non-linéaire des entrées
- Cette structure est typique d’une S-box utilisée en cryptographie pour créer de la confusion dans les données
Solution avec du code Verilog
Code Verilog
Le fichier circuit.v est édité dans Visual Studio Code (+ extension Verilog de Masahiro Hiramori).
module circuit_test;
    reg [3:0] x;
    wire [3:0] w, y;
    reg [3:0] y_exp;
    // portes NOR
    nor(w[3], x[3], x[2]);
    nor(w[2], x[2], x[1]);
    nor(w[1], x[1], y[3]);
    nor(w[0], y[3], y[2]);
    // portes XOR
    xor(y[3], x[0], w[3]);
    xor(y[2], x[3], w[2]);
    xor(y[1], x[2], w[1]);
    xor(y[0], x[1], w[0]);
    initial begin
        // Premier test avec x = 4'b1000
        x = 4'b1000;
        y_exp = 4'b0011;
        #10;
        
        if (y !== y_exp) 
            $display("Test 1 failed: y incorrect\n val %b\n exp %b", y, y_exp);
        else
            $display("Test 1 passed: y = %b", y);
            
        // Deuxième test avec x = 4'b1010
        x = 4'b1010;
        #10;
        $display("Test 2 result: y = %b", y);
        
        $display("Test complete");
    end
    
    initial
        $monitor("Time=%0t\nIN  x=%b\n    w=%b\nOUT y=%b\n", $time, x, w, y);
endmodule
Simulation
Le logiciel Icarus Verilog permet de réaliser la simulation https://steveicarus.github.io/iverilog/index.html
Installation sur Kali
$ apt install iverilog
$ iverilog -o circuit circuit.v
$ vvp circuit
Time=0
IN  x=1000
    w=0111
OUT y=0011
Test 1 passed: y = 0011
Time=10
IN  x=1010
    w=0000
OUT y=0101
Test 2 result: y = 0101
Test complete
Le flag est FCSC{0101}.
Solution avec du code VHDL
Code VHDL
Le fichier circuit.vhd est édité avec Visual Studio Code (+ extension VHDL de Pu Zhao).
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use STD.textio.all;
entity circuit_test is
end circuit_test;
architecture behavior of circuit_test is
signal x: std_logic_vector(0 to 3);
signal w: std_logic_vector(0 to 3);
signal y: std_logic_vector(0 to 3);
signal y_exp: std_logic_vector(0 to 3);
-- Fonction simple pour convertir std_logic en character
function to_char(sl: std_logic) return character is
begin
    case sl is
        when '0' => return '0';
        when '1' => return '1';
        when others => return 'X';
    end case;
end function;
-- Fonction pour convertir std_logic_vector en string
function to_str(slv: std_logic_vector) return string is
variable result: string(1 to slv'length);
begin
    for i in slv'range loop
        result(i + 1) := to_char(slv(i));
    end loop;
    return result;
end function;
begin
-- portes NOR
    w(0) <= x(0) nor x(1);
    w(1) <= x(1) nor x(2);
    w(2) <= x(2) nor y(0);
    w(3) <= y(0) nor y(1);
-- portes XOR
    y(0) <= x(3) xor w(0);
    y(1) <= x(0) xor w(1);
    y(2) <= x(1) xor w(2);
    y(3) <= x(2) xor w(3);
-- Process de test
process
begin
    -- Premier test
    x <= "1000";
    y_exp <= "0011";
    wait for 10 ns;
    if (y /= y_exp) then
        report "Test 1 failed: y incorrect" & LF &
        "val " & to_str(y) & LF &
        "exp " & to_str(y_exp);
    else
        report "Test 1 passed: y = " & to_str(y);
    end if;
    -- Deuxième test
    x <= "1010";
    wait for 10 ns;
    report "Test 2 result: y = " & to_str(y);
    report "Test complete";
    wait;
end process;
-- Process pour le monitoring
process(x, w, y)
begin
    report "Time=" & time'image(now) & LF &
    "IN  x=" & to_str(x) & LF &
    "    w=" & to_str(w) & LF &
    "OUT y=" & to_str(y);
end process;
end behavior;
Installation sur Kali
Ajout des paquets Debian Bookworm (2024).
sudo apt-get install ghdl gtkwave
Simulation
Analyse du fichier
$ ghdl -a circuit.vhd
Élaboration de l’entité
$ ghdl -e circuit_test
Lancement de la simulation :
$ ghdl -r circuit_test
circuit.vhd:74:5:@0ms:(report note): Time=0 fs
IN  x=XXXX
    w=XXXX
OUT y=XXXX
circuit.vhd:74:5:@0ms:(report note): Time=0 fs
IN  x=1000
    w=XXXX
OUT y=XXXX
circuit.vhd:74:5:@0ms:(report note): Time=0 fs
IN  x=1000
    w=01XX
OUT y=XXXX
circuit.vhd:74:5:@0ms:(report note): Time=0 fs
IN  x=1000
    w=01XX
OUT y=00XX
circuit.vhd:74:5:@0ms:(report note): Time=0 fs
IN  x=1000
    w=0111
OUT y=00XX
circuit.vhd:74:5:@0ms:(report note): Time=0 fs
IN  x=1000
    w=0111
OUT y=0011
circuit.vhd:60:9:@10ns:(report note): Test 1 passed: y = 0011
circuit.vhd:74:5:@10ns:(report note): Time=10000000 fs
IN  x=1010
    w=0111
OUT y=0011
circuit.vhd:74:5:@10ns:(report note): Time=10000000 fs
IN  x=1010
    w=0001
OUT y=0010
circuit.vhd:74:5:@10ns:(report note): Time=10000000 fs
IN  x=1010
    w=0001
OUT y=0100
circuit.vhd:74:5:@10ns:(report note): Time=10000000 fs
IN  x=1010
    w=0000
OUT y=0100
circuit.vhd:74:5:@10ns:(report note): Time=10000000 fs
IN  x=1010
    w=0000
OUT y=0101
circuit.vhd:66:5:@20ns:(report note): Test 2 result: y = 0101
circuit.vhd:67:5:@20ns:(report note): Test complete
Le flag est FCSC{0101}.