aboutsummaryrefslogtreecommitdiff
path: root/dashboard/dashboard.go
blob: 6f384f9474423f38762f1e7a8f9e18f530119ba1 (plain)
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
package dashboard

import (
	"bytes"
	"crypto/ed25519"
	"encoding/base32"
	"encoding/json"

	"kesim.org/seal"
	"kesim.org/seal/nizk/commit"
)

type Dashboard interface {
	NewAuction(description *seal.SignedDescription) (auctionId string, e error)
	Auctions(state AuctionState) map[string]*seal.SignedDescription
	Join(auctionId string, commitment SignedCommitment, bidderId ed25519.PublicKey) error
	Commitments(auctionId string) (bidders map[string]SignedCommitment, e error)
	Publish(auctionId string, round uint8, message SignedMessage, bidderId ed25519.PublicKey) error
	Messages(auctionId string, round uint8) (messages map[string]SignedMessage, e error)
	Cancel(auctionId string, reason SignedMessage, bidderId ed25519.PublicKey) error
	Result(auctionId string) (price uint64, winner ed25519.PublicKey, e error)
}

type SignedMessage struct {
	Message   []byte
	Signature []byte
}

type SignedCommitment struct {
	*commit.Commitment
	Signature []byte
}

type Error int

const (
	ErrUnknownError Error = iota

	ErrSellerIncorrectSignature
	ErrSellerAuctionExists

	ErrAuctionUnknown
	ErrAuctionNotStarted
	ErrAuctionNotReady
	ErrAuctionNotRunning
	ErrAuctionFinished
	ErrAuctionCanceled
	ErrAuctionTimeout
	ErrAuctionInvalidRound

	ErrBidderUnknown
	ErrBidderTimeout
	ErrBidderEmptyMessage
	ErrBidderIncorrectSignature
	ErrBidderWrongRound
	ErrBidderVerificationFailed
)

func (d Error) Error() string {
	switch d {
	case ErrUnknownError:
		return "unknown error"

	case ErrSellerIncorrectSignature:
		return "incorrect seller signature"
	case ErrSellerAuctionExists:
		return "auction with that id already exists"

	case ErrAuctionUnknown:
		return "unknown auction"
	case ErrAuctionNotStarted:
		return "auction not started yet"
	case ErrAuctionNotReady:
		return "auction not ready"
	case ErrAuctionNotRunning:
		return "auction is not running"
	case ErrAuctionFinished:
		return "auction is finished"
	case ErrAuctionTimeout:
		return "action has timed out"
	case ErrAuctionCanceled:
		return "auction has been canceled"
	case ErrAuctionInvalidRound:
		return "invalid round"

	case ErrBidderUnknown:
		return "bidder is unknown"
	case ErrBidderTimeout:
		return "bidder has timed out"
	case ErrBidderEmptyMessage:
		return "empty message"
	case ErrBidderIncorrectSignature:
		return "incorrect signature from bidder"
	case ErrBidderWrongRound:
		return "wrong round"
	case ErrBidderVerificationFailed:
		return "round data couldn't be verified"

	default:
		panic("should not happen")
	}
}

type AuctionState int

const (
	AuctionStateUnknown AuctionState = iota

	AuctionStateReady
	AuctionStateRunning
	AuctionStateFinished
	AuctionStateCanceled
	AuctionStateTimeout

	AuctionStateLAST
)

func (s *SignedMessage) Verify(pubkey ed25519.PublicKey) bool {
	return ed25519.Verify(pubkey, s.Message, s.Signature)
}

func (s *SignedCommitment) Verify(pubkey ed25519.PublicKey) bool {
	buf := &bytes.Buffer{}
	e := json.NewEncoder(buf).Encode(s.Commitment)
	if e != nil {
		return false
	}

	return ed25519.Verify(pubkey, buf.Bytes(), s.Signature)
}

func Pub2String(pubkey ed25519.PublicKey) string {
	return base32.StdEncoding.EncodeToString(pubkey)
}