• No results found

Implementing Cryptographic Program Obfuscation

N/A
N/A
Protected

Academic year: 2020

Share "Implementing Cryptographic Program Obfuscation"

Copied!
19
0
0

Loading.... (view fulltext now)

Full text

(1)

Implementing Cryptographic Program Obfuscation

Daniel Apon∗ Yan Huang† Jonathan Katz∗ Alex J. Malozemoff∗

Abstract

Program obfuscation is the process of making a program “unintelligible” without changing the program’s underlying input/output behavior. Although there is a long line of work on heuristic techniques for obfuscation, such approaches do not provide any cryptographic guar-antee on their effectiveness. A recent result by Garg et al. (FOCS 2013), however, shows that cryptographic program obfuscation is indeed possible based on a new primitive called agraded encoding scheme.

In this work, we present the first implementation of such an obfuscator. We describe several challenges and optimizations we made along the way, present a detailed evaluation of our im-plementation, and discuss research problems that need to be addressed before such obfuscators can be used in practice.

1

Introduction

The goal ofprogram obfuscationis to make programs “unintelligible” while preserving their original behavior. Formally, an obfuscator O is a compiler taking as input a program f (expressed, say, in C code or as a Boolean circuit) and outputting an obfuscated program f0 = O(f) such that

f0(x) =f(x) for all inputs x. Intuitively, the security requirement is that the obfuscated code f0

reveals nothing about the internal structure of the original program f other than what can be inferred from its input/output behavior and (a bound on) its size/running time.

For decades, program obfuscation has been suggested for, e.g., protecting intellectual prop-erty [24] or avoiding static or dynamic code analysis [23, 29, 31]. Generally, researchers have approached the problem by applying a series of static program transformations, hoping to ob-tain an incomprehensible (but equivalent) version of the original program. Unfortunately, such approaches do not offer any cryptographic guarantee of security. However, the recent landmark result of Garg et al. [17] demonstrates that cryptographic program obfuscation can be achieved, assuming agraded encoding scheme. Since then, many papers have been written improving various aspects of the original construction [3,5,11,25] and utilizing the technique for many interesting applications [10,16,20,26].

The construction of Garg et al. [17] satisfies a weaker notion of obfuscation than the virtual black-box obfuscationnotion described intuitively above (which is known to be impossible to achieve in general [6]). This weaker notion, calledindistinguishability obfuscation, ensures that for any two equivalent programs f and g (i.e., programs such thatf(x) =g(x) for all x), an obfuscation off

is indistinguishable (in a cryptographic sense) from an obfuscation of g. While weaker than vir-tual black-box obfuscation, indistinguishability obfuscation is surprisingly powerful. Applications

University of Maryland. {dapon,jkatz,amaloz}@cs.umd.edu †

(2)

of indistinguishability obfuscation include deniable encryption [26], efficient traitor tracing [10], two-round multiparty computation with succinct messages [16], full domain hash without a ran-dom oracle [20], and more. In addition, many obfuscation constructions have been shown to be virtual black-box obfuscators in a generic model [3,5, 11], and it appears that such constructions may indeed be virtual black-box obfuscators for particular classes of functions, such as evasive

functions [4].

Yet despite the fast growing body of literature on cryptographic program obfuscation, the idea has thus far remained entirely theoretical. It was not even clear whether these new constructions are even close to practically feasible.

Contributions. This work investigates the practicality of cryptographic program obfuscation through implementation and experimentation.

• We implement a full program-obfuscation toolchain for the first time, based on schemes from the literature [5,11] and using the formula-to-branching-program construction of Ananth et al. [3]; see Section 2 and Section 3. Our code is publicly available for the benefit of the research community.1

• We investigate the practicality of program obfuscation through experiments; see Section 4. We find that program obfuscation is still far from being deployable, with the most complex functionality we are able to obfuscate being a 16-bit point function (i.e., a function that outputs 1 if the input matches some secret value, and 0 otherwise).

• We discuss the implications of our work and the bottlenecks that researchers should focus on to make obfuscation more practical; see Section5.

2

Overview

In this section, we provide a self-contained overview of the techniques underlying cryptographic program obfuscation and our implementation. Our obfuscator O takes as input a program repre-sented as aBoolean formula. (We only implement “basic” obfuscation and not the “bootstrapping” step which requires obfuscating an FHE logic implemented purely by Boolean formulas to obfus-cate generic Boolean circuits. Note that any circuit can be expressed as a formula; although this results in exponential blowup asymptotically, for moderately-sized circuits converting the circuit to a formula and using basic obfuscation should be more efficient than applying bootstrapping to the original circuit.) A Boolean formula is a binary tree where each vertex is labeled with some Boolean gate type — in our implementation, AND, NOT, or XOR — and each leaf is labeled with some input bit xi for i∈ {1, . . . , n}; the root of the tree corresponds to the (1-bit) output.2 The

depth dof a formula is the number of vertices on the longest path from any leaf to the root, and thesize sof a formula is the number of vertices in the entire tree.

Given a Boolean formulaf, our obfuscator proceeds through a sequence of transformations (see Figure 1) before producing the final obfuscated program O(f). We give a general outline of these steps before giving further details:

1https://github.com/amaloz/obfuscation 2

In order to obfuscate a function withk output bits one would need to constructk Boolean formulas, with the

(3)

f[7] or [28]BPf convert M BPf randomize MBP^f encode O(f) evaluate on xf(x)

Section2.1 Section2.2 Section2.3 Section 2.4 Section 2.5

Figure 1: Workflow diagram for obfuscation. Starting from a Boolean formula f, we first convert f to a branching program BPf using one of two methods. We then convert this to a matrix branching

pro-gram MBPf. Next,MBPf is randomized to giveMBP^f. Finally, each matrix element inMBP^f is encoded

using a graded encoding scheme. The output of this procedure is an obfuscationO(f) off. Any party given O(f) can evaluate it on any inputxof their choice to computeO(f)(x) =f(x).

1. The Boolean formula f is converted into a functionally equivalent branching program BPf, written as a directed, acyclic graph (Section2.1.1). (Branching programs are defined below.)

2. The branching programBPf is mapped to amatrix branching program MBPf, which consists of a sequence of pairs of matrices (Section 2.2).

3. The matrix branching programMBPf israndomized to give^MBPf (Section2.3). Intuitively,

this step (in combination with the next step) prevents an attacker from mixing-and-matching different pieces of the computation together.

