/
protocol.go
126 lines (105 loc) · 2.55 KB
/
protocol.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
package smp
import (
"crypto/rand"
"errors"
"io"
"math/big"
)
const Version = 1
// Event represents SMP events
type Event int
const (
// Success means the SMP completed with success and the secrets match
Success Event = iota
// InProgress means update the auth progress dialog with progress_percent
InProgress
// Abort means the SMP protocol has been aborted
Abort
// Cheated means the SMP protocol has been cheated
Cheated
// Error means the SMP protocol terminated due an error in the protocol, like a verification failure
Error
// Failure means the SMP protocol failed due errors extrinsic to the protocol
Failure
)
var (
errUnspecifiedSecret = errors.New("missing secret")
errShortRandomRead = errors.New("short read from rand source")
)
// Message represents an SMP message
type Message interface {
MPIs() []*big.Int
received(*Protocol) (Message, error)
}
// Options represents configuration options for the SMP protocol
type Options interface {
ParameterLength() int
IsGroupElement(*big.Int) bool
}
// Protocol represents the SMP protocol
type Protocol struct {
Options
Rand io.Reader
Question string
Secret *big.Int
eventC chan Event
smpState
s1 *smp1State
s2 *smp2State
s3 *smp3State
s4 *smp4State
}
// NewProtocol returns an SMP protocol
func NewProtocol(options Options) *Protocol {
return &Protocol{
Options: options,
smpState: smpStateExpect1{},
Rand: rand.Reader,
eventC: make(chan Event, 1),
}
}
// Receive process the incoming message and potentially returns a message
// addressed to the other peer
func (p *Protocol) Receive(m Message) (Message, error) {
send, err := m.received(p)
if err != nil {
p.event(Failure)
return nil, err
}
return send, nil
}
func (p *Protocol) Abort() (ret Message) {
//err is always nil
p.smpState, ret, _ = sendSMPAbortAndRestartStateMachine()
p.event(Abort)
return
}
// Compare starts the protocol and generates a message addressed to the other
// peer
func (p *Protocol) Compare() (Message, error) {
if p.Secret == nil {
p.event(Failure)
return nil, errUnspecifiedSecret
}
m, err := p.newSMP1Message()
if err != nil {
p.event(Failure)
return nil, err
}
p.smpState = smpStateExpect2{}
p.event(InProgress)
return m, nil
}
func (p *Protocol) startMessage() (Message, error) {
if len(p.Question) > 0 {
return p.newSMP1QMessage(p.Question)
}
return p.newSMP1Message()
}
// Events returns the events channel for this Protocol
func (p Protocol) Events() <-chan Event {
return p.eventC
}
func (p Protocol) event(e Event) {
go func() { p.eventC <- e }()
}