main.go 2.68 KB
Newer Older
Thomas Hoffmann's avatar
Thomas Hoffmann committed
1
2
3
4
5
package main

import (
	"crycomp/internal/blood"
	"crycomp/internal/crypto/homomorphic"
Anders Jensen Løvig's avatar
Anders Jensen Løvig committed
6
	"crycomp/internal/crypto/util"
Anders Jensen Løvig's avatar
Anders Jensen Løvig committed
7
	"crypto/rand"
Thomas Hoffmann's avatar
Thomas Hoffmann committed
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
	"fmt"
	"math/big"
)

func main() {
	bloodA, bloodB := blood.Type_ABn, blood.Type_ABn
	z, err := RunProtocol(bloodA, bloodB)
	if err != nil {
		fmt.Println("Protocol failed with error:", err)
	} else if z == blood.Table[bloodA][bloodB] {
		fmt.Println("Protocol succeded")
	} else {
		fmt.Printf("Protocol failed, output was %t, but should be %t", z, blood.Table[bloodA][bloodB])
	}
}

type Party struct {
Anders Jensen Løvig's avatar
Anders Jensen Løvig committed
25
	conn chan *big.Int
Thomas Hoffmann's avatar
Thomas Hoffmann committed
26
27
}

Anders Jensen Løvig's avatar
Anders Jensen Løvig committed
28
func (alice *Party) RunAlice(x int, priv *homomorphic.PrivateKey) (result bool, err error) {
Thomas Hoffmann's avatar
Thomas Hoffmann committed
29
30
	xval := make([]int, 3)
	//Negate values
Anders Jensen Løvig's avatar
Anders Jensen Løvig committed
31
32
33
34
	for i, val := range util.Int2Bools(x, 3) {
		if !val {
			xval[i] = 1
		}
Thomas Hoffmann's avatar
Thomas Hoffmann committed
35
36
37
	}

	// Send encoded input ints to bob
Anders Jensen Løvig's avatar
Anders Jensen Løvig committed
38
	for i := 0; i < 3; i++ {
Anders Jensen Løvig's avatar
Anders Jensen Løvig committed
39
40
41
42
43
		c, err := homomorphic.Encrypt(rand.Reader, xval[i], &priv.PublicKey)
		if err != nil {
			return false, err
		}
		alice.conn <- c
Thomas Hoffmann's avatar
Thomas Hoffmann committed
44
45
46
	}

	//Receive and decode result from bob
Anders Jensen Løvig's avatar
Anders Jensen Løvig committed
47
48
	result = homomorphic.Decrypt(<-alice.conn, priv) == 1 //Convert 1 -> true
	// result = alice.HEProt.Decode(<-alice.conn, *alice.sKey) == 1 //Convert 1 -> true
Thomas Hoffmann's avatar
Thomas Hoffmann committed
49
50
51
	return
}

Anders Jensen Løvig's avatar
Anders Jensen Løvig committed
52
func (bob *Party) RunBob(y int, pub *homomorphic.PublicKey) (err error) {
Anders Jensen Løvig's avatar
Anders Jensen Løvig committed
53
54
	c_y := make([]*big.Int, 3)
	for i, val := range util.Int2Bools(y, 3) {
Thomas Hoffmann's avatar
Thomas Hoffmann committed
55
		bit := 0
Anders Jensen Løvig's avatar
Anders Jensen Løvig committed
56
57
58
		if val {
			bit = 1
		}
Anders Jensen Løvig's avatar
Anders Jensen Løvig committed
59
60
61
62
		c_y[i], err = homomorphic.Encrypt(rand.Reader, bit, pub)
		if err != nil {
			return
		}
Anders Jensen Løvig's avatar
Anders Jensen Løvig committed
63
		// c_y[i] = bob.HEProt.Encode(bit)
Thomas Hoffmann's avatar
Thomas Hoffmann committed
64
65
66
67
68
	}

	//Receive ciphertexts from alice
	c_x := make([]*big.Int, 3)
	for i := range c_x {
Anders Jensen Løvig's avatar
Anders Jensen Løvig committed
69
		c_x[i] = <-bob.conn
Thomas Hoffmann's avatar
Thomas Hoffmann committed
70
	}
Anders Jensen Løvig's avatar
Anders Jensen Løvig committed
71

Anders Jensen Løvig's avatar
Anders Jensen Løvig committed
72
73
74
75
76
	c, err := evaluate(c_x, c_y, pub)
	if err != nil {
		return
	}
	bob.conn <- c
Anders Jensen Løvig's avatar
Anders Jensen Løvig committed
77
	// bob.conn <- *bob.HEProt.Eval(c_x, c_y)
Anders Jensen Løvig's avatar
Anders Jensen Løvig committed
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
	return
}

func evaluate(x, y []*big.Int, pub *homomorphic.PublicKey) (result *big.Int, err error) {
	one, err := homomorphic.Encrypt(rand.Reader, 1, pub)
	if err != nil {
		return
	}
	tmp := make([]*big.Int, 3)

	for i := 0; i < 3; i++ {
		v := new(big.Int).Mul(x[i], y[i])
		tmp[i] = v.Add(v, one)
	}

	result = new(big.Int).Mul(tmp[0], tmp[1])
	result.Mul(result, tmp[2])
	return
Thomas Hoffmann's avatar
Thomas Hoffmann committed
96
97
98
99
100
}

// RunProtocol runs the protocol between receiving blood type x and donor blood
// type y.
func RunProtocol(x, y int) (z bool, err error) {
Anders Jensen Løvig's avatar
Anders Jensen Løvig committed
101
102
103
	conn := make(chan *big.Int)
	Alice := &Party{conn}
	Bob := &Party{conn}
Anders Jensen Løvig's avatar
Anders Jensen Løvig committed
104
	privKey, err := homomorphic.GenerateKey(rand.Reader, 1000, 1000000, 40, 1000)
Thomas Hoffmann's avatar
Thomas Hoffmann committed
105
106
107
108
109
110
	if err != nil {
		return
	}

	// Concurrently run Bob
	go func() {
Anders Jensen Løvig's avatar
Anders Jensen Løvig committed
111
		err := Bob.RunBob(y, &privKey.PublicKey)
Thomas Hoffmann's avatar
Thomas Hoffmann committed
112
113
114
115
116
		if err != nil {
			panic(err) // TODO do not panic
		}
	}()

Anders Jensen Løvig's avatar
Anders Jensen Løvig committed
117
	z, err = Alice.RunAlice(x, privKey)
Thomas Hoffmann's avatar
Thomas Hoffmann committed
118
	return
Anders Jensen Løvig's avatar
Anders Jensen Løvig committed
119
}