4. The randomized matrix branching program^MBPf is then encoded, matrix element by matrix element, using a graded encoding scheme (Section2.4). This step can be viewed, naively, as encryptingMBPf using a scheme that enables homomorphic evaluation ofMBPf, and is the

only step that relies on a cryptographic hardness assumption. It has the effect of hiding from the attacker all details of the matrix branching program as well any information about the computation being performed (other than the final output).

We now describe each of these steps in more detail. In order to illustrate the concepts, we use the running example of obfuscating a single AND gate, i.e., the Boolean formulaf(x1, x2) =x1∧x2. Notation. We letλdenote the security parameter. That is, an obfuscation with security parameter

λ is designed to bound the probability of successful attacks by 2−λ. We let [k] = {1, . . . , k}, use bold letters to denote vectors, and use capital letters to denote matrices.

2.1 Branching Programs

Letf :{0,1}n→ {0,1}be some Boolean formula, and letx∈ {0,1}nbe the input withxidenoting the ith bit of x. A branching program is a directed acyclic graph whose vertices are partitioned into disjoint layers, defined as follows:

Definition 1 A branching program of widthw and length m is a directed acyclic graph with s vertices, such that the following constraints hold:

Each vertex is either a source vertex, an internal vertex or a finalvertex.

(4)

There are two final vertices; both have out-degree zero and one is labeled ‘0’ and the other ‘1’.There is a unique source vertex with in-degree zero.

The vertices are partitioned into m layers Lj, where |Lj| ≤ w. All vertices in a layer have the same label ‘xi’.

Edges starting in layer Lj end in some layerLj0 with j0 > j.Both final vertices are in the same layer, Lm.

Note that the notation ‘xi’ stresses it is the symbol, rather than the bit value represented by the

symbol, which is associated with a vertex.

We can evaluate a branching program as follows. On input x=x1· · ·xn, start from the source

node in the branching program and traverse the edges corresponding to the Boolean value of the current node’s label. For example, suppose the source node has label ‘xj’. Then, on an input x

wherexj = 1, we would take the outgoing edge labeled ‘1’. The 0/1 label of the final vertex is the

output of the program.

2.1.1 From Formulas to Branching Programs

At the time of writing, there were two approaches for compiling Boolean formulas into branching programs: using Barrington’s theorem [7] (as done in the work of Garg et al. [17], among others), or using the approach of Sauerhoff et al. [28] (as proposed in the work of Ananth et al. [3]).3 Barrington’s theorem shows how to convert any Boolean formula of depth d into a branching program of width 5 and length at most 4d, whereas the approach of Sauerhoff et al. converts formulas of sizesinto branching programs of width at most 2s+ 4 and length at mosts. However, the approach of Sauerhoff et al. is more efficient both asymptotically [3] and in practice, and thus our implementation focuses on this approach.

The transformation of Sauerhoff et al. from formulas to branching programs is inductive. The base case is a “trivial” branching program—one for each input wire—consisting of only three ver-tices: the source node, the reject node, and the accept node. There is a directed edge labeled ‘1’ from source to accept, and a directed edge labeled ‘0’ from source to reject.

We then proceed inductively. Given a branching program BPf for some formula f, we can construct the branching program for the formula ¬f by swapping the labels of the accept and reject nodes inBPf.

Given two branching programsBPf and BPg for the formulasf and g, we can “AND” the two formulas, producing the branching programBPf∧g, as follows: First, we merge the accept node of BPf with the source node ofBPg. Second, we merge the reject node of BPf with the reject node of BPg. Finally, we let the source node of BPf be the source node of BPf∧g, and let the accept

and reject nodes of BPg be the accept and reject nodes, respectively, of BPf∧g. (Figure 2 shows

the branching program obtained by applying this approach to a single AND gate.)

Lastly, given two branching programs BPf and BPg for the formulas f and g, we can “XOR” the two formulas, producing the branching program BPf⊕g as follows: Without loss of generality,

assume BPg is the smaller of the two branching programs (otherwise we can swap the order of f

andg). We first duplicateBPg and use the NOT-transformation to produceBP¬g. Next, we merge

the accept node ofBPf with the source node ofBP¬g and merge the reject node of BPf with the 3Recently, two new approaches [27,32] to constructing obfuscators present asymptotic improvements to the

(5)

src

acc

rej

1

0

1

0

x0 x1

Figure 2: Branching program for an AND gate. To evaluate on inputx0x1, look at each layer of the graph

(denoted by the dotted rectangles). If the layer corresponds to the ith input bit, then remove all outgoing edges from that layer that are not labeled by the valuexi. The output is 1 iff there is a path from src to acc

in the resulting graph.

source node of BPg. Finally, we merge the accept nodes (and, respectively, the reject nodes) of BPg and BP¬g. The branching program BPf⊕g has the same source node as BPf and the same

accept and reject nodes as BPg (equivalently, BP¬g).

We now prove that given a branching program constructed as above, then for all inputsx there exists at most one path from the source to the accept node.

Lemma 1 Let BPf be a branching program constructed using the above procedure. Then for all x, there exists at most one path from the source to the accept node in BPf.

Proof. We prove the result by induction. Clearly, this holds for the base case (namely, the “trivial” branching program described above). Likewise, it is easy to see that given BPf, the construction

BP¬f also maintains the invariant.

Now let BPf and BPg be two branching programs. We first show that the invariant is

main-tained when we construct BPf∧g. The resulting branching program merges the accept node of BPf with the source node ofBPg; this step maintains the invariant as by induction there exists a single path to the accept node inBPf. Likewise, the resulting branching program merges the reject node of BPf with the reject node of BPg; as this does not affect the accept node the invariant is

maintained.

The proof that the invariant is maintained when we construct BPf⊕g is similar to the above

case, and thus omitted.

2.2 Matrix Branching Programs

The next step is to compile the graph-based branching programBPf into a functionally equivalent

matrix branching program MBPf, which can be evaluated by iterated matrix multiplication. We utilize the notion of a matrix branching program, defined as follows:

Definition 2 A matrix branching program of width w and length m for n-bit inputs is given by a tuple

MBPf =inp,s,(Bj,0, Bj,1)j∈[m],t

where Bj,b ∈ {0,1}w×w, for j ∈ [m] and b ∈ {0,1}, inp : [m] → [n] is a function mapping layer indices j to input-bit indices i, s := (1,0, . . . ,0), and t := (0, . . . ,0,1)T. The output of MBPf on input x∈ {0,1}n is defined as:

