Vous êtes sur la page 1sur 20

Secure function evaluation using garbled ciruits built from

propositional formulae.
Research Seminar in Cryptography
Timo Petmanson
Oleg Šelajev
29. november 2009

Abstract
In this seminar paper we describe a method doing secure function evaluation (SFE) using
garbled circuits. We show how to use propositional logic formulae to construct a garbled
circuit and how to evaluate it afterwards. We also describe some specific implementation
details that were used in our implementation along with some benchmarking results.

Keywords: secure function evaluation, garbled circuits, propositional formulae

1 Introduction
In bussinesses and private lives of people there is lot of confidential data that is used in number
of different situations. Examples of such data are medical records, accounting reports, credit
card numbers etc. The need to keep such data confidential is crucial as otherwise it would make
possible to compromise people or bussinesses holding value in the data. For example revealing
your credit card number to malicious counterparts results in probably compromising your bank
account, allowing access to somebody’s medical data would allow to reveal probably delicate
information about a person to public.
To fight that kind of threats, mathematical methods are used to hide the data in such way
that only counterparts who are allowed to access data would be able to understand it. The
science that deals with such mathematical models is called cryptography.
Now let’s consider another private data processing example. Let’s think of a millionaire club,
where each year a new president is elected. The person, who is most wealthiest in a given year,
will be elected as the president of the club. In such case, each member of the club wishes to keep
the total value of his/her bussinesses confidential, but still they want to determine, who would
be the president. The method able to achieve this is called secure function evaluation (SFE),
which has been the subject of interest of many researches.
Let’s define general case of the problem: let there be n parties P1 , . . . , Pn , each having their
private inputs xi , i ∈ {1, . . . , n}, who want to evaluate a function f = (x1 , . . . , xn ). There are
several methods to do that, but in this paper we will study the one proposed by Andrew Yao [1].
The method Yao proposed, based on idea doing SFE with boolean circuits. A boolean circuit
is a directed acyclic graph where nodes represent boolean operators (such as and, or, xor and
others) and arcs represent the connections between them. For example see Figure 1. We see
that this is a DAG with two inputs: X1 , X2 and two outputs Y1 , Y2 . The signals from input

1
wires go through logic gates, which perform computations on the signals and transmit the result
through the output wires of the circuit. If we recall our millionaire club example, we could give
the amount of money of each member as inputs to the circuit (one input wire of the circuit can
represent a bit of a integer containing some members net value) and use the circuit to calculate,
who will be the next president.

Figure 1: An example of a boolean DAG

Such a plain boolean circuit alone is not enough to keep the data confidential, though. To
make the process secret, we must ensure that the inputs of millionaire club members are hidden
and we also need to ensure that possible eavesdroppers would be unable to determine the actual
functionality of the circuit. This works by garbling the input values and the actual contents of
the boolean circuit, hence resulting in, what we call, “garbled” circuits.
TODO: write about the whole protocol.
In next section we describe how to use propositional logic formulae to build a Boolean circuit
that could be garbled later and used for evaluating a function.

2 Constructing a Boolean circuit


2.1 Propositional logic formulae
In classical mathematical logic, a propositional logic formula is a formula containing boolean
variables and operators, namely all the variables and the result of a formula can be either true
or false. A formulae can contain several variables that can viewed as the inputs of the formula.
These variables can be nested together by boolean operators to create more complex formulae.
The general rules obtaining or determining legal propositional logic formulae are given below:

• Every variable is a propositional logic formula.


• If υ is a propositional logic formula, then ¬υ is also a propositional logic formula.
• If υ and ω are propositional logic formulas and ◦ is a binary operator, then (υ ◦ ω) is also
a propositional logic formula.

The reason we are interested in such formulae is that they can be represented as a tree
structure. For example a formulae (A ∨ B) ∧ C has a tree structure, where operator ∧ is the
root with child nodes ∨ and C. That property can be used to easily build a Boolean circuit from
several different propositional logic formulae. For example, let’s recall the circuit on Figure 1
and let’s look at two formulae:

