\mainsection{User Defined Local Functions}
\label{sec:Local}
As you write complex applications you will soon see the
need to execute local operations on each player which are
rather complex. For example this might be formatting data,
or performing some local arithmetic which does not need
to be done securely. 
Prior to v1.5 there was two ways of doing this:
\begin{enumerate}
\item Write the local function in MAMBA or SCALE byte-codes
directly. This is often both a pain from a programming point
of view, and also produced highly inefficient code.
\item Use the calling application to execute the local
operations, and then use the I/O class to interact
between the two. This requires people to have calling
applications, which any deployed application will have),
but which a quick experimental setup is unlikely to
bother with.
But it also requires expensive interaction between the
SCALE engine and the external application via the I/O
class.
\end{enumerate}
Having implemented the user defined circuits for Garbling
we decided to also, in a similar manner, add a third method
of implementing local functions; namely via user-defined
C++-code.
To see this in operation we suggest looking at the directory
\verb|src/Local/|, and looking at the files there. Here
we implement some basic linear algebra routines.
Look at those files whilst reading this explanation.

\subsection{Defining Local Functions in C++}
Every local function is one which involves no interaction
between the parties.
It can thus be {\em any} function on clear data, and
only a {\em linear} function on private data.
A local function is defined using the C++ signature
\begin{lstlisting}
    void apply_Function(int instr);
\end{lstlisting}
Where the variable \verb|instr| is the instruction number; which is akin to the
earlier circuit number for garbled circuits.
We reserve all numbers less than 65536 for use by the developers, leaving
you to define numbers greater than 65536.
Once again, if you have a good function which might be useful to others
please let us know.

The local function is registered with an instruction number in the
system by adding the function pointer to the \verb|functions| map
in the file \verb|src/Local/Local_Functions.cpp|.
Must like user defined Garbled Circuits were added into the
system earlier.

Each local function obtains it arguments by popping any required
data off the stacks, the functions outputs are then placed on the
stacks in a similar manner.
See the \verb|BLAS.cpp| example linear algebra routines for
some examples.

\subsection{Defining Local Functions in the MAMBA/byte-code Language} 
On the byte-code side of system we have one instruction
\verb|LF| which takes a single argument, namely the
number of the local function being called.

\subsection{BLAS Examples}
In our Basic Linear Algebra System (BLAS) we provide currently four
routines
\begin{center}
\begin{tabular}{c|l}
Instruction Number & Function \\
\hline
0 & cint n-by-k matrix A by cint k-by-m matrix B \\
1 & sint n-by-k matrix A by cint k-by-m matrix B \\
2 & cint n-by-k matrix A by sint k-by-m matrix B \\
3 & Row Reduction of a n-by-m cint matrix A \\
\end{tabular}
\end{center}
In these examples the dimensions are passed via 
pushing to the \verb|regint| stack, with data
being passed by pushing to the \verb|cint| (resp.
\verb|sint|) stack.
The matrices are packed using a standard row-wise configuration.
In the following code example (given in \verb|Programs/Local_test/|)
we illustrate this with the matrices
\[
  A = \left( \begin{array}{ccc}
  1 & 2 & 3 \\  
  4 & 5 & 6 \end{array} \right) \quad \quad
  B = \left( \begin{array}{cc}
  7 & 8 \\
  9 & 10 \\
  11 & 12 
  \end{array} \right).
\]
\begin{lstlisting}
def push_Cint_matrix(A,n,m):
  regint.push(regint(n))
  regint.push(regint(m))
  for i in range(n):
    for j in range(m):
       cint.push(A[i][j])

def push_Sint_matrix(A,n,m):
  regint.push(regint(n))
  regint.push(regint(m))
  for i in range(n):
    for j in range(m):
       sint.push(A[i][j])

def pop_Cint_matrix(A,n,m):
  mm=regint.pop()
  nn=regint.pop()
  if_then(nn!=n or m!=mm)
  print_ln("Something wrong")
  print_ln("%s %s",nn,mm)
  end_if()
  for i in range(n-1,-1,-1):
    for j in range(m-1,-1,-1):
       A[i][j]=cint.pop()

def pop_Sint_matrix(A,n,m):
  mm=regint.pop()
  nn=regint.pop()
  if_then(nn!=n or m!=mm)
  print_ln("Something wrong")
  print_ln("%s %s",nn,mm)
  end_if()
  for i in range(n-1,-1,-1):
    for j in range(m-1,-1,-1):
       A[i][j]=sint.pop()


n=2
l=3
m=2

# Mult the two matrices
#  A = [1,2,3;4,5,6]
#  B = [7,8;9,10;11,12]
# which should give us
#  C = [58,64; 139, 154]

Cp_A=cint.Matrix(n,l)
Cp_B=cint.Matrix(l,m)
Cp_out=cint.Matrix(n,m)
CpGE_out=cint.Matrix(n,l)
Sp_A=sint.Matrix(n,l)
Sp_B=sint.Matrix(l,m)
Sp_out=sint.Matrix(n,m)

cnt=1
for i in range(n):
  for j in range(l):
     Cp_A[i][j]=cint(cnt)
     Sp_A[i][j]=sint(cnt)
     cnt=cnt+1

for i in range(l):
  for j in range(m):
     Cp_B[i][j]=cint(cnt)
     Sp_B[i][j]=sint(cnt)
     cnt=cnt+1

push_Cint_matrix(Cp_A,n,l)
push_Cint_matrix(Cp_B,l,m)
LF(0)
pop_Cint_matrix(Cp_out,n,m)

print_ln("Final CC Product is...")
for i in range(n):
  for j in range(m):
    print_str('%s ', Cp_out[i][j])
  print_ln('')

push_Sint_matrix(Sp_A,n,l)
push_Cint_matrix(Cp_B,l,m)
LF(1)
pop_Sint_matrix(Sp_out,n,m)

print_ln("Final SC Product is...")
for i in range(n):
  for j in range(m):
    print_str('%s ', Sp_out[i][j].reveal())
  print_ln('')

push_Cint_matrix(Cp_A,n,l)
push_Sint_matrix(Sp_B,l,m)
LF(2)
pop_Sint_matrix(Sp_out,n,m)

print_ln("Final CS Product is...")
for i in range(n):
  for j in range(m):
    print_str('%s ', Sp_out[i][j].reveal())
  print_ln('')


push_Cint_matrix(Cp_A,n,l)
LF(3)
pop_Cint_matrix(CpGE_out,n,l)

print_ln("Final Gauss Elim on A is...")
for i in range(n):
  for j in range(l):
    print_str('%s ', CpGE_out[i][j])
  print_ln('')
\end{lstlisting}







