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

Add RunProtocol again

parent 7dce3d78
......@@ -33,29 +33,10 @@ var BloodTable = [][]bool{
{true, true, true, true, true, true, true, true},
}
// Params contains the global protocol paramteres that are shared between Dealer, Alice and Bob.
type Params struct {
n int
nPow int // pow(2, n)
}
// NewParams returns a new Params struct with n and precomputed 2^n (pow(2, n)).
func NewParams(n int) *Params {
return &Params{
n: n,
nPow: int(math.Pow(2, float64(n))),
}
}
// mod computes the modulo a%n but handles negative arguments correctly.
func mod(a, n int) int {
return (a%n + n) % n
}
// Int2Bools return x as a slice containing the binary representation.
func Int2Bools(x, bits int) []bool {
var output = make([]bool, 0)
var tmp = 0
output := make([]bool, 0)
tmp := 0
for i := bits - 1; i >= 0; i-- {
tmp = int(math.Exp2(float64(i)))
output = append(output, (x&tmp)/tmp == 1)
......@@ -64,72 +45,70 @@ func Int2Bools(x, bits int) []bool {
}
type Party struct {
rand *rand.Rand
vals []bool
stack []bool
in chan bool
out chan bool
}
func InitParty(rand *rand.Rand, in, out chan bool) *Party {
func InitParty(in, out chan bool) *Party {
return &Party{
rand: rand,
vals: make([]bool, 0),
in: in,
out: out,
stack: make([]bool, 0),
in: in,
out: out,
}
}
func (a *Party) Input(x bool) int {
xb := a.rand.Intn(2) == 1
xb := rand.Intn(2) == 1
xa := x != xb // x XOR xb
a.vals = append(a.vals, xa)
a.stack = append(a.stack, xa)
a.out <- xb //Send to other party
return len(a.vals) - 1
return len(a.stack) - 1
}
func (a *Party) Receive() int {
a.vals = append(a.vals, <-a.in)
return len(a.vals) - 1
a.stack = append(a.stack, <-a.in)
return len(a.stack) - 1
}
func (a *Party) Send(wire int) {
a.out <- a.vals[wire]
a.out <- a.stack[wire]
}
func (a *Party) Combine(xwire, ywire int) int {
a.vals = append(a.vals, a.vals[xwire] && a.vals[ywire])
return len(a.vals) - 1
a.stack = append(a.stack, a.stack[xwire] && a.stack[ywire])
return len(a.stack) - 1
}
func (a *Party) XORC(xwire int, c bool, mode bool) int {
var xa = a.vals[xwire]
var xa = a.stack[xwire]
if mode { //Only one party is supposed to do the XOR
a.vals = append(a.vals, xa != c)
a.stack = append(a.stack, xa != c)
} else {
a.vals = append(a.vals, xa)
a.stack = append(a.stack, xa)
}
return len(a.vals) - 1
return len(a.stack) - 1
}
func (a *Party) ANDC(xwire int, c bool) int {
var xa = a.vals[xwire]
a.vals = append(a.vals, xa && c)
return len(a.vals) - 1
var xa = a.stack[xwire]
a.stack = append(a.stack, xa && c)
return len(a.stack) - 1
}
func (a *Party) XOR2W(xwire, ywire int) int {
var xa, xb = a.vals[xwire], a.vals[ywire]
a.vals = append(a.vals, xa != xb)
return len(a.vals) - 1
var xa, xb = a.stack[xwire], a.stack[ywire]
a.stack = append(a.stack, xa != xb)
return len(a.stack) - 1
}
type Protocol struct {
rand *rand.Rand
A, B *Party
A *Party
B *Party
}
func (P *Protocol) AND(xwire, ywire int) int {
var rand, A, B = P.rand, P.A, P.B
A, B := P.A, P.B
//1a. Generate [u], [v] and [w]
u := rand.Intn(2) == 1
ua := rand.Intn(2) == 1
......@@ -173,8 +152,8 @@ func (P *Protocol) AND(xwire, ywire int) int {
var idx_e, _ = A.XOR2W(idx_e1, idx_e2), B.XOR2W(idx_e1, idx_e2)
//6b. Compute [z]-parts
var idx_z1, _ = A.ANDC(xwire, A.vals[idx_e]), B.ANDC(xwire, B.vals[idx_e])
var idx_z2, _ = A.ANDC(ywire, A.vals[idx_d]), B.ANDC(ywire, B.vals[idx_d])
var idx_z1, _ = A.ANDC(xwire, A.stack[idx_e]), B.ANDC(xwire, B.stack[idx_e])
var idx_z2, _ = A.ANDC(ywire, A.stack[idx_d]), B.ANDC(ywire, B.stack[idx_d])
var idx_z3, _ = A.Combine(idx_e, idx_d), B.Combine(idx_e, idx_d)
//6c. Compute [z]
......@@ -208,8 +187,9 @@ func (P *Protocol) XOR2W(xwire, ywire int) int {
}
func (P *Protocol) NOT(xwire int) int {
var idx, _ = P.A.XORC(xwire, true, true), P.B.XORC(xwire, true, false)
return idx
i := P.A.XORC(xwire, true, true)
_ = P.B.XORC(xwire, true, false)
return i
}
func (P *Protocol) Output(wire int, A_Learns, B_Learns bool) []bool {
......@@ -224,28 +204,26 @@ func (P *Protocol) Output(wire int, A_Learns, B_Learns bool) []bool {
if A_Learns {
var idx_A = A.Receive()
var idx_outA = A.XOR2W(wire, idx_A)
output = append(output, A.vals[idx_outA])
output = append(output, A.stack[idx_outA])
}
if B_Learns {
var idx_B = A.Receive()
var idx_outB = A.XOR2W(wire, idx_B)
output = append(output, B.vals[idx_outB])
output = append(output, B.stack[idx_outB])
}
return output
}
func InitProtocol(seed int64) *Protocol {
var rand = rand.New(rand.NewSource(seed))
func NewProtocol() *Protocol {
var a2b = make(chan bool, 1) //Directional non-blocking channels
var b2a = make(chan bool, 1)
return &Protocol{
rand: rand,
A: InitParty(rand, b2a, a2b),
B: InitParty(rand, a2b, b2a),
A: InitParty(b2a, a2b),
B: InitParty(a2b, b2a),
}
}
func (P *Protocol) RunProtocol(x, y []bool) bool {
func (P *Protocol) Run(x, y []bool) bool {
//alice := P.A
//bob := P.B
......@@ -253,13 +231,14 @@ func (P *Protocol) RunProtocol(x, y []bool) bool {
return false
}
//Input round
var idx_s, _ = P.Input(x[0], y[0])
var idx_s, _ = P.Input(x[2], y[2])
var idx_A, _ = P.Input(x[1], y[1])
var idx_B, _ = P.Input(x[2], y[2])
var idx_B, _ = P.Input(x[0], y[0])
//Compute f(x,y) = (x_sign OR NOT y_sign) AND
// (x_A OR NOT y_A) AND
// (x_B OR NOT y_B)
//Compute f(x,y) =
// (x_sign OR NOT y_sign) AND
// (x_A OR NOT y_A) AND
// (x_B OR NOT y_B)
//a. Compute (x_sign OR NOT y_sign) = NOT (NOT x_sign AND y_sign)
//var idx_f1 = alice.XORC(idx_s, true , true) //compute NOT x_sign
......@@ -284,31 +263,23 @@ func (P *Protocol) RunProtocol(x, y []bool) bool {
return output[0]
}
func RunProtocol(x, y int) bool {
protocol := NewProtocol()
encodingX := Int2Bools(x, 3)
encodingY := Int2Bools(y, 3)
return protocol.Run(encodingX, encodingY)
}
func main() {
var p = InitProtocol(1)
var bloodA, BloodB = BloodType_ABn, BloodType_ABp
x, y := Int2Bools(bloodA, 3), Int2Bools(BloodB, 3) //[]bool{false, false, false}, []bool{true, true, true}
z := p.RunProtocol(x, y)
if z == BloodTable[bloodA][BloodB] {
bloodA, bloodB := BloodType_ABn, BloodType_ABp
z := RunProtocol(bloodA, bloodB)
if z == BloodTable[bloodA][bloodB] {
fmt.Println("Protocol succeded")
fmt.Println(z)
} else {
fmt.Printf("Protocol failed, output was %t, but should be %t", z, BloodTable[bloodA][BloodB])
fmt.Printf("Protocol failed, output was %t, but should be %t", z, BloodTable[bloodA][bloodB])
}
}
// 0 - 0 - 1
// 0 - 1 - 0
// 1 - 0 - 1
// 1 - 1 - 1
// 0 - 0 - 1
// 0 - 1 - 0
// 1 - 0 - 1
// 1 - 1 - 1
// NOT (NOT x AND Y)
// 0 - 0 - 0
// 0 - 1 - 1
// 1 - 0 - 0
// 1 - 1 - 0
......@@ -28,3 +28,15 @@ func TestInt2Bools(t *testing.T) {
t.Run("AB-", func(t *testing.T) { CheckBloodType(t, BloodType_ABn, []bool{true, true, false}) })
t.Run("AB+", func(t *testing.T) { CheckBloodType(t, BloodType_ABp, []bool{true, true, true}) })
}
func TestProtocol(t *testing.T) {
// Runs the protocol for all combinations of recipient and donor blood types.
n := len(BloodTable)
for x := 0; x < n; x++ {
for y := 0; y < n; y++ {
if z := RunProtocol(x, y); z != BloodTable[x][y] {
t.Fatalf("Failed blood compatibility test for index [%d,%d]. Expected %t, got %t", x, y, !z, z)
}
}
}
}
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