今天记录下一个spdz开源库里的while_do函数的用法
测试版本0.3.0
while_do函数的介绍: 一句一句解释一下While-do loop. :函数是用来做while循环的。
The decorator requires an initialization, :解释器需要一个初始化,可以理解为在这里为循环赋初始状态(值)
and the loop body function must return a suitable input for condition.:loop body也是一个函数,它被while_do函数修饰,可以理解为循环体也作为一个参数被传入while_do函数里执行。如果不懂可以百度下python中@函数修饰符的作用。
Parameters
condition – function returning public integer (regint/cint/int):字面翻译是条件的意思,实际应该是一个函数,这个函数执行的是某个条件的判断。(不要疑惑,我们在小学二年级就学过,python的函数的传参也可以传函数。)
args – arguments given to condition and loop body:一些参数,这些参数被用在条件函数和循环体。可以用来给解释器初始化。
def while_do(condition, *args):
def decorator(loop_body):
while_loop(loop_body, condition, *args)
return loop_body
return decorator
源代码不多说了。
官方给的实例:@while_do(lambda x: x < 10, regint(0))
def f(i):
...
return i + 1
lambda:是python内置的一个表达式语法,不熟悉的同学可以百度下。在这个例子中就是判断传入的参数x是否小于10
regint(0):表示初始值为0。也就是一开始i=0。regint是spdz库定义的一个类型,没看过可以暂时放一放,可以把它看作int
def f(i):定义了一个循环体函数
return i+1:循环体函数返回了i+1
实例代码的运行流程:
i被赋予初值i=0...做了某些操作返回了i+1判断i+1是否<10若小于10,继续执行循环体函数若大于等于10跳出循环,结束
等价代码:
while i<10: ... i = i + 1上手实例:快速排序
原始的python语法实现:
def insertsort(a, low, high):
for i in range(low + 1, high):
j = i
while j > 0 and a[j] < a[j - 1]:
a[j], a[j - 1] = a[j - 1], a[j]
j -= 1
我们根据上面的代码,转换成按照spdz库语法写的代码。
def insertsort(a,low,high):
@for_range(low+1,high)
def _(i):
@while_do(lambda j:j>0, i)
def _(j):
a[j],a[j-1] = cond_swap(a[j],a[j-1])
return j-1
for_range就是for循环,没见过的小伙伴可以跳过,我们这里主要讲while_do的用法。
直接看最里面的while层。
为循环体的j赋初值j=ia[j],a[j-1] = cond_swap(a[j],a[j-1]) 这个是spdz定义的函数,如果ajreturn j-1:让j的值减一判断j是否大于0,不满足则跳出循环。
另一个版本: 将lambda替换成了函数
def insertsort1(a,low,high):
@for_range(low+1,high)
def _(i):
def jian(k):
return k>0
@while_do(jian, i)
def _(j):
a[j],a[j-1] = cond_swap(a[j],a[j-1])
return j-1
完整的测试代码:test.mpc
a = Array(10,sint)
a.assign([45,65,1,427,11,54,154,254,96,47])
print_ln("a = %s",a.reveal())
low = 0
high = 10
def insertsort(a,low,high):
@for_range(low+1,high)
def _(i):
@while_do(lambda j:j>0, i)
def _(j):
a[j],a[j-1] = cond_swap(a[j],a[j-1])
return j-1
def insertsort1(a,low,high):
@for_range(low+1,high)
def _(i):
def jian(k):
return k>0
@while_do(jian, i)
def _(j):
a[j],a[j-1] = cond_swap(a[j],a[j-1])
return j-1
insertsort1(a,low,high)
print_ln("a = %s",a.reveal())
a.sort()
print_ln("a = %s",a.reveal())
编译:./compile.py -F 64 test
执行:scripts/run-online.sh test
运行结果:
Running /home/spdz030/scripts/../Player-Online.x 0 test -pn 16118 -h localhost -N 2 Running /home/spdz030/scripts/../Player-Online.x 1 test -pn 16118 -h localhost -N 2 a = [45, 65, 1, 427, 11, 54, 154, 254, 96, 47] a = [427, 254, 154, 96, 65, 54, 47, 45, 11, 1] REWINDING - onLY FOR BENCHMARKING a = [1, 11, 45, 47, 54, 65, 96, 154, 254, 427] The following timing is exclusive preprocessing. Time = 0.0522126 seconds Data sent = 0.423992 MB in ~892 rounds (party 0) Global data sent = 0.847968 MB (all parties) This program might benefit from some protocol options. Consider adding the following at the beginning of 'test.mpc': program.use_edabit(True)



