%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% The Ascon S-box
%
% public domain (CC0 1.0 https://creativecommons.org/publicdomain/zero/1.0/)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\documentclass[11pt]{standalone}

\newif\ifsans
\newif\ifflip

%%% CONFIGURATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% preferably use build.py

%\sanstrue  % for sans-serif fonts (slides, web)
\sansfalse  % for serif fonts (article)

%\fliptrue  % flip to vertical view (top-to-bottom)
\flipfalse  % keep horizontal view (left-to-right)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\ifsans
\renewcommand*\familydefault{\sfdefault}
\usepackage{sfmath}
\fi

\usepackage{tikz}
\usepackage{amsmath, amssymb}

\tikzset{sparsam/.style={inner sep=1pt}}
\ifsans
  \tikzset{next/.style={->, >=latex}}
\else
  \tikzset{next/.style={->, >=latex}}
\fi

\begin{document}
\begin{tikzpicture}
  \ifflip
    \newcommand{\tright}{below}
    \newcommand{\tleft}{above}
    \newcommand{\teast}{south}
    \newcommand{\lognot}{\tikz{\draw[draw=white] (0,-6.5pt) circle (1.2pt); \draw (0,0) node {\rotatebox{0}{$\bigtriangledown$}}; \draw[fill=white] (0,-5pt) circle (1.2pt);}}
  \else
    \newcommand{\tright}{right}
    \newcommand{\tleft}{left}
    \newcommand{\teast}{east}
    \newcommand{\lognot}{\tikz{\draw (0,0) node[left=.8pt] {\rotatebox{90}{$\bigtriangledown$}}; \draw[fill=white] (0,0) circle (1.2pt);}\,}
  \fi

  \ifsans
    \newcommand{\xor}[1]{ node[circle, inner sep=-1.3pt, name={#1}] {\tikz{\draw[] (0,0) circle (3.75pt) +(3.75pt,0) -- +(-3.75pt,0) +(0,3.75pt) -- +(0,-3.75pt);}}}
    \newcommand{\mul}[1]{ node[circle, inner sep=-1.3pt, name={#1}] {\tikz{\draw[] (0,0) circle (3.75pt); \draw[fill=black] (0,0) circle (.7pt);}}}
    \newcommand{\inv}[1]{ node[circle, inner sep=-2.0pt, name={#1}] {\lognot}}
  \else
    \newcommand{\xor}[1]{ node[circle, inner sep=-1.3pt, name={#1}] {$\oplus$}}
    \newcommand{\mul}[1]{ node[circle, inner sep=-1.3pt, name={#1}] {$\odot$}}
    \newcommand{\inv}[1]{ node[circle, inner sep=-2.0pt, name={#1}] {\lognot}}
  \fi

  \newcommand{\word}[1]{-#1*0.8cm}
  \newcommand{\minnext}{.4}


  \ifflip
  \begin{scope}[xscale=-1, rotate=270]
  \else
  \begin{scope}[]
  \fi
  % --- inputs ---
  \pgfmathsetmacro\offset{0}
  \draw (\offset,\word{0}) node[\tleft,sparsam] (x0) {$x_0$};
  \draw (\offset,\word{1}) node[\tleft,sparsam] (x1) {$x_1$};
  \draw (\offset,\word{2}) node[\tleft,sparsam] (x2) {$x_2$};
  \draw (\offset,\word{3}) node[\tleft,sparsam] (x3) {$x_3$};
  \draw (\offset,\word{4}) node[\tleft,sparsam] (x4) {$x_4$};

  % --- input xors ---
  \draw (\minnext,\word{0}) \xor{in0};
  \draw[next] (x0) -- (in0);
  \draw[next] (\minnext,\word{4}) -- (in0);
  \draw (2*\minnext,\word{2}) \xor{in2};
  \draw[next] (x2) -- (in2);
  \draw[next] (2*\minnext,\word{1}) -- (in2);
  \draw (2*\minnext,\word{4}) \xor{in4};
  \draw[next] (x4) -- (in4);
  \draw[next] (2*\minnext,\word{3}) -- (in4);

  % --- nots ---
  \pgfmathsetmacro\offset{\offset + 1.8}
  \draw (\offset,\word{0.5}) \inv{not0};
  \draw (\offset,\word{1.5}) \inv{not1};
  \draw (\offset,\word{2.5}) \inv{not2};
  \draw (\offset,\word{3.5}) \inv{not3};
  \draw (\offset,\word{4.5}) \inv{not4};

  \draw[next] (\offset-\minnext,\word{0}) -- ++(0,\word{0.5}) -- (not0);
  \draw[next] (\offset-\minnext,\word{1}) -- ++(0,\word{0.5}) -- (not1);
  \draw[next] (\offset-\minnext,\word{2}) -- ++(0,\word{0.5}) -- (not2);
  \draw[next] (\offset-\minnext,\word{3}) -- ++(0,\word{0.5}) -- (not3);
  \draw[next] (\offset-\minnext,\word{4}) -- ++(0,\word{0.5}) -- (not4);

  % --- ands ---
  \pgfmathsetmacro\offset{\offset + 1.4*\minnext}
  \draw (\offset,\word{0.5}) \mul{and0};
  \draw (\offset,\word{1.5}) \mul{and1};
  \draw (\offset,\word{2.5}) \mul{and2};
  \draw (\offset,\word{3.5}) \mul{and3};
  \draw (\offset,\word{4.5}) \mul{and4};

  \draw[next] (not0) -- (and0);
  \draw[next] (not1) -- (and1);
  \draw[next] (not2) -- (and2);
  \draw[next] (not3) -- (and3);
  \draw[next] (not4) -- (and4);
  \draw[next] (\offset,\word{1}) -- (and0);
  \draw[next] (\offset,\word{2}) -- (and1);
  \draw[next] (\offset,\word{3}) -- (and2);
  \draw[next] (\offset,\word{4}) -- (and3);
  \draw[next] (\offset-1.15,\word{0}) -- ++(0,\word{5}) -- ++(1.15,0) -- (and4);

  % --- middle xors ---
  \pgfmathsetmacro\offset{\offset + 1.0}
  \draw (\offset,\word{0}) \xor{mid0};
  \draw (\offset,\word{1}) \xor{mid1};
  \draw (\offset,\word{2}) \xor{mid2};
  \draw (\offset,\word{3}) \xor{mid3};
  \draw (\offset,\word{4}) \xor{mid4};

  \draw[next] (in0) -- (mid0);
  \draw[next] ( x1) -- (mid1);
  \draw[next] (in2) -- (mid2);
  \draw[next] ( x3) -- (mid3);
  \draw[next] (in4) -- (mid4);

  \draw[next] (and1.\teast) --+(.1,0) -- (\offset,\word{0.5}) -- (mid0);
  \draw[next] (and2.\teast) --+(.1,0) -- (\offset,\word{1.5}) -- (mid1);
  \draw[next] (and3.\teast) --+(.1,0) -- (\offset,\word{2.5}) -- (mid2);
  \draw[next] (and4.\teast) --+(.1,0) -- (\offset,\word{3.5}) -- (mid3);
  \draw[next] (and0.\teast) --+(.1,0) -- (\offset-.5,\word{4.5}) -- +(.5,0) -- (mid4);

  % --- output xors ---
  \pgfmathsetmacro\offset{\offset + 1.4*\minnext}
  \draw (\offset,\word{1}) \xor{out1};
  \draw[next] (mid1) -- (out1);
  \draw[next] (\offset,\word{0}) -- (out1);
  \draw (\offset,\word{3}) \xor{out3};
  \draw[next] (mid3) -- (out3);
  \draw[next] (\offset,\word{2}) -- (out3);

  \pgfmathsetmacro\offset{\offset + \minnext}
  \draw (\offset,\word{0}) \xor{out0};
  \draw[next] (mid0) -- (out0);
  \draw[next] (\offset,\word{4}) -- (out0);
  
  \pgfmathsetmacro\offset{\offset + \minnext}
  \draw (\offset,\word{2}) \inv{outnot2};
  \draw[next] (mid2) -- (outnot2);

  % --- outputs ---
  \pgfmathsetmacro\offset{\offset + \minnext}
  \draw (\offset,\word{0}) node[\tright,sparsam] (y0) {$x_0$};
  \draw (\offset,\word{1}) node[\tright,sparsam] (y1) {$x_1$};
  \draw (\offset,\word{2}) node[\tright,sparsam] (y2) {$x_2$};
  \draw (\offset,\word{3}) node[\tright,sparsam] (y3) {$x_3$};
  \draw (\offset,\word{4}) node[\tright,sparsam] (y4) {$x_4$};

  \draw[next] (out0) -- (y0);
  \draw[next] (out1) -- (y1);
  \draw[next] (outnot2) -- (y2);
  \draw[next] (out3) -- (y3);
  \draw[next] (mid4) -- (y4);
  \end{scope}
\end{tikzpicture}

\end{document}
