forked from ldsec/CS523-Project1
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathparties.go
153 lines (129 loc) · 3.33 KB
/
parties.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package main
import (
"encoding/binary"
"errors"
"fmt"
"net"
"sync"
)
type PartyID uint64
type Party struct {
ID PartyID
Addr string
}
type LocalParty struct {
Party
*sync.WaitGroup
Peers map[PartyID]*RemoteParty
}
func check(err error) {
if err != nil {
panic(err.Error())
}
}
func NewLocalParty(id PartyID, peers map[PartyID]string) (*LocalParty, error) {
// Create a new local party from the peers map
p := &LocalParty{}
p.ID = id
p.Peers = make(map[PartyID]*RemoteParty, len(peers))
p.Addr = peers[id]
var err error
for pId, pAddr := range peers {
p.Peers[pId], err = NewRemoteParty(pId, pAddr)
if err != nil {
return nil, err
}
}
return p, nil
}
func (lp *LocalParty) String() string {
// Print the party number
return fmt.Sprintf("party-%d", lp.ID)
}
type Message struct {
MPCMessage *MPCMessage
BeaverMessage *BeaverMessage
}
type MessageType uint64
const (
MPC MessageType = iota
Beaver
)
type RemoteParty struct {
Party
SendingChan chan Message // One sending channel per peer
ReceiveChan chan Message // One receiving channel per peer
}
func (rp *RemoteParty) String() string {
return fmt.Sprintf("party-%d", rp.ID)
}
func NewRemoteParty(id PartyID, addr string) (*RemoteParty, error) {
p := &RemoteParty{}
p.ID = id
p.Addr = addr
p.SendingChan = make(chan Message, 32)
p.ReceiveChan = make(chan Message, 32)
return p, nil
}
// Handle each channel input (receiving and sending). It will send the message by marshalling the structure depending on the message type. The message type is the first field sent to that the unmarshalling is made easier.
func (lp *LocalParty) BindNetwork(nw *TCPNetworkStruct) {
for partyID, conn := range nw.Conns {
if partyID == lp.ID {
continue
}
rp := lp.Peers[partyID]
// Receiving loop from remote
go func(conn net.Conn, rp *RemoteParty) {
for {
var msgType MessageType
var msg Message
err := binary.Read(conn, binary.BigEndian, &msgType)
check(err)
switch msgType {
case MPC:
var val uint64
var out WireID
var err error
err = binary.Read(conn, binary.BigEndian, &val)
check(err)
err = binary.Read(conn, binary.BigEndian, &out)
check(err)
msg.MPCMessage = &MPCMessage{
Value: val,
Out: out,
}
case Beaver:
var size uint64
err = binary.Read(conn, binary.BigEndian, &size)
check(err)
val := make([]byte, size)
err = binary.Read(conn, binary.BigEndian, &val)
check(err)
msg.BeaverMessage = &BeaverMessage{Size: size, Value: val}
default:
check(errors.New("unknown message type"))
}
rp.ReceiveChan <- msg
}
}(conn, rp)
// Sending loop of remote
go func(conn net.Conn, rp *RemoteParty) {
var m Message
var open = true
for open {
m, open = <-rp.SendingChan
if beaverMsg := m.BeaverMessage; beaverMsg != nil {
check(binary.Write(conn, binary.BigEndian, Beaver))
check(binary.Write(conn, binary.BigEndian, beaverMsg.Size))
check(binary.Write(conn, binary.BigEndian, beaverMsg.Value))
} else if mpcMsg := m.MPCMessage; mpcMsg != nil {
check(binary.Write(conn, binary.BigEndian, MPC))
check(binary.Write(conn, binary.BigEndian, mpcMsg.Value))
check(binary.Write(conn, binary.BigEndian, mpcMsg.Out))
} else {
check(errors.New("no message to send"))
}
}
}(conn, rp)
}
}