\mainsection{The IO Class}
\label{sec:IO}

A major change in SCALE over SPDZ is the way input and output
is handled in the system to an outside data source/sync.
In SPDZ various hooks were placed within the compiler/byte-code
to enable external applications to connect. This resulted in
code-bloat as the run-time had to support all possible
ways someone would want to connect.

In SCALE this is simplified to a simple IO procedure for
getting data in and out of the MPC engine. It is then up
to the application developer to write code (see below)
which catches and supplies this data in the way that is
wanted by their application.
This should be done without needing to modify then byte-code,
runtime system, or any compiler being used.

\subsection{Adding your own IO Processing}
We identify a number of different input/output scenarios
which are captured in the C++ abstract class
\begin{verbatim}
    src/Input_Output/Input_Output_Base.h
\end{verbatim}
To use this interface, an application programmer will have to
write their own derived class, just like in the example
class
\begin{verbatim}
    src/Input_Output/Input_Output_Simple.h
\end{verbatim}
given in the distribution.
Then to compile the system they will need to place the
name of their derived class the correct place in the
main program,
\begin{verbatim}
    src/Player.cpp
\end{verbatim}
including any configuration needed.
To load your own IO functionality you alter the line
\begin{verbatim}
    auto ios= std::make_unique<Input_Output_Simple>();
\end{verbatim}
To configure your IO functionality you alter the line
\begin{verbatim}
    ios->init(cin,cout,true);
\end{verbatim}
Internally the IO class can maintain any number of ``channels''
for each of the various operations below.
The runtime byte-codes can then pass the required channel to the
IO class; if no channel is specified in the MAMBA language
then channel zero is selected by default (although for
the \verb+input_shares+ and \verb+output_shares+ commands
you {\em always} need to specify a channel.
Channels are assumed to be bidirectional, i.e. they can
communicate for both reading and writing.
Note, these are logical channels purely for the IO class;
they are nothing to do with the main communication channels
between the players.

\subsubsection{C FFI Interface}
There is also a \verb|Input_Output_C| class, which you are
not expected to interact with directly, but instead use pure
C ABI compatible functions to drive the SCALE engine from a
C or Rust program. When driving SCALE via the C API ($run_scale_from_rust$), it will
default to \verb|Input_Output_Simple| which uses cin/cout for
data input and output. If you want to use the C API, you need
to set the $io_constructor$ argument to the pointer returned
by $create_input_output_base_rust$.

This will cause the C interface to get linked to your project,
causing linker errors forcing you to implement various C functions.
The relevant functions are implemented in Rust in $src/src/scale_mamba_handler.rs$,
so you do not actually need to do this. Instead, you implement the
$ScaleMambaHandler$ trait for a $struct$ of your choosing and
use that to store any relevant information like you would in a
C++ subclass of \verb|Input_Output_Base|. You can then pass a pointer
to your struct in the $io_handle$ argument of $run_scale_from_rust$ as
follows:

\begin{verbatim}
    let mut your_struct = ...; // somehow initialize your object
    let handle = ScaleMambaHandle { handler: &mut your_struct };
    let exit_code = run_scale_from_rust(
        ...,
        create_input_output_base_rust,
        &mut handle,
    );
    assert_eq!(exit_code, 0);
\end{verbatim}

\subsection{Types of IO Processing}
In this section we outline the forms of input and
output supported by the new IO system.
All IO instructions must be executed from thread zero, this is
to ensure that the order of IO functions is consistent across
all executions.

\subsubsection{Private Output}
To obtain an $\F_p$ element privately to one party one
executes the byte-code
\begin{center}
    \verb+PRIVATE_OUTPUT+.
\end{center}
These correspond to a combination of the old SPDZ byte-codes
\verb+STARTPRIVATEOUTPUT+ and \verb+STOPPRIVATEOUTPUT+.
The instruction enables a designated party to obtain output of
one of the secretly shared variables, this is then passed
to the sytem by a call to the function
\verb+IO.private_output_gfp(const gfp& output,unsigned int channel)+ in the C++ IO class.

\subsubsection{Private Input}
This is the oppposite operation to the one above and it
is accomplised by the byte-code
\begin{center}
    \verb+PRIVATE_INPUT+.
\end{center}
This correspond to the old SPDZ byte-codes
\verb+STARTINPUT+ and \verb+STOPINPUT+.
The instruction enables a designated party to enter a value into
the computation.
The value that the player enters is obtained via a call to the
member function
\verb+IO.private_input_gfp(unsigned int channel)+ in the C++ IO class.

\subsubsection{Public Output}
To obtain public output, i.e. the output of an opened variable,
then the byte-code is \verb+OUTPUT_CLEAR+, corresponding to
old SPDZ byte-code \verb+RAWOUTPUT+.
This output needs to be caught by the C++ IO class in
the member function \verb+IO.public_output_gfp(const gfp& output,unsigned int channel)+.

For the same functionality but for \verb|regint| type we have
that the byte-code is \verb+OUTPUT_INT+.
This output needs to be caught by the C++ IO class in
the associated member function
\verb+IO.public_output_int(...)+.

\subsubsection{Public Input}
A clear public input value is something which is input to
    {\em all} players; and must be the same input for all players.
This hooks into the C++ IO class function
\verb+IO.public_input_gfp(unsigned int channel)+, and corresponds to the byte-code
\verb+INPUT_CLEAR+.
This is a bit like the old SPDZ byte-code \verb+PUBINPUT+
but with slightly different semantics.
For the \verb|regint| type this becomes the byte-code \verb+INPUT_INT+
and the C++ IO class function
\verb+IO.public_input_int(...)+.

Any derived class from \verb+Input_Output_Base+ needs to call
the function \verb+IO.Update_Checker(y,channel)+ from within the
function \verb+IO.public_input_gfp(...)+,
or the function \verb+IO.public_input_int(...)+.
See the example given in the demonstration \verb+Input_Output_Simple+ class provided.

\subsubsection{Share Output}
In some situations the system might want to store some
internal state, in particular the shares themselves.
To enable this we provide the \verb+OUTPUT_SHARES+
byte-code (corresponding roughly to the old
\verb+READFILESHARE+ byte-code from SPDZ). The IO class can do
whatever it would like with this share obtained. However,
one needs to be careful that any usage does not break the
MPC security model.
The member function hook to deal with this type of
output is the function
\verb+IO.output_shares(const Share& S,unsigned int channel)+.

\subsubsection{Share Input}
Finally, shares can be input from an external source
(note they need to be correct/suitably MAC'd). This
is done via the byte-code \verb+INPUT_SHARES+ and the
member function \verb+IO.input_share(unsigned int channel)+.
Again the same issues re careful usage of this function
apply, as they did for the \verb+OUTPUT_SHARES+ byte-code.


\subsection{Other IO Processing}

\subsubsection{Opening and Closing Channels}
As some IO functionalities will require the explicit opening
and closing of specific channels we provide two functions
for this purpose;
\verb+IO.open_channel(unsigned int n)+
and
\verb+IO.close_channel(unsigned int n)+.
These correspond to the byte-codes \verb+OPEN_CHANNEL+ and
\verb+CLOSE_CHANNEL+.
For our default IO functionality one does not need to
explicitly call these functions before, or after,
using a channel.
However, it is good programming practice to do so, just
in case the default IO functionality is replaced by another
user of your code.
The \verb+open_channel+ command returns a \verb+regint+
value which could be used to signal a problem opening a channel.
This is captured in MAMBA via the \verb+open_channel_with_return+
function.

\subsubsection{Trigger}
There is a special function \verb+IO.trigger(Schedule& schedule)+
which is used for the parties to signal that they are content with
performing a \verb+RESTART+ command.
See Section \ref{sec:restart} for further details.

\subsubsection{Debug Output}
There is a function \verb+IO.debug_output(const stringstream &ss)+
which passes the responsed from the \verb+PRINTxxx+ byte-codes.
In the default instantiation this just sends the contents
of the \verb+stringstream+ to standard output.

\subsubsection{Crashing}
The byte-code \verb+CRASH+ calls the function
\verb+IO.crash(unsigned int PC, unsigned int thread_num)+.
This enables the IO class to be able to process any crash
in an application specific way if needs be.
If the \verb+IO.crash+ command returns, as opposed to causing
a system shut-down, then the \verb+RESTART+ instruction will
be called immediately.
This means an online program can crash, and then a new one
can be restarted without loosing all the offline data that
has been produced.

\subsection{MAMBA Hooks}
These functions can be called from the MAMBA language via,
for \verb+a+ of type \verb+sint+, \verb+b+ of type \verb+cint+
and \verb+c+ of type \verb+regint+.
\begin{verbatim}
    # Private Output to player 2 on channel 0 and on channel 11
    a.reveal_to(2)
    a.reveal_to(2,11)

    # Private Input from player 0 on channel 0 and on channel 15
    a=sint.get_private_input_from(0)
    a=sint.get_private_input_from(0,15)

    # Public Output on channel 0 and on channel 5
    b=cint.public_output()
    b.public_output(5)

    # Public Input on default channel 0 and on channel 10
    b=cint.public_input()
    b=public_input(10)

    # Share Output on channel 1000
    output_shares(1000,[sint(1)])

    # Share Input on channel 2000
    inp=[sint()]
    input_shares(2000,*inp)

    # Regint input and output on channel 4
    a=open_channel_with_return(4)
    e=regint.public_input(4)
    e.public_output(4)
    close_channel(4)
\end{verbatim}
The \verb+IO.trigger(Schedule& schedule)+ is called only when a \verb+restart()+ command
is executed from MAMBA.
