mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-09 14:48:08 -05:00
[research/mpc] spdz in sage
This commit is contained in:
19
script/research/mpc/beaver.sage
Normal file
19
script/research/mpc/beaver.sage
Normal file
@@ -0,0 +1,19 @@
|
||||
load('share.sage')
|
||||
|
||||
import random
|
||||
class Source(object):
|
||||
def __init__(self, p):
|
||||
self.a = random.randint(0,p)
|
||||
self.b = random.randint(0,p)
|
||||
self.c = self.a*self.b
|
||||
self.left_a = random.randint(0,self.a)
|
||||
self.right_a = self.a - self.left_a
|
||||
self.left_b = random.randint(0,self.b)
|
||||
self.right_b = self.b - self.left_b
|
||||
self.left_c = random.randint(0,self.c)
|
||||
self.right_c = self.c - self.left_c
|
||||
|
||||
def triplet(self, party_id):
|
||||
triplet = [self.left_a, self.left_b, self.left_c] if party_id==0 else [self.right_a, self.right_b, self.right_c]
|
||||
return [AuthenticatedShare(share) for share in triplet]
|
||||
|
||||
43
script/research/mpc/curve.sage
Normal file
43
script/research/mpc/curve.sage
Normal file
@@ -0,0 +1,43 @@
|
||||
# stark curve https://docs.starkware.co/starkex/crypto/stark-curve.html
|
||||
|
||||
p = 3618502788666131213697322783095070105623107215331596699973092056135872020481
|
||||
alpha = 1
|
||||
# $$y^2 = x^3 + \alpha \dot x + \beta$$ (mod p)
|
||||
beta = 3141592653589793238462643383279502884197169399375105820974944592307816406665
|
||||
K = GF(p)
|
||||
E = EllipticCurve(K, (alpha,beta))
|
||||
ec_order = E.order()
|
||||
# ECDSA scheme generator
|
||||
G = E(874739451078007766457464989774322083649278607533249481151382481072868806602, 152666792071518830868575557812948353041420400780739481342941381225525861407)
|
||||
|
||||
import random
|
||||
class CurvePoint():
|
||||
def __init__(self, x=None, y=None):
|
||||
if x==None or y==None:
|
||||
self.point = CurvePoint.random()
|
||||
else:
|
||||
self.point = E(x,y)
|
||||
self.x = self.point[0]
|
||||
self.y = self.point[1]
|
||||
|
||||
def __repr__(self):
|
||||
return "[ x: %s, y: %s, z: 1]"%(self.x, self.y)
|
||||
|
||||
def random(max=p):
|
||||
return G* random.randint(0, max)
|
||||
|
||||
def __add__(self, rhs):
|
||||
return self.point + rhs.point
|
||||
|
||||
def __sub__(self, rhs):
|
||||
return self.point - rhs.point
|
||||
|
||||
def __neg__(self):
|
||||
return -1 * self.point
|
||||
|
||||
def generator():
|
||||
return G
|
||||
|
||||
def __mul__(self, factor):
|
||||
return factor * self.point
|
||||
|
||||
9
script/research/mpc/pedersen.sage
Normal file
9
script/research/mpc/pedersen.sage
Normal file
@@ -0,0 +1,9 @@
|
||||
load('curve.sage')
|
||||
|
||||
class PedersenCommitment(object):
|
||||
def __init__(self, value, blinder=None):
|
||||
self.value = value
|
||||
self.blinder = blinder if blinder is not None else random.randint(0,p)
|
||||
|
||||
def commitment(self):
|
||||
return CurvePoint.generator() * self.value + CurvePoint.generator() * self.blinder
|
||||
76
script/research/mpc/share.sage
Normal file
76
script/research/mpc/share.sage
Normal file
@@ -0,0 +1,76 @@
|
||||
load('pedersen.sage')
|
||||
|
||||
def open_2pc(party0_share, party1_share):
|
||||
return party0_share + party1_share
|
||||
|
||||
def verify_2pc_mac_check(party0_mac, party1_mac):
|
||||
assert party0_mac+party1_mac == 0
|
||||
|
||||
global_key = random.randint(0,100)
|
||||
|
||||
class AuthenticatedShare(object):
|
||||
"""
|
||||
additive share
|
||||
"""
|
||||
def __init__(self, share, mac=None, modifier=None):
|
||||
self.share = share
|
||||
self.mac = global_key * self.share if mac==None else mac
|
||||
self.public_modifier = 0 if modifier == None else modifier # carry out extra addition/subtraction by public scalars until opening
|
||||
|
||||
def __repr__(self):
|
||||
return "share: %s, mac: %s"%(self.share, self.mac)
|
||||
|
||||
# SPDZ mac authentication
|
||||
def authenticated_open(self, peer_authenticated_share):
|
||||
opened_share = open_2pc(self.share, peer_authenticated_share.share)
|
||||
mac_key = random.randint(0,global_key)
|
||||
mac_share = mac_key * (opened_share + self.public_modifier) - self.mac
|
||||
|
||||
peer_mac_key = global_key - mac_key
|
||||
peer_mac_share = peer_mac_key * (opened_share + peer_authenticated_share.public_modifier) - peer_authenticated_share.mac
|
||||
assert (mac_share + peer_mac_share) == 0
|
||||
|
||||
return opened_share
|
||||
|
||||
def sub_scalar(self, scalar, party_id):
|
||||
return AuthenticatedShare(self.share - scalar, self.mac, self.public_modifier + scalar) if party_id == 0 else AuthenticatedShare(self.share , self.mac, self.public_modifier + scalar)
|
||||
|
||||
def add_scalar(self, scalar, party_id):
|
||||
return AuthenticatedShare(self.share + scalar, self.mac , self.public_modifier - scalar) if party_id ==0 else AuthenticatedShare(self.share, self.mac, self.public_modifier - scalar)
|
||||
|
||||
def mul_scalar(self, scalar):
|
||||
return AuthenticatedShare(self.share * scalar, self.mac * scalar, self.public_modifier * scalar)
|
||||
|
||||
def __add__(self, rhs):
|
||||
'''
|
||||
add additive shares
|
||||
'''
|
||||
return AuthenticatedShare(self.share + rhs.share, self.mac + rhs.mac, self.public_modifier + rhs.public_modifier)
|
||||
|
||||
def __sub__(self, rhs):
|
||||
'''
|
||||
sub additive shares
|
||||
'''
|
||||
return AuthenticatedShare(self.share - rhs.share, self.mac - rhs.mac, self.public_modifier - rhs.public_modifier)
|
||||
|
||||
|
||||
class MultiplicationAuthenticatedShares(object):
|
||||
def __init__(self, alpha, beta, triplet, party_id):
|
||||
# authenticated shares
|
||||
self.alpha_as = alpha
|
||||
self.beta_as = beta
|
||||
self.a_as = triplet[0]
|
||||
self.b_as = triplet[1]
|
||||
self.c_as = triplet[2]
|
||||
self.party_id = party_id
|
||||
|
||||
def __mul__(self, peer_share):
|
||||
masked_d_share = self.alpha_as - self.a_as
|
||||
peer_masked_d_share = peer_share.alpha_as - peer_share.a_as
|
||||
d = open_2pc(masked_d_share.share, peer_masked_d_share.share)
|
||||
|
||||
masked_e_share = self.beta_as - self.b_as
|
||||
peer_masked_e_share = peer_share.beta_as - peer_share.b_as
|
||||
e = open_2pc(masked_e_share.share, peer_masked_e_share.share)
|
||||
|
||||
return (self.b_as.mul_scalar(d) + self.a_as.mul_scalar(e) + self.c_as).add_scalar(d*e, self.party_id)
|
||||
69
script/research/mpc/spdz.sage
Normal file
69
script/research/mpc/spdz.sage
Normal file
@@ -0,0 +1,69 @@
|
||||
load('beaver.sage')
|
||||
p = 10
|
||||
|
||||
party0_val = 3
|
||||
party1_val = 22
|
||||
public_scalar = 2
|
||||
|
||||
# additive share distribution, and communication of private values
|
||||
party0_random = random.randint(0,p)
|
||||
alpha1 = AuthenticatedShare(party0_random)
|
||||
alpha2 = AuthenticatedShare(party0_val - party0_random)
|
||||
assert (alpha1.authenticated_open(alpha2) == party0_val)
|
||||
|
||||
party1_random = random.randint(0,p)
|
||||
beta1 = AuthenticatedShare(party1_random)
|
||||
beta2 = AuthenticatedShare(party1_val - party1_random)
|
||||
assert (beta1.authenticated_open(beta2) == party1_val)
|
||||
|
||||
# mul_scalar by public scalar
|
||||
mul_left_share = alpha1.mul_scalar(public_scalar)
|
||||
mul_right_share = alpha2.mul_scalar(public_scalar)
|
||||
assert (mul_left_share.authenticated_open(mul_right_share) == (public_scalar * party0_val))
|
||||
|
||||
|
||||
# sub_scalar by public scalar
|
||||
sub_left_share = alpha1.sub_scalar(public_scalar, 0)
|
||||
sub_right_share = alpha2.sub_scalar(public_scalar, 1)
|
||||
assert (sub_left_share.authenticated_open(sub_right_share) == (party0_val - public_scalar))
|
||||
|
||||
|
||||
|
||||
# add_scalar by public scalar
|
||||
add_left_share = alpha1.add_scalar(public_scalar, 0)
|
||||
add_right_share = alpha2.add_scalar(public_scalar, 1)
|
||||
assert (add_left_share.authenticated_open(add_right_share) == (public_scalar + party0_val))
|
||||
|
||||
|
||||
|
||||
# add authenticated shares
|
||||
add_party0_share = alpha1 + beta2
|
||||
add_party1_share = alpha2 + beta1
|
||||
|
||||
lhs = add_party0_share.authenticated_open(add_party1_share)
|
||||
|
||||
assert (lhs == (party0_val + party1_val))
|
||||
|
||||
|
||||
# sub authenticated shares
|
||||
sub_party0_share = alpha1 - beta2
|
||||
sub_party1_share = alpha2 - beta1
|
||||
|
||||
lhs = sub_party0_share.authenticated_open(sub_party1_share)
|
||||
|
||||
assert (lhs == (party0_val - party1_val))
|
||||
|
||||
|
||||
|
||||
# mul authenticated shares
|
||||
mul_res = party0_val * party1_val
|
||||
|
||||
s = Source(p)
|
||||
alpha1beta1_share = MultiplicationAuthenticatedShares(alpha1, beta1, s.triplet(0), 0)
|
||||
alpha2beta2_share = MultiplicationAuthenticatedShares(alpha2, beta2, s.triplet(1), 1)
|
||||
|
||||
lhs_share = alpha1beta1_share*alpha2beta2_share
|
||||
rhs_share = alpha2beta2_share*alpha1beta1_share
|
||||
lhs = lhs_share.authenticated_open(rhs_share)
|
||||
|
||||
assert (lhs == (party0_val * party1_val)), 'lhs: {}, rhs: {}'.format(lhs, party0_val * party1_val)
|
||||
Reference in New Issue
Block a user