/
vdcs.go
2322 lines (2027 loc) · 69.2 KB
/
vdcs.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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
package vdcs
import (
"bufio"
"bytes"
"crypto"
"crypto/aes"
"crypto/cipher"
cryptoRand "crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"log"
"math"
"math/big"
"math/rand"
"net"
"net/http"
"os"
"os/exec"
"strconv"
"strings"
"sync"
"./elgamal"
)
//Wire wire abstraction
type Wire struct {
WireID []byte `json:"WireID"`
WireLabel []byte `json:"WireLabel"`
}
//Gate gate abstraction
type Gate struct {
GateID []byte `json:"GateID"`
GateInputs [][]byte `json:"GateInputs"`
}
//CircuitGate a gate in a boolean circuit
type CircuitGate struct {
Gate
TruthTable []bool `json:"TruthTable"`
}
//GarbledGate a gate in a garbled circuit
type GarbledGate struct {
Gate
KeyY [][]byte `json:"EncryptedY"`
GarbledValuesC1 [][]byte `json:"GarbledValuesC1"`
GarbledValuesC2 [][]byte `json:"GarbledValuesC2"`
GarbledValues [][]byte `json:"GarbledValues"` //to be removed later.
}
//ComID computation ID abstraction
type ComID struct {
CID []byte `json:"ComID"`
}
//Circuit circuit abstraction
type Circuit struct {
InputGates []CircuitGate `json:"CircuitInputGates"`
MiddleGates []CircuitGate `json:"CircuitMiddleGates"`
OutputGates []CircuitGate `json:"CircuitOutputGates"`
}
//Randomness container for randomness
type Randomness struct {
Rin int64 `json:"Rin"`
Rout int64 `json:"Rout"`
Rmask int64 `json:"Rmask"`
Rgc int64 `json:"Rgc"`
LblLength int `json:"LblLength"`
}
//CircuitMessage a complete circuit message
type CircuitMessage struct {
Circuit
ComID
Randomness
}
//GarbledCircuit garbled circuit abstraction
type GarbledCircuit struct {
InputGates []GarbledGate `json:"GarbledInputGates"`
MiddleGates []GarbledGate `json:"GarbledMiddleGates"`
OutputGates []GarbledGate `json:"GarbledOutputGates"`
ComID
}
//GarbledMessage complete garbled circuit message
type GarbledMessage struct {
InputWires []Wire `json:"GarbledInputWires"`
GarbledCircuit
OutputWires []Wire `json:"GarbledOutputWires"`
}
//ResEval evaluation result abstraction
type ResEval struct {
Res [][]byte `json:"Result"`
ComID
}
//PartyInfo container for general information about a node
type PartyInfo struct {
IP []byte `json:"IP"`
Port int `json:"Port"`
PublicKey []byte `json:"PublicKey"`
UserName []byte `json:"UserName"`
}
//MyInfo container for general and private information about a node
type MyInfo struct {
PartyInfo
CleosKey []byte `json:"CleosKey"`
PrivateKey []byte `json:"PrivateKey"`
}
//ServerCapabilities server capabilities abstraction
type ServerCapabilities struct {
NumberOfGates int `json:"NumberOfGates"`
FeePerGate float64 `json:"FeePerGate"`
}
//Token a token container for the ease of message passing
type Token struct {
TokenGen []byte `json:"TokenGen"`
}
//ServerInfo container for server relevant info in Directory of Service
type ServerInfo struct {
PartyInfo
ServerCapabilities
}
//ClientInfo container for client relevant info in Directory of Service
type ClientInfo struct {
PartyInfo
}
//RegisterationMessage a complete registration message
type RegisterationMessage struct {
Type []byte `json:"Type"` //Server, Client
Server ServerInfo `json:"ServerInfo"`
}
//FunctionInfo a container for function requirements
type FunctionInfo struct {
Token
NumberOfServers int `json:"NumberOfServers"`
ServerCapabilities //in this case we describe the capabilities needed to compute the circuit
}
//CycleRequestMessage Wrapping In case we needed to add new request types for failure handling
type CycleRequestMessage struct {
FunctionInfo
}
//Cycle cycle wrapper
type Cycle struct {
ServersCycle []PartyInfo `json:"ServersCycle"`
}
//CycleMessage a complete cycle message reply
type CycleMessage struct {
Cycle
TotalFee int `json:"TotalFee"`
}
//Message passed through cycle
type Message struct {
Type []byte `json:"Type"` //Garble, Rerand, Eval
Circuit
GarbledMessage
InputWires []Wire `json:"GeneralInputWires"`
Randomness
ComID
NextServer PartyInfo `json:"NextServer"`
}
//MessageArray container of messages
type MessageArray struct {
Array []Message `json:"Array"`
Keys [][]byte `json:"Keys"`
}
//ChannelContainer contains what is passed through message channels within the client code
type ChannelContainer struct {
InputWires []Wire `json:"InputWires"`
OutputWires []Wire `json:"OutputWires"`
PartyInfo
Keys [][]byte `json:"Keys"`
}
//local Gate gate abstraction
type localgate struct {
GateID string `json:"GateID"`
GateInputs []string `json:"GateInputs"`
}
type localcircuitgate struct {
localgate
TruthTable []bool `json:"TruthTable"`
}
type localcircuit struct {
InputGates []localcircuitgate `json:"InputGates"`
MiddleGates []localcircuitgate `json:"MiddleGates"`
OutputGates []localcircuitgate `json:"OutputGates"`
}
//DirctoryInfo Global Variable to store Directory communication info
var DirctoryInfo = struct {
Port int
IP []byte
}{
Port: 0,
IP: []byte(""),
}
//DecentralizedDirectoryInfo Global Variable to store Directory communication info
var DecentralizedDirectoryInfo = struct {
URL string
ActionAccount string
PasswordWallet string
}{
URL: "",
ActionAccount: "",
PasswordWallet: "",
}
//MyOwnInfo personal info container
var MyOwnInfo MyInfo
//MyToken holds directory sent token
var MyToken Token
//Decentralization indicates whether the central or decentralized directory of service is used
var Decentralization bool
//ReadyFlag is a simulation for channels between the post handler and the eval function
var ReadyFlag bool
//ReadyMutex is a simulation for channels between the post handler and the eval function
var ReadyMutex = sync.RWMutex{}
//MyResult is a simulation for channels between the post handler and the eval function
var MyResult ResEval
// mutex for local com
var cMutex = sync.RWMutex{}
//SetMyInfo sets the info of the current node
func SetMyInfo(username string, cleosKey string) {
pI, sk := GetPartyInfo(username)
MyOwnInfo = MyInfo{
PartyInfo: pI,
CleosKey: []byte(cleosKey),
PrivateKey: sk,
}
}
//SetDirectoryInfo to set the dircotry info
func SetDirectoryInfo(ip []byte, port int) {
DirctoryInfo.Port = port
DirctoryInfo.IP = ip
}
//SetDecentralizedDirectoryInfo to set the decentralized dircotry info
func SetDecentralizedDirectoryInfo(url string, actionAccount string, passwordWallet string) {
DecentralizedDirectoryInfo.URL = url
DecentralizedDirectoryInfo.ActionAccount = actionAccount
DecentralizedDirectoryInfo.PasswordWallet = passwordWallet
}
//GetCircuitSize get the number of gates in a circuit
func GetCircuitSize(circ Circuit) int {
return len(circ.InputGates) + len(circ.MiddleGates) + len(circ.OutputGates)
}
//GetInputSizeOutputSize returns the number of inputs and outputs of a given circuit
func GetInputSizeOutputSize(circ Circuit) (inputSize int, outputSize int) {
inputSize = len(circ.InputGates) * 2
outputSize = len(circ.OutputGates)
return
}
//convertLocalToGlobal converts local context circuits into global context
func convertLocalToGlobal(lc localcircuit) (c Circuit) {
for _, val := range lc.InputGates {
tmp := CircuitGate{
Gate: Gate{
GateID: []byte(val.GateID),
},
TruthTable: val.TruthTable,
}
for _, val2 := range val.GateInputs {
tmp.GateInputs = append(tmp.GateInputs, []byte(val2))
}
c.InputGates = append(c.InputGates, tmp)
}
for _, val := range lc.MiddleGates {
tmp := CircuitGate{
Gate: Gate{
GateID: []byte(val.GateID),
},
TruthTable: val.TruthTable,
}
for _, val2 := range val.GateInputs {
tmp.GateInputs = append(tmp.GateInputs, []byte(val2))
}
c.MiddleGates = append(c.MiddleGates, tmp)
}
for _, val := range lc.OutputGates {
tmp := CircuitGate{
Gate: Gate{
GateID: []byte(val.GateID),
},
TruthTable: val.TruthTable,
}
for _, val2 := range val.GateInputs {
tmp.GateInputs = append(tmp.GateInputs, []byte(val2))
}
c.OutputGates = append(c.OutputGates, tmp)
}
return
}
//ClientRegister registers a client to directory of service
func ClientRegister() {
SetMyInfo("", "")
regMsg := RegisterationMessage{
Type: []byte("Client"),
Server: ServerInfo{
PartyInfo: MyOwnInfo.PartyInfo,
ServerCapabilities: ServerCapabilities{
NumberOfGates: 0,
FeePerGate: 0,
},
},
}
for !SendToDirectory(regMsg, DirctoryInfo.IP, DirctoryInfo.Port) {
}
}
//ClientRegisterDecentralized registers a client to the decentralized directory of service
func ClientRegisterDecentralized(username string, cleosKey string) {
SetMyInfo(username, cleosKey)
regMsg := RegisterationMessage{
Type: []byte("Client"),
Server: ServerInfo{
PartyInfo: MyOwnInfo.PartyInfo,
ServerCapabilities: ServerCapabilities{
NumberOfGates: 0,
FeePerGate: 0,
},
},
}
err := UnlockWallet(DecentralizedDirectoryInfo.URL, DecentralizedDirectoryInfo.PasswordWallet)
CreateAccount(DecentralizedDirectoryInfo.URL, regMsg)
err = RegisterOnDecentralizedDS(DecentralizedDirectoryInfo.URL, DecentralizedDirectoryInfo.ActionAccount, regMsg)
if err != nil {
panic(err)
}
}
//SolveToken recieves a token challenge and solves it
func SolveToken(token Token) Token {
ans, err := RSAPrivateDecrypt(RSAPrivateKeyFromBytes(MyOwnInfo.PrivateKey), token.TokenGen)
if err != nil {
panic("Wrong Token!")
}
return Token{TokenGen: ans}
}
//GetHandlerClient recieves a token challenge and solves it
func GetHandlerClient(w http.ResponseWriter, r *http.Request) {
if r.Method == "GET" {
var x Token
jsn, err := ioutil.ReadAll(r.Body)
if err != nil {
log.Fatal("Error reading", err)
}
err = json.Unmarshal(jsn, &x)
if err != nil {
log.Fatal("bad decode", err)
}
ret := SolveToken(x)
MyToken = ret
responseJSON, err := json.Marshal(ret)
if err != nil {
fmt.Fprintf(w, "error %s", err)
}
w.Header().Set("Content-Type", "application/json")
w.Write(responseJSON)
}
}
//PostHandlerClient recieves the result of evaluation
func PostHandlerClient(w http.ResponseWriter, r *http.Request) {
if r.Method == "POST" {
var x ResEval
jsn, err := ioutil.ReadAll(r.Body)
if err != nil {
log.Fatal("Error reading", err)
}
err = json.Unmarshal(jsn, &x)
if err != nil {
log.Fatal("bad decode", err)
}
ReadyMutex.Lock()
ReadyFlag = true
MyResult = x
ReadyMutex.Unlock()
//Pass the result to the interested eval function
}
}
//ClientHTTP Client listeners
func ClientHTTP() {
http.HandleFunc("/post", PostHandlerClient)
http.HandleFunc("/get", GetHandlerClient)
http.ListenAndServe(":"+strconv.Itoa(MyOwnInfo.Port), nil)
}
//Comm basically, the channel will need to send the input/output mapping as well
func Comm(cir string, cID int64, numberOfServers int, feePerGate float64, chVDCSCommCircRes chan<- ChannelContainer) {
file, _ := ioutil.ReadFile(cir + ".json")
localmCirc := localcircuit{}
err := json.Unmarshal([]byte(file), &localmCirc) //POSSIBLE BUG
if err != nil {
log.Fatal(err)
}
// rand.Seed(int64(cID))
mCirc := convertLocalToGlobal(localmCirc)
circuitSize := GetCircuitSize(mCirc)
cycleRequestMessage := CycleRequestMessage{
FunctionInfo{
Token: MyToken,
NumberOfServers: numberOfServers,
ServerCapabilities: ServerCapabilities{
NumberOfGates: circuitSize,
FeePerGate: feePerGate,
},
},
}
cycleMessage := CycleMessage{}
ok := false
if Decentralization == true {
ok, cycleMessage = FetchCycleDecentralized(DecentralizedDirectoryInfo.URL, DecentralizedDirectoryInfo.ActionAccount, cycleRequestMessage)
} else {
cycleMessage, ok = GetFromDirectory(cycleRequestMessage, DirctoryInfo.IP, DirctoryInfo.Port)
for ok == false {
cycleMessage, ok = GetFromDirectory(cycleRequestMessage, DirctoryInfo.IP, DirctoryInfo.Port)
}
}
msgArray, randNess, keys := GenerateMessageArray(cycleMessage, cID, mCirc)
//fmt.Println(cycleMessage)
//fmt.Println(keys) //store the keys somewhere for recovery or pass on channel
ipS1 := cycleMessage.ServersCycle[0].IP
portS1 := cycleMessage.ServersCycle[0].Port
for !SendToServer(msgArray, ipS1, portS1) {
}
//Generate input wires
arrIn, arrOut := GenerateInputWiresValidate(mCirc, randNess, cID)
//Send Circuit to channel
var cc ChannelContainer
for _, val := range arrIn {
cc.InputWires = append(cc.InputWires, Wire{WireLabel: val})
}
for _, val := range arrOut {
cc.OutputWires = append(cc.OutputWires, Wire{WireLabel: val})
}
cc.PartyInfo = cycleMessage.ServersCycle[numberOfServers-1]
cc.Keys = keys
chVDCSCommCircRes <- cc
}
//GenerateMessageArray Takes a CycleMessage, a cID, and a circuit and creates a message array encrypted and returns it with the corresponding randomness for the user to use
func GenerateMessageArray(cycleMessage CycleMessage, cID int64, circ Circuit) (mArr MessageArray, rArr []Randomness, keys [][]byte) {
cMutex.Lock()
numberOfServers := len(cycleMessage.ServersCycle)
rArr = GenerateRandomness(numberOfServers, cID)
message := Message{
Type: []byte("Garble"),
Circuit: circ,
Randomness: rArr[0],
ComID: ComID{CID: []byte(strconv.FormatInt(cID, 10))},
NextServer: cycleMessage.ServersCycle[1],
}
k1 := RandomSymmKeyGen()
messageEnc := EncryptMessageAES(k1, message)
keys = append(keys, k1)
k1, err := RSAPublicEncrypt(RSAPublicKeyFromBytes(cycleMessage.ServersCycle[0].PublicKey), k1)
if err != nil {
panic("Invalid PublicKey")
}
mArr = MessageArray{
Array: append(mArr.Array, messageEnc),
Keys: append(mArr.Keys, k1),
}
for i := 1; i < numberOfServers-1; i++ {
message = Message{
Type: []byte("ReRand"),
Randomness: rArr[i],
ComID: ComID{CID: []byte(strconv.FormatInt(cID, 10))},
NextServer: cycleMessage.ServersCycle[i+1],
}
k1 = RandomSymmKeyGen()
messageEnc = EncryptMessageAES(k1, message)
keys = append(keys, k1)
k1, err = RSAPublicEncrypt(RSAPublicKeyFromBytes(cycleMessage.ServersCycle[i].PublicKey), k1)
if err != nil {
panic("Invalid PublicKey")
}
mArr = MessageArray{
Array: append(mArr.Array, messageEnc),
Keys: append(mArr.Keys, k1),
}
}
message = Message{
Type: []byte("SEval"),
ComID: ComID{CID: []byte(strconv.FormatInt(cID, 10))},
NextServer: MyOwnInfo.PartyInfo,
}
k1 = RandomSymmKeyGen()
messageEnc = EncryptMessageAES(k1, message)
keys = append(keys, k1)
k1, err = RSAPublicEncrypt(RSAPublicKeyFromBytes(cycleMessage.ServersCycle[numberOfServers-1].PublicKey), k1)
if err != nil {
panic("Invalid PublicKey")
}
mArr = MessageArray{
Array: append(mArr.Array, messageEnc),
Keys: append(mArr.Keys, k1),
}
cMutex.Unlock()
return
}
//EncryptCircuitGatesAES encrypts an array of circuit gates with a given symmetric key using AES algorithm
func EncryptCircuitGatesAES(key []byte, gates []CircuitGate) []CircuitGate {
encGates := gates
var tmp []byte
var ok bool
for k, val := range gates {
//Encrypt gateID
tmp, ok = EncryptAES(key, []byte(val.GateID))
if !ok {
panic("!ok message encryption")
}
encGates[k].GateID = tmp
//Encrypt gate inputs
var concat [][]byte
for _, val2 := range val.GateInputs {
tmp, ok = EncryptAES(key, []byte(val2))
if !ok {
panic("!ok message encryption")
}
concat = append(concat, tmp)
}
encGates[k].GateInputs = concat
//Encrypt truth table
//Left for now for further discussion
}
return encGates
}
//DecryptCircuitGatesAES decrypts an array of circuit gates with a given symmetric key using AES algorithm
func DecryptCircuitGatesAES(key []byte, gates []CircuitGate) []CircuitGate {
decGates := gates
var tmp []byte
var ok bool
for k, val := range gates {
//Decrypt gateID
tmp, ok = DecryptAES(key, []byte(val.GateID))
if !ok {
panic("!ok message decryption")
}
decGates[k].GateID = tmp
//Encrypt gate inputs
var concat [][]byte
for _, val2 := range val.GateInputs {
tmp, ok = DecryptAES(key, []byte(val2))
if !ok {
panic("!ok message decryption")
}
concat = append(concat, tmp)
}
decGates[k].GateInputs = concat
//decrypt truth table
//Left for now for further discussion
}
return decGates
}
//EncryptGarbledGatesAES encrypts an array of garbled gates with a given symmetric key using AES algorithm
func EncryptGarbledGatesAES(key []byte, gates []GarbledGate) []GarbledGate {
encGates := gates
var tmp []byte
var ok bool
for k, val := range gates {
//Encrypt gateID
tmp, ok = EncryptAES(key, []byte(val.GateID))
if !ok {
panic("!ok message encryption")
}
encGates[k].GateID = tmp
//Encrypt gate inputs
var concat [][]byte
for _, val2 := range val.GateInputs {
tmp, ok = EncryptAES(key, []byte(val2))
if !ok {
panic("!ok message encryption")
}
concat = append(concat, tmp)
}
encGates[k].GateInputs = concat
//Encrypt GarbledTable
var concat2 [][]byte
for _, val2 := range val.GarbledValues {
tmp, ok = EncryptAES(key, val2)
if !ok {
panic("!ok message encryption")
}
concat2 = append(concat2, tmp)
}
encGates[k].GarbledValues = concat2
}
return encGates
}
//DecryptGarbledGatesAES decrypts an array of garbled gates with a given symmetric key using AES algorithm
func DecryptGarbledGatesAES(key []byte, gates []GarbledGate) []GarbledGate {
decGates := gates
var tmp []byte
var ok bool
for k, val := range gates {
//Decrypt gateID
tmp, ok = DecryptAES(key, []byte(val.GateID))
if !ok {
panic("!ok message decryption")
}
decGates[k].GateID = tmp
//Dcrypt gate inputs
var concat [][]byte
for _, val2 := range val.GateInputs {
tmp, ok = DecryptAES(key, []byte(val2))
if !ok {
panic("!ok message decryption")
}
concat = append(concat, tmp)
}
decGates[k].GateInputs = concat
//Decrypt GarbledTable
var concat2 [][]byte
for _, val2 := range val.GarbledValues {
tmp, ok = DecryptAES(key, val2)
if !ok {
panic("!ok message decryption")
}
concat2 = append(concat2, tmp)
}
decGates[k].GarbledValues = concat2
}
return decGates
}
//EncryptWiresAES encrypts an array of wires with a given key using AES Algorithm
func EncryptWiresAES(key []byte, wArr []Wire) []Wire {
nWArr := wArr
var ok bool
for k, val := range wArr {
//Encrypt wireID
//Encrypt WireLabel
nWArr[k].WireLabel, ok = EncryptAES(key, val.WireLabel)
if !ok {
panic("!ok message encryption")
}
}
return nWArr
}
//DecryptWiresAES decrypts an array of wires with a given key using AES Algorithm
func DecryptWiresAES(key []byte, wArr []Wire) []Wire {
nWArr := wArr
var ok bool
for k, val := range wArr {
//Encrypt wireID
//Encrypt WireLabel
nWArr[k].WireLabel, ok = DecryptAES(key, val.WireLabel)
if !ok {
panic("!ok message decryption")
}
}
return nWArr
}
//EncryptRandomnessAES encrypts a randomness container with a given key using AES Algorithm
func EncryptRandomnessAES(key []byte, rArr Randomness) Randomness {
nRArr := rArr
//Everything has to be converted into byte arrays.. message wise
return nRArr
}
//DecryptRandomnessAES decrypts a randomness container with a given key using AES Algorithm
func DecryptRandomnessAES(key []byte, rArr Randomness) Randomness {
nRArr := rArr
//Everything has to be converted into byte arrays.. message wise
return nRArr
}
//EncryptPartyInfoAES encrypts PartyInfo container with a given key using AES Algorithm
func EncryptPartyInfoAES(key []byte, pI PartyInfo) (nPI PartyInfo) {
var ok bool
//Encrypt IP
nPI.IP, ok = EncryptAES(key, pI.IP)
if !ok {
panic("!ok message encryption")
}
//Encrypt Port
nPI.Port = pI.Port
//Should be converted into byte array
//Encrypt PublicKey
nPI.PublicKey, ok = EncryptAES(key, pI.PublicKey)
if !ok {
panic("!ok message encryption")
}
return
}
//DecryptPartyInfoAES decrypts PartyInfo container with a given key using AES Algorithm
func DecryptPartyInfoAES(key []byte, pI PartyInfo) (nPI PartyInfo) {
var ok bool
//Encrypt IP
nPI.IP, ok = DecryptAES(key, pI.IP)
if !ok {
panic("!ok message decryption")
}
//Decrypt Port
nPI.Port = pI.Port
//Should be converted into byte array
//Decrypt PublicKey
nPI.PublicKey, ok = DecryptAES(key, pI.PublicKey)
if !ok {
panic("!ok message decryption")
}
return
}
//EncryptMessageAES takes a symmetric key and message, and encrypts the message using that key
func EncryptMessageAES(key []byte, msg Message) (nMsg Message) {
nMsg = msg
var ok bool
var tmp []byte
if string(msg.Type) == "Garble" {
//Encrypt input gates
nMsg.Circuit.InputGates = EncryptCircuitGatesAES(key, msg.Circuit.InputGates)
//Encrypt Middle Gates
nMsg.Circuit.MiddleGates = EncryptCircuitGatesAES(key, msg.Circuit.MiddleGates)
//Encrypt Output Gates
nMsg.Circuit.OutputGates = EncryptCircuitGatesAES(key, msg.Circuit.OutputGates)
//Encrypt Randomness
nMsg.Randomness = EncryptRandomnessAES(key, msg.Randomness)
//Encrypt NextServer Info
nMsg.NextServer = EncryptPartyInfoAES(key, msg.NextServer)
} else if string(msg.Type) == "ReRand" {
//Encrypt input gates
nMsg.GarbledMessage.InputGates = EncryptGarbledGatesAES(key, msg.GarbledMessage.InputGates)
//Encrypt middle gates
nMsg.GarbledMessage.MiddleGates = EncryptGarbledGatesAES(key, msg.GarbledMessage.MiddleGates)
//Encrypt output gates
nMsg.GarbledMessage.OutputGates = EncryptGarbledGatesAES(key, msg.GarbledMessage.OutputGates)
//Encrypt GarbledMessage Input wires
nMsg.GarbledMessage.InputWires = EncryptWiresAES(key, msg.GarbledMessage.InputWires)
//Encrypt GarbledMessage Output wires
nMsg.GarbledMessage.OutputWires = EncryptWiresAES(key, msg.GarbledMessage.OutputWires)
//Encrypt Randomness
nMsg.Randomness = EncryptRandomnessAES(key, msg.Randomness)
//Encrypt NextServer Info
nMsg.NextServer = EncryptPartyInfoAES(key, msg.NextServer)
} else if string(msg.Type) == "SEval" {
if len(msg.GarbledMessage.InputGates) != 0 {
//Encrypt input gates
nMsg.GarbledMessage.InputGates = EncryptGarbledGatesAES(key, msg.GarbledMessage.InputGates)
//Encrypt middle gates
nMsg.GarbledMessage.MiddleGates = EncryptGarbledGatesAES(key, msg.GarbledMessage.MiddleGates)
//Encrypt output gates
nMsg.GarbledMessage.OutputGates = EncryptGarbledGatesAES(key, msg.GarbledMessage.OutputGates)
}
//Encrypt NextServer Info
nMsg.NextServer = EncryptPartyInfoAES(key, msg.NextServer)
} else if string(msg.Type) == "CEval" {
//Encrypt InputWires
nMsg.InputWires = EncryptWiresAES(key, msg.InputWires)
//Encrypt NextServer Info
nMsg.NextServer = EncryptPartyInfoAES(key, msg.NextServer)
}
//Encrypt the type
tmp, ok = EncryptAES(key, []byte(msg.Type))
if !ok {
panic("!ok message encryption")
}
nMsg.Type = tmp
return nMsg
}
//DecryptMessageAES takes a symmetric key and message, and decrypts the message using that key
func DecryptMessageAES(key []byte, msg Message) (nMsg Message) {
nMsg = msg
var ok bool
var tmp []byte
//Decrypt the type
tmp, ok = DecryptAES(key, []byte(msg.Type))
if !ok {
panic("!ok message encryption")
}
nMsg.Type = tmp
if string(nMsg.Type) == "Garble" {
//Decrypt input gates
nMsg.Circuit.InputGates = DecryptCircuitGatesAES(key, msg.Circuit.InputGates)
//Decrypt Middle Gates
nMsg.Circuit.MiddleGates = DecryptCircuitGatesAES(key, msg.Circuit.MiddleGates)
//Decrypt Output Gates
nMsg.Circuit.OutputGates = DecryptCircuitGatesAES(key, msg.Circuit.OutputGates)
//Decrypt Randomness
nMsg.Randomness = DecryptRandomnessAES(key, msg.Randomness)
//Decrypt NextServer Info
nMsg.NextServer = DecryptPartyInfoAES(key, msg.NextServer)
} else if string(nMsg.Type) == "ReRand" {
//Decrypt input gates
nMsg.GarbledMessage.InputGates = DecryptGarbledGatesAES(key, msg.GarbledMessage.InputGates)
//Decrypt middle gates
nMsg.GarbledMessage.MiddleGates = DecryptGarbledGatesAES(key, msg.GarbledMessage.MiddleGates)
//Decrypt output gates
nMsg.GarbledMessage.OutputGates = DecryptGarbledGatesAES(key, msg.GarbledMessage.OutputGates)
//Decrypt GarbledMessage Input wires
nMsg.GarbledMessage.InputWires = DecryptWiresAES(key, msg.GarbledMessage.InputWires)
//Decrypt GarbledMessage Output wires
nMsg.GarbledMessage.OutputWires = DecryptWiresAES(key, msg.GarbledMessage.OutputWires)
//Decrypt Randomness
nMsg.Randomness = DecryptRandomnessAES(key, msg.Randomness)
//Decrypt NextServer Info
nMsg.NextServer = DecryptPartyInfoAES(key, msg.NextServer)
} else if string(nMsg.Type) == "SEval" {
if len(msg.GarbledMessage.InputGates) != 0 {
//Decrypt input gates
nMsg.GarbledMessage.InputGates = DecryptGarbledGatesAES(key, msg.GarbledMessage.InputGates)
//Decrypt middle gates
nMsg.GarbledMessage.MiddleGates = DecryptGarbledGatesAES(key, msg.GarbledMessage.MiddleGates)
//Decrypt output gates
nMsg.GarbledMessage.OutputGates = DecryptGarbledGatesAES(key, msg.GarbledMessage.OutputGates)
}
//Decrypt NextServer Info
nMsg.NextServer = DecryptPartyInfoAES(key, msg.NextServer)
} else if string(nMsg.Type) == "CEval" {
//Decrypt InputWires
nMsg.InputWires = DecryptWiresAES(key, msg.InputWires)
//Decrypt NextServer Info
nMsg.NextServer = DecryptPartyInfoAES(key, msg.NextServer)
}
return nMsg
}
//RandomSymmKeyGen Generates a random key for the AES algorithm
func RandomSymmKeyGen() (key []byte) {
key = make([]byte, 32)
_, err := cryptoRand.Read(key)
if err != nil {
panic("Error generating random symmetric key")
}
return
}
//GenerateInputWiresValidate Given circuit and randomness generate the input wires corresponding to server n-1
func GenerateInputWiresValidate(circ Circuit, rArr []Randomness, cID int64) (in [][]byte, out [][]byte) {
cMutex.Lock()
inputSize, outputSize := GetInputSizeOutputSize(circ)
in = YaoGarbledCkt_in(rArr[0].Rin, rArr[0].LblLength, inputSize)
out = YaoGarbledCkt_out(rArr[0].Rout, rArr[0].LblLength, outputSize)
for i := 1; i < len(rArr)-1; i++ {
randIn := genRandomR(len(circ.InputGates), 1, rArr[i].Rin)
randOut := genRandomR(len(circ.OutputGates), 1, rArr[i].Rout)
in = reRandWires(randIn, in, true)
out = reRandWires(randOut, out, false)
}
cMutex.Unlock()
return
}
func reRandWires(Randoms []*big.Int, wires [][]byte, in bool) [][]byte {
for j := 0; j < len(Randoms); j++ {
R := Randoms[j]
if in {
newWire := new(big.Int).SetBytes(wires[j*4])
newWire = newWire.Mul(newWire, R)
newWire = newWire.Mod(newWire, fromHex(primeHex))
wires[j*4] = newWire.Bytes()
newWire = new(big.Int).SetBytes(wires[j*4+1])
newWire = newWire.Mul(newWire, R)
newWire = newWire.Mod(newWire, fromHex(primeHex))
wires[j*4+1] = newWire.Bytes()
newWire = new(big.Int).SetBytes(wires[j*4+2])
newWire = newWire.Mul(newWire, R)
newWire = newWire.Mod(newWire, fromHex(primeHex))
wires[j*4+2] = newWire.Bytes()
newWire = new(big.Int).SetBytes(wires[j*4+3])
newWire = newWire.Mul(newWire, R)
newWire = newWire.Mod(newWire, fromHex(primeHex))
wires[j*4+3] = newWire.Bytes()
} else {
newWire := new(big.Int).SetBytes(wires[j*2])
newWire = newWire.Mul(newWire, R)
newWire = newWire.Mod(newWire, fromHex(primeHex))
wires[j*2] = newWire.Bytes()
newWire = new(big.Int).SetBytes(wires[j*2+1])
newWire = newWire.Mul(newWire, R)
newWire = newWire.Mod(newWire, fromHex(primeHex))
wires[j*2+1] = newWire.Bytes()
}
}
return wires
}
//GenerateRandomness generates randomness array corresponding to NumberOfServers with a certain computation ID
func GenerateRandomness(numberOfServers int, cID int64) []Randomness {
rArr := make([]Randomness, numberOfServers)
rand.Seed(cID)
for k := range rArr {
rArr[k] = Randomness{
Rin: rand.Int63(),
Rout: rand.Int63(),
Rgc: rand.Int63(),
LblLength: 16, //Should be rand.Int()%16 + 16
}
}
return rArr
}
//CompareWires Takes a garbled circuit and compares wires to input,output wires provided by the user
func CompareWires(gcm GarbledMessage, arrIn [][]byte, arrOut [][]byte) bool {
for k, val := range gcm.InputWires {
if bytes.Compare(arrIn[k], val.WireLabel) != 0 {
fmt.Println("I was cheated on this: ", arrIn[k], val.WireLabel)
// panic("The server has cheated me") //redo the process, by recovering from panic by recalling comm
return false
}
}
for k, val := range gcm.OutputWires {