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

Handin 2 - Final

parent 853ee03d
......@@ -6,6 +6,7 @@ import (
"math/rand"
)
// Enumeration of blood types. The 'n'-suffix means negative and 'p'-suffix means positive.
const (
BloodType_On = 0
BloodType_Op = 1
......@@ -17,8 +18,10 @@ const (
BloodType_ABp = 7
)
// T is the blood type compatibily truth table, with rows being the recipient's
// blood type and columns being the donor's blood type.
// BloodTable contains the blood type compatibility truth table. Rows are the
// recipient's blood type and the columns are the donor's blood type.
//
// The table contains bools, since we compute a boolean function. Duh!
var BloodTable = [][]bool{
{true, false, false, false, false, false, false, false},
{true, true, false, false, false, false, false, false},
......@@ -30,13 +33,13 @@ var BloodTable = [][]bool{
{true, true, true, true, true, true, true, true},
}
// The parameters for the protocol
// Params contains the global protocol paramteres that are shared between Dealer, Alice and Bob.
type Params struct {
n int
nPow int // pow(2, n)
}
// Creates a new Params with n and 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,
......@@ -44,11 +47,12 @@ func NewParams(n int) *Params {
}
}
// mod computes the modulo a%n but handles negative a correctly.
// mod computes the modulo a%n but handles negative arguments correctly.
func mod(a, n int) int {
return (a%n + n) % n
}
// Dealer is the trusted party in the protocol.
type Dealer struct {
// Input to Alice
r int
......@@ -59,8 +63,10 @@ type Dealer struct {
mb [][]bool
}
// NewDealer creates a dealer with initialized parameters.
// NewDealer creates a Dealer and initialises the parameters, that are to be
// send to Alice and Bob.
func NewDealer(seed int64, T [][]bool, params *Params) *Dealer {
// Initialize a random source.
rand := rand.New(rand.NewSource(seed))
var d Dealer
......@@ -93,15 +99,18 @@ func NewDealer(seed int64, T [][]bool, params *Params) *Dealer {
return &d
}
// DealA returns the dealers input to Alice.
func (d *Dealer) DealA() (int, [][]bool) {
return d.r, d.ma
}
// DealB returns the dealers input to Bob.
func (d *Dealer) DealB() (int, [][]bool) {
return d.s, d.mb
}
// Alice represents the recipient in the protocol.
// Alice is the recipient in the protocol. Alice contains only the parameters,
// that Alice will learn during the protocol.
type Alice struct {
params *Params
......@@ -113,6 +122,7 @@ type Alice struct {
zb bool
}
// NewAlice creates an Alice and computes u = x + r mod 2^n.
func NewAlice(x, r int, ma [][]bool, params *Params) *Alice {
return &Alice{
params: params,
......@@ -123,20 +133,24 @@ func NewAlice(x, r int, ma [][]bool, params *Params) *Alice {
}
}
// Send returns u, which are send to Bob.
func (p *Alice) Send() int {
return p.u
}
// Receive handles the values (v, zb) that are send from Bob.
func (p *Alice) Receive(v int, zb bool) {
p.v = v
p.zb = zb
}
// Output returns true if Alice can receive blood from Bob. Otherwise false.
func (p *Alice) Output() bool {
return p.ma[p.u][p.v] != p.zb
}
// Bob represents the donor in the protocol.
// Bob is the donor in the protocol. Bob contains only the parameters,
// that Bob will learn during the protocol.
type Bob struct {
params *Params
......@@ -147,6 +161,7 @@ type Bob struct {
v int
}
// NewBob initializes a Bob and computes v = y + s mod 2^n.
func NewBob(y, s int, mb [][]bool, params *Params) *Bob {
return &Bob{
params: params,
......@@ -157,14 +172,19 @@ func NewBob(y, s int, mb [][]bool, params *Params) *Bob {
}
}
// Receive handles u, that is received from Alice.
func (p *Bob) Receive(u int) {
p.u = u
}
// Send returns (v, zb), that is send to Alice.
func (p *Bob) Send() (int, bool) {
return p.v, p.mb[p.u][p.v]
}
// RunProtocol runs the protocol with x being the blood type of Alice and y the
// blood type of Bob. This function returns true if Alice can receive blood
// from Bob.
func RunProtocol(x, y int) bool {
// Init protocol parameters and dealer
params := NewParams(3)
......@@ -185,6 +205,7 @@ func RunProtocol(x, y int) bool {
}
func main() {
// Test if AB+ can receive from B+ (should be true).
z := RunProtocol(BloodType_ABp, BloodType_Bp)
if z == BloodTable[BloodType_ABp][BloodType_Bp] {
fmt.Println("Protocol succeded")
......
......@@ -5,6 +5,8 @@ import (
)
func TestBloodTable(t *testing.T) {
// Check the dimensions of BloodTable.
if len(BloodTable) != 8 {
t.Fatalf("Expected 8 rows, got %d", len(BloodTable))
}
......@@ -17,6 +19,7 @@ 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)
......@@ -27,9 +30,10 @@ func TestParams(t *testing.T) {
}
func TestProtocol(t *testing.T) {
// Runs the protocol for all combinations of recipient and donor.
for x := range BloodTable {
for y := range BloodTable[x] {
// 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