Solution de s-celles pour Sbox

intro hardware circuit

30 novembre 2024

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 :

  1. Premier niveau (portes NOR image ) - 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)
  1. Deuxième niveau (portes XOR image ) - 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}.