2
Y1 = ¬(X1 ∧ X2 ) ⊕ (X1 ⊕ X2 )
Y2 = (X1 ∧ X2 ) ∨ (X1 ⊕ X2 )
The first formula defines an output Y1 and second one Y2 . We see that both formulae have
common subformulae (X1 ∧ X2 ) and (X1 ⊕ X2 ). It is easy to see, that combining common
subformulae and adding missing gates it is easy to build a DAG based on tree-structure formulae.
Taking that into account, we can define a formula for every output of the circuit such way.
We can go even further by labeling commong subformulae and using these labels to link them
into other formulae. For example, if we would label (X1 ∧ X2 ) as A, we could define as Y2 =
A ∨ (X1 ⊕ X2 ) which is less complicated and easier to read.

2.2 Turning infix notation formulae into postfix notation


Usually logic formulas are written in infix notation, so that binary operators lie between the
arguments. Also braces are used to denote, which operators should be evaluated before others,
to override default operator precedence order. This form is very intuitive and easy to read for
humans, but if we want to implement a method constructing a DAG from formulae, we might
wish to convert these formulase into postfix (also known as reverse polish) notation, that has a
tree structure. As we showed before, it is rather convinient to build a DAG from trees.
To do that, we use an algorithm called Shunting-Yard algorithm [2], that can convert infix
notation formulas to postfix notation formulas in O(n) time. For example, a propositional logic
formula (X1 ∧ Y 1) ∨ (¬X2 ↔ Y 2) is equivalent to X1 X2 ∧ X2 ¬ Y 2 ↔ ∨ in postfix notation.
We use a simplified version of the Shunting-Yard algorithm to convert infix notation formulae
to postfix notation, that is fine-tuned for propositional logic. See algorithm in appendix A for
details.

2.3 Merging postfix notation variables into a DAG


Given a bunch of logic formulae, we start constructing a DAG first by counting all variables in
the subformulae. Then insert all possible variables into an empty DAG as input nodes. An input
node xi represents the i’th input of the circuit.
If this is done, we can start merging formulae one by one into the circuit. Recall that we
discussed the option of labeling common subformulae before. If using this feature, we can start
from inserting common subformulae first and then insert other formulae that depend on these
subformulae. For example, consider Figure 2, we can define following subformulae:

3
Figure 2: Naive Boolean circuit for evaluating f (X, Y ) = (X = Y, X > Y ), where X and Y are
3-bit unsigned integers

E1 = X1 ↔ Y1
E2 = X1 ↔ Y2
E3 = X1 ↔ Y3
G1 = ¬E1 ∧ (X1 → Y1 )
G2 = ¬E2 ∧ (X2 → Y2 )
G3 = ¬E3 ∧ (X3 → Y3 )
Let’s also define the outputs:

Z1 = E1 ∧ E2 ∧ E3
Z2 = G1 ∨ E1 ∧ G2 ∨ E1 ∧ E2 ∧ G3
If defining the formulae such way, we can start with formulae that only depend on the presence
of the input gates. In our example we start with formulae E1 , E2 , E3 . The order of insertion
is not important as they do not depend on each other. But they definetly have to be inserted

4
before formulae G1 , G2 , G3 as G1 depends on E1 , G2 depends on E2 etc. Therefore the general
idea is that before inserting some subformula, it is necessary to insert all subformulae that given
formula depends on. This also means, that formulae that define outputs should be that last ones
to be inserted.
In our implementation, the process of determining common subformulae is up to the user as
the one of the two main objectives of doing this is to simplify the reading of the formulae, thus
making it easier for the user to design circuits; the second objective is to optimize the number
of gates in the circuit by not inserting commong subformulae several times. The optimizing part
can also be done automatically - if given 2 formulae that can be represented as trees, determining
the number and locations of the commong subtrees is an application of dynamic programming,
hence it can be done in feasible time. The approach is not implemented in our code, though.
You can see details of the algorithm in our implementation in Appendix B and you can see
details of the input file format for formulae used in the implementation in Appendix C.
In next section we describe the process of turning a Boolean circuit into a garbled circuit.

3 Garbling the circuit


As we stated in the introduction, the purpose of garbling a Boolean circuit is to hide the function-
ality of the circuit e.g. the function the circuit calculates. For example, recall the circuit given in
Figure 2. It is easy to see that output Z1 is true if and only if inputs (X1 , X2 , X3 ) = (Y1 , Y2 , Y3 ),
hence we know that part of the circuit implements equality function. By knowing the function
and the outcome of the circuit, it is thus possible to reveal some information about the inputs or
revealing them completely just by knowing the function of the circuit and the outcome. In our
example, knowing that Z1 is true, we also know that inputs (X1 , X2 , X3 ) equal to (Y1 , Y2 , Y3 ).
We do not get the actual inputs, though, but still we gain knowledge.
To overcome this issue, we use combination of encryption and random reordering of the truth
tables of the gates to achieve security.

3.1 Hiding the contents of the gates


The problem, why we need to reorder the contents of the truth tables of the gates, is that it is
trivial to guess the function of a gate just by seeing it’s truth table. For example let’s look at
the truth tables of implication and equivalence:
X Y X→Y X↔Y
0 0 1 1
0 1 1 0
1 0 0 0
1 1 1 1
The combinations of input values are given in order and there is corresponding place in the
tables for the relevant outputs. So by seeing that, we can easily identify the function the is gate
performing.
To hide it, we use following method: we toss a fair coin for every wire to decide a rewrite rule
for it (every wire having 50 per cent of chance). By that we mean that if rewrite rule is applied
to some wire, we transmit bit value 1 instad of value 0 and vice versa on that wire. For example
let’s see Figure 3.

5
Figure 3: Function tables of gates ↔ and → before and after modifying truth tables according
to rewriting rule of edge e2 . The table on top shows the original truth tables and table in bottom
shows the modified variants.

We have applied a rewrite rule for wire e2 . If we do not change the truth table of the
implication gate that uses e2 is an input, the gate may output a wrong value. The implication
gate receives values from gates e2 and e4 , thus if it sees input (0, 0), then it actually corresponds
to input (1, 0) as e2 has a rewriting rule. So, first we need to modify the tables such that they
would output the correct result while taking into account the rewriting rules of input wires. This
is merely reordering the contents of the truth table according to input wire rewrite rules, thus
result is permutation of the contents of the original truth table (See the lower table for a modified
truth table of the implication gate).
The second step is to actually encode the rewriting rules into the truth tables. For example,
if a gate has only one output wire with a rewrite rule, then encoding this into the truth table of
the gate is just a matter of replacing all 0 values by 1 and vice versa in the truth table, e.g. the
gate will output values according to the wire’s rewrite rules, it outputs 1 instead of 0 and vice
versa. However, as one gate can have several output wires with different rewrite rules, we need
to extend the function tables such that they would hold output values for every outgoing wire.
For example, let’s see Figure 4.

Figure 4: Extended truth table of gate ↔ before (upper table) and after (lower table) applying
rewriting rule to edge e5 .

The equivalence gate has two outputs e5 and e6 where e5 has the rewrite rule and we hold output
values for both wires in the gate’s extended truth table. Now to encode the rewrite rule, we just

6
have to flip the output values of wire e5 to get the lower table in the figure.
Also note that the circuits also have input and outputs gates, which do not contain truth
tables, but rather resemble input and output wires of the circuit. To make the circuit usable,
the party constructing the circuit needs to store the rewrite rules of all input and output wires.
For example, if circuit has two input wires X and Y , where Y has a rewrite rule, then instead
of giving inputs (X = 0, Y = 0) to the circuit, we must give (X = 0, Y = 1) as the inputs to
make the circuit function correctly. Also if an output wire with a rewrite rule outputs value 0,
it should be interpreted as 1.
Having modified the truth tables of all function gates in the circuit, we have successfully
hidden the functionality of the gates as it is no longer trivial to determine what type of function
is a gate performing for other parties just by looking at it’s truth table and thus determining the
function of the circuit is not trivial.

3.2 Encrypting the contents of the gates


Next step is to encrypt the contents of the gates to make the functionality of the circuit even
harder to discover by allowing the evaluating party only to see the relevant cells in truth tables
that are needed for calculating the result, but no more.
To achieve this, we will first generate a pair of AES keys (ke0 , ke1 ) for every wire e in the
circuit, where one of them will represent value 0 and the other one represents value 1 and store
them along with the wire output values in the extended truth tables of the gates. See Figure 5
for an example.

Figure 5: Extended function table of gate ↔ after generating AES keys.

When evaluating a circuit, we only need to see the contents of one cell of the gate’s truth
be 1
table that corresponds to input values (be1 , be3 ), if gate is given input valur pairs (be1 , ke1 ) and
be 3 n n
(be3 , ke3 ). As for a n-ary gate, there are 2 distinct combinations of inputs and 2 cells, we
can encrypt every cell with the corresponding keys of the inputs. Therefore we can ensure, that
the evaluator can only decrypt the cell that he/she has correct keys for and nothing more. The
algorithm we used to encrypt the contents of the cells is called External AESStretch. See
Algorithm 1 for details.

7
Algorithm 1: External AESStretch
foreach combination of input values x1 , . . . , xn ∈ {0, 1}n of a n-ary gate g do
Get a tuple of keys (kex11 , . . . , kexnn ) , where ei ∈ E, such that e represents an input wire
of g.
foreach key ki ∈ (kex11 , . . . , kexnn ) do
zxi := AESS tretch(xi , kexii )
z := zx1 ⊕ . . . ⊕ zxn
XOR the contents of the corresponding cell of the extended function table with the
value z to obtain encrypted cell.

For an example, recall Figure 5 where we had the extended truth table of equivalence gate
0 0
along with the keys. To encrypt the first cell of the gate, we use inputs (0, ke1 ) and (0, ke3 ).
0 0
Then we calculate ze1 by encrypting value 0 with key ke1 and ze3 by encrypting 0 with key ke3 .
Then the last step is to XOR both ze1 and ze3 with the contents of the cell.
Repeating that procedure with all cells results in an encrypted truth table of the gate. After
encrypting all function gates of the curcuit, we have finished garbling the circuit. Next thing to
do is to send the circuit for other parties for evaluation. For that purpose, in our implementation
we save the circuit as an XML file suitable for easy reconstruction of the garbled circuit. The
detailed file format is described in Appendix D.

4 Recreation garbled circuit from xml representation


4.1 Basics of recreation process
The basic idea of a protocol for using garbled circuits to evaluate a function f = (X, Y ) for two
parties P1 and P2 is following [3]
1. Party P1 creates the circuit and sends it with all the internal contents of the gates to P2
along with it’s input wire signals corresponding to his/her inputs
2. Party P2 obtains the signals for his/her inputs from P1 throught one-out-of-two oblivious
transfer.
3. Party P2 evaluates the circuit and distributes the results as needed.
This chapter will describe the system built through current investigation. Notice that, there-
fore, it is not so general and related more to designed system than the SFE field.
Lets assume circuit is transferred to party P2 which is going to evaluate it. In the beginning
of evaluation circuit process, P2 is going to ensure that the transfer was done correctly and
no information about circle was lost. We represent circuit as a directed acyclic graph (DAG)
G(V, E) where vertices are gates of the circut and edges are wires, so that for all gates (, v) such
that exists output wire of u which is an input wire for v there exist edge between vertices (u, v)
in the result graph. In such case we will name node u as parent of node v and node v as child
of u.
The xml representation specifies additional information about the circuit such as:
1. number of gates (total)
2. number of wires (total)

8
3. number of input-output wires for each gate
This information should be checked on circuit reconstruction time to provide basic xml con-
struction and transfer error check procedure.
Then the evaluation of the circuit could be thought as distribution of information through
the edges (wires) of a DAG. Notice than in order to be able to specify inputs of the circle we
need one more node in the graph. The same way we need one more node to connect output wires
to. These two nodes do not necessary are different, so we extend the graph with a special circuit
node c, see Figure ??.

9
Figure 6: An example of circuit DAG with 3 gates and a special circuit node

10
This breaks the requirement of the graph to be acyclic, but this is done to make evaluation
process easier, and it does not change any principled part of the system.
Now we know that circuit representation does not differ much from a gate representation
(both are nodes in our graph), so we introduce composite design pattern into our system, which
means:
Circuit is an object that can hold connected nodes or circuits.
This will not going to be used directly in this paper, but it makes possible to define a named
circuit (structure of connected nodes) and then use it by name in other circuit xml representation.

4.2 Gate internals


Each node contains referencies to parent nodes, additionally maintaining the information about
which parent it is (numerically, index of parent) and which child this node is to its parent
(numerically, parents child index). This information is needed to know which output of the
parent is provided to this node and how to arrange inputs of the parent on this node’s side.
Lines of garbled table are stored in array of base64 encoded strings. Every line represents an
encrypted sequence of 17 byte value, every of which contains:
1. 16 byte AES key,
2. 1 byte value (only 1 bit used).

4.3 Topological sorting


In order to efficiently evaluate the circuit we topologically sort created DAG. The reason is that
if there exists edge (u, v) then in general case node v could not be evaluated before node u is.
Thus the meaning of nodes in our graph coincide with sheduled jobs definition in the canonical
problem of topological sorting.
We sort the nodes using the backward depth-first-search (from child to parent) see ?? taken
from [4], which works by adding the node to topologically sorted list only when all dependant
nodes are already added there.
Now we have reconstructed circuit and are ready to evaluate it.

5 Input specification
In order to evaluate a circuit we need to specify some input values to all its input wires. The
input file has the following format:
1. for 8 bit greater or equal formulae: 16 values from 0, 1 separated with spaces (which
represent 2 8-bit numbers)
2. for 32 bit greater or equal formulae: 64 values from 0, 1 separated with spaces (which
represent 2 32-bit numbers)
For instance for 8-bit numbers greatness-equality testing circuit will accept input like:
0000111100010000
In the reading input stage we assign each value to corresponding input value wire of a previ-
ously read circuit. It is done in the following manner:
the i-th value from an input file is assigned to i-th input wire. If in the end of reading input file
there will be wire with no input value assigned, circuit will not be evaluated.

11
It may seem that the solution provided within this paper just compares two 8-bit (32-bit)
numbers. In this case in the above example we want to test if 15 is greater or equal to 16.
In the real-life environment parties should use some oblivious transfer protocol [3] in order to
garble the input bits, in order not to correlate with plain binary representation of the numbers.
Then bit 0 on some position i in the input file will mean using key0 of the i-th wire and 1 will
mean to use key1 of the wire.

6 Evaluation of garbled circuit


Evaluation of the circiut is done according to a topological sorting found previously in the DAG
that represents this circuit. Each node in the graph evaluates itself with the following algorithm:
The evaluated node’s output values are populated then.
The last node to be evaluated is circuit node c. It will just collect output values from the
parent nodes (which are the circuit finishing gates) and copy as the circuit’s own output.
At this moment we have obtained the result and the evaluation of circuit is completed.

