Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Thomas Hoffmann
CryComp
Commits
85d17e6c
Commit
85d17e6c
authored
Sep 19, 2021
by
Anders Jensen Løvig
Browse files
Comment
parent
62fbeb29
Changes
2
Hide whitespace changes
Inline
Side-by-side
cmd/handin3/main.go
View file @
85d17e6c
...
...
@@ -54,6 +54,8 @@ func Int2Bools(x, n int) []bool {
return
output
}
// Party represents one of the parties in the protocol. They contain a slice
// of all known wires and channels for communication with the other party.
type
Party
struct
{
wires
[]
bool
...
...
@@ -61,6 +63,7 @@ type Party struct {
out
chan
bool
}
// NewParty returns a new party that communicates on the specified channels.
func
NewParty
(
in
,
out
chan
bool
)
*
Party
{
return
&
Party
{
wires
:
make
([]
bool
,
0
),
...
...
@@ -86,33 +89,37 @@ func (p *Party) Input(x bool) int {
return
p
.
Push
(
xa
)
}
// Receive a value from the other party and push to known wires.
func
(
p
*
Party
)
Receive
()
int
{
return
p
.
Push
(
<-
p
.
in
)
}
// Send the wire at the specified index to the other party.
func
(
p
*
Party
)
Send
(
wire
int
)
{
p
.
out
<-
p
.
wires
[
wire
]
}
func
(
p
*
Party
)
Combine
(
xwire
,
ywire
int
)
int
{
// Multiplies two binary values. Used in AND
func
(
p
*
Party
)
Mult
(
xwire
,
ywire
int
)
int
{
return
p
.
Push
(
p
.
wires
[
xwire
]
&&
p
.
wires
[
ywire
])
}
func
(
p
*
Party
)
XORC
(
xwire
int
,
c
bool
,
mode
bool
)
int
{
if
mode
{
//Only one party is supposed to do the XOR
return
p
.
Push
(
p
.
wires
[
xwire
]
!=
c
)
}
else
{
return
p
.
Push
(
p
.
wires
[
xwire
])
}
// XORC computes XOR with constant and returns the index of the output wire.
func
(
p
*
Party
)
XORC
(
xwire
int
,
c
bool
)
int
{
return
p
.
Push
(
p
.
wires
[
xwire
]
!=
c
)
}
// ANDC computes AND with constant and returns the index of the output wire.
func
(
p
*
Party
)
ANDC
(
xwire
int
,
c
bool
)
int
{
return
p
.
Push
(
p
.
wires
[
xwire
]
&&
c
)
}
func
(
p
*
Party
)
XOR2W
(
xwire
,
ywire
int
)
int
{
// XOR computes XOR between two wires and returns the index of output wire.
func
(
p
*
Party
)
XOR
(
xwire
,
ywire
int
)
int
{
return
p
.
Push
(
p
.
wires
[
xwire
]
!=
p
.
wires
[
ywire
])
}
// Dealer is responsible for providing random values in AND
type
Dealer
struct
{
}
...
...
@@ -120,6 +127,7 @@ func NewDealer() *Dealer {
return
&
Dealer
{}
}
// Deal returns shares for [u], [v], [w] for the AND subprotocol.
func
(
d
*
Dealer
)
Deal
()
(
bool
,
bool
,
bool
,
bool
,
bool
,
bool
)
{
u
:=
rand
.
Intn
(
2
)
==
1
ua
:=
rand
.
Intn
(
2
)
==
1
...
...
@@ -134,6 +142,7 @@ func (d *Dealer) Deal() (bool, bool, bool, bool, bool, bool) {
return
ua
,
ub
,
va
,
vb
,
wa
,
wb
}
// Protocol is responsible for evaluating rounds.
type
Protocol
struct
{
A
*
Party
B
*
Party
...
...
@@ -141,6 +150,7 @@ type Protocol struct {
Dealer
*
Dealer
}
// NewProtocol returns a new protocol with two parties.
func
NewProtocol
()
*
Protocol
{
a2b
:=
make
(
chan
bool
,
1
)
//Directional non-blocking channels
b2a
:=
make
(
chan
bool
,
1
)
...
...
@@ -151,6 +161,7 @@ func NewProtocol() *Protocol {
}
}
// AND computes the subprotocol for AND between two wires.
func
(
p
*
Protocol
)
AND
(
xwire
,
ywire
int
)
int
{
A
,
B
:=
p
.
A
,
p
.
B
//1a. Generate [u], [v] and [w]
...
...
@@ -168,10 +179,10 @@ func (p *Protocol) AND(xwire, ywire int) int {
idx_w
,
_
:=
A
.
Receive
(),
B
.
Receive
()
//2 compute [d] = [x] XOR [u]
idx_d1
:=
p
.
XOR
2W
(
xwire
,
idx_u
)
//A.XOR2W(xwire, idx_u), B.XOR2W(xwire, idx_u)
idx_d1
:=
p
.
XOR
(
xwire
,
idx_u
)
//A.XOR2W(xwire, idx_u), B.XOR2W(xwire, idx_u)
//3. compute [e] = [y] XOR [v]
idx_e1
:=
p
.
XOR
2W
(
ywire
,
idx_v
)
//A.XOR2W(ywire, idx_v), B.XOR2W(ywire, idx_v)
idx_e1
:=
p
.
XOR
(
ywire
,
idx_v
)
//A.XOR2W(ywire, idx_v), B.XOR2W(ywire, idx_v)
//4. Open d
A
.
Send
(
idx_d1
)
...
...
@@ -184,22 +195,23 @@ func (p *Protocol) AND(xwire, ywire int) int {
idx_e2
,
_
:=
A
.
Receive
(),
B
.
Receive
()
//6a. Compute d and e
idx_d
:=
p
.
XOR
2W
(
idx_d1
,
idx_d2
)
//A.XOR2W(idx_d1, idx_d2), B.XOR2W(idx_d1, idx_d2)
idx_e
:=
p
.
XOR
2W
(
idx_e1
,
idx_e2
)
//A.XOR2W(idx_e1, idx_e2), B.XOR2W(idx_e1, idx_e2)
idx_d
:=
p
.
XOR
(
idx_d1
,
idx_d2
)
//A.XOR2W(idx_d1, idx_d2), B.XOR2W(idx_d1, idx_d2)
idx_e
:=
p
.
XOR
(
idx_e1
,
idx_e2
)
//A.XOR2W(idx_e1, idx_e2), B.XOR2W(idx_e1, idx_e2)
//6b. Compute [z]-parts
idx_z1
,
_
:=
A
.
ANDC
(
xwire
,
A
.
wires
[
idx_e
]),
B
.
ANDC
(
xwire
,
B
.
wires
[
idx_e
])
idx_z2
,
_
:=
A
.
ANDC
(
ywire
,
A
.
wires
[
idx_d
]),
B
.
ANDC
(
ywire
,
B
.
wires
[
idx_d
])
idx_z3
,
_
:=
A
.
Combine
(
idx_e
,
idx_d
),
B
.
Combine
(
idx_e
,
idx_d
)
idx_z3
,
_
:=
A
.
Mult
(
idx_e
,
idx_d
),
B
.
Mult
(
idx_e
,
idx_d
)
//6c. Compute [z]
idx_z4
,
_
:=
A
.
XOR
2W
(
idx_w
,
idx_z1
),
B
.
XOR
2W
(
idx_w
,
idx_z1
)
idx_z5
,
_
:=
A
.
XOR
2W
(
idx_z4
,
idx_z2
),
B
.
XOR
2W
(
idx_z4
,
idx_z2
)
idx_z
,
_
:=
A
.
XORC
(
idx_z5
,
A
.
wires
[
idx_z3
]
,
true
),
B
.
XORC
(
idx_z5
,
B
.
wires
[
idx_z
3
],
false
)
idx_z4
,
_
:=
A
.
XOR
(
idx_w
,
idx_z1
),
B
.
XOR
(
idx_w
,
idx_z1
)
idx_z5
,
_
:=
A
.
XOR
(
idx_z4
,
idx_z2
),
B
.
XOR
(
idx_z4
,
idx_z2
)
idx_z
,
_
:=
A
.
XORC
(
idx_z5
,
A
.
wires
[
idx_z3
]
),
B
.
Push
(
B
.
wires
[
idx_z
5
]
)
return
idx_z
}
// Input the x bit to
// Input x to Alice and y to Bob, and send shares to eachother and return the
// index of new wires.
func
(
P
*
Protocol
)
Input
(
x
,
y
bool
)
(
int
,
int
)
{
idx1
:=
P
.
A
.
Input
(
x
)
P
.
B
.
Receive
()
...
...
@@ -208,29 +220,33 @@ func (P *Protocol) Input(x, y bool) (int, int) {
return
idx1
,
idx2
}
// XORC computes XOR with constant between Alice and Bob.
func
(
P
*
Protocol
)
XORC
(
wire
int
,
c
bool
)
int
{
idx
,
_
:=
P
.
A
.
XORC
(
wire
,
c
,
true
),
P
.
B
.
XORC
(
wire
,
c
,
false
)
idx
,
_
:=
P
.
A
.
XORC
(
wire
,
c
),
P
.
B
.
Push
(
P
.
B
.
wires
[
wire
]
)
return
idx
}
// ANDC computes AND with constant between Alice and Bob.
func
(
P
*
Protocol
)
ANDC
(
wire
int
,
c
bool
)
int
{
idx
,
_
:=
P
.
A
.
ANDC
(
wire
,
c
),
P
.
B
.
ANDC
(
wire
,
c
)
return
idx
}
func
(
P
*
Protocol
)
XOR2W
(
xwire
,
ywire
int
)
int
{
idx
,
_
:=
P
.
A
.
XOR2W
(
xwire
,
ywire
),
P
.
B
.
XOR2W
(
xwire
,
ywire
)
// XOR computes XOR between two wires for Alice and Bob.
func
(
P
*
Protocol
)
XOR
(
xwire
,
ywire
int
)
int
{
idx
,
_
:=
P
.
A
.
XOR
(
xwire
,
ywire
),
P
.
B
.
XOR
(
xwire
,
ywire
)
return
idx
}
//
Only 1 share should be flipped
//NOT A == A XOR 1
//
Computes a NOT gate, using XOR and AND.
//
NOT A == A XOR 1
func
(
P
*
Protocol
)
NOT
(
xwire
int
)
int
{
i
:=
P
.
A
.
XORC
(
xwire
,
true
,
true
)
_
=
P
.
B
.
XORC
(
xwire
,
true
,
false
)
i
:=
P
.
A
.
XORC
(
xwire
,
true
)
_
=
P
.
B
.
Push
(
P
.
B
.
wires
[
xwire
]
)
return
i
}
// Computes Output.
func
(
P
*
Protocol
)
Output
(
wire
int
,
A_Learns
,
B_Learns
bool
)
[]
bool
{
A
,
B
:=
P
.
A
,
P
.
B
output
:=
make
([]
bool
,
0
)
...
...
@@ -242,12 +258,12 @@ func (P *Protocol) Output(wire int, A_Learns, B_Learns bool) []bool {
}
if
A_Learns
{
idx_A
:=
A
.
Receive
()
idx_outA
:=
A
.
XOR
2W
(
wire
,
idx_A
)
idx_outA
:=
A
.
XOR
(
wire
,
idx_A
)
output
=
append
(
output
,
A
.
wires
[
idx_outA
])
}
if
B_Learns
{
idx_B
:=
B
.
Receive
()
idx_outB
:=
B
.
XOR
2W
(
wire
,
idx_B
)
idx_outB
:=
B
.
XOR
(
wire
,
idx_B
)
output
=
append
(
output
,
B
.
wires
[
idx_outB
])
}
return
output
...
...
@@ -309,6 +325,8 @@ func (P *Protocol) Run(x, y []bool) (bool, error) {
return
output
[
0
],
nil
}
// RunProtocol runs the protocol between receiving blood type x and donor blood
// type y.
func
RunProtocol
(
x
,
y
int
)
(
bool
,
error
)
{
protocol
:=
NewProtocol
()
...
...
cmd/handin3/main_test.go
View file @
85d17e6c
...
...
@@ -64,7 +64,7 @@ func TestPartyCombine(t *testing.T) {
b
:=
A
.
Input
(
false
)
ASizeBefore
,
BSizeBefore
:=
len
(
p
.
A
.
wires
),
len
(
p
.
B
.
wires
)
idx
:=
p
.
A
.
Combine
(
a
,
b
)
idx
:=
p
.
A
.
Mult
(
a
,
b
)
if
len
(
p
.
A
.
wires
)
!=
ASizeBefore
+
1
&&
len
(
p
.
B
.
wires
)
!=
BSizeBefore
{
t
.
Error
()
}
...
...
@@ -77,21 +77,13 @@ func TestPartyXORC(t *testing.T) {
A
:=
NewParty
(
nil
,
make
(
chan
bool
,
10
))
A
.
Input
(
true
)
idx1
:=
A
.
XORC
(
0
,
true
,
true
)
idx1
:=
A
.
XORC
(
0
,
true
)
if
len
(
A
.
wires
)
!=
2
{
t
.
Errorf
(
"Expected len(A.wires) == %d, was %d"
,
2
,
len
(
A
.
wires
))
}
if
idx1
!=
1
{
t
.
Errorf
(
"Expected idx1 == %d, was %d"
,
1
,
idx1
)
}
idx2
:=
A
.
XORC
(
0
,
true
,
false
)
if
len
(
A
.
wires
)
!=
3
{
t
.
Errorf
(
"Expected len(A.wires) == %d, was %d"
,
3
,
len
(
A
.
wires
))
}
if
idx2
!=
2
{
t
.
Errorf
(
"Expected idx2 == %d, was %d"
,
2
,
idx2
)
}
}
func
TestPartyANDC
(
t
*
testing
.
T
)
{
...
...
@@ -113,7 +105,7 @@ func TestPartyXOR(t *testing.T) {
A
.
Input
(
true
)
A
.
Input
(
false
)
idx
:=
A
.
XOR
2W
(
0
,
1
)
idx
:=
A
.
XOR
(
0
,
1
)
if
len
(
A
.
wires
)
!=
3
{
t
.
Errorf
(
"Expected len(A.wires) == %d, was %d"
,
3
,
len
(
A
.
wires
))
}
...
...
@@ -202,10 +194,10 @@ func TestProtocolXOR2W(t *testing.T) {
idxTrue
,
idxFalse
:=
p
.
Input
(
true
,
false
)
//True XOR True
idxTT
:=
p
.
XOR
2W
(
idxTrue
,
idxTrue
)
idxTF
:=
p
.
XOR
2W
(
idxTrue
,
idxFalse
)
idxFT
:=
p
.
XOR
2W
(
idxFalse
,
idxTrue
)
idxFF
:=
p
.
XOR
2W
(
idxFalse
,
idxFalse
)
idxTT
:=
p
.
XOR
(
idxTrue
,
idxTrue
)
idxTF
:=
p
.
XOR
(
idxTrue
,
idxFalse
)
idxFT
:=
p
.
XOR
(
idxFalse
,
idxTrue
)
idxFF
:=
p
.
XOR
(
idxFalse
,
idxFalse
)
resTT
,
resTF
,
resFT
,
resFF
:=
p
.
A
.
wires
[
idxTT
]
!=
p
.
B
.
wires
[
idxTT
],
p
.
A
.
wires
[
idxTF
]
!=
p
.
B
.
wires
[
idxTF
],
p
.
A
.
wires
[
idxFT
]
!=
p
.
B
.
wires
[
idxFT
],
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment