aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÖzgür Kesim <oec@kesim.org>2024-11-10 11:53:19 +0100
committerÖzgür Kesim <oec@kesim.org>2024-11-10 11:53:19 +0100
commitf98e43234a3b7a9823ac9b9e68c7c595c10ebe7d (patch)
tree2e1e5dac6c3a3ae4465baeb9179d0718c5cd8b28
parent2100500f1a0a8534a5d6f900b4e35ad9a09aa339 (diff)
start refactor
-rw-r--r--auction.go130
-rw-r--r--bidder/auction.go67
-rw-r--r--bidder/bid.go77
-rw-r--r--bidder/bid_test.go27
-rw-r--r--bidder/option.go18
-rw-r--r--nizk/commit/commit.go22
-rw-r--r--option.go15
7 files changed, 155 insertions, 201 deletions
diff --git a/auction.go b/auction.go
index e4f53b7..32e9758 100644
--- a/auction.go
+++ b/auction.go
@@ -6,7 +6,13 @@ import (
"crypto/sha512"
"encoding/base32"
"encoding/json"
+ "errors"
+ "fmt"
+ "log/slog"
"time"
+
+ "kesim.org/seal/nizk/commit"
+ "kesim.org/seal/nizk/stage1"
)
type Type int
@@ -55,4 +61,126 @@ func (d *Description) Hash() (hash string, e error) {
}
h := sha512.Sum512(buf.Bytes())
return base32.StdEncoding.EncodeToString(h[:]), nil
-} \ No newline at end of file
+}
+
+func (d *Description) validate() error {
+ if d == nil {
+ return fmt.Errorf("description is nil")
+ }
+ if d.BitLength > MAXBITLENGTH {
+ return fmt.Errorf("invalid BitLength in description: %d", d.BitLength)
+ }
+ return nil
+}
+
+type Auction interface {
+ Start() error
+ Cancel() error
+ Message(msg []byte) error
+}
+
+type Result struct {
+ Price uint32
+ Winner string
+ Error error
+}
+
+type auction struct {
+ description *Description
+
+ // non nil if run by an bidder, via Join()
+ bidder Bidder
+ // non nil if run by an observer, via Observe()
+ observer Observer
+
+ // The commitments we received from the bidders.
+ bidders map[string][]*commit.Commitment
+
+ // sorted list of the bidders.
+ bidder_ids []string
+
+ // Stage 1 data per round
+ stage1 []*stage1.Statement
+
+ log *slog.Logger
+}
+
+func (a *auction) Start() error {
+ return errors.New("Start not implemented")
+}
+
+func (a *auction) Cancel() error {
+ return errors.New("Cancel not implemented")
+}
+
+// Message is called by the Bidder or Visitor
+// whenever a message came in for the auction via the dashboard
+// or other means of communication.
+func (a *auction) Message(msg []byte) error {
+ return fmt.Errorf("Auction.Received not implemented")
+}
+
+const MAXBITLENGTH = 64
+
+// Bidder is the interface that the Auction engine uses to interact
+type Bidder interface {
+ Broadcast([]byte) error
+ Result(Result)
+ Start()
+}
+
+func Join(
+ bidder Bidder,
+ description *Description,
+ options ...Option) (Auction, error) {
+
+ if bidder == nil {
+ return nil, fmt.Errorf("missing bidder")
+ }
+ if e := description.validate(); e != nil {
+ return nil, e
+ }
+
+ a := &auction{
+ description: description,
+ bidder: bidder,
+ log: slog.Default(),
+ }
+
+ for _, opt := range options {
+ opt(a)
+ }
+
+ return a, nil
+}
+
+// Observer
+type Observer interface {
+ Result(Result)
+ Start()
+}
+
+func Observe(
+ observer Observer,
+ description *Description,
+ options ...Option) (Auction, error) {
+
+ if observer == nil {
+ return nil, fmt.Errorf("missing observer")
+ }
+ if e := description.validate(); e != nil {
+ return nil, e
+ }
+
+ a := &auction{
+ description: description,
+ observer: observer,
+ log: slog.Default(),
+ }
+
+ for _, opt := range options {
+ opt(a)
+ }
+
+ return a, nil
+}
diff --git a/bidder/auction.go b/bidder/auction.go
deleted file mode 100644
index a22f005..0000000
--- a/bidder/auction.go
+++ /dev/null
@@ -1,67 +0,0 @@
-package bidder
-
-import (
- "fmt"
- "log"
- "os"
-
- "kesim.org/seal"
- "kesim.org/seal/nizk/commit"
-)
-
-// Auction is the simple interface for the engine
-type Auction interface {
- Join(bidder Bidder) // A bidder calls this to join the auction
- GotMessage(msg []byte, sig []byte) error // A bidder uses this method to publish a message
-}
-
-// Bidder is the interface that the Auction engine uses to communicate
-type Bidder interface {
- Commitment() *commit.Commitment
- Start(map[string]*commit.Commitment)
- Result()
- Receive(msg []byte) error
-}
-
-type auction struct {
- description *seal.Description
-
- bidder Bidder
-
- log func(string, ...any)
- verbose func(string, ...any)
- debug func(string, ...any)
-}
-
-func nullf(string, ...any) {}
-
-func NewAuction(description *seal.Description, options ...Option) (a *auction, e error) {
- if description.BitLength > 63 {
- return nil, fmt.Errorf("Invalid BitLength in description: %d", description.BitLength)
- }
-
- logger := log.New(os.Stdout, "[seal::client] ", log.LstdFlags)
-
- a = &auction{
- description: description,
- log: logger.Printf,
- verbose: nullf,
- debug: nullf,
- }
-
- for _, opt := range options {
- opt(a)
- }
-
- return a, nil
-}
-
-func (a *auction) Join(bidder Bidder) {
- a.bidder = bidder
-}
-
-// Received is called by the bidder whenever a message came in for the auction via the dashboard
-// or other means of communication.
-func (a *auction) Received(msg []byte) error {
- return fmt.Errorf("Auction.Received not implemented")
-} \ No newline at end of file
diff --git a/bidder/bid.go b/bidder/bid.go
deleted file mode 100644
index 5f98a0c..0000000
--- a/bidder/bid.go
+++ /dev/null
@@ -1,77 +0,0 @@
-package bidder
-
-import (
- "crypto/ed25519"
- "fmt"
-
- . "kesim.org/seal/nizk"
-
- "kesim.org/seal/nizk/commit"
- "kesim.org/seal/nizk/stage1"
-)
-
-type bid struct {
- id ed25519.PrivateKey
- Id ed25519.PublicKey
-
- price uint64 // bigendian encoding of the bid
- bitlength uint8 // number of bits encoded in price.
-
- // bits are derived from zbid and the zero element in
- // the slice corresponds to the highest bit in zbid
- bits []*commit.Statement
-
- // The commitments we received from the bidders.
- bidders map[string][]*commit.Commitment
-
- // sorted list of the bidders.
- bidder_ids []string
-
- // Stage 1 data per round
- stage1 []*stage1.Statement
-}
-
-// newBid creates a new Bidder for the given price, using the lower bits up to bitlength
-func newBid(price uint64, bitlength uint8) (b *bid, e error) {
- if bitlength > 63 {
- return nil, fmt.Errorf("bitlength too large, maximum is 63")
- } else if 0 != (price >> bitlength) {
- return nil, fmt.Errorf("price %d too large for given bitlength %d", price, bitlength)
- }
-
- b = &bid{
- price: price,
- bitlength: bitlength,
- }
-
- b.Id, b.id, e = ed25519.GenerateKey(nil)
- if e != nil {
- return nil, e
- }
-
- b.bits = make([]*commit.Statement, bitlength)
- for i := bitlength; i > 0; i-- {
- set := (price>>(i-1)&1 != 0)
- x, r := Curve.RandomScalar(), Curve.RandomScalar()
- b.bits[i-1] = commit.NewStatement(x, r, set)
- }
-
- return b, nil
-}
-
-// Commit returns the public commitment to the bits and a signature
-// TODO: return signature over bid
-func (bid *bid) Commit() (c []*commit.Commitment) {
- c = make([]*commit.Commitment, len(bid.bits))
- for i := range bid.bits {
- c[i] = bid.bits[i].Commit(Bites(bid.Id))
- }
- return c
-}
-
-func (bid *bid) Result() {
-}
-
-func (bid *bid) Send(msg []byte, sig []byte) error {
- return fmt.Errorf("bidder.Send not implemented")
-} \ No newline at end of file
diff --git a/bidder/bid_test.go b/bidder/bid_test.go
deleted file mode 100644
index a479e5d..0000000
--- a/bidder/bid_test.go
+++ /dev/null
@@ -1,27 +0,0 @@
-package bidder
-
-import (
- "testing"
-)
-
-func TestBitlengthTooLarge(t *testing.T) {
- bid, e := newBid(0xFFFFFF, 70)
- if e == nil {
- t.Fatalf("failure expected, but got bid: %#v", bid)
- }
-}
-
-func TestPriceTooLarge(t *testing.T) {
- bid, e := newBid(0xFFFFFF, 8)
- if e == nil {
- t.Fatalf("failure expected, but got bid: %#v", bid)
- }
-}
-
-func TestBidOK(t *testing.T) {
- bid, e := newBid(102400, 24)
- if e != nil {
- t.Fatalf("unexpected error: %v", e)
- }
- t.Logf("Bid: %+v", bid)
-} \ No newline at end of file
diff --git a/bidder/option.go b/bidder/option.go
deleted file mode 100644
index d1c9783..0000000
--- a/bidder/option.go
+++ /dev/null
@@ -1,18 +0,0 @@
-package bidder
-
-import (
- "log"
- "os"
-)
-
-type Option func(auction *auction)
-
-func OptVerbose(a *auction) {
- logger := log.New(os.Stdout, "[seal::client][verbose] ", log.LstdFlags)
- a.verbose = logger.Printf
-}
-
-func OptDebug(a *auction) {
- logger := log.New(os.Stdout, "[seal::client][debug] ", log.LstdFlags)
- a.debug = logger.Printf
-}
diff --git a/nizk/commit/commit.go b/nizk/commit/commit.go
index d044077..84ba8e5 100644
--- a/nizk/commit/commit.go
+++ b/nizk/commit/commit.go
@@ -12,10 +12,10 @@ import (
// for given C, A and B
type Statement struct {
+ bitSet bool
a *Scalar
b *Scalar
- plus bool
- *Commitment
+ Commitment
}
type Commitment struct {
@@ -25,25 +25,25 @@ type Commitment struct {
Proof *Proof
}
-func NewStatement(a, b *Scalar, plus bool) *Statement {
+func NewStatement(a, b *Scalar, bitSet bool) *Statement {
return &Statement{
a: a,
b: b,
- plus: plus,
- Commitment: commitment(a, b, plus),
+ bitSet: bitSet,
+ Commitment: commitment(a, b, bitSet),
}
}
-func commitment(a, b *Scalar, plus bool) *Commitment {
+func commitment(a, b *Scalar, bitSet bool) Commitment {
var C *Point
c := a.Mul(b)
- if plus {
+ if bitSet {
C = G.Exp(c.Add(One))
} else {
C = G.Exp(c)
}
- return &Commitment{
+ return Commitment{
C: C,
A: G.Exp(a),
B: G.Exp(b),
@@ -52,7 +52,7 @@ func commitment(a, b *Scalar, plus bool) *Commitment {
func (s *Statement) Commit(id Bytes) *Commitment {
s.Commitment.Proof = s.Proof(id)
- return s.Commitment
+ return &s.Commitment
}
type Proof struct {
@@ -72,7 +72,7 @@ func (s *Statement) Proof(id Bytes) *Proof {
r2 = Curve.RandomScalar()
w = Curve.RandomScalar()
- if s.plus {
+ if s.bitSet {
e[0][0] = G.Exp(r1)
e[0][1] = s.B.Exp(r1).Mul(G.Exp(w))
e[1][0] = G.Exp(r2)
@@ -87,7 +87,7 @@ func (s *Statement) Proof(id Bytes) *Proof {
ch := Challenge(G, s.C, s.A, s.B, e[0][0], e[0][1], e[1][0], e[1][1], id)
pr := &Proof{Id: id}
- if s.plus {
+ if s.bitSet {
pr.C.Ch[0] = w
pr.C.Ch[1] = ch.Sub(w)
pr.C.R[0] = r1.Sub(s.a.Mul(pr.C.Ch[0]))
diff --git a/option.go b/option.go
new file mode 100644
index 0000000..8f7212f
--- /dev/null
+++ b/option.go
@@ -0,0 +1,15 @@
+package seal
+
+import "log/slog"
+
+type Option func(auction *auction)
+
+func OptionSetLoggerLevel(level slog.Level) Option {
+ return func(_ *auction) {
+ slog.SetLogLoggerLevel(level)
+ }
+}
+
+func OptionDebug() Option {
+ return OptionSetLoggerLevel(slog.LevelDebug)
+}