MBPf(x) = (

1 if s·Qm

j=1Bj,xinp(j)

·t≥1

(6)

               1 0 0 0      |{z} s ,          

1 0 1 0

0 1 0 0

0 0 1 0

0 0 0 1

     ,     

1 1 0 0

0 1 0 0

0 0 1 0

0 0 0 1

         

| {z }

x0 ,          

1 0 0 0

0 1 1 0

0 0 1 0

0 0 0 1

     ,     

1 0 0 0

0 1 0 1

0 0 1 0

0 0 0 1

         

| {z }

x1 ,      0 0 0 1      |{z} t          

Figure 3: Matrix branching program for an AND gate. To evaluate on inputx0x1, proceed as follows. If xi= 0, choose the first matrix; otherwise choose the second matrix. Multiply the matrices; if the [1,4] entry

of the resulting matrix is 1 then the output is 1; otherwise, the output is 0.

Note that the output of a matrix branching program is the entry in the first row and last column of the iterated matrix product, and the vectors sand t simply select this entry as the output.

To convert a branching program to a matrix branching program, we proceed as follows. For each layer Lj of BPf, we produce two w-by-w 0/1-valued matrices Bj,0, Bj,1. The matrix Bj,b is the adjacency matrix composed of edges leaving layer Lj with label b. Additionally, we set the diagonal entries to 1 (i.e., we include self-loops in the adjacency matrix), which is needed since as an optimization we allow layers in our branching program construction to have differing numbers of nodes. (In Figure3we depict the matrix branching program generated from the branching program from Figure2.)

We now prove that when using the above procedure to convert branching programs to their matrix equivalents, it in fact holds thats·Qm

j=1Bj,xinp(j)

·t∈ {0,1}, which saves us from running

therandBP0 step as detailed by Ananth et al. [3].

Lemma 2 Let MBPf be a matrix branching program converted from a branching program BPf

using the above procedure. Then for all inputs x, it holds thats·Qm

j=1Bj,xinp(j)

·t∈ {0,1}.

Proof. This follows directly from combining Lemma 1 with the proof of Lemma 2 from the work of Ananth et al. [3]. Namely, in the latter proof, we can utilize the fact that there exists at most one path between any two vertices in the graph of BPf to conclude that the resulting matrix

computation contains only 0/1 values.

2.2.1 Oblivious Branching Programs

Depending on the setting, it may also be necessary to ensure that the inp function does not leak information about the underlying formulaf. (This is needed in order to satisfy the formal definition of obfuscation. But in settings where some information aboutf is known anyway—e.g., when f is known to be a point function, and only the hidden point must remain secret—this step may not be needed.) This can be done by fixinginpindependently off, settinginpto cycle through each of the input bits x1, x2, . . . , xn in order,mtimes. “Dummy” layers are filled in with a pair of identity

matrices, thus preserving correctness of the iterated matrix multiplication.

(7)

transforming the graph into a matrix branching program to prevent the attacker from learning information about what gate is being computed by simply looking at the width of the matrix branching program.

2.3 Randomized Matrix Branching Programs

The first step toward hiding the underlying computation is to randomize the matrices [21]. This randomization ensures that an attacker cannot “mix-and-match” steps of the computation once the matrices have been encoded under the graded encoding scheme.

Let g be a prime, and define the procedurerandg(MBPf) as follows:

1. Uniformly samplem+ 1 invertible matrices from Zw×wg , denoted R0, . . . , Rm.

2. LetBej,b:=Rj−1Bj,bRj−1 for all j∈[m], b∈ {0,1}.

3. Compute two “bookend” vectorses:= (1,0, . . . ,0)·R01 andet:=Rm·(0, . . . ,0,1)T. 4. Output^MBPf,g =

inp,es,

e

Bj,0,Bej,1

j∈[m],et

.

Indeed, we have that for all inputs x∈ {0,1}n,

^

MBPf,g(x) =es· 

m Y

j=1 e Bj,xinp(j)

·et=s·R01· 

m Y

j=1

Rj−1Bj,bRj1 

·Rm·t

=s·

m Y

j=1

Bj,xinp(j)

·t=MBPf(x),

where matrix multiplication arithmetic is performed modulo g. For notational convenience, we drop theg subscript and write ^MBPf when the modulus is understood.

2.4 Graded Encoding Schemes

While the prior randomization step ensures that a valid sequence of matrices must be multiplied in order, we still need to ensure that (1) only valid sequences of matrices give meaningful output, and (2) the matrix values themselves are hidden—or more generally, that inspecting the obfuscated program does not leak distinguishing information about the underlying implementation. Concretely, observe that randomized matrix branching programs can suffer from attacks that try to compute something other than the original functionf(x). For example, if two layersLj andLj0 of^MBPf are

labeled with the same input bitxi, it is possible to includeBj,e 0and Bej0,1 in the product and obtain

some output where the randomRj terms still cancel out. This equates to computing a functionf0

that is different from f, which enables the attacker to do things that are impossible merely from access tof.

To thwart such attacks, we need to use some cryptographic mechanism to hide the entries of the matrices and to prevent an attacker from using inconsistent matrices for some input bit. The cryptographic primitive used is a graded encoding scheme [15].

(8)

encoding u0 of a message m0, can add u +u0 to get a new encoding of the message m +m0. Similarly, multiplying encodingsu·u0 gives a new encoding of the message m·m0.

Unlike FHE, however, each encoding u is defined relative to some subset S of a universe [Z]. These subsets restrict the way in which encodings may be added and multiplied. In particular, two encodings may only be added if they are encoded relative to the same setS, and their sum is encoded relative toS as well. Moreover, two encodings may only be multiplied if they are encoded relative to twodisjoint setsSandS0, and their product is encoded relative to theunionofS andS0. Finally, and again in contrast to FHE, there is a public “zero-test parameter” pzt that is used

to test if an encoding u encodes the plaintext 0. However, zero-testing only works on encodings relative to theentire universe [Z].

Definition 3 A graded encoding scheme is a tuple of probabilistic polynomial time algorithms

(InstGen, Enc,Add, Mult, isZero) that behave as follows:

Instance Generation: (sp,pp)←InstGen(1λ,1κ).

InstGen takes as input the security parameter λand multilinearity parameter κ, and outputs

secret parametersspand public parameterspp. The secret parametersspcontain an integerZ with κZ ≤2κ, primes g1, . . . , gN, where N = poly(λ, κ), and a collection of sets {ESm : mZg1 × · · · ×ZgN, S ⊆[Z]}. We view ESm as the set of possible encodings of the value m with respect to the setS. The public parameters pp enable the public operations on encodings described below.

Encoding: u←Enc(sp, m, S).

Enctakes as input the secret parameters sp, a plaintext valuemZg1× · · · ×ZgN, and a set

S⊆[Z], and outputs a randomized encoding of m with respect to the setS, denoted uESm.Addition: u←Add(pp, u, u0).

Add takes as input the public parameterspp and encodingsuESm, u0 ∈ESm00, and outputs an encoding uESm+m0 if S =S0, andotherwise.

Multiplication: u←Mult(pp, u, u0).

Mult takes as input the public parameters pp and encodings uESm, u0 ∈ ESm00, and outputs an encoding uES∪Sm·m00 if SS0 =∅, and ⊥ otherwise.

Zero Test: b←isZero(pp, u).

isZero takes as input the public parameters pp and an encoding u and outputs 1 if uE[0Z]

(i.e., u is an encoding of 0 with respect to the entire universe [Z]), and 0 otherwise.

We defer a discussion of security until later, but informally, a graded encoding scheme is secure if (1) the only way an evaluator can produce an encodingu∗of the all-zeros plaintext with respect to the entire universe [Z] is by combininggivenencodings{u1, u2, . . .}by addition and multiplication, and (2) only such encodingsu∗ pass the zero-test.

2.4.1 Choosing a Set System

(9)

to a fixed setting of each input bit xi ∈ {0,1}. In particular, we ensure that only combinations

of matrices in^MBPf that are consistent with some well-defined inputx produce an encoding that forms an exact set cover of [Z]. Thus, we associate each matrix of ^MBPf with a distinct subset

S ⊂[Z]. This means that for any fixed matrix of^MBPf, we encode each of its individual elements using the same set S. The vectorssand t are each encoded using a distinct element in [Z].

More concretely, we group the matrices of ^MBPf according to their input bit label ‘xi’. For

example, denote the matrices associated with x1 as Bej1,0,Bej1,1, . . . ,Bej

k,0,Bejk,1 (for some k). We

assign setsS to these matrices as follows:

• We assign the matricesBej1,0,Bej2,0, . . . ,Bej

k,0the sets{1,2},{3,4}, . . . ,{2k−3,2k−2},{2k−1}

(in that order).

• We assign the matrices Bj1,e 1,Bj2,e 1, . . . ,Bje k,1 the sets {1}, {2,3}, . . . , {2k−2,2k−1} (in that order).

We continue this process for each such group of matrices (associated with the remaining labels ‘x2’, . . . , ‘xn’) using increased set-indices, until every matrix is assigned a distinct subsetS ⊂[Z]. This process allows us to determine the value ofZ needed in our implementation, which we increase by two to account for encoding the vectors s and t.

Note the attacker cannot use inconsistent values for a given variable since sets corresponding to the inconsistent values are not disjoint (as valid multiplications require disjoint sets). The attacker cannot run a zero-test on a partially evaluated program either, because the encoding of a partial result is always formed with respect to a strict subset of Z whereas zero-testing only works for encodings regarding the (full) setZ.

2.5 Executing Obfuscated Programs

Putting everything together, an evaluator can use the Add and Mult procedures of the graded encoding scheme to evaluate the iterated matrix multiplication of an underlying, randomized matrix branching program^MBPf on some input x, retrievingEnc(s·Qm

j=1Bj,xinp(jt) =u. The evaluator

can then use isZero to zero-test this result; namely, if isZero(pp, u) = 1 then f(x) = 0, otherwise

f(x) = 1.

3

Implementation

We have implemented an obfuscator using both Barrington’s theorem [5] and the approach of Sauerhoff et al. [3] for converting formulas to branching programs. Our implementation is written in a combination of Python and C, using Sage [30] for algebraic operations, the GNU Multiple Precision Arithmetic Library [1] for efficient large number computations, and OpenMP [2] for parallelization. We program all the computationally expensive steps in C, and thus our use of Python does not significantly affect the overall performance.4

As shown in Figure 1, our tool takes as input a Boolean formula f and produces as output its obfuscated form O(f), which can then be evaluated by anyone who receives a copy of it. In

4

For example, when obfuscating and evaluating f(x0, x1) = x0∧x1 with security parameter 128 we find that

(10)

the rest of this section, we provide details about our implementation and discuss some challenges encountered during implementation along with the various optimizations we made to address them.

3.1 Implementing Graded Encodings

We utilize the graded encoding scheme of Coron et al. [14] (the “CLT scheme”), which has better space efficiency than the scheme based on ideal lattices [15]. The CLT graded encoding scheme is instantiated as follows. (We discuss the concrete values of all parameters in Section3.1.2.)

• InstGen: Let Z be the desired size of the set system (cf. Section 2.4.1), and N a value

that depends on Z and the security parameter λ (see Section 3.1.2). First, we generate

N (large) secret primes {pi}Ni=1 and compute their product q = QN

i=1pi. In addition, we generate N (small) secret primes {gi}Ni=1,N random integers {hi}Ni=1, andZ random values

z1, . . . , zZ∈Zq.

Next, we construct a zero-test parameter, defined as the integer5

pzt= N X

i=1 hi·

Z Y

j=1

zj ·gi 1 modpi

· Y

i06=i

pi0 modq.

The secret parameters are{zi}Zi=1,{gi}Ni=1,{pi}Ni=1

; the public parameters are (pzt, q).

• Enc: An encoding of a message m = (m1, . . . , mN) ∈ Zg1 × · · · ×ZgN relative to the set

S⊆[Z] is a valueuZq such that for all 1≤iN,

uriQ·gi+mi j∈Szj

(modpi) (1)

for (small, random) integers ri.

• Add: Givenu, u0 ∈Zq with

i: uriQ·gi+mi j∈Szj

(modpi), u0≡ r 0

i·gi+m0i Q

j∈Szj

(modpi),

it is easy to see that

i: u+u0 ≡ (ri+r 0

igi+ (mi+m0i) Q

j∈Szj

(modpi),

which lies inESm+m0 assuming (ri+r0igi+ (mi+m0i)< pi for all i. • Mult: Let S and S0 be sets such thatSS0 =∅. Given u, u0∈Zq with

i: uriQ·gi+mi j∈Szj

(modpi), u0 ≡

rigi+m0i Q

j∈S0zj

(modpi)

5Note that here we are utilizing the heuristic as presented by Coron et al. [14, §6] of using a single zero-testing

(11)

it is easy to see that

i: u·u0≡ (rir 0

i+rim0i+ri0migi+mim0i Q

j∈S∪S0zj

(mod pi),

which lies inES∪Sm·m00 assuming (rir0i+rim0i+r0imigi+mim0i < pi for all i.

• isZero: Using pzt, we zero-test an element u encoded with respect to [Z] by first computing

ω:=pzt·u (mod q)

where

pzt·u=   N X i=1 hi·   Z Y j=1

zj·gi−1 modpi

· Y

i06=i pi0

  ·   N X i=1

(ri·gi+mi

Z Y

j=1

zj−1 modpi

· 

 Y

i06=i

pi0(p−1

i0 modpi)

 

 (modq)

=

N X

i=1 hi·

Z Y

j=1

zj·gi−1 modpi

·(ri·gi+mi)· 

Z Y

j=1

zj1 modpi

· Y

i06=i

pi0 (modq)

=

N X

i=1

hi·ri+mi·(gi−1modpi)·Y i06=i

pi0 (modq).

Then, we test whether ω ∈ Z is “small” compared to q or not. (Concretely, ω is small if

|ω|< q·2−ν−λ−2.) In particular,ω is small if mi = 0 for alli∈[N], as otherwise for some i, the relatively large gi−1modpi term does not vanish in the final expression.

3.1.1 Using the CLT Graded Encoding Scheme

We make use of the CLT graded encoding scheme as follows:

1. We first construct a (non-randomized) matrix branching programMBPf. Using this we can derive the multilinearityκ of the graded encoding scheme, and thus run InstGen to generate the public and secret parameters.

2. Using the gis generated in the previous step, we can now construct a randomized matrix branching programMBP^f,g1 corresponding to the first “slot” of the plaintext space.

3. Finally, we encode the matrices element by element, where each element is the vector corre-sponding to the same-position matrix element in the randomized matrix branching program.

4. To evaluate on an inputx, we multiply together the matrices (as specified byxandinp) along with the bookend vectors, and zero-test the resulting value.6

6

An earlier version of our implementation did not compute multiplications modulo q as specified in the

Mult procedure above, and also naively computed s ·Qm

j=1Bj,xinp(j)

· t instead of the much more efficient (((s·B1,xinp(1))B2,xinp(2))· · ·Bm,xinp(m)t. We thank Daniel J. Bernstein, Andreas H¨ulsing, Tanja Lange, and Ruben

(12)

κ α β ρ ρf η ν N

10 52 52 52 1060 1276 115 7273

14 52 52 52 1484 1700 115 9690

18 52 52 52 1908 2124 115 12107

Table 4: Concrete parameter settings for various settings of κ. The security parameter λ is fixed at 52. Note that these are the parameters for the obfuscations presented in Table5.

3.1.2 Setting Parameters

The parameters given by Coron et al. [14] were chosen to support their particular use-case of mul-tiparty key exchange, which requires a public mechanism forre-randomizing encodings. However, in the case of program obfuscation, there is no need to re-randomize. This allows us to optimize the parameters of the scheme to gain improved efficiency. That is, sinceAdd and Multgive correct results as long as the growth of the noise termsri does not cause any of the respective numerators of an encoding to exceed the moduli pi, we only need to set the size of the pi sufficiently large to

ensure we can perform all the operations required to evaluate the obfuscated program.

Similarly, we can bound ρf, the maximum size in bits of the noise terms ri, at the maximum

depth of multiplication (i.e., when κ initial encodings have been multiplied together) as ρf = κ(2λ+ 2). Using the parameters specified by Coron et al. would have given us ρf κ(5λ+ 2).

Reducing the size of ρf greatly improves efficiency, as it affects the size η of the primes pi, which

subsequently affects the vector dimension. Both of these parameters appear to be the main efficiency bottlenecks.

For completeness, we list all the parameters we use for the CLT scheme, and the reasoning behind our choices. Recall that λ denotes the security parameter. These settings are designed in order to achieve 2λ security against known attacks.

α (the bit-size of the primes gi): λ, to prevent a brute-force attack on the plaintext space. β (the bit-size of thehi values used to constructpzt): λ, due to a GCD-based attack [14,§5.2].7 ρ(the bit-size of the randomri values): λ, to prevent a brute-force attack on the noise [12,14].

η (the bit-size of the primespi): ρf +α+ 2β+λ+ 8, due to [14, Lemma 3]. Recall that ρf is a bound on the noise after performing all the necessary multiplications.

ν (for zero-testing; ω is “small” if the ν most-significant bits of ω are all zeroes): α+β+ 11, due to [14, Lemma 3].

N (the vector dimension of the plaintext space): ηlog2λ, to prevent an orthogonal lattice reduction attack [14,§5.1].

Table4 presents concrete numbers for various settings ofκwith a fixed security parameter of 52.

3.2 Security of Our Implementation

To date, the security of general-purpose obfuscators has been argued in three general ways:

1. By showing the virtual black-box (VBB) property in an ideal model [5,11],

7

(13)

# CLT param gen BP rand Bookends enc Layer enc Obf time

pi/gi CRT zi pzt total avg total avg total

8 168.55 38.88 6.57 58.21 272.22 3.52 12.66 25.44 88.21 705.68 1007.40 12 428.94 76.85 12.88 116.73 635.42 11.88 30.16 60.45 346.25 4154.98 4863.87 16 944.25 164.68 24.65 212.89 1346.50 28.25 61.27 122.71 1359.19 21747.12 23246.24

Table 5: Microbenchmarks for point function obfuscation, with security parameterλ= 52. All timings are in seconds. ‘#’ denotes the input size of the point function. ‘pi/gi’ denotes the time to generate random

pis and gis, as well as computeq=Qpi. ‘CRT’ denotes the time to compute CRT coefficients for thepi’s,

which is used when encoding. Likewise, ‘zi’ and ‘pzt’ denote the time required to generatezis and the zero

test elementpzt. ‘BP rand’ denotes the time required to randomizeλbranching programs. (This is the only

computationally expensive step not implemented in C.) ‘Bookend enc’ denotes the time to construct and encode the bookend vectors. ‘Layer enc’ denotes the time to encode each layer of the randomized matrix branching program. ‘Obf time’ denotes the total time to obfuscate (which includes the CLT parameter generation time and encoding times). See Table4 for the concrete CLT parameters for these obfuscations.

# Obfuscation Evaluation

Time Size RAM Time RAM

8 1007.40 1.75 8.95 57.85 0.51 12 4863.87 9.07 21.09 213.13 1.10 16 23246.24 31.13 41.20 655.40 2.58

Table 6: Time, RAM usage, and size for obfuscating and evaluating different sized point functions. ‘#’ de-notes the input size of the point function. ‘Time’ dede-notes the running time (in seconds) to obfuscate/evaluate a given point function. ‘Size’ denotes the size (in GB) of the resulting obfuscation. ‘RAM’ denotes the max-imum amount of memory (in GB) used during obfuscation/evaluation. See Table4 for the concrete CLT parameters for these obfuscations.

2. By an exponential number of “semantically-secure graded encoding” assumptions [9,25], or

3. By a single assumption on multilinear groups (and CLT encodings’ quality as an instantiation of multilinear groups) plus complexity leveraging [19].

An ideal model proof of VBB security for our scheme would follow that of Barak et al. [5], except that we do not use dual-input branching programs in our implementation (as an efficiency optimization). Consequently, we do not know how to directly prove Claim 5 in their work [5,§6], namely that, to use their terminology, profiles of all single-input elements are complete. Nonetheless, we observe that an ideal model proof of VBB security for our scheme should go through in a straightforward way assuming the Bounded Speedup Hypothesis [11].

4

Evaluation

To evaluate our implementation, we obfuscated point functions of various sizes. We ran the code8 on a 64-core machine using the Intel Xeon Processor E7-8830 and one terabyte of RAM, and we thank David Archer and Getty Ritter of Galois, Inc., for providing access to the machine. We limited the number of cores used to 32 and used non-oblivious branching programs.

8

(14)

We obfuscated point functions taking 8, 12, and 16 bits of input, using security parameter 52 throughout.9 These functions produce branching programs of widths 10, 14, and 18, respectively. Due to the time it took to obfuscate and evaluate each function, we only conducted a single run for each. Table 5 breaks down the cost of each step in the obfuscation process, Table 6 breaks down the cost (in time and RAM usage) of obfuscating and evaluating each function.

Note that the majority of time is spent encoding elements; the CLT parameter generation takes only 4–10% of the overall running time. Also note the large amount of RAM required to obfuscate. A large portion (90%+) of this is to compute and store the CRT coefficients which are needed to make encoding efficient. Finally, note that evaluation is much faster (between 17× and 35×) than obfuscation, and in addition uses much less RAM. This is “promising” in the sense that evaluation is more important “in practice” than obfuscation, as obfuscation can be thought of as a one-time operation, whereas parties can evaluate the obfuscated circuit any number of times. (Of course, evaluation is still too costly for nearly all realistic applications.)

5

Discussion and Conclusion

In this work, we provide the first implementation of cryptographic program obfuscation. We discuss both challenges encountered and optimizations made over the course of our development, and present a detailed evaluation of the performance of such obfuscators. Although we show that obfuscation is still far from practical, we are still able to obfuscate some “meaningful” programs. We hope that the availability of an obfuscation prototype will spur further work in both making obfuscation more practical as well as understanding the underlying security primitives better.

The evaluation results from Section 4 show that work still needs to be done before program obfuscation is usable in practice. In fact, the most complex function we obfuscate with meaningful security is a 16-bit point function, which contains just 15 AND gates. Even such a simple function requires about 9 hours to obfuscate and results in an obfuscation of 31.1 GB. Perhaps more importantly (since the obfuscation time is a one-time cost), evaluating the 16-bit point obfuscation on a single input takes around 3.3 hours. However, it is important to note that the fact that we can produce any “useful” obfuscations at all is surprising. Also, both obfuscation and evaluation are embarrassingly parallel and thus would run significantly faster with more cores (the largest machine we experimented on had 32 cores). Hopefully our implementation will help spur further research into making obfuscation more practical.

Regarding the main bottlenecks in efficiency, the most immediate one is the efficiency of the underlying graded encoding scheme, and in particular, the size η of the primes and the vector dimensionN. Recall thatκrepresents the multilinearity of our graded encoded scheme, and grows linear in the length of the matrix branching program. The size ofη, which affects both the encoding time and overall size of the obfuscation, is roughlyO(κλ). Likewise, N, which also greatly affects the encoding time and size, is roughlyO(ηlogλ) =O(κλlogλ). Unfortunately, these parameters need to be set as such due to known attacks [14]. A possible research direction would be to analyze the practical impact of these attacks, and determine whether these values can be reduced in any way without impacting the overall security.

Ideally, we would even prefer to have a mechanism for graded encoding schemes that func-tions akin to bootstrapping or modulus switching for fully homomorphic encryption, allowing the evaluator to control the growth of the various system parameters mid-computation while retaining

9

(15)

security. Unfortunately, all known noise management techniques for fully homomorphic encryption implicitly rely on the plaintext space being public, while in the case of graded encoding schemes, the parameters that define the plaintext space — the primes gi — must remain secret in order to hide the encoded values.

Another major bottleneck is the use of branching programs, which restrict us to obfuscating

single-bit Boolean formulas. This (1) precludes computing more than n−1 gates in one circuit, and (2) requires obfuscating the computation of every single output bit independently. While branching programs generated using Barrington’s approach suffer from exponential growth with the circuit depth, the work of Ananth et al. [3] is a very important step in reducing the overhead due to branching programs. More recently, Zimmerman [32] devised a construction which avoids branching programs altogether; investigating the practical impact of this approach is left as future work.

Finally, to aid in thecryptanalysisof program obfuscation and the underlying cryptographic tool of graded encoding schemes, we have released a “challenge” to the community: we have published an obfuscated point function with a hidden secret10; the challenge is to determine the secret.11 We hope this (and any future) challenge will inspire cryptanalysts to focus on attacking the cryptographic constructs used in program obfuscation, both to improve confidence in the constructions themselves as well as to better understand the concrete parameters needed for the underlying graded encoding scheme in order to achieve real-world security.

Acknowledgments

The authors thank Prabhanjan Ananth for identifying that Definition 2 from v1.0 stated that

M BPf(x) ∈ {0,1} without a proof. We also thank Daniel J. Bernstein, Andreas H¨ulsing, Tanja

Lange, and Ruben Niederhagen for solving our first challenge, and in the process improving the running time of our evaluation procedure. Finally, we thank David Archer and Getty Ritter of Galois, Inc., for providing access to the machine used to run our evaluation experiments.

This work was supported in part by NSF awards #1111599 and #1223623. Work of Alex J. Malozemoff was conducted with Government support through the National Defense Science and Engineering Graduate (NDSEG) Fellowship, 32 CFG 168a, awarded by DoD, Air Force Office of Scientific Research.

10Note that there are much more efficient ways to obfuscate point functions (such as releasing the SHA hash of the

point). The point here is that the construction presented in this work is “generic” (i.e., works for arbitrary polynomial-size circuits), and point functions are just one example of a function which can be obfuscated, and unfortunately the most “interesting” function we can currently obfuscate in a reasonable amount of time.

11

(16)

References

[1] The GNU Multiple Precision Arithmetic Library. https://gmplib.org. Accessed on May 11 2014.

[2] The OpenMPR API specification for parallel programming. https://openmp.org. Accessed

on May 11 2014.

[3] P. Ananth, D. Gupta, Y. Ishai, and A. Sahai. Optimizing obfuscation: Avoiding Barrington’s theorem. Cryptology ePrint Archive, Report 2014/222, Version 20140329:175740, 2014.https:

//eprint.iacr.org/2014/222.

[4] B. Barak, N. Bitansky, R. Canetti, Y. T. Kalai, O. Paneth, and A. Sahai. Obfuscation for evasive functions. In Y. Lindell, editor,TCC 2014: 11th Theory of Cryptography Conference, volume 8349 ofLecture Notes in Computer Science, pages 26–51, San Diego, CA, USA, Feb. 24– 26, 2014. Springer, Berlin, Germany. Full version available at https://eprint.iacr.org/ 2013/668.

[5] B. Barak, S. Garg, Y. T. Kalai, O. Paneth, and A. Sahai. Protecting obfuscation against algebraic attacks. In P. Q. Nguyen and E. Oswald, editors,Advances in Cryptology – EURO-CRYPT 2014, volume 8441 of Lecture Notes in Computer Science, pages 221–238, Copen-hagen, Denmark, May 11–15, 2014. Springer, Berlin, Germany. Full version available at

https://eprint.iacr.org/2013/631.

[6] B. Barak, O. Goldreich, R. Impagliazzo, S. Rudich, A. Sahai, S. P. Vadhan, and K. Yang. On the (im)possibility of obfuscating programs. In J. Kilian, editor,Advances in Cryptology – CRYPTO 2001, volume 2139 of Lecture Notes in Computer Science, pages 1–18, Santa Barbara, CA, USA, Aug. 19–23, 2001. Springer, Berlin, Germany. Full version available at

https://eprint.iacr.org/2001/069.

[7] D. A. Barrington. Bounded-width polynomial-size branching programs recognize exactly those languages inNC1. Journal of Computer and System Sciences, 38(1):150–164, 1989.

[8] D. J. Bernstein, A. H¨ulsing, T. Lange, and R. Niederhagen. Bad directions in cryptographic hash functions. 2014.

[9] N. Bitansky, R. Canetti, Y. T. Kalai, and O. Paneth. On virtual grey box obfuscation for general circuits. In J. A. Garay and R. Gennaro, editors, Advances in Cryptology – CRYPTO 2014, Part II, volume 8617 of Lecture Notes in Computer Science, pages 108–125, Santa Barbara, CA, USA, Aug. 17–21, 2014. Springer, Berlin, Germany. Full version available

athttps://eprint.iacr.org/2014/580.

(17)

[11] Z. Brakerski and G. N. Rothblum. Virtual black-box obfuscation for all circuits via generic graded encoding. In Y. Lindell, editor,TCC 2014: 11th Theory of Cryptography Conference, volume 8349 ofLecture Notes in Computer Science, pages 1–25, San Diego, CA, USA, Feb. 24– 26, 2014. Springer, Berlin, Germany. Full version available at https://eprint.iacr.org/ 2013/563.

[12] Y. Chen and P. Q. Nguyen. Faster algorithms for approximate common divisors: Breaking fully-homomorphic-encryption challenges over the integers. In D. Pointcheval and T. Johans-son, editors, Advances in Cryptology – EUROCRYPT 2012, volume 7237 of Lecture Notes in Computer Science, pages 502–519, Cambridge, UK, Apr. 15–19, 2012. Springer, Berlin, Germany. Full version available at https://eprint.iacr.org/2011/436.

[13] J. H. Cheon, K. Han, C. Lee, H. Ryu, and D. Stehl´e. Cryptanalysis of the multilinear map over the integers. Cryptology ePrint Archive, Report 2014/906, 2014.https://eprint.iacr. org/2014/906.

[14] J.-S. Coron, T. Lepoint, and M. Tibouchi. Practical multilinear maps over the integers. In R. Canetti and J. A. Garay, editors,Advances in Cryptology – CRYPTO 2013, Part I, volume 8042 ofLecture Notes in Computer Science, pages 476–493, Santa Barbara, CA, USA, Aug. 18– 22, 2013. Springer, Berlin, Germany. Full version available at https://eprint.iacr.org/ 2013/183.

[15] S. Garg, C. Gentry, and S. Halevi. Candidate multilinear maps from ideal lattices. In T. Jo-hansson and P. Q. Nguyen, editors, Advances in Cryptology – EUROCRYPT 2013, volume 7881 of Lecture Notes in Computer Science, pages 1–17, Athens, Greece, May 26–30, 2013. Springer, Berlin, Germany. Full version available athttps://eprint.iacr.org/2012/610.

[16] S. Garg, C. Gentry, S. Halevi, and M. Raykova. Two-round secure MPC from indis-tinguishability obfuscation. In Y. Lindell, editor, TCC 2014: 11th Theory of Cryptog-raphy Conference, volume 8349 of Lecture Notes in Computer Science, pages 74–94, San Diego, CA, USA, Feb. 24–26, 2014. Springer, Berlin, Germany. Full version available at

https://eprint.iacr.org/2013/601.

[17] S. Garg, C. Gentry, S. Halevi, M. Raykova, A. Sahai, and B. Waters. Candidate indistin-guishability obfuscation and functional encryption for all circuits. In54th Annual Symposium on Foundations of Computer Science, pages 40–49, Berkeley, CA, USA, Oct. 26–29, 2013. IEEE Computer Society Press. Full version available athttps://eprint.iacr.org/2013/601.

[18] C. Gentry, S. Gorbunov, and S. Halevi. Graded multilinear maps from lattices. Cryptology ePrint Archive, Report 2014/645, 2014. https://eprint.iacr.org/2014/645.

[19] C. Gentry, A. Lewko, A. Sahai, and B. Waters. Indistinguishability obfuscation from the multilinear subgroup elimination assumption. Cryptology ePrint Archive, Report 2014/309, 2014. http://eprint.iacr.org/2014/309.

(18)

201–220, Copenhagen, Denmark, May 11–15, 2014. Springer, Berlin, Germany. Full version available athttps://eprint.iacr.org/2013/509.

[21] J. Kilian. Founding cryptography on oblivious transfer. In 20th Annual ACM Symposium on Theory of Computing, pages 20–31, Chicago, Illinois, USA, May 2–4, 1988. ACM Press.

[22] H. T. Lee and J. H. Seo. Security analysis of multilinear maps over the integers. In J. A. Garay and R. Gennaro, editors, Advances in Cryptology – CRYPTO 2014, Part I, volume 8616 of

Lecture Notes in Computer Science, pages 224–240, Santa Barbara, CA, USA, Aug. 17–21, 2014. Springer, Berlin, Germany. Full version available athttps://eprint.iacr.org/2014/ 574.

[23] C. Linn and S. K. Debray. Obfuscation of executable code to improve resistance to static disassembly. In S. Jajodia, V. Atluri, and T. Jaeger, editors,ACM CCS 03: 10th Conference on Computer and Communications Security, pages 290–299, Washington D.C., USA, Oct. 27– 30, 2003. ACM Press.

[24] X. Luo, P. Zhou, E. W. W. Chan, W. Lee, R. K. C. Chang, and R. Perdisci. HTTPOS: Sealing information leaks with browser-side obfuscation of encrypted flows. In ISOC Network and Distributed System Security Symposium – NDSS 2011, San Diego, California, USA, Feb. 6–9, 2011. The Internet Society.

[25] R. Pass, K. Seth, and S. Telang. Indistinguishability obfuscation from semantically-secure multilinear encodings. In J. A. Garay and R. Gennaro, editors, Advances in Cryptology – CRYPTO 2014, Part I, volume 8616 ofLecture Notes in Computer Science, pages 500–517, Santa Barbara, CA, USA, Aug. 17–21, 2014. Springer, Berlin, Germany. Full version available

athttps://eprint.iacr.org/2013/781.

[26] A. Sahai and B. Waters. How to use indistinguishability obfuscation: deniable encryption, and more. In D. B. Shmoys, editor,46th Annual ACM Symposium on Theory of Computing, pages 475–484, New York, NY, USA, May 31 – June 3, 2014. ACM Press. Full version available at

https://eprint.iacr.org/2013/454.

[27] A. Sahai and M. Zhandry. Obfuscating low-rank matrix branching programs. Cryptology ePrint Archive, Report 2014/773, 2014. https://eprint.iacr.org/2014/773.

[28] M. Sauerhoff, I. Wegener, and R. Werchner. Relating branching program size and formula size over the full binary basis. In C. Meinel and S. Tison, editors, STACS 99: 16th Annual Symposium on Theoretical Aspects of Computer Science, volume 1563 of Lecture Notes in Computer Science, pages 57–67, Trier, Germany, Mar. 4–6, 1999. Springer, Berlin, Germany.

[29] M. I. Sharif, A. Lanzi, J. T. Giffin, and W. Lee. Impeding malware analysis using conditional code obfuscation. InISOC Network and Distributed System Security Symposium – NDSS 2008, San Diego, California, USA, Feb. 10–13, 2008. The Internet Society.

(19)

[31] Z. Wang, J. Ming, C. Jia, and D. Gao. Linear obfuscation to combat symbolic execution. In V. Atluri and C. D´ıaz, editors, ESORICS 2011: 16th European Symposium on Research in Computer Security, volume 6879 of Lecture Notes in Computer Science, pages 210–226, Leuven, Belgium, Sept. 12–14, 2011. Springer, Berlin, Germany.

[32] J. Zimmerman. How to obfuscate programs directly. Cryptology ePrint Archive, Report 2014/776, 2014. https://eprint.iacr.org/2014/776.

Changelog

• Version 2.0 (February 10, 2015):

Removed randomized matrix branching program figure.

Removed section on “attack” which leaks g1 if one slot is filled. It appears that leaking g1 does not break the security of obfuscation [13, Footnote 5].

Reworded first paragraph of Section2.1.1and removed footnote.

Removed comment about the lattice-based multilinear map [18] in Section3.1, which has since been broken.

Added Lemma 1 to Section 2.1.1 and updated Section 2.2 by fixing Definition 2 and adding Lemma2.

Added the fact that the challenge (cf. Section5) has been broken.

Added footnote in Section 3.1.1about the improved evaluation procedure. Updated link to code.

Updated Acknowledgments.

References

Related documents

Cross – dockové centrum (CD centrum) v tomto prípade má za úlohu pretriedenie materiálových vstupov, ktoré prichádzajú vo vä č ších objemoch od jednotlivých dodávate ľ ov

The initial definitions of LsE within both the small business and the tourism and hospitality literature, are linked with two main arguments: firstly, this

HCV RNA detection HCV RNA detection (sensitive qualitative assay) (sensitive qualitative assay) at the end of treatment and 24 weeks later at the end of treatment and 24 weeks

Consequentially, for 1024-bit it is presently necessary to use a sub- optimal choice of the algebraic factor base bound B a in order to fit all progressions into a single wafer,

However, in developed Microfinance markets I find that for-profit firms charge 7 percentage points higher interest rates.. I also find that regulated firms charge significantly

Allow complete validation and editing of data at the point of entry based on user defined criteria (e.g., transaction, tables, archived records, transaction status, etc.)T. TEC

In conclusion, this evidence-based review of the intersection between e-HRM and strategic HRM has led us to four primary findings in the literature: 1) implementation of

treatment works (Table 5), pumping stations (Tables 4 and 10), service reservoirs (Table 8) and stormwater culverts (Table 20) have increased significantly more than the capital cost