Commit 1da78dfa authored by Thomas Hoffmann's avatar Thomas Hoffmann
Browse files

Merge 2.0

parents 57462bad fa385a77
......@@ -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]
......@@ -210,8 +189,9 @@ func (P *Protocol) XOR2W(xwire, ywire int) int {
//Only 1 share should be flipped
//NOT A == A XOR 1
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 {
......@@ -226,28 +206,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 = B.Receive()
var idx_outB = B.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
......@@ -255,28 +233,29 @@ func (P *Protocol) RunProtocol(x, y []bool) bool {
return false
}
//Input round
var idx_xS, idx_yS= P.Input(x[0], y[0])
var idx_xS, idx_yS = P.Input(x[2], y[2])
var idx_xA, idx_yA = P.Input(x[1], y[1])
var idx_xB, idx_yB = P.Input(x[2], y[2])
var idx_xB, idx_yB = 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 = P.NOT(idx_xS)
idx_f1 = P.AND(idx_f1, idx_yS) // NOT x_sign AND y_sign
idx_f1 = P.NOT(idx_f1) //NOT (NOT x_sign AND y_sign)
idx_f1 = P.NOT(idx_f1) //NOT (NOT x_sign AND y_sign)
//b. Compute (x_A OR NOT y_A) = NOT (NOT x_A AND y_A)
var idx_f2 = P.NOT(idx_xA) //compute NOT x_A
idx_f2 = P.AND(idx_f2, idx_yA) // NOT x_A AND y_A
idx_f2 = P.NOT(idx_f2) //NOT (NOT x_A AND y_A)
idx_f2 = P.NOT(idx_f2) //NOT (NOT x_A AND y_A)
//c. Compute (x_B OR NOT y_B) = NOT (NOT x_B AND y_B)
var idx_f3 = P.NOT(idx_xB) //compute NOT x_B
idx_f3 = P.AND(idx_f3, idx_yB) // NOT x_B AND y_B
idx_f3 = P.NOT(idx_f3) //NOT (NOT x_B AND y_B)
idx_f3 = P.NOT(idx_f3) //NOT (NOT x_B AND y_B)
//d. Compute f(x,y)
var idx_f = P.AND(idx_f1, idx_f2)
......@@ -285,31 +264,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
package main
import (
"fmt"
"testing"
)
var p Protocol
func init() {
p = *InitProtocol(69420)
p = *NewProtocol()
}
func TestBloodTable(t *testing.T) {
......@@ -25,31 +24,6 @@ func TestBloodTable(t *testing.T) {
}
}
func TestParams(t *testing.T) {
// Check that params are calculated correctly.
p := NewParams(7)
if p.n != 7 {
t.Fatalf("Expected 7, got %d", p.n)
}
if p.nPow != 128 {
t.Fatalf("Expected 128, got %d", p.nPow)
}
}
func TestProtocol(t *testing.T) {
// Runs the protocol for all combinations of recipient and donor blood types.
n := len(BloodTable)
fmt.Println(n)
for x := 0; x < n; x++ {
for y := 0; y < n; y++ {
p = *InitProtocol(69420)
var px, py = Int2Bools(x, 3), Int2Bools(y, 3)
if z := p.RunProtocol(px, py); z != BloodTable[x][y] {
t.Errorf("Failed blood compatibility test for index [%d,%d]. Expected %t, got %t", x, y, !z, z)
}
}
}
}
func CheckBloodType(t *testing.T, bloodType int, expected []bool) {
actual := Int2Bools(bloodType, 3)
......@@ -73,7 +47,7 @@ func TestPartyStack(t *testing.T) {
//Adds 1 value to A and 0 to B
func TestStackInput(t *testing.T) {
var idx = p.A.Input(true)
if len(p.A.vals) != 1 && len(p.B.vals) != 0 {
if len(p.A.stack) != 1 && len(p.B.stack) != 0 {
t.Error()
}
if idx != 1 {
......@@ -85,7 +59,7 @@ func TestStackInput(t *testing.T) {
func TestStackReceive(t *testing.T) {
p.B.Input(true)
var idx = p.A.Receive()
if len(p.A.vals) != 1 && len(p.B.vals) != 1 {
if len(p.A.stack) != 1 && len(p.B.stack) != 1 {
t.Error()
}
if idx != 1 {
......@@ -99,9 +73,9 @@ func TestStackCombine(t *testing.T) {
p.B.Receive()
var b = p.A.Input(false)
var ASizeBefore, BSizeBefore = len(p.A.vals), len(p.B.vals)
var ASizeBefore, BSizeBefore = len(p.A.stack), len(p.B.stack)
var idx = p.A.Combine(a, b)
if len(p.A.vals) != ASizeBefore+1 && len(p.B.vals) != BSizeBefore {
if len(p.A.stack) != ASizeBefore+1 && len(p.B.stack) != BSizeBefore {
t.Error()
}
if idx != 2 {
......@@ -113,15 +87,15 @@ func TestStackCombine(t *testing.T) {
func TestStackXORC(t *testing.T) {
p.A.Input(true)
var ASizeBefore, BSizeBefore = len(p.A.vals), len(p.B.vals)
var ASizeBefore, BSizeBefore = len(p.A.stack), len(p.B.stack)
var idx1 = p.A.XORC(0, true, true)
if len(p.A.vals) != ASizeBefore+1 && len(p.B.vals) != BSizeBefore {
if len(p.A.stack) != ASizeBefore+1 && len(p.B.stack) != BSizeBefore {
t.Error()
}
ASizeBefore, BSizeBefore = len(p.A.vals), len(p.B.vals)
ASizeBefore, BSizeBefore = len(p.A.stack), len(p.B.stack)
var idx2 = p.A.XORC(0, true, false)
if len(p.A.vals) != ASizeBefore+1 && len(p.B.vals) != BSizeBefore {
if len(p.A.stack) != ASizeBefore+1 && len(p.B.stack) != BSizeBefore {
t.Error()
}
if idx1 != 1 || idx2 != 2 {
......@@ -133,9 +107,9 @@ func TestStackXORC(t *testing.T) {
func TestStackANDC(t *testing.T) {
var a = p.A.Input(true)
var ASizeBefore, BSizeBefore = len(p.A.vals), len(p.B.vals)
var ASizeBefore, BSizeBefore = len(p.A.stack), len(p.B.stack)
var idx = p.A.ANDC(a, true)
if len(p.A.vals) != ASizeBefore+1 && len(p.B.vals) != BSizeBefore {
if len(p.A.stack) != ASizeBefore+1 && len(p.B.stack) != BSizeBefore {
t.Error()
}
if idx != 1 {
......@@ -148,7 +122,7 @@ func TestStackXOR2W(t *testing.T) {
p.B.Receive()
var b = p.A.Input(false)
var idx = p.A.XOR2W(a, b)
if len(p.A.vals) != 3 && len(p.B.vals) != 1 {
if len(p.A.stack) != 3 && len(p.B.stack) != 1 {
t.Error()
}
if idx != 2 {
......@@ -163,7 +137,7 @@ func TestStackAND(t *testing.T) {
p.B.Receive()
var idx = p.AND(a, b)
if len(p.A.vals) != 17 || len(p.B.vals) != 17 {
if len(p.A.stack) != 17 || len(p.B.stack) != 17 {
t.Error()
}
if idx != 16 {
......@@ -182,11 +156,11 @@ func TestProtocolFunctions(t *testing.T) {
func TestProtocolInput(t *testing.T) {
var idxA, idxB = p.Input(true, false)
var shareA, shareB = p.A.vals[idxA] != p.B.vals[idxA], p.A.vals[idxB] != p.B.vals[idxB]
var shareA, shareB = p.A.stack[idxA] != p.B.stack[idxA], p.A.stack[idxB] != p.B.stack[idxB]
if shareA != true || shareB != false {
t.Fatal("Shares has wrong values")
}
if len(p.A.vals) != len(p.B.vals) {
if len(p.A.stack) != len(p.B.stack) {
t.Fatal("Party stack size is not equal after function call")
}
}
......@@ -199,14 +173,14 @@ func TestProtocolXORC(t *testing.T) {
var idxTF = p.XORC(idxTrue, false)
var idxFT = p.XORC(idxFalse, true)
var idxFF = p.XORC(idxFalse, false)
var resTT, resTF, resFT, resFF = p.A.vals[idxTT] != p.B.vals[idxTT],
p.A.vals[idxTF] != p.B.vals[idxTF],
p.A.vals[idxFT] != p.B.vals[idxFT],
p.A.vals[idxFF] != p.B.vals[idxFF]
var resTT, resTF, resFT, resFF = p.A.stack[idxTT] != p.B.stack[idxTT],
p.A.stack[idxTF] != p.B.stack[idxTF],
p.A.stack[idxFT] != p.B.stack[idxFT],
p.A.stack[idxFF] != p.B.stack[idxFF]
if resTT != false || resTF != true || resFT != true || resFF != false {
t.Fatal("Shares has wrong values")
}
if len(p.A.vals) != len(p.B.vals) {
if len(p.A.stack) != len(p.B.stack) {
t.Fatal("Party stack size is not equal after function call")
}
}
......@@ -219,14 +193,14 @@ func TestProtocolANDC(t *testing.T) {
var idxTF = p.ANDC(idxTrue, false)
var idxFT = p.ANDC(idxFalse, true)
var idxFF = p.ANDC(idxFalse, false)
var resTT, resTF, resFT, resFF = p.A.vals[idxTT] != p.B.vals[idxTT],
p.A.vals[idxTF] != p.B.vals[idxTF],
p.A.vals[idxFT] != p.B.vals[idxFT],
p.A.vals[idxFF] != p.B.vals[idxFF]
var resTT, resTF, resFT, resFF = p.A.stack[idxTT] != p.B.stack[idxTT],
p.A.stack[idxTF] != p.B.stack[idxTF],
p.A.stack[idxFT] != p.B.stack[idxFT],
p.A.stack[idxFF] != p.B.stack[idxFF]
if resTT != true || resTF != false || resFT != false || resFF != false {
t.Fatal("Shares has wrong values")
}
if len(p.A.vals) != len(p.B.vals) {
if len(p.A.stack) != len(p.B.stack) {
t.Fatal("Party stack size is not equal after function call")
}
}
......@@ -239,14 +213,14 @@ func TestProtocolXOR2W(t *testing.T) {
var idxTF = p.XOR2W(idxTrue, idxFalse)
var idxFT = p.XOR2W(idxFalse, idxTrue)
var idxFF = p.XOR2W(idxFalse, idxFalse)
var resTT, resTF, resFT, resFF = p.A.vals[idxTT] != p.B.vals[idxTT],
p.A.vals[idxTF] != p.B.vals[idxTF],
p.A.vals[idxFT] != p.B.vals[idxFT],
p.A.vals[idxFF] != p.B.vals[idxFF]
var resTT, resTF, resFT, resFF = p.A.stack[idxTT] != p.B.stack[idxTT],
p.A.stack[idxTF] != p.B.stack[idxTF],
p.A.stack[idxFT] != p.B.stack[idxFT],
p.A.stack[idxFF] != p.B.stack[idxFF]
if resTT != false || resTF != true || resFT != true || resFF != false {
t.Fatal("Shares has wrong values")
}
if len(p.A.vals) != len(p.B.vals) {
if len(p.A.stack) != len(p.B.stack) {
t.Fatal("Party stack size is not equal after function call")
}
}
......@@ -257,12 +231,12 @@ func TestProtocolNOT(t *testing.T) {
var idxT = p.NOT(idxTrue)
var idxF = p.NOT(idxFalse)
var resT, resF = p.A.vals[idxT] != p.B.vals[idxF],
p.A.vals[idxF] != p.B.vals[idxF]
var resT, resF = p.A.stack[idxT] != p.B.stack[idxF],
p.A.stack[idxF] != p.B.stack[idxF]
if resT != false || resF != true {
t.Fatal("Shares has wrong values")
}
if len(p.A.vals) != len(p.B.vals) {
if len(p.A.stack) != len(p.B.stack) {
t.Fatal("Party stack size is not equal after function call")
}
}
......@@ -312,3 +286,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