diff options
author | Özgür Kesim <oec@codeblau.de> | 2024-04-07 13:21:53 +0200 |
---|---|---|
committer | Özgür Kesim <oec@codeblau.de> | 2024-04-07 13:21:53 +0200 |
commit | 438b69e74b416918ef855c4a28d90779ea1e455c (patch) | |
tree | 7a5d02831cb63ebda981d05b6b9a826fa2bc7596 /bidder | |
parent | 5733f293044bfe0d3210e7c4688172d53d54a7e0 (diff) |
client->bidder
Diffstat (limited to 'bidder')
-rw-r--r-- | bidder/auction.go | 60 | ||||
-rw-r--r-- | bidder/bid.go | 69 | ||||
-rw-r--r-- | bidder/bid_test.go | 27 | ||||
-rw-r--r-- | bidder/option.go | 18 |
4 files changed, 174 insertions, 0 deletions
diff --git a/bidder/auction.go b/bidder/auction.go new file mode 100644 index 0000000..7991504 --- /dev/null +++ b/bidder/auction.go @@ -0,0 +1,60 @@ +package bidder + +import ( + "fmt" + "log" + "os" + + "kesim.org/seal" +) + +type Auction struct { + description *seal.Description + + bidder seal.Bidder + + log func(string, ...any) + verbose func(string, ...any) + debug func(string, ...any) +} + +func nullf(string, ...any) {} + +func NewAuction(description *seal.Description, options ...Option) (auction *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) + + auction = &Auction{ + description: description, + log: logger.Printf, + verbose: nullf, + debug: nullf, + } + + for _, opt := range options { + opt(auction) + } + + return auction, nil +} + +func (a *Auction) Join(price uint64) error { + bidder, e := newBid(price, a.description.BitLength) + if e != nil { + return e + } + + a.debug("created bid: %#v\n", bidder.(*bid)) + + a.bidder = bidder + return nil +} + +// Received is called by the consumer 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 new file mode 100644 index 0000000..5aa27c2 --- /dev/null +++ b/bidder/bid.go @@ -0,0 +1,69 @@ +package bidder + +import ( + "crypto/ed25519" + "fmt" + + "kesim.org/seal" + . "kesim.org/seal/nizk" + + "kesim.org/seal/nizk/commit" +) + +type bid struct { + id ed25519.PrivateKey + ID ed25519.PublicKey + + price uint64 // bigendian encoding of the bid + n uint8 // number of bits encoded in zbid. + + // bits are derived from zbid and the zero element in + // the slice corresponds to the highest bit in zbid + bits []*commit.Statement +} + +// NewBid creates a new Bidder for the given price, using the lower bits up to bitlength +func newBid(price uint64, bitlength uint8) (seal.Bidder, 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) + } + + var ( + e error + bid = &bid{ + price: price, + } + ) + + bid.ID, bid.id, e = ed25519.GenerateKey(nil) + if e != nil { + return nil, e + } + + bid.bits = make([]*commit.Statement, bitlength) + for i := bitlength; i > 0; i-- { + set := (price>>(i-1)&1 != 0) + a, b := Curve.RandomScalar(), Curve.RandomScalar() + bid.bits[i-1] = commit.NewStatement(a, b, set) + } + + return bid, nil +} + +// Commit returns the public commitment to the bits and a signature +// TODO: return signature over bid +func (bid *bid) Commit() (c []*commit.Commitment, pub ed25519.PublicKey, sig []byte) { + c = make([]*commit.Commitment, len(bid.bits)) + for i := range bid.bits { + c[i] = bid.bits[i].Commit() + } + return c, bid.ID, nil +} + +func (bid *bid) Result() { +} + +func (bid *bid) Send(msg []byte, sig []byte) { +}
\ No newline at end of file diff --git a/bidder/bid_test.go b/bidder/bid_test.go new file mode 100644 index 0000000..a479e5d --- /dev/null +++ b/bidder/bid_test.go @@ -0,0 +1,27 @@ +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 new file mode 100644 index 0000000..45b4729 --- /dev/null +++ b/bidder/option.go @@ -0,0 +1,18 @@ +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 +} |