%%
%% Copyright (C) 2024-2026 Anders Andersen, UiT The Arctic University of Norway
%%
%% This file may be distributed and/or modified under the conditions of the
%% LaTeX Project Public License, either version 1.3c of this license or (at
%% your option) any later version. The latest version of this license is in
%%
%%     http://www.latex-project.org/lppl.txt
%%
%% and version 1.3c or later is part of all distributions of LaTeX
%% version 2008-05-04 or later.
%%


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
%%
%% The `aspen` package for simple crypto notation in LaTeX
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\RequirePackage{rcs}
\RCS$Date: 2026/02/06 09:54:33 $
\RCS$RCSfile: aspen.sty,v $
\RCS$Revision: 1.26 $
\RCS$Author: aa $
\typeout{Package: `aspen' v\RCSRevision\space <\RCSRawDate> (AA)}
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{aspen}%[\RCSRawDate]


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Required packages
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Need some help commands and symbols from other packages
\RequirePackage[Mapstochar,Mapsto]{stmaryrd}
\RequirePackage{mathtools}
\RequirePackage{ifthen}
\RequirePackage{suffix}

% Need color support
\RequirePackage[dvipsnames,x11names]{xcolor}

% Use xkeyval to prosess key-val option `color` and `ban` 
\RequirePackage{xkeyval}

% Need to compare strings (lualatex: using `\pdf@strcmp` from `pdftexcmds`)
% From https://tex.stackexchange.com/questions/391735/question-of-ifstrequal-in-etoolbox
\newcommand{\@ifstringequal}[4]{%
  \ifthenelse{\equal{#1}{#2}}{#3}{#4}}

% Some global length changes 
\AtBeginDocument{%
  \setlength{\abovedisplayskip}{-\baselineskip}
  \setlength{\belowdisplayskip}{0pt}
  \setlength{\abovedisplayshortskip}{0pt}
  \setlength{\belowdisplayshortskip}{0pt}}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Option: color, color=style
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% No colors (default)
\def\@@aval#1{#1}	% value
\def\@@apri#1{#1}	% principal
\def\@@akey#1{#1}	% key
\def\@@anonce#1{#1}	% nonce / random
\def\@@ats#1{#1}	% timestamp
\def\@@avar#1{#1}	% variable
\def\@@astr#1{#1}	% string
\def\@@afunc#1{#1}	% function
\def\@@acmd#1{#1}	% code
\def\@@alabel#1{#1}	% label
\def\@@anop#1{\textcolor{black}{#1}}	% binary operator
  
% The default aspen colors
\@namedef{aspen@PY@tok@no}{\def\PY@tc##1{\textcolor{violet}{##1}}}
\@namedef{aspen@PY@tok@na}{\def\PY@tc##1{\textcolor{CadetBlue}{##1}}}
\@namedef{aspen@PY@tok@kt}{\def\PY@tc##1{\textcolor{LightPink4}{##1}}}
\@namedef{aspen@PY@tok@nn}{\def\PY@tc##1{\textcolor{DodgerBlue4}{##1}}}
\@namedef{aspen@PY@tok@nt}{\def\PY@tc##1{\textcolor{Khaki4}{##1}}}
\@namedef{aspen@PY@tok@nv}{\def\PY@tc##1{\textcolor{purple}{##1}}}
\@namedef{aspen@PY@tok@sc}{\def\PY@tc##1{\textcolor{RedViolet}{##1}}}
\@namedef{aspen@PY@tok@nf}{\def\PY@tc##1{\textcolor{teal}{##1}}}
\@namedef{aspen@PY@tok@gp}{\def\PY@tc##1{\textcolor{NavyBlue}{##1}}}
\@namedef{aspen@PY@tok@nl}{\def\PY@tc##1{\textcolor{LightBlue3}{##1}}}
%\@namedef{aspen@PY@tok@nl}{\def\PY@tc##1{\textcolor[rgb]{0.48,0.48,0.80}{##1}}}	% from manni (but darker)

% Introduce colors default
\DeclareOptionX{color}[aspen]{
  \gdef\@@aval##1{\csname #1@PY@tok@no\endcsname \PY@tc{##1}}	%value
  \gdef\@@apri##1{\csname #1@PY@tok@na\endcsname \PY@tc{##1}}	%principal
  \gdef\@@akey##1{\csname #1@PY@tok@kt\endcsname \PY@tc{##1}}	%key
  \gdef\@@anonce##1{\csname #1@PY@tok@nn\endcsname \PY@tc{##1}}	%nonce
  \gdef\@@ats##1{\csname #1@PY@tok@nt\endcsname \PY@tc{##1}}	%timestamp
  \gdef\@@avar##1{\csname #1@PY@tok@nv\endcsname \PY@tc{##1}}	%variable
  \gdef\@@astr##1{\csname #1@PY@tok@sc\endcsname \PY@tc{##1}}	%string
  \gdef\@@afunc##1{\csname #1@PY@tok@nf\endcsname \PY@tc{##1}}	%function
  \gdef\@@acmd##1{\csname #1@PY@tok@gp\endcsname \PY@tc{##1}}	%code
  \gdef\@@alabel##1{\csname #1@PY@tok@nl\endcsname \PY@tc{##1}}	%label
}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Option: ban
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% BAN logic
% From https://gist.github.com/hkkhuang/aae21285714566a5c72c68921f1add9a
% Keke Huang | Doubleke (hkkhuang), Fujian Normal University
% https://gist.github.com/hkkhuang/
% But maybe originally from:
% https://gist.github.com/psoftware/5d9860a86f12edaebe1638e0e12080a2
% Antonio Le Caldare, psoftware www.lecaldare.com
% https://gist.github.com/psoftware

% Option `ban=aa` updates two macros to better match font setup in `aspen-doc`
\DeclareOptionX{ban}[tug]{%
  \newcommand{\believes}{\ensuremath{\,\mid\equiv\,}}
  \newcommand{\sees}{\ensuremath{\,\triangleleft\,}}
  \newcommand{\oncesaid}{\ensuremath{\,\mid\sim\,}}
  %\newcommand{\Controls}{\ensuremath{\,\Rrightarrow\,}}
  \newcommand{\controls}{\ensuremath{\,\Mapsto\,}}
  \newcommand{\fresh}[1]{\ensuremath{\sharp(\aval{##1})}}
  \newcommand{\encryptedwith}[2]{\ensuremath{\{\aval{##2}\}_{\akey{##1}}}}
  \newcommand{\combine}[2]{\ensuremath{{\langle ##1 \rangle}_{##2}}}
  \newcommand{\asharedkey}[1]{\ensuremath{\,\xleftrightarrow{\akey{##1}}\,}}
  \newcommand{\thepubkey}[1]{\ensuremath{\xmapsto{\akey{##1}}\,}}
  \newcommand{\asecret}[1]{\ensuremath{\,\xleftrightharpoons{\aval{##1}}\,}}
  \@ifstringequal{#1}{aa}{%
    \renewcommand{\controls}{\ensuremath{%
        \,\raisebox{0.25pt}{\ensuremath{\Mapstochar}}\kern-2pt\Rightarrow\,}}
    \renewcommand{\thepubkey}[1]{%
      \ensuremath{\mapstochar\kern 1pt\xrightarrow{\akey{##1}}\,}}}{}
  \@ifstringequal{#1}{tug}{%
    \renewcommand{\controls}{\ensuremath{%
        \,\raisebox{0.0pt}{\ensuremath{\Mapstochar}}\kern-2.5pt\Rightarrow\,}}
    \renewcommand{\thepubkey}[1]{%
      \ensuremath{\mapstochar\xrightarrow{\akey{##1}}\,}}}{}}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Notation variants
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% pubkey and privkey (trad means traditional key notation)
\gdef\@pubkeynotation{aspen}
\DeclareOptionX{tradpubkey}[trad]{%
  \gdef\@pubkeynotation{#1}}
\gdef\@privkeynotation{aspen}
\DeclareOptionX{tradprivkey}[trad]{%
  \gdef\@privkeynotation{#1}}

% Concatenation operator
\newcommand{\adotconcat}{\;\mathbin{.}\;}
\newcommand{\adblbarconcat}{\;\mathbin{\|}\;}
\newcommand{\aplusconcat}{\;\mathbin{+}\;}
\let\@aconcat\adotconcat	% Default
\DeclareOptionX{concat}[dot]{%
  \@ifstringequal{#1}{dot}{\global\let\@aconcat\adotconcat}{%
    \@ifstringequal{#1}{dblbar}{\global\let\@aconcat\adblbarconcat}{%%
      \@ifstringequal{#1}{plus}{\global\let\@aconcat\aplusconcat}{}}}}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Process all options
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\ProcessOptionsX


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Dumped from pygments (with unique commands for each given style)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% pygmentsstyles


\def\PY@reset{\let\PY@it=\relax \let\PY@bf=\relax%
    \let\PY@ul=\relax \let\PY@tc=\relax%
    \let\PY@bc=\relax \let\PY@ff=\relax}
\def\PY@tok#1{\csname PY@tok@#1\endcsname}
\def\PY@toks#1+{\ifx\relax#1\empty\else%
    \PY@tok{#1}\expandafter\PY@toks\fi}
\def\PY@do#1{\PY@bc{\PY@tc{\PY@ul{%
    \PY@it{\PY@bf{\PY@ff{#1}}}}}}}
\def\PY#1#2{\PY@reset\PY@toks#1+\relax+\PY@do{#2}}


\@namedef{autumn@PY@tok@kt}{\def\PY@tc##1{\textcolor[rgb]{0.00,0.67,0.67}{##1}}}
\@namedef{autumn@PY@tok@nf}{\def\PY@tc##1{\textcolor[rgb]{0.00,0.67,0.00}{##1}}}
\@namedef{autumn@PY@tok@nn}{\let\PY@ul=\underline\def\PY@tc##1{\textcolor[rgb]{0.00,0.67,0.67}{##1}}}
\@namedef{autumn@PY@tok@nv}{\def\PY@tc##1{\textcolor[rgb]{0.67,0.00,0.00}{##1}}}
\@namedef{autumn@PY@tok@no}{\def\PY@tc##1{\textcolor[rgb]{0.67,0.00,0.00}{##1}}}
\@namedef{autumn@PY@tok@na}{\def\PY@tc##1{\textcolor[rgb]{0.12,0.56,1.00}{##1}}}
\@namedef{autumn@PY@tok@nt}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.12,0.56,1.00}{##1}}}
\@namedef{autumn@PY@tok@gp}{\def\PY@tc##1{\textcolor[rgb]{0.33,0.33,0.33}{##1}}}
\@namedef{autumn@PY@tok@sc}{\def\PY@tc##1{\textcolor[rgb]{0.67,0.33,0.00}{##1}}}


\@namedef{colorful@PY@tok@kt}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.20,0.20,0.60}{##1}}}
\@namedef{colorful@PY@tok@nf}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.40,0.73}{##1}}}
\@namedef{colorful@PY@tok@nn}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.05,0.52,0.71}{##1}}}
\@namedef{colorful@PY@tok@nv}{\def\PY@tc##1{\textcolor[rgb]{0.60,0.40,0.20}{##1}}}
\@namedef{colorful@PY@tok@no}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.20,0.40}{##1}}}
\@namedef{colorful@PY@tok@nl}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.60,0.47,0.00}{##1}}}
\@namedef{colorful@PY@tok@na}{\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.80}{##1}}}
\@namedef{colorful@PY@tok@nt}{\def\PY@tc##1{\textcolor[rgb]{0.00,0.47,0.00}{##1}}}
\@namedef{colorful@PY@tok@sc}{\def\PY@tc##1{\textcolor[rgb]{0.00,0.27,0.87}{##1}}}
\@namedef{colorful@PY@tok@gp}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.78,0.36,0.04}{##1}}}


\@namedef{default@PY@tok@kt}{\def\PY@tc##1{\textcolor[rgb]{0.69,0.00,0.25}{##1}}}
\@namedef{default@PY@tok@nf}{\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,1.00}{##1}}}
\@namedef{default@PY@tok@nn}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,1.00}{##1}}}
\@namedef{default@PY@tok@nv}{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}}
\@namedef{default@PY@tok@no}{\def\PY@tc##1{\textcolor[rgb]{0.53,0.00,0.00}{##1}}}
\@namedef{default@PY@tok@nl}{\def\PY@tc##1{\textcolor[rgb]{0.46,0.46,0.00}{##1}}}
\@namedef{default@PY@tok@na}{\def\PY@tc##1{\textcolor[rgb]{0.41,0.47,0.13}{##1}}}
\@namedef{default@PY@tok@nt}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\@namedef{default@PY@tok@gp}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.50}{##1}}}
\@namedef{default@PY@tok@sc}{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}


\@namedef{emacs@PY@tok@kt}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.73,0.00}{##1}}}
\@namedef{emacs@PY@tok@nf}{\def\PY@tc##1{\textcolor[rgb]{0.00,0.63,0.00}{##1}}}
\@namedef{emacs@PY@tok@nn}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,1.00}{##1}}}
\@namedef{emacs@PY@tok@nv}{\def\PY@tc##1{\textcolor[rgb]{0.72,0.53,0.04}{##1}}}
\@namedef{emacs@PY@tok@no}{\def\PY@tc##1{\textcolor[rgb]{0.53,0.00,0.00}{##1}}}
\@namedef{emacs@PY@tok@nl}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.00}{##1}}}
\@namedef{emacs@PY@tok@na}{\def\PY@tc##1{\textcolor[rgb]{0.73,0.27,0.27}{##1}}}
\@namedef{emacs@PY@tok@nt}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\@namedef{emacs@PY@tok@gp}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.50}{##1}}}
\@namedef{emacs@PY@tok@sc}{\def\PY@tc##1{\textcolor[rgb]{0.73,0.27,0.27}{##1}}}


\@namedef{friendly@PY@tok@kt}{\def\PY@tc##1{\textcolor[rgb]{0.56,0.13,0.00}{##1}}}
\@namedef{friendly@PY@tok@nf}{\def\PY@tc##1{\textcolor[rgb]{0.02,0.16,0.49}{##1}}}
\@namedef{friendly@PY@tok@nn}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.05,0.52,0.71}{##1}}}
\@namedef{friendly@PY@tok@nv}{\def\PY@tc##1{\textcolor[rgb]{0.73,0.38,0.84}{##1}}}
\@namedef{friendly@PY@tok@no}{\def\PY@tc##1{\textcolor[rgb]{0.38,0.68,0.84}{##1}}}
\@namedef{friendly@PY@tok@nl}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.13,0.44}{##1}}}
\@namedef{friendly@PY@tok@na}{\def\PY@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}
\@namedef{friendly@PY@tok@nt}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.02,0.16,0.45}{##1}}}
\@namedef{friendly@PY@tok@gp}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.78,0.36,0.04}{##1}}}
\@namedef{friendly@PY@tok@sc}{\def\PY@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}


\@namedef{fruity@PY@tok@nt}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.98,0.40,0.04}{##1}}}
\@namedef{fruity@PY@tok@nv}{\def\PY@tc##1{\textcolor[rgb]{0.98,0.40,0.04}{##1}}}
\@namedef{fruity@PY@tok@na}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{1.00,0.00,0.53}{##1}}}
\@namedef{fruity@PY@tok@nf}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{1.00,0.00,0.53}{##1}}}
\@namedef{fruity@PY@tok@kt}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.80,0.79,0.66}{##1}}}
\@namedef{fruity@PY@tok@no}{\def\PY@tc##1{\textcolor[rgb]{0.00,0.53,0.82}{##1}}}
\@namedef{fruity@PY@tok@nl}{\def\PY@tc##1{\textcolor[rgb]{1.00,1.00,1.00}{##1}}}
\@namedef{fruity@PY@tok@nn}{\def\PY@tc##1{\textcolor[rgb]{1.00,1.00,1.00}{##1}}}
\@namedef{fruity@PY@tok@sc}{\def\PY@tc##1{\textcolor[rgb]{0.00,0.53,0.82}{##1}}}
\@namedef{fruity@PY@tok@gp}{\def\PY@tc##1{\textcolor[rgb]{1.00,1.00,1.00}{##1}}}


\@namedef{gruvboxlight@PY@tok@nv}{\def\PY@tc##1{\textcolor[rgb]{0.03,0.40,0.47}{##1}}}
\@namedef{gruvboxlight@PY@tok@no}{\def\PY@tc##1{\textcolor[rgb]{0.56,0.25,0.44}{##1}}}
\@namedef{gruvboxlight@PY@tok@nf}{\def\PY@tc##1{\textcolor[rgb]{0.26,0.48,0.35}{##1}}}
\@namedef{gruvboxlight@PY@tok@nn}{\def\PY@tc##1{\textcolor[rgb]{0.26,0.48,0.35}{##1}}}
\@namedef{gruvboxlight@PY@tok@nt}{\def\PY@tc##1{\textcolor[rgb]{0.26,0.48,0.35}{##1}}}
\@namedef{gruvboxlight@PY@tok@na}{\def\PY@tc##1{\textcolor[rgb]{0.71,0.46,0.08}{##1}}}
\@namedef{gruvboxlight@PY@tok@gp}{\def\PY@tc##1{\textcolor[rgb]{0.49,0.44,0.39}{##1}}}
\@namedef{gruvboxlight@PY@tok@kt}{\def\PY@tc##1{\textcolor[rgb]{0.62,0.00,0.02}{##1}}}
\@namedef{gruvboxlight@PY@tok@sc}{\def\PY@tc##1{\textcolor[rgb]{0.47,0.45,0.05}{##1}}}


\@namedef{manni@PY@tok@kt}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.47,0.53}{##1}}}
\@namedef{manni@PY@tok@nf}{\def\PY@tc##1{\textcolor[rgb]{0.80,0.00,1.00}{##1}}}
\@namedef{manni@PY@tok@nn}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.80,1.00}{##1}}}
\@namedef{manni@PY@tok@nv}{\def\PY@tc##1{\textcolor[rgb]{0.00,0.20,0.20}{##1}}}
\@namedef{manni@PY@tok@no}{\def\PY@tc##1{\textcolor[rgb]{0.20,0.40,0.00}{##1}}}
\@namedef{manni@PY@tok@nl}{\def\PY@tc##1{\textcolor[rgb]{0.60,0.60,1.00}{##1}}}
\@namedef{manni@PY@tok@na}{\def\PY@tc##1{\textcolor[rgb]{0.20,0.00,0.60}{##1}}}
\@namedef{manni@PY@tok@nt}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.20,0.00,0.60}{##1}}}
\@namedef{manni@PY@tok@gp}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.60}{##1}}}
\@namedef{manni@PY@tok@sc}{\def\PY@tc##1{\textcolor[rgb]{0.80,0.20,0.00}{##1}}}


\@namedef{staroffice@PY@tok@kt}{\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.50}{##1}}}
\@namedef{staroffice@PY@tok@na}{\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\@namedef{staroffice@PY@tok@no}{\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\@namedef{staroffice@PY@tok@nf}{\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\@namedef{staroffice@PY@tok@nl}{\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\@namedef{staroffice@PY@tok@nn}{\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\@namedef{staroffice@PY@tok@nt}{\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\@namedef{staroffice@PY@tok@nv}{\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\@namedef{staroffice@PY@tok@sc}{\def\PY@tc##1{\textcolor[rgb]{0.93,0.00,0.00}{##1}}}
\@namedef{staroffice@PY@tok@gp}{\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.50}{##1}}}



\def\PYZbs{\char`\\}
\def\PYZus{\char`\_}
\def\PYZob{\char`\{}
\def\PYZcb{\char`\}}
\def\PYZca{\char`\^}
\def\PYZam{\char`\&}
\def\PYZlt{\char`\<}
\def\PYZgt{\char`\>}
\def\PYZsh{\char`\#}
\def\PYZpc{\char`\%}
\def\PYZdl{\char`\$}
\def\PYZhy{\char`\-}
\def\PYZsq{\char`\'}
\def\PYZdq{\char`\"}
\def\PYZti{\char`\~}
% for compatibility with earlier versions
\def\PYZat{@}
\def\PYZlb{[}
\def\PYZrb{]}




%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Values, variables, strings, functions and commands (code)
% The @@ methods implement the colors, and the @ methods implement the styles
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% The name of the package
\newcommand{\aspen}{\textsc{Aspen}}

% Session mark
\def\smark{'}
\def\@smark{'}

% A value
\def\@aval#1{\ensuremath{#1}}
\def\aval#1{\@@aval{\@aval{#1}}}

% A principal
\def\@apri#1{\ensuremath{#1}}
\def\apri#1{\@@apri{\@apri{#1}}}

% A key
\def\@akey#1{\ensuremath{#1}}
\def\akey#1{\@@akey{\@akey{#1}}}

% A nonce
\def\@anonce#1{\ensuremath{#1}}
\def\anonce#1{\@@anonce{\@anonce{#1\smark}}}
%\def\nonce#1{\anonce{N_{#1}}}
\NewDocumentCommand{\nonce}{O{N}m}{\anonce{#1_{#2}}}

% An index or counter
\def\acounter#1{\@@anonce{\@anonce{#1}}}
\NewDocumentCommand{\counter}{O{I}m}{\acounter{#1_{#2}}}

% A random value
\NewDocumentCommand\arandom{t'm}{%
  \IfBooleanTF{#1}{}{\global\let\smark\empty}%
  \anonce{#2}%
  \global\let\smark\@smark}
\NewDocumentCommand\random{t'O{R}m}{%
  \IfBooleanTF{#1}{\arandom'{#2_{#3}}}{\arandom{#2_{#3}}}}

% A time stamp or other time related values
\def\@ats#1{\ensuremath{#1}}
\def\ats#1{\@@ats{\@ats{#1}}}
\NewDocumentCommand{\ts}{O{T}m}{\ats{#1_{#2}}}
\let\attl\ats
\NewDocumentCommand{\ttl}{O{L}m}{\attl{#1_{#2}}}

% A variable
\def\@avar#1{\ensuremath{#1}}
\def\avar#1{\@@avar{\@avar{#1}}}

% A text string
\def\@astr#1{\ensuremath{\textrm{``\texttt{#1}''}}}
\def\astr#1{\@@astr{\@astr{#1}}}

% A function
\def\@afunc#1{\ensuremath{#1}}
\def\afunc#1{\@@afunc{\@afunc{#1}}}

% A command (code)
\def\@acmd#1{\ensuremath{\texttt{#1}}}
\def\acmd#1{\@@acmd{\@acmd{#1}}}

% A label
\def\@alabel#1{\ensuremath{#1}}
\def\alabel#1{\@@alabel{\@alabel{#1}}}

% A references to a label
\def\aref#1{\@@alabel{\@alabel{\ref{#1}}}}

% A binary operator
\def\@anop#1{\ensuremath{#1}}
\def\anop#1{\@@anop{\@anop{#1}}}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
% Help functions/commands
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Parse each function argument as a value
% Inspired by: https://tex.stackexchange.com/questions/87407/iterating-through-comma-separated-arguments
\newcommand{\@fargs}[1]{%
  \def\nextitem{\def\nextitem{,}}% Separator
  \renewcommand*{\do}[1]{\nextitem\aval{##1}}% How to process each item
  \docsvlist{#1}% Process list
}

% Some scaled sizes
\newcommand{\@ssscript}[1]{\raisebox{1.5pt}{\scalebox{.25}{$\mathbf{#1}$}}}
\newcommand{\@sscript}[1]{\raisebox{2pt}{\scalebox{.55}{$\mathbf{#1}$}}}

% Command that eat its arguments
\newcommand{\@eatit}[1]{}

% Help function used to handle the markers (used in all commands with markers)
\global\let\@tkey\empty
\newcommand{\@setmarker}[5]{% t-t+t!
  % #1		-> true, if marker * is used (no specific type of key / manually specify key type)
  % #2		-> true, if marker - is used (private key)
  % #3		-> true, if marker + is used (public key)
  % #4		-> true, if marker ! is used (no specific, but key of a principal/name)
  % #5		-> true, if marker ' is used (session key)
  % <none>	-> true, if no marker is used (secret/shared/symmetric key)
  \let\@bckp@tkey\@tkey%
  \IfBooleanTF{#1}{\global\let\@tkey\akey}{%
    \IfBooleanTF{#2}{\global\let\@tkey\privkey}{%
      \IfBooleanTF{#3}{\global\let\@tkey\pubkey}{%
        \IfBooleanTF{#4}{\global\let\@tkey\aname}{%
          \IfBooleanTF{#5}{\global\let\@tkey\sessionkey}{%
            \global\let\@tkey\sharedkey}}}}}}
\newcommand{\@restoremarker}{\global\let\@tkey\@bckp@tkey}

% Create different sizes of parenthesis/braces/brackets
% From https://tex.stackexchange.com/questions/389989/how-to-get-really-big-curly-braces
\newcommand\@makebig[2]{%
  \@xp\newcommand\@xp*\csname#1\endcsname{\bBigg@{#2}}%
  \@xp\newcommand\@xp*\csname#1l\endcsname{\@xp\mathopen\csname#1\endcsname}%
  \@xp\newcommand\@xp*\csname#1r\endcsname{\@xp\mathclose\csname#1\endcsname}%
}
\@makebig{biggg}  {3.0}
\@makebig{Biggg}  {3.5}
\@makebig{bigggg} {4.0}
\@makebig{Bigggg} {5.0}
\@makebig{biggggg}{5.5}
\@makebig{Biggggg}{6.0}

% Help function used to handle the different sized brackets (given as an
% optional argument in many of the commands below: big, Big, bigg, Bigg, ...)
\newcommand{\@getbracket}[2]{%
  % #1		-> size
  % #2		-> bracket (type)
  \IfNoValueTF{#1}{#2}{\csname #1\endcsname #2}}

% Help function for better spaces around commas in key labels
% https://tex.stackexchange.com/questions/225919/how-to-split-input-string-in-a-latex-command
\protected\def\averythinspace{%
  \ifmmode
    \mskip0.5\thinmuskip
  \fi}
\def\@ascomma{,\averythinspace}
\newcommand\@acs[1]{%
  \let\@acomma\empty
  \@for\tmp:=#1\do{\@acomma\tmp\let\@acomma\@ascomma}}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% The crypto notation commands
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%
% Crypto keys: \key, \sharedkey, \sessionkey, \pubkey, \privkey
%

% A public key (of a public-private key pair): \pubkey / \key+
% \newcommand{\@pubkey}[1]{\@key{#1}}
\newcommand{\@newpubkey}[2]{\ensuremath{#1_{\@acs{#2}}^{\@sscript{+}}}}	% The new notation
\newcommand{\@tradpubkey}[2]{\ensuremath{#1_{\@acs{#2}}}}		% The traditional notation
\@ifstringequal{\@pubkeynotation}{trad}{% Choose new or traditional
  \let\@pubkey\@tradpubkey}{\let\@pubkey\@newpubkey}
\NewDocumentCommand{\pubkey}{O{K}m}{% The user command (use this or `\key+`)
  % #1		-> Key symbol (default K)
  % #2		-> Label of key (owner of key)
  \akey{\@pubkey{#1}{#2}}}

% A private key (of a public-private key pair): \sprivkey
% with smaller -1 superscript (this command is rarely used)
\newcommand{\@newsprivkey}[2]{\ensuremath{#1_{\@acs{#2}}^{\@sscript{-}}}}	% The new notation
\newcommand{\@tradsprivkey}[2]{\ensuremath{#1_{\@acs{#2}}^{\@ssscript{-1}}}}% The traditional notation
\@ifstringequal{\@privkeynotation}{trad}{% Choose new or traditional
  \let\@sprivkey\@tradsprivkey}{\let\@sprivkey\@newsprivkey}
\NewDocumentCommand{\sprivkey}{O{K}m}{% The user command
  % #1		-> Key symbol (default K)
  % #2		-> Label of key (owner of key)
  \akey{\@sprivkey{#1}{#2}}}

% A private key (of a public-private key pair): \privkey / \key-
\newcommand{\@newprivkey}[2]{\ensuremath{#1_{\@acs{#2}}^{\@sscript{-}}}}	% The new notation
\newcommand{\@tradprivkey}[2]{\ensuremath{#1_{\@acs{#2}}^{\@sscript{-1}}}}	% The traditional notation
\@ifstringequal{\@privkeynotation}{trad}{% Choose new or traditional
  \let\@privkey\@tradprivkey}{\let\@privkey\@newprivkey}
\NewDocumentCommand{\privkey}{O{K}m}{% The user command (use this or `\key-`)
  % #1		-> Key symbol (default K)
  % #2		-> Label of key (owner of key)
  \akey{\@privkey{#1}{#2}}}

% A shared (secret) key: \sharedkey / \key*
\newcommand{\@sharedkey}[2]{%
  \let\@sgnc\@groupnamecmd	% To correctly typeset shared key for a group
  \let\@groupnamecmd\akey	% (typeset the group as a key, and not as a group name)
  \ensuremath{#1_{\@acs{#2}}}%
  \let\@groupnamecmd\@sgnc}	% Restore group name
\NewDocumentCommand{\sharedkey}{O{K}m}{% The user command (use this or `\key*`)
  % #1		-> Key symbol (default K)
  % #2		-> Label of key (owner of key)
  \akey{\@sharedkey{#1}{#2}}}

% A session key (a shared/secret key for a session): \sessionkey / \key'
\NewDocumentCommand{\sessionkey}{O{K}m}{% The user command (use this or `\key*`)
  % #1		-> Key symbol (default K)
  % #2		-> Label of key (owner of key)
  \akey{\@sharedkey{#1}{#2}\smark}}

% The generic key: \key (including `\key*`, `\key+`, `\key-`, and `\key!`)
\NewDocumentCommand\key{st-t+t!t'm}{%
  % #1			-> true, if marker * is used (no specific/manually specify, key type)
  % #2			-> true, if marker - is used (private key)
  % #3			-> true, if marker + is used (public key)
  % #4			-> true, if marker ! is used (key associated with principal)
  % #5			-> true, if marker ' is used (session key)
  % <none>		-> #1-#5 false, if no marker is used (symmetric/shared key)
  % #6			-> Key label
  \@setmarker{#1}{#2}{#3}{#4}{#5}%
  \akey{\@tkey{#6}}%
  \@restoremarker}


%
% A name (in square brackets): \aname (used, for example, in the context of signed by whom)
% A function name: \afname
%
\newcommand{\aname}[1]{\apri{[#1\/]}}
\newcommand{\afname}[1]{\afunc{\textit{#1}}}


%
% Boolean values true and false: \atrue, \afalse
%
\newcommand{\@atrue}{\textit{true}}
\newcommand{\atrue}{\aval{\@atrue}}
\newcommand{\@afalse}{\textit{false}}
\newcommand{\afalse}{\aval{\@afalse}}

%
% Operators
%
\newcommand{\@axor}{\;\oplus\;}
\newcommand{\axor}{\anop{\@axor}}
\newcommand{\aconcat}{\anop{\@aconcat}}


%
% «if, then» and «if, and only if, then»: \aifthen, \aiffthen
%
\newcommand{\aifthen}{\ensuremath{\Rightarrow}}
\newcommand{\aiffthen}{\ensuremath{\Leftrightarrow}}


%
% Produces (typically, functions): \produces, \ret
%
\newcommand{\produces}{\ensuremath{\rightarrow}}
\newcommand{\returns}[1]{\ensuremath{{}\produces\aval{#1}}}
\newcommand{\ret}{\returns{\empty}}


%
% If optional return value is given, typeset it
%
\def\@getreturn[#1]{\returns{#1}}
\newcommand\@hasreturn{%
  \@ifnextchar[{\@getreturn}{}}


%
% Sends (typically, messages): \sends
%
\newcommand{\sends}{\ensuremath{\longrightarrow}}
\newcommand{\csends}{\ensuremath{\rightarrow}}
\let\@sends\sends
\let\@sopspc\empty


%
% Structured values
%

% A structured value (or message): \sval, \msg
\NewDocumentCommand\sval{O{}m}{%
  % #1		-> Size of brackets (optional)
  % #2		-> The content of the message
  \aval{\@getbracket{#1}{\{}#2\@getbracket{#1}{\}}}}
\let\msg\sval

% The typed structured value
\NewDocumentCommand\tval{sO{}mE{_}{}m}{%
  \aval{\textit{#3\/}%
    \IfValueT{#4}{_{\textit{#4}}}%
    \IfBooleanTF{#1}{#5}{\@getbracket{#2}{\{}#5\@getbracket{#2}{\}}}}}

% Help function for \mktval
\NewDocumentCommand\@tval{sO{}E{_}{}m}{%
  \IfBooleanTF{#1}{%
    \tval*[#2]{\@currenttypename}_{#3}{#4}}{%
    \tval[#2]{\@currenttypename}_{#3}{#4}}}

% Help function for encrypted values (expected that \@setmarker is called)
\NewDocumentCommand\@encrypted{O{}E{_}{}mm}{%
  \ensuremath{\tval[#1]{}_{#2}{#4}_{\@tkey{#3}}}}

% Help function for encrypted values (expected that \@setmarker is called)
\NewDocumentCommand\@signed{O{}E{_}{}mm}{%
  \ensuremath{\tval[#1]{}_{#2}{#4}^{\@tkey{#3}}}}

% Help function for \mketval
\NewDocumentCommand\@etval{st-t+t!t'O{}E{_}{}mm}{%
  \@setmarker{#1}{#2}{#3}{#4}{#5}%
  \tval*{\@currenttypename}_{#7}{\@encrypted[#6]{#8}{#9}}%
  \@restoremarker}

% Help function for \mkstval
\NewDocumentCommand\@stval{st-t+t!t'O{}E{_}{}mm}{%
  \@setmarker{#1}{#2}{#3}{#4}{#5}%
  \tval*{\@currenttypename}_{#7}{\@signed[#6]{#8}{#9}}%
  \@restoremarker}

% Create a new type of typed structured value
\NewDocumentCommand\mktval{om}{%
  \IfValueTF{#1}{%
    \@namedef{#1}{\gdef\@currenttypename{#2}\@tval}}{%
    \@namedef{tval#2}{\gdef\@currenttypename{#2}\@tval}}}

% Create a new type of encrypted typed structured value
\NewDocumentCommand\mketval{om}{%
  \IfValueTF{#1}{%
    \@namedef{#1}{\gdef\@currenttypename{#2}\@etval}}{%
    \@namedef{etval#2}{\gdef\@currenttypename{#2}\@etval}}}

% Create a new type of signed typed structured value
\NewDocumentCommand\mkstval{om}{%
  \IfValueTF{#1}{%
    \@namedef{#1}{\gdef\@currenttypename{#2}\@stval}}{%
    \@namedef{stval#2}{\gdef\@currenttypename{#2}\@stval}}}


%
% Functions
%

% A function: \func
\NewDocumentCommand\func{O{}mE{_}{}m}{%
  % #1		-> Size (of brackets)
  % #2		-> Function name
  % #3		-> Markers (more details)
  % #4		-> Function arguments
  % #5		-> Function return values (optional)
  \ensuremath{%
    \afunc{%
      \textit{#2\/}%
      \IfValueT{#3}{_{\aval{\textit{#3}}}}%
      \@getbracket{#1}{(}%
      \@fargs{#4}%
      \@getbracket{#1}{)}}}%
  \@hasreturn}

% Help function for \mkfunc
\NewDocumentCommand\@func{O{}E{_}{}m}{%
  % #1		-> Size (of brackets)
  % #2		-> Markers (more details)
  % #3		-> Function arguments
  % #4		-> Function return values (optional)
  \func[#1]{\@currentfuncname}_{#2}{#3}}

% Create a new type of function
\NewDocumentCommand\mkfunc{om}{%
  \IfValueTF{#1}{%
    \@namedef{#1}{\gdef\@currentfuncname{#2}\@func}}{%
    \@namedef{func#2}{\gdef\@currentfuncname{#2}\@func}}}

% Help functions for \mkkfunc
\NewDocumentCommand\@kfunc{st-t+t!t'O{}E{_}{}mm}{%
  \@setmarker{#1}{#2}{#3}{#4}{#5}%
  \func[#6]{\@currentfuncname}_{#7}{\@tkey{#8},#9}%
  \@restoremarker
  \@hasreturn}

% Create a new type of function where first argument is a key
\NewDocumentCommand\mkkfunc{om}{%
  \IfValueTF{#1}{%
    \@namedef{#1}{\gdef\@currentfuncname{#2}\@kfunc}}{%
    \@namedef{func#2}{\gdef\@currentfuncname{#2}\@kfunc}}}


%
% Send a message from a sender to a receiver: \send
%

% Wrap data sent in a message
\NewDocumentCommand\@sendmsg{O{}m}{\msg[#1]{#2}}

% Do not wrap data sent in a message
\NewDocumentCommand\@ssendmsg{O{}m}{#2}

% Send a message #5 from #3 to #4
\NewDocumentCommand\send{sO{}mmm}{%
  % #1		-> Do not wrap in message (if * given)
  % #2		-> Size of brackets (optional)
  % #3		-> Send message from (the sender)
  % #4		-> Send message to (the receiver)
  % #5		-> The content of the message
  \ensuremath{\apri{#3}\@sopspc\@sends\@sopspc\apri{#4}\@sopspc:\@sopspc
    \IfBooleanTF{#1}{\@ssendmsg{#5}}{\@sendmsg[#2]{#5}}}}

% A more compact version of send (needs less space)
\NewDocumentCommand\csend{sO{}mmm}{%
  \let\@sends\csends
  \let\@sopspc\!
  \IfBooleanTF{#1}{\send*[#2]{#3}{#4}{#5}}{\send[#2]{#3}{#4}{#5}}%
  \let\@sends\sends
  \let\@sopspc\empty}

% Save the original \send so it can be restored when it is changed (in the `steps` environment)
\let\@send\send


%
% A group: \agroup
%
\let\@groupnamecmd\apri
\NewDocumentCommand\agroup{sO{1}O{n}m}{%
  % #1		-> If set, use ... to span group, otherwise use -- (*)
  % #2		-> Start index of group members (optional, default 1)
  % #3		-> End index of group members (optional, default n)
  % #4		-> Name of group
  \IfBooleanTF{#1}%
  {\ensuremath{\@groupnamecmd{#4_{#2}},\ldots,\@groupnamecmd{#4_{#3}}}}%
  {\ensuremath{\@groupnamecmd{#4_{#2}}\text{--}\@groupnamecmd{#4_{#3}}}}}


%
% Commands for encryption/decryption: \encrypted, \encrypt, \decrypt
%

% The text used for the encrypt and decrypt functions
\newcommand{\encrypttext}{Encrypt}
\newcommand{\decrypttext}{Decrypt}

% An encrypted message
\mketval[encrypted]{}

% The encrypt function
\mkkfunc[encrypt]{\encrypttext}

% The decrypt function
\mkkfunc[decrypt]{\decrypttext}


%
% Cryptographic hash value: \hash
%

% The text used for the hash value and function
\newcommand{\hashtext}{H}
\newcommand{\hashfunctext}{H}

% A cryptographic hash value 
\mktval[chash]{\hashtext}
  
% A cryptographic hash function
\mkfunc[chashf]{\hashfunctext}


%
% Message authentication code: \mac, \cmac, \hmac
%

% The text used for the hash value and function
\newcommand{\mactext}{MAC}
\newcommand{\macfunctext}{\mactext}
\newcommand{\cmactext}{CMAC}
\newcommand{\cmacfunctext}{\cmactext}
\newcommand{\hmactext}{HMAC}
\newcommand{\hmacfunctext}{\hmactext}

% Message authentication code 
\mkstval[mac]{\mactext}

% Message authentication code function
\mkkfunc[macf]{\macfunctext}

% Message authentication code 
\mkstval[cmac]{\cmactext}

% Message authentication code function
\mkkfunc[cmacf]{\cmacfunctext}

% Message authentication code 
\mkstval[hmac]{\hmactext}

% Message authentication code function
\mkkfunc[hmacf]{\hmacfunctext}


% 
% Signatures, signing, and signed messages: \sig, \sign, \signed
%

% The text used for the signature type and sign function
\newcommand{\sigtext}{Sig}
\newcommand{\sigfunctext}{Sig}
\newcommand{\signtext}{Sign}

% A signature value
\mkstval[sig]{\sigtext}

% A signature function
\mkkfunc[sigf]{\sigfunctext}

% The sign function
\mkkfunc[sign]{\signtext}

% A signed message
\mkstval[signed]{}


%
% Verify: \verify
%

% The text used for the verify function
\newcommand{\verifytext}{Verify}

% The verify function
\mkkfunc[verify]{\verifytext}


%
% Certificate: \certificate
%

% The text used for the certificate type
\newcommand{\certtext}{Cert}

% A certificate value
\mkstval[certificate]{\certtext}

% A certificate value
\NewDocumentCommand\cert{st-t+t!t'O{}E{_}{}mm}{%
  \@setmarker{#1}{#2}{#3}{#4}{#5}%
  \tval*{\certtext}_{#7}{\@signed[#6]{#8}{\apri{#9},\pubkey{#9}}}%
  \@restoremarker}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% The `steps` environment is a list with different types of numbered items
% (default S with \astep and M with \send)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%
% Counters are used to number each types of steps (and be able to refer to them)
%

% Check if a counter is defined: \ifcounter{counter}{do if defined}{do if not defined)
\newcommand*\ifcounter[1]{%
  \ifcsname c@#1\endcsname
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
}

% We are counting each series of steps (each `steps` environment)
\newcounter{mlistcounter}

% Reset the listed counters in series of steps (and create counter if
% it does not exits)
\NewDocumentCommand\reset@or@create@counter{sm}{%
  \ifcounter{counter#2}{% Does this counter exist?
    \IfBooleanTF{#1}{}{\setcounter{counter#2}{0}}% Do not reset counters for steps*
  }{%
    \newcounter{counter#2}[mlistcounter]% If counter do not exist, create it
  }%
  \@namedef{acounter#2}{\stepcounter{counter#2}\arabic{counter#2}}% Command to step+present counter
  \@namedef{thecounter#2}{\ensuremath{#2_{\arabic{counter#2}}}}% % Command to type the label with counter
}

% A named version of the *-version of \reset@or@create@counter
\def\sreset@or@create@counter#1{\reset@or@create@counter*{#1}}


%
% Lengths
%

% Left and right margins of steps environment
\newlength{\stepsleftmargin}
\newlength{\@stepslmarg}
\setlength{\stepsleftmargin}{\tabcolsep}
\newlength{\stepsrightmargin}
\newlength{\@stepsrmarg}
\setlength{\stepsrightmargin}{\tabcolsep}

% Space between label and step (1em -> \quad, 2em -> \qquad)
\newlength{\stepslabelspace}
\newlength{\@stepslabelspace}
\setlength{\stepslabelspace}{1.5em}


%
% Each step
%

% A step or item (can be different types) in the message list
% (\send can be used a special kind of step of type M)

\NewDocumentCommand\@amstep{sO{S}mo}{%
  \alabel{#2_{\csname acounter#2\endcsname}}%
  \IfNoValueTF{#4}{}{%
    \addtocounter{counter#2}{-1}\refstepcounter{counter#2}\label{#4}}%
  \IfBooleanTF{#1}{%
    & \multicolumn{4}{@{}l@{}}{} & #3}{%
    & \multicolumn{5}{@{}l@{\hskip\@stepsrmarg\relax}}{#3}}}

\NewDocumentCommand\@anstep{sm}{%
  \IfBooleanTF{#1}{%
    & \multicolumn{4}{@{}l@{}}{} & #2}{%
    & \multicolumn{5}{@{}l@{\hskip\@stepsrmarg\relax}}{#2}}}

\NewDocumentCommand\@amstepat{sO{S}mmo}{%
  \alabel{#2_{\csname acounter#2\endcsname}}%
  \IfNoValueTF{#5}{}{%
    \addtocounter{counter#2}{-1}\refstepcounter{counter#2}\label{#5}}%
  \IfBooleanTF{#1}{%
    & \multicolumn{2}{@{}l@{}}{} & \apri{#3} & : & #4}{%
    & \multicolumn{5}{@{}l@{\hskip\@stepsrmarg\relax}}{\apri{#3}\;:\;#4}}}

\NewDocumentCommand\@anstepat{smm}{%
  \IfBooleanTF{#1}{%
    & \multicolumn{2}{@{}l@{}}{} & \apri{#2} & : & #3}{%
    & \multicolumn{5}{@{}l@{\hskip\@stepsrmarg\relax}}{\apri{#2}\;:\;#3}}}

\NewDocumentCommand\@amrawstep{O{S}O{}O{}O{}O{}mo}{%
  \alabel{#1_{\csname acounter#1\endcsname}}%
  \IfNoValueTF{#7}{}{%
    \addtocounter{counter#1}{-1}\refstepcounter{counter#1}\label{#7}}%
  & #2 & #3 & #4 & #5 & #6}
\NewDocumentCommand\@anrawstep{O{}O{}O{}O{}m}{%
  & #1 & #2 & #3 & #4 & #5}

% An implementation of \send used in the `steps` environment
\NewDocumentCommand\@msend{sO{}mmmo}{%
  % #1		-> Do not wrap in message (if * given)
  % #2		-> Size of brackets (optional)
  % #3		-> Send message from (the sender)
  % #4		-> Send message to (the receiver)
  % #5		-> The content of the message
  % #6		-> A label (can be used to refer to a step in a `steps` environment)
  \IfBooleanTF{#1}{\global\let\@msendmsg\@ssendmsg}{\global\let\@msendmsg\@sendmsg}%
  \IfNoValueTF{#6}{%
    \@amrawstep[M][\apri{#3}][\sends][\apri{#4}][:]{\@msendmsg[#2]{#5}}}{%
    \@amrawstep[M][\apri{#3}][\sends][\apri{#4}][:]{\@msendmsg[#2]{#5}}[#6]}}

% An implementation of \send used in the `steps*` environment
\NewDocumentCommand\@nsend{sO{}mmm}{%
  % #1		-> Do not wrap in message (if * given)
  % #2		-> Size of brackets (optional)
  % #3		-> Send message from (the sender)
  % #4		-> Send message to (the receiver)
  % #5		-> The content of the message
  \IfBooleanTF{#1}{\global\let\@nsendmsg\@ssendmsg}{\global\let\@nsendmsg\@sendmsg}%
  \@anrawstep[\apri{#3}][\sends][\apri{#4}][:]{\@nsendmsg[#2]{#5}}}

% Possible keyvals for the steps environment
\def\@stepslabels{}
\define@key{steps}{labels}{\def\@stepslabels{#1}}
\define@key{steps}{lmarg}[\stepsleftmargin]{\setlength{\@stepslmarg}{#1}}
\define@key{steps}{rmarg}[\stepsrightmargin]{\setlength{\@stepsrmarg}{#1}}
\define@key{steps}{lspace}[\stepslabelspace]{\setlength{\@stepslabelspace}{#1}}

% A series (list) of messages or other steps: \begin{steps} ... \end{steps}
\NewDocumentEnvironment{steps}{sO{}+b}{% The `steps` environment
  \setlength{\@stepslmarg}{\stepsleftmargin}%
  \setlength{\@stepsrmarg}{\stepsrightmargin}%
  \setlength{\@stepslabelspace}{\stepslabelspace}%
  \setkeys{steps}{#2}%
  \IfBooleanTF{#1}{% *-version of the environment
    \sreset@or@create@counter{M}% A message step with an M-label (using \send)
    \sreset@or@create@counter{S}% A normal step with an S-label (using \astep)
    %\forcsvlist{\sreset@or@create@counter}{\@stepslabels}% Other steps (and other labels using \astep[labels])
    \expandafter\forcsvlist\expandafter{\expandafter\sreset@or@create@counter\expandafter}\expandafter{\@stepslabels}%
    % See https://tex.stackexchange.com/questions/173383/splitting-a-csv-list-from-a-xkeyval-key-argument-into-parts
  }{%
    \stepcounter{mlistcounter}% Normal version of the environment
    \reset@or@create@counter{M}% A message step with an M-label (using \send)
    \reset@or@create@counter{S}% A normal step with an S-label (using \astep)
    %\forcsvlist{\reset@or@create@counter}{\@stepslabels}% Other steps (and other labels using \astep[labels])
    \expandafter\forcsvlist\expandafter{\expandafter\reset@or@create@counter\expandafter}\expandafter{\@stepslabels}%
    % See https://tex.stackexchange.com/questions/173383/splitting-a-csv-list-from-a-xkeyval-key-argument-into-parts
  }%
  \let\arawstep\@amrawstep%
  \let\astep\@amstep%
  \let\astepat\@amstepat%
  \let\send\@msend%
  \renewcommand{\arraystretch}{1.3}%
  \begin{tabular}{@{\hskip\@stepslmarg\relax}c@{\hskip\@stepslabelspace\relax}c@{\;}c@{\;}c@{\;}c@{\;}l@{%
    \hskip\@stepsrmarg\relax}}
    #3
  \end{tabular}%
  \let\send\@send
  \def\@stepslabels{}\ignorespacesafterend}

% without label
\NewDocumentEnvironment{steps*}{O{}+b}{%
  \setlength{\@stepslmarg}{\stepsleftmargin}%
  \setlength{\@stepsrmarg}{\stepsrightmargin}%
  \setkeys{steps}{#1}%
  \let\arawstep\@anrawstep%
  \let\astep\@anstep%
  \let\astepat\@anstepat%
  \let\send\@nsend%
  \renewcommand{\arraystretch}{1.3}%
  \begin{tabular}{@{\hskip\@stepslmarg\relax}p{0pt}@{}c@{\;}c@{\;}c@{\;}c@{\;}l@{%
    \hskip\@stepsrmarg\relax}}
    #2
  \end{tabular}\let\send\@send\ignorespacesafterend}