7 Performance metrics
The system for the SFE constructed through this paper is written in C++. It is able to:
1. parse the logical formulae,
2. construct and garble boolean circuit,
3. persist circle into xml representation,
4. read the circuit xml representation and recreate circuit for evaluation,
5. evaluate circuit with given input values.
The following third party libraties are used:
• openssl crypto lib (AESkey generation, encryption),
• tinyxml (xml creation and reading).
The full circuit evaluation cycle from the list specified above was repeated multiple times to
approximately measure performance of the programm.
The system was tested on the computer with the following configuration: Intel Pentium M
1,73 GHz, L2 cache 2MB, 797 MHz 1GB RAM, Windows XP SP3.
Programm was compiled with O2 optimisation with gcc version 3.4.5 compiler. See Appendix
E for detailed information about the running programm.
The output of test script is presented in the following table.

12
Figure 7: Sample performance results in seconds

times creation time 8 bit evaluation time 8 bit creation time 32 bit evaluation time 32 bit
5 0.304129994175 0.161853811029 0.332936169262 0.241215014757
10 0.366092338551 0.324529514226 0.657778851781 0.489517522478
20 0.744392373891 0.651649581162 1.34976791743 0.998860749062
30 1.14182389103 1.00350631156 2.03381100112 1.49557108515
40 1.52139671383 1.33434472817 2.71874945 1.99166849418
50 1.90188389865 1.65362748617 3.3944375612 2.49556382166
70 2.67554088578 2.31742665618 4.73973004949 3.50005852699
90 3.42722133679 2.99062366865 6.09611277411 4.49906817766
110 4.19639144081 3.63969359234 7.47251619968 5.5060221341
130 4.96280030004 4.32581990169 8.83163167386 6.50996537269
150 5.71367981126 4.9787263465 10.1602795886 7.48305329309
200 7.62804574324 6.63451695676 13.5514594732 9.9980019807
250 9.5525869908 8.32414426973 16.9667019132 12.4815058897
500 19.0409227988 16.6128636461 33.9313451849 24.9934223484
750 28.5730041109 24.4528882861 49.8471836504 36.6244290825
1000 37.6735867268 32.5658649353 66.5969557583 48.9378239413
1500 56.0511338732 48.7719081615 99.8258317747 73.4829460169

The first thing to notice is that the time grows linearly with the grow of number of repetitions
(obvious, as 1 time circuit evaluation takes the same amount of time every execution).
Another note is that 32 bit numbers comparison circuit is created and evaluated about 1.5-2
times longer than 8 bit one.
8 bit numbers comparison circuit is averagely created in 37 milliseconds (data is derived from
1000 and 1500 rows). 32 bit numbers comparison circuit is averagely evaluated in 32 milliseconds
(data is derived from 1000 and 1500 rows).
32 bit numbers comparison circuit is averagely created in 66 milliseconds (data is derived from
1000 and 1500 rows). 32 bit numbers comparison circuit is averagely evaluated in 48 milliseconds
(data is derived from 1000 and 1500 rows).
These results could be used to give a prediction how the system will behave compared to
another scheme of garbling and encrypting a circuit. Another reason to have them here is to
compare them with the performance of the programm ran on another architecture (for instance
with hardware AES instructions included).
Both these questions could be a starting point for the following research of this problem.

13
8 References
References
[1] Andrew Chi-Chih Yao. Protocols for secure computations (ex-tended abstract). In Proceedings
of the 21st Annual IEEE Symposium on the Foundations of Computer Science, pages 160-164,
1982
[2] Edsger Dijkstra. Stichting Mathematisch Centrum Rekenafdeling. ALGOL Bulletin Supple-
ment nr 10. ALGOL-60 Translation. 1961
[3] Dan Bogdanov. On the (in)feasibility of information-theoretically secure circuit evaluation.
Research Seminar in Cryptography. 2009
[4] Introductions to algorithms. Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest,
Clifford Stein.

14
A The Shunting-Yard algorithm

Algorithm 2: The simplified version of Shunting-Yard algorithm


