/
offline_stage_simple.go
119 lines (102 loc) · 2.87 KB
/
offline_stage_simple.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
package ecdsa_tss
/*
#cgo CFLAGS:-I${SRCDIR}/bls-tss/include
#include <stdio.h>
#include <stdlib.h>
#include <tss.h>
*/
import "C"
import (
log "github.com/sirupsen/logrus"
"unsafe"
)
type OfflineStageSimple struct {
msgHash string
i int
n int
localKey string
state unsafe.Pointer
buffer unsafe.Pointer
output *SignManual
}
func NewOfflineStageSimple(msgHash string, i int, sL []int, n int, localKey string) *OfflineStageSimple {
cKey := C.CString(localKey)
defer C.free(unsafe.Pointer(cKey))
buffer := C.malloc(C.size_t(BufferSize))
indices := make([]C.int, len(sL))
for i, partyI := range sL {
indices[i] = C.int(partyI)
}
state := C.new_offline_stage(C.int(i), (*C.int)(unsafe.Pointer(&indices[0])), C.int(len(sL)), cKey)
return &OfflineStageSimple{msgHash, i, n, localKey, state, buffer, nil}
}
func (k *OfflineStageSimple) Free() {
C.free(k.buffer)
C.free_offline_stage(k.state)
}
func (k *OfflineStageSimple) Init() []string {
k.proceedIfNeeded()
return k.getOutgoing()
}
func (k *OfflineStageSimple) Handle(msg string) (bool, []string, error) {
k.handleIncoming(msg)
k.proceedIfNeeded()
outgoing := k.getOutgoing()
output := k.finishIfPossible()
finished := output != nil
if finished {
k.output = output
}
return finished, outgoing, nil
}
func (k *OfflineStageSimple) Output() *SignManual {
return k.output
}
func (k *OfflineStageSimple) proceedIfNeeded() {
res := C.offline_stage_wants_to_proceed(k.state)
k.trace("offline_stage_wants_to_proceed", res)
if res == 1 {
res = C.offline_stage_proceed(k.state)
k.trace("offline_stage_proceed", res)
}
}
func (k *OfflineStageSimple) getOutgoing() []string {
var outgoing []string
res := C.offline_stage_has_outgoing(k.state)
k.trace("offline_stage_has_outgoing", res)
for res > 0 {
outgoingBytesSize := C.offline_stage_outgoing(k.state, (*C.char)(k.buffer), BufferSize)
k.trace("offline_stage_outgoing_size", outgoingBytesSize)
out := C.GoString((*C.char)(k.buffer))
k.trace("offline_stage_outgoing", out[:50])
outgoing = append(outgoing, C.GoString((*C.char)(k.buffer)))
res = C.offline_stage_has_outgoing(k.state)
}
return outgoing
}
func (k *OfflineStageSimple) handleIncoming(msg string) {
k.trace("offline_stage_incoming", msg[:50])
cText := C.CString(msg)
defer C.free(unsafe.Pointer(cText))
C.offline_stage_incoming(k.state, cText)
}
func (k *OfflineStageSimple) finishIfPossible() *SignManual {
finished := C.offline_stage_is_finished(k.state)
if finished != 1 {
return nil
}
cHash := C.CString(k.msgHash)
defer C.free(unsafe.Pointer(cHash))
res := C.offline_stage_to_sign_manual(k.state, cHash)
if res != nil {
return NewSignManual(k.i, k.n, res)
}
return nil
}
func (k *OfflineStageSimple) trace(funcName string, result interface{}) {
log.WithFields(log.Fields{
"participant": k.i,
"funcName": funcName,
"result": result,
}).Trace("statusCheck")
}