• No results found

Scaling

In document Machine learning on encrypted data (Page 119-123)

To avoid the use of this fractional encoding, we now instead show how to map rational numbers to integers by scaling. In previous work (e.g. [AEH15]), rational numbers have often been approximated by multiplying with a power of some number, called the scaling factor (e.g. 10 or 2), and rounding to obtain an integer. However, note that generally when multiplying two rational numbers with k bits of precision, we obtain a number with 2k bits of precision (whereas addition does not change the precision). If we were working on unencrypted numbers, we might just round to obtain k bits of precision again, or we could truncate (truncation after k bits yields the same accuracy as rounding to k − 1 bits). However, things are more difficult when operating on encrypted data, as rounding is generally not possible here and thus these extra bits of precision accumulate. To see this, suppose we would like to work with a precision of k bits, and the scaling factor w. This means that we multiply a rational number with wk and round (or truncate)

to the nearest integer, which is then encoded and encrypted as in the previous sections. Dividing the decrypted decoded number by wkagain yields the rounded rational. However, the problem of doubling precision with multiplication is prevalent here. Consider what would happen if we were to multiply two such numbers: Suppose we have two rational numbers a and b that we would like to encode as integers a0 and b0 with k digits of precision, so we have a0 = da · wkc and b0 = db · wkc. Multiplying a0 and b0, we get

c00 = a0 · b0 ≈ a · wk· b · wk = (a · b) · w2k. Thus, having reversed the encoding, the

obtained value c00 must be divided by w2k. This is a problem because we cannot remove the extra bits by dividing by wk, so the party performing the algorithm must now divulge what power of w to divide the obtained result by after decryption. This leaks information about the multiplicative depth of the function used and thus constitutes a privacy breach for the computing party. Additionally, there is also the problem during computation that the sizes of the encoded numbers will increase substantially.

Example 4.4: Let a = 1.342 and b = 4.11. We pick a precision of k = 2 and a scaling factor of w = 10, so we get the integers

a0 = b1.342 · 102e = 134 and b0 = b4.11 · 102e = 411.

Multiplying these two numbers, we get 134 · 411 = 55074. To get the right result, we now have to divide by (102)2 = 10000, yielding 5.5074 ≈ 1.342 · 4.1 = a · b. Note that the result has 4 digits of precision even though we encoded the inputs with only 2 digits of precision, and thus requires a larger bitlength.

Recall from Lemma 9 in Section 4.1.2 that deleting the last k bits corresponds to dividing by 2k and truncating the result. To utilize this fact, we propose the following approach: Instead of scaling by a power of an arbitrary number w, we set w = 2 and truncate to obtain an integer. As in the previous chapters, we encode this integer in binary fashion, so that we can encrypt each bit separately. This eliminates the above problem: Multiplying two numbers a0 and b0 with k bits of precision still yields c00 = (a · b) · 22k, but since we are encoding bit by bit, we can manipulate the individual bits and thus simply delete the last k (encrypted) bits of the product, which corresponds to dividing by 2k and truncating as per Lemma 9. This way, the party performing the computations can bring the product c00 back down to the required precision after every step by discarding the last k bits and thus obtaining c0= a · b · 2k. This solves the above problem because the party which holds the data must now always divide the decoded result by 2k no matter what operations were applied. This has the benefit of not only hiding the data from the computing party, but also hiding the function from the party with the data while simultaneously avoiding superfluous bitlength. The exact workings can be seen in Algorithm 9.

Algorithm 9: Multiplication using scaling Encoding():

Input: A rational number a Input: The scaling factor k // Scale and truncate.

1 a0 := b2k· ac

// Encode with Two’s Complement or Sign-Magnitude or Hybrid Encoding.

2 ˜a := Encode(a0)

Output: ˜a

Multiplication():

Input: A number ˜a as encoded above Input: A number ˜b as encoded above

Input: The scaling factor k (must be the same for ˜a and ˜b) // Multiply using bitwise algorithm of choice

3 c = cn. . . c1c0:= Mult(˜a, ˜b)

// Delete last k bits

4 ˜c := cn. . . ck+1ck= dn0. . . d1d0

Output: ˜c

Decoding():

Input: A number dn0. . . d1d0 as encoded above

Input: The scaling factor k // Obtain integer 5 d0 = n0 P i=0 di2i

// Divide by scaling factor

6 d := d0/2k

To make the algorithm clearer, consider the following example:

Example 4.5: We return to the above example with a = 1.342 and b = 4.11. We pick a precision of k = 7, so we get the integers

a0 = b1.342 · 27e = 172 and b0 = b4.11 · 27e = 526.

Multiplying these two numbers, we get 172 · 526 = 90472. To get the right result, we would now have to divide by (27)2 = 16384. However, we are operating bitwise, so we have the

result (in encrypted form) as 90472 = 10110000101101000.

Deleting the last k = 7 bits, we are left with c0 = 1011000010, which encodes the number 706. If the user receives this encrypted result he can divide be the original scaling factor 27 after decrypting to obtain the final value 706/(27) ≈ 5.52. Thus, the user has obtained the correct result without needing any further information that depends on the applied function in order to decode correctly.

Note also that the result c0 in the above example now only has k = 7 bits of precision instead of 2 · k = 14 as it would traditionally. This is especially important if the value is an input to further computations, as we have seen in Chapter 3 that most elemen- tary functions are linear or quadratic in the input length, so shorter lengths mean faster computation.

4.2.1 Relation to Floating Point Representation

As our scaling approach is somewhat similar to the floating point representation used to represent rational numbers in unencrypted computations, we briefly discuss differences and similarities.

In floating point representation, a number is represented by a significand s and and expo- nent e relative to some base b. The number is then computed as s·be, which of course looks very similar to our scaling encoding. However, in floating point representation, the expo- nent is explicitly part of the representation and involved in the computations: To add two numbers in different representations, one scales the smaller number to have the larger ex- ponent as well (e.g., in base 10, we would scale 13.21 = 1.321 · 102 to 13.21 = 0.001321 · 105 to get from exponent 2 to exponent 5) and then adds the two significands. To multiply two numbers, the significands are multiplied and the exponents are added.

Thus, for floating point computations, the exponents would have to be encrypted as well as the significands, and especially scaling to the same exponent for addition may prove complex to do homomorphically. If we do not encrypt the exponents, they may leak information about the operations that were performed. Either way, this approach also suffers from the issue of doubling precision with each multiplication, though we could likely manage this by an approach similar to our above one.

In essence, our representation is like the floating point representation, but with a fixed exponent that stays the same throughout all computations, instead introducing more variability into the significand. True floating point representation would be somewhat complex to perform on encrypted numbers, but a combination with our approach (i.e., leaving the exponents unencrypted, but reducing precision to hide what computation was performed) would likely be feasible, though a higher efficiency than our approach is improbable due to the more complex nature of the computations.

In document Machine learning on encrypted data (Page 119-123)