Data: L is the list of tokens in infix notation
S is an empty LIFO stack for temporal storage for tokens
Result: O is the output list, that will eventually contain the tokens in postfix notation.
while L is not empty do
pop next element from L to t switch type of the token t do
case t is a variable or a opening brace
push t to output O
case t is a operator
while stack S is not empty do
pop l from S
if l is a opening brace then
push l back to S
break
else
if t is a ¬ operator or t is some other operator and
precedence(t) ≥ precedence(l) then
push l to output O

push t to stack S
case t is a closing brace
openingBraceF ound := f alse
while there are more tokens on the stack S do
pop l from stack S
if t is a opening brace then
openingBraceF ound := true
break
else
push l to output O
if openingBraceF ound = f alse then
report a parenthesis mismatch error

while S is not empty do


pop k from stack S
if k is an opening brace then
report a parenthesis mismatch error
else
push k to output O

15
B DAG construction algorithm
Algorithm 3: The algorithm, that constructs a DAG from postfix notation formulas
Data: Let T be a set of formulae in postfix notation, let S be an empty LIFO stack for
temporary storage for nodes, let Ψ is a list of input variable names being used in
the propositional logic formulae. First element being the first input etc.
Result: Graph G = (I, F, O, E), with set of input nodes I, function nodes F , output
nodes O and set of edges E.
Let Λ(x) denote the variable name corresponding to some node.
let Ω(t) denote the function table, that corresponds to operator t
— Create all the input nodes first —
foreach ψ ∈ Ψ do
xψ = CreateInputNode()
let Λ(xψ ) := ψ
push ψ to I
foreach Ti ∈ T do
while there are more tokens in Ti do
pop t from Ti
switch type of t do
case t is a variable name
let x ∈ G be the node, such that Λ(x) = t
push x to stack S
case t is a unary ¬ operator
if sizeof (S) = 0 then
report a parsing error
else
push x to stack S
y = CreateF unctionN ode(f unctionT able = Ω(¬))
push edge (x, y) to E
push y to F and S
case t is a binary operator
if sizeof (S) ≤ 1 then
report a parsing error
else
pop x1 , x2 from stack S
y := CreateF unctionN ode(f unctionT able = Ω(t))
push (x1 , y) to E
push (x2 , y) to E
push y to F and S

if sizeof (S) 6= 1 then


report a parsing error
x←S
if Ti defines a new variable ψ then
Let Λ(x) := ψ
push x to F
else
Let y := CreateOutputN ode()
push edge (x, y) to E
push y to O
if sizeof (S) 6= 0 then
report a parsing error 16
C Input file format of the DAG
C.1 The overall file structure
1. On the first line there must be exactly n strings s1,...,sn, where si is the variable name
for the i’th input of the circuit.
2. All the following lines have 3 options:
• A blank line
• A comment line, which starts with character #.
• A line beginning with def SUBFORMULANAME Gi, where SUBFORMULANAME denotes the
variable name associated with the subformula Gi. Between tokens def, SUBFORMULANAME,
Gi must be exactly 1 space character.
• A line containing Fi, that is a formula, whose output value is associated to i’th output
wire of the circuit.

