Commit 85d17e6c authored by Anders Jensen Løvig's avatar Anders Jensen Løvig
Browse files

Comment

parent 62fbeb29
......@@ -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.XOR2W(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.XOR2W(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.XOR2W(idx_d1, idx_d2) //A.XOR2W(idx_d1, idx_d2), B.XOR2W(idx_d1, idx_d2)
idx_e := p.XOR2W(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.XOR2W(idx_w, idx_z1), B.XOR2W(idx_w, idx_z1)
idx_z5, _ := A.XOR2W(idx_z4, idx_z2), B.XOR2W(idx_z4, idx_z2)
idx_z, _ := A.XORC(idx_z5, A.wires[idx_z3], true), B.XORC(idx_z5, B.wires[idx_z3], 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_z5])
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.XOR2W(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.XOR2W(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()
......
......@@ -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.XOR2W(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.XOR2W(idxTrue, idxTrue)
idxTF := p.XOR2W(idxTrue, idxFalse)
idxFT := p.XOR2W(idxFalse, idxTrue)
idxFF := p.XOR2W(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],
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment