3

What I want to do

I want to draw diagrams of operation modes of block ciphers like this one of the ECB mode. I did this before without defining shapes for particular parts of the diagram. However, this time I wanted to do it properly and define shapes for the XOR operation and the blocks of plaintext, ciphertext and IV.

For the XOR operation the question has been asked before. However, I need to define a new shape the blocks of plaintext, ciphertext and IV.

My approach

My approach now is to define a new shape based on the rectangle shape and draw 9 evenly distributed vertical lines inside the rectangle using a for loop. This then yields 10 compartments of the same size inside the rectangle. To do so I calculate the distance between two vertical lines. I then start from the saved anchor north.east and draw 9 vertical lines in the calculated distance. I did this in the following MWE:

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}

\makeatletter
\pgfdeclareshape{block}
{
  \inheritsavedanchors[from=rectangle] % this is a rectanble
  \inheritanchorborder[from=rectangle]
  \inheritanchor[from=rectangle]{north}
  \inheritanchor[from=rectangle]{north west}
  \inheritanchor[from=rectangle]{north east}
  \inheritanchor[from=rectangle]{center}
  \inheritanchor[from=rectangle]{west}
  \inheritanchor[from=rectangle]{east}
  \inheritanchor[from=rectangle]{mid}
  \inheritanchor[from=rectangle]{mid west}
  \inheritanchor[from=rectangle]{mid east}
  \inheritanchor[from=rectangle]{base}
  \inheritanchor[from=rectangle]{base west}
  \inheritanchor[from=rectangle]{base east}
  \inheritanchor[from=rectangle]{south}
  \inheritanchor[from=rectangle]{south west}
  \inheritanchor[from=rectangle]{south east}
  \inheritbackgroundpath[from=rectangle]

  \foregroundpath{
    \setlength{\pgf@ya}{\pgfshapeminheight}
    \setlength{\pgf@xa}{\pgfshapeminwidth}
    \pgfmathsetlength\pgfutil@tempdima{\pgf@xa / 10}
    \pgfpathmoveto{\northeast}
    \foreach \i in {1,...,9}
    {%
      \pgfpathmoveto{\pgfpointadd{\pgfpoint{\pgf@x}{\pgf@y}}{\pgfpoint{-\pgfutil@tempdima}{0pt}}}
      \pgfpathlineto{\pgfpointadd{\pgfpoint{\pgf@x}{\pgf@y}}{\pgfpoint{0pt}{-2\pgf@ya}}}
    }
  }
}

\makeatother


\begin{document}
\tikzset{blockstyle/.style={draw, minimum width = 4cm, minimum height = 0.4cm, shape=block}}
\begin{tikzpicture}
\node[blockstyle] (p1) at (0.1cm,0.1cm)  {};
\node[above] at (p1.north) {Plaintext 1};x
\end{tikzpicture}

\end{document}

The problem

Drawing a block at (0,0) works fine, but as soon as a block is drawn at another position the drawing of the vertical lines is messed up with the lines drawn out of the rectangle as shown in the following picture: enter image description here

Hence my question: What is wrong with the calculation of the drawing of the lines?

EDIT It seems the problems occurs when the node is not placed at (0,0). This might be a hint towards the source of the problem. I adopted the MWE and the text accordingly.

  • @marmot I did just now but it did not change the result. I will edit the MWE accordingly. – Dave Nov 2 '18 at 15:37
  • The \pgfpathmoveto moves the current point to a new position. In this case the old position plus \pgfpoint{-\pgfutil@tempdima}{0pt}. This (should) move the current position \pgfutil@tempdima to the left. \pgfpathlineto then only draws the line without changing the current position if I understood it correctly. – Dave Nov 2 '18 at 15:46
  • Yes \pgfpathmoveto{\northeast} moves the current position to the \northeast-anchor. This is done directly before the for loop. Inside the loop, the current position is moved to the left by \pgfutil@tempdima each iteration. This moves the current position to the left incrementeally. (No problem, have a nice day/evening) – Dave Nov 2 '18 at 15:55
2

I changed the loop to become a bit more explicit, which seems to work. You are right about \pgfpathmoveto{\northeast}. I also gave the shape and node styles different names. (Let me also mention that you could also work with pics and local bounding box).

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}

\makeatletter
\pgfdeclareshape{fblock}
{
  \inheritsavedanchors[from=rectangle] % this is a rectanble
  \inheritanchorborder[from=rectangle]
  \inheritanchor[from=rectangle]{north}
  \inheritanchor[from=rectangle]{north west}
  \inheritanchor[from=rectangle]{north east}
  \inheritanchor[from=rectangle]{center}
  \inheritanchor[from=rectangle]{west}
  \inheritanchor[from=rectangle]{east}
  \inheritanchor[from=rectangle]{mid}
  \inheritanchor[from=rectangle]{mid west}
  \inheritanchor[from=rectangle]{mid east}
  \inheritanchor[from=rectangle]{base}
  \inheritanchor[from=rectangle]{base west}
  \inheritanchor[from=rectangle]{base east}
  \inheritanchor[from=rectangle]{south}
  \inheritanchor[from=rectangle]{south west}
  \inheritanchor[from=rectangle]{south east}
  \inheritbackgroundpath[from=rectangle]

  \foregroundpath{
    \setlength{\pgf@ya}{\pgfshapeminheight}
    \setlength{\pgf@xa}{\pgfshapeminwidth}
    \pgfmathsetlength\pgfutil@tempdima{\pgf@xa / 10}
    \foreach \i in {1,...,9}
    {  
      \pgfpathmoveto{\pgfpointadd{\northeast}{\pgfpoint{-\i*\pgfutil@tempdima}{0pt}}}
      \pgfpathlineto{\pgfpointadd{\northeast}{\pgfpoint{-\i*\pgfutil@tempdima}{-2\pgf@ya}}}
    }
  }
}

\makeatother


\begin{document}
\tikzset{block/.style={draw, minimum width = 4cm, minimum height = 0.4cm,
shape=fblock}}
\begin{tikzpicture}%[every block/.style={draw}]
\node[block] (p1) at (0,0)  {};
\node[above] at (p1.north) {Plaintext 1};
\node[block, left=1.5cm] (iv) at (p1.west) {};
\end{tikzpicture}
\end{document}

enter image description here

  • 1
    Thank you. I didn't knew that one could do calculations inside \pgfpoint. That makes everything a lot simpler! I also found out in the meantime that \pgfpointadd internally uses \pgf@xa which might explain the problem. – Dave Nov 2 '18 at 17:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.