C.2 Legal variable names, that can be used to name input variables
names and subformulae names must satisfy following constraints
1. A variable name starts with an uppercase latin character. All the following characters may
be in addition to uppercase latin characters be any numerical character in range 0,...,9
(some legal variable names are X1, X55B, YVWE98.
2. Maximum allowed variable length is 32 characters.

C.3 The characters used to notate propositional logic operators are


1. ¬ is character ! as negation
2. ∧ is character & as conjuction
3. ∨ is character v as disjunction
4. → is character i as implication
5. ↔ is character = as equivalence
6. ⊕ is character ^ as exclusive-or

C.4 Example file


0: X1 X2 X3 Y1 Y2 Y3
1:
2: def E1 X1=Y1
3: def E2 X2=Y2
4: def E3 X3=Y3
5: def G1 !E1&(X1iY1)
6: def G2 !E2&(X2iY2)
7: def G3 !E3&(X3iY3)
8:
9: E1&E2&E3
10: G1vE1&G2vE1&E2&G3

17
In the example file we see a function f (x, y) = (x = y, x > y) = Z for two 3-bit unsigned
integers x and y. This file describes the circuit on Figure 1. As we see, on the first line of the
input, there are defined 6 variable names: X1 X2 X3 Y1 Y2 Y3, that by specification mean, that
the first input is X1, the second X2 etc.
Next lines define subformulae E1 E2 E G1 G2 G3, where the ones beginning with letter E
are true, if the corresponding bits of the integers are equivalent. The subformulae starting with
character G denote that the bit of the first integer is greater than the corresponding bit of the
second integer.
Last two lines define two formulae. First one is : E1 ∧ E2 ∧ E3, that’s value is true if all the
bits of the integers are equivalent. This formula also defines the first output Z1 of the DAG. The
second formula is G1∨E1∧G2∨E1∧E2∧G3 that is true, if X = (X1 , X2 , X3 ) > Y = (Y1 , Y2 , Y3 ).
This also defines the second output Z2 of the circuit.

D XML format used to save a garbled circuit


<?xml version="1.0" encoding="UTF-8" ?>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="circuit">
<xs:complexType>
<xs:sequence>
<xs:element ref="node" maxOccurs="unbounded"/>
<xs:element ref="edge" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="numNodes" type="xs:integer" use="required" />
<xs:attribute name="numEdges" type="xs:integer" use="required" />
<xs:attribute name="id" type="xs:string" use="required" />
</xs:complexType>
</xs:element>

<xs:element name="edge">
<xs:complexType>
<xs:attribute name="srcIndex" type="xs:integer" use="required" />
<xs:attribute name="dstIndex" type="xs:integer" use="required" />
<xs:attribute name="src" type="xs:integer" use="required" />
<xs:attribute name="dst" type="xs:integer" use="required" />
</xs:complexType>
</xs:element>

<xs:element name="node">
<xs:complexType>
<xs:sequence>
<xs:element ref="table" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="numInputs" type="xs:string" use="required" />
<xs:attribute name="numOutputs" type="xs:string" use="required" />
<xs:attribute name="id" type="xs:integer" use="required" />
</xs:complexType>

18
</xs:element>

<xs:element name="table">
<xs:complexType mixed="true" />
</xs:element>

E Performance test scripts


The following python script was ran from the project’s directory.

#!/usr/bin/python

import timeit

f=open(’benchmark.txt’,’w’)

f.write("how_many_repetitions\tcreating_time_8bit\tevaluating_time_8bit\t
creating_time_32bit\tevaluating_time_32bit\n");
for times in [5, 10, 20, 30, 40, 50, 70, 90, 110, 130, 150, 200, 250, 500, 750, 1000, 1500]:
s =’’’
import subprocess

subprocess.Popen(’bin\yao.exe create formulae\uint8_ge.formula circuit keys rewriterules’,


shell=True).wait()
’’’

t = timeit.Timer(stmt=s)
f.write(’{0}\t{1}\t’.format(times, t.timeit(number=times)))

s =’’’
import subprocess

subprocess.Popen(’bin\yao.exe evaluate circuit keys rewriterules inputs outputs’,


shell=True).wait()
’’’

t = timeit.Timer(stmt=s)
f.write(’{0}\t’.format(t.timeit(number=times)))

s =’’’
import subprocess

subprocess.Popen(’bin\yao.exe create formulae\uint32_ge.formula circuit keys rewriterules’,


shell=True).wait()
’’’

t = timeit.Timer(stmt=s)
f.write(’{0}\t’.format(t.timeit(number=times)))

19
s =’’’
import subprocess

subprocess.Popen(’bin\yao.exe evaluate circuit keys rewriterules inputs outputs’,


shell=True).wait()
’’’

t = timeit.Timer(stmt=s)
f.write(’{0}\n’.format(t.timeit(number=times)))
f.flush()

f.close()

20