[viff-devel] How to structure code with callbacks
Hello, I have a problem with how to structure codes with much callback in VIFF. I want to do some stuff with shares, reveal some values, do more calculations with shares, reveal more values, and so on. For illustration purposes, lets say I have a bitwise secret shared value r (r and r_as_bits), and I want to compute c = x + r. Then reveal c and print it and reveal c. But this is only done if bits of r are not all zero. Below is the psudocode and the real code. The real code does not work, because it will return the last result only if the reactor is not shut down prematurely. So my question is how do I get a working program that looks more like my psaudocode? psaudocode: -- def protocol(r_as_bits, mask, r, x): test = test_not_all_zero(r_as_bits, mask) if test == True c = r + x c = open(c) print c else print False def test_not_all_zero(r_as_bits, mask) #reveal (sum(bits) - number_of_bits)*mask temp = sum(r_as_bits[:]) - len(r_as_bits)) * mask temp = open(temp) if temp == 0 return False return True - real code:def protocol_part_1(self, r_as_bits, r, mask, x): test = self.test_not_all_zero(r_as_bits, mask) self.r = r self.x = x return test.addCallback(self.protocol_part_2) def protocol_part_2(self, test): if test: c = self.r + self.x c_open = self.runtime.open(c) result = gather_shares([c_open]) callback_result = result.addCallback(self.print_answer) return callback_result else: print No value, False return False def print_answer(self, value): print Result , value return True def test_not_all_zero(self, r_as_bits, mask): #reveal (sum(bits))*mask temp = sum(r_as_bits[:]) * mask temp_open = self.runtime.open(temp) def check_result(check): print Comparing , check, to 0 if check[0].value == 0: return False return True ___ viff-devel mailing list (http://viff.dk/) viff-devel@viff.dk http://lists.viff.dk/listinfo.cgi/viff-devel-viff.dk
[viff-devel] Error when coding with callbacks and reveals
Hello, Continuing on my previous email about how to code things in VIFF. I hereby present the complete test code. It seems my calculations are done at the same time that the reactor is closing down so sometimes my code does not return any printed values. This is a mistake, either in my understanding of VIFF or in the framework itself. See the two runs below. C:\Documents and Settings\item\Desktop\VIFF\viff-dev\appstir_test.py --no-ssl player-3.ini Seeding random generator with random seed 5522 Not using SSL Listening on port 9003 Synchronizing shutdown... done. Closing connections... Comparing [{6}] to 0 Result [{12}] Result True done. Stopping reactor... done. C:\Documents and Settings\item\Desktop\VIFF\viff-dev\appstir_test.py --no-ssl player-3.ini Seeding random generator with random seed 3023 Not using SSL Listening on port 9003 Synchronizing shutdown... done. Closing connections... done. Stopping reactor... done. #!/usr/bin/python # Copyright 2007, 2008 VIFF Development Team. # # This file is part of VIFF, the Virtual Ideal Functionality Framework. # # VIFF is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License (LGPL) as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. # # VIFF is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General # Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with VIFF. If not, see http://www.gnu.org/licenses/. # This example is a tribute to the original example of secure # multi-party computation by Yao in 1982. In his example two # millionaires meet in the street and they want to securely compare # their fortunes. They want to do so without revealing how much they # own to each other. This problem would be easy to solve if both # millionaires trust a common third party, but we want to solve it # without access to a third party. # # In this example the protocol is run between three millionaires and # uses a protocol for secure integer comparison by Toft from 2005. # # Give a player configuration file as a command line argument or run # the example with '--help' for help with the command line options. from optparse import OptionParser from twisted.internet import reactor from viff.field import GF from viff.runtime import create_runtime, gather_shares from viff.comparison import Toft05Runtime, ComparisonReistad08Mixin from viff.config import load_config from viff.util import rand # We start by defining the protocol, it will be started at the bottom # of the file. class Protocol: def __init__(self, runtime): # Save the Runtime for later use self.runtime = runtime own_id = self.runtime.id Zp = GF(43) test_vector = [0, 1, 6, 0] self.value = test_vector[own_id - 1] m1, m2, m3 = runtime.shamir_share([1, 2, 3], Zp, self.value) shares = [m1, m2, m3] r_as_bits = [m1, m2, m1] r = m3 mask = m3 x = m3 result = self.protocol_part_1(r_as_bits, r, mask, x) callback_result = result.addCallback(self.print_answer) #results.addCallback(lambda _: runtime.synchronize()) m1.addCallback(lambda _: runtime.shutdown()) #Create_random_bits #Convert_to_test_values #Test_values if useable use random bits otherwise find new bits #c = r + x #Compare (c,r) def protocol_part_1(self, r_as_bits, r, mask, x): test = self.test_not_all_zero(r_as_bits, mask) self.r = r self.x = x return test.addCallback(self.protocol_part_2) def protocol_part_2(self, test): if test: c = self.r + self.x c_open = self.runtime.open(c) result = gather_shares([c_open]) callback_result = result.addCallback(self.print_answer) return callback_result else: print No value, False return False def print_answer(self, value): print Result , value return True def test_not_all_zero(self, r_as_bits, mask): #reveal (sum(bits))*mask temp = sum(r_as_bits[:]) * mask temp_open = self.runtime.open(temp) def check_result(check): print Comparing , check, to 0 if check[0].value == 0: return False return True results = gather_shares([temp_open]) test_results = results.addCallback(check_result) return test_results #test = self.check_not_all_one(r_as_bits, r) # test.addCallback(self.protcol_part_2) #def print_answer(self, value): #print Result , value # #def tests(self, shares, test): #open_shares = [] #
[viff-devel] Distributed RSA
Hi Atle and hi list, You might have looked at this paper already, but I was talking with Gert Mikkelsen today about RSA, and he pointed me to a paper with a protocol for distributed generation of RSA keys: Dan Boneh, Matthew K. Franklin: Efficient Generation of Shared RSA Keys (Extended Abstract). CRYPTO 1997: 425-439 It might be possible to implement this protocol directly in VIFF, instead of building things from scratch. The paper can be found here: http://www.springerlink.com/content/bq1jxkcuygj287cy/ -- Martin Geisler ___ viff-devel mailing list (http://viff.dk/) viff-devel@viff.dk http://lists.viff.dk/listinfo.cgi/viff-devel-viff.dk
[viff-devel] [issue79] Specify keysize for generate-config-file.py
New submission from Janus Dam Nielsen janus.niel...@alexandra.dk: Add a parameter to specify the keysize in the script generate-config- file.py -- assignedto: jdn keyword: simple messages: 308 nosy: jdn, mg status: in-progress title: Specify keysize for generate-config-file.py type: wish VIFF Issue Tracker trac...@viff.dk http://tracker.viff.dk/issue79 ___ viff-devel mailing list (http://viff.dk/) viff-devel@viff.dk http://lists.viff.dk/listinfo.cgi/viff-devel-viff.dk
Re: [viff-devel] Error when coding with callbacks and reveals
Tord Ingolf Reistad to...@stud.ntnu.no writes: Hi Tord, Please use the list-reply function in your mail program (it might be called reply to all or something like that). I'm sending this reply back on the list. Thank you for the help, with the coding problem. No problem! I am also trying to understand was the use of deferred objects. So I understand that a share is a deferred object, but can I also compute with field elements as deferred objects? You should think of Share objects as deferred field elements. The Share class is a subclass of Deferred, so every Share is a Deferred. Share objects promise to call their callbacks with a field element as argument. So if we do this: from pprint import pprint from viff.runtime import Share from viff.field import GF Zp = GF(17) s = Share(None, Zp) then s is a Share object which promisses to eventually contain a field element from the Zp field. We can now add callbacks: s.addCallback(lambda x: x + 3) Share at 0xabc596c s.addCallback(pprint) Share at 0xabc596c s.callback(Zp(10)) {13} The reason why we have this specialized Deferred class is that it overloads the arithmetic operators. So s + 3 will result in something very similar to s.addCallback(lambda x: x + 3) Here the x in the lambda expression is a field element, which itself overload the aritmetic operators to do the right thing. The end result is that we can use normal infix notation to do arithmetic on (future) field elements in shares. I would also have liked to contain the callbacks in test = self.test_not_all_zero(r_as_bits, mask) such that the protocol was oblivious to if there was a callback in the code test_not_all_zero and I just got the boolean value back, but that is probably not possible? Here's the code: def protocol_part_1(self, r_as_bits, r, mask, x): test = self.test_not_all_zero(r_as_bits, mask) self.r = r self.x = x return test.addCallback(self.protocol_part_2) def protocol_part_2(self, test): if test: c = self.r + self.x c_open = self.runtime.open(c) result = gather_shares([c_open]) callback_result = result.addCallback(self.print_answer) return callback_result else: print No value, False return False Since you really need to branch on the boolean result, you cannot avoid adding an explicit callback. The reason is that you cannot wait on a value in VIFF, you always have to tell VIFF what it should do when the value arrives at some point in the future. My goal is to keep most of the code oblivious as to if it is computing with shares or field elements. This greatly simplifies the testing and readability of the code. I see, that is indeed a nice property. And it can work some of the way, as you've seen, but only for simple functions which only do arithmetic on the shares. Tord -- Martin Geisler VIFF (Virtual Ideal Functionality Framework) brings easy and efficient SMPC (Secure Multiparty Computation) to Python. See: http://viff.dk/. pgpEF8LaONDNQ.pgp Description: PGP signature ___ viff-devel mailing list (http://viff.dk/) viff-devel@viff.dk http://lists.viff.dk/listinfo.cgi/viff-devel-viff.dk
Re: [viff-devel] Error when coding with callbacks and reveals
Tord Ingolf Reistad to...@stud.ntnu.no writes: I just took a closer look at your code -- some comments below :-) #!/usr/bin/python # Copyright 2007, 2008 VIFF Development Team. The year should be 2009 since this is the first year in which this code is released. class Protocol: def __init__(self, runtime): # Save the Runtime for later use self.runtime = runtime own_id = self.runtime.id Zp = GF(43) test_vector = [0, 1, 6, 0] self.value = test_vector[own_id - 1] m1, m2, m3 = runtime.shamir_share([1, 2, 3], Zp, self.value) shares = [m1, m2, m3] r_as_bits = [m1, m2, m1] r = m3 mask = m3 x = m3 result = self.protocol_part_1(r_as_bits, r, mask, x) callback_result = result.addCallback(self.print_answer) The addCallback method returns self -- so after that assignment we have callback_result == result So normally you wont save the result of addCallback. #results.addCallback(lambda _: runtime.synchronize()) m1.addCallback(lambda _: runtime.shutdown()) #Create_random_bits #Convert_to_test_values #Test_values if useable use random bits otherwise find new bits #c = r + x #Compare (c,r) def protocol_part_1(self, r_as_bits, r, mask, x): test = self.test_not_all_zero(r_as_bits, mask) self.r = r self.x = x return test.addCallback(self.protocol_part_2) def protocol_part_2(self, test): if test: c = self.r + self.x c_open = self.runtime.open(c) result = gather_shares([c_open]) The gather_shares function may have an unfortunate name... it is not used to collect the shares from a single number. Instead it is used to collect a list of several shares. So if you need to wait on a and b you do: x = gather_shares([a, b]) Now x is a Share which will call its callbacks with a list of *two* field elements. This means that we can do this: x.addCallback(lambda results: result[0] + result[1]) You have now made a Share which represents the future sum of a and b! So in your case I would do c_open = self.runtime.open(c) c_open.addCallback(self.print_answer) return c_open def test_not_all_zero(self, r_as_bits, mask): #reveal (sum(bits))*mask temp = sum(r_as_bits[:]) * mask temp_open = self.runtime.open(temp) def check_result(check): print Comparing , check, to 0 if check[0].value == 0: Here you see how check_result is called with a 1-item list because you use gather_shares below. If you simply add check_result as a callback to temp_open, then things become simpler. And you can just compare a field element with an integer, so if check == 0 should work just fine. return False return True results = gather_shares([temp_open]) test_results = results.addCallback(check_result) return test_results Like above you can just add the check_result callback to temp_open and return temp_open. -- Martin Geisler VIFF (Virtual Ideal Functionality Framework) brings easy and efficient SMPC (Secure Multiparty Computation) to Python. See: http://viff.dk/. pgpkP14OfTr9I.pgp Description: PGP signature ___ viff-devel mailing list (http://viff.dk/) viff-devel@viff.dk http://lists.viff.dk/listinfo.cgi/viff-devel-viff.dk
Re: [viff-devel] Mystery of the quadratic running time solved?
Marcel Keller mkel...@cs.au.dk writes: You're talking about this two-threaded solution as if it is something that exists and will solve all our problems... No, for now, it's just an imagination in my mind, a proposal for the next meeting, and a strong feeling that it's the right way to do it. Yeah, I think it would help too. But I still haven't seen it, and I would like to see how you can cleanly seperate the work of the two threads. I'm afraid that the threads will be alternating between working and waiting on the other thread in such a way that we could just as well use one thread. My idea is that the Twisted main loop runs in one thread and most of the VIFF code in the other. The Twisted thread only waits for I/O and the VIFF thread only waits if there is no work to be done. It's funny -- then we'll have sort of two event loops. If the group decides to give this idea a try, I would be happy to implement it. I would claim that it can be done in one or two weeks. So you'll have something when I get back from PKC? :) Seriously, I think you're right, the code is fairly well partitioned already, so we should be able to make this change without too much trouble. Also, threading in Python is unfortunately not optimal :-( The Python VM will use a single thread to execute the bytecode, even when using multiple thread in Python. It is only if the threads do things blocking for I/O that you will see a performance increase by using multiple threads. I'm aware that Python only runs on one CPU, a friend pointed that out to me today. However, the Twisted thread mentioned above would block on I/O. Right, that should help us! Janus has been looking more into Python threads, so be sure to discuss it with him too. -- Martin Geisler VIFF (Virtual Ideal Functionality Framework) brings easy and efficient SMPC (Secure Multiparty Computation) to Python. See: http://viff.dk/. pgpNe3r9JiJcA.pgp Description: PGP signature ___ viff-devel mailing list (http://viff.dk/) viff-devel@viff.dk http://lists.viff.dk/listinfo.cgi/viff-devel-viff.dk