aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--auction.go44
-rw-r--r--client/bid.go62
-rw-r--r--client/bid_test.go27
-rw-r--r--client/client.go54
-rw-r--r--client/option.go18
-rw-r--r--commitment/commitment.go59
-rw-r--r--main.go35
7 files changed, 205 insertions, 94 deletions
diff --git a/auction.go b/auction.go
new file mode 100644
index 0000000..50d6a2b
--- /dev/null
+++ b/auction.go
@@ -0,0 +1,44 @@
+package seal
+
+import (
+ "crypto"
+ "net/url"
+ "time"
+)
+
+type Type int
+
+const (
+ TypHighest = iota
+ TypSecondHighest
+)
+
+// Auction describes the asset of an auction and other
+// relevant meta-data
+type Description struct {
+ DashboardUrl *url.URL // can be empty
+ Start time.Time
+ End time.Time
+ RoundTimeout time.Duration // Timeout per round by which all responses must have arrived
+ BitLength uint8 // Length of the price encoding
+ Currency string
+ Type Type
+ SellerPublicKey crypto.PublicKey // Public key of the Seller
+}
+
+// The SignedAuction contains an Auction and the signature,
+// signed by the seller's public key off the SHA512 hash of
+// the normalized JSON-object.
+// TODO(oec): normalized?
+type SignedDesciption struct {
+ Description
+ SellerSignature string
+}
+
+// Bidder is the interface that the Auction engine uses to communicate
+// with an bidder implementation
+type Bidder interface {
+ Result()
+ Broadcast()
+ Unicast()
+}
diff --git a/client/bid.go b/client/bid.go
new file mode 100644
index 0000000..3651d1d
--- /dev/null
+++ b/client/bid.go
@@ -0,0 +1,62 @@
+package client
+
+import (
+ "crypto/ed25519"
+ "fmt"
+
+ . "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) (*bid, 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
+} \ No newline at end of file
diff --git a/client/bid_test.go b/client/bid_test.go
new file mode 100644
index 0000000..52c4c3c
--- /dev/null
+++ b/client/bid_test.go
@@ -0,0 +1,27 @@
+package client
+
+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/client/client.go b/client/client.go
new file mode 100644
index 0000000..19f0d35
--- /dev/null
+++ b/client/client.go
@@ -0,0 +1,54 @@
+package client
+
+import (
+ "fmt"
+ "log"
+ "os"
+
+ "kesim.org/seal"
+)
+
+type Auction struct {
+ description *seal.Description
+
+ bid *bid
+
+ 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 {
+ bid, e := newBid(price, a.description.BitLength)
+ if e != nil {
+ return e
+ }
+
+ a.debug("created bid: %#v\n", bid)
+
+ a.bid = bid
+ return nil
+}
diff --git a/client/option.go b/client/option.go
new file mode 100644
index 0000000..c2b1e5d
--- /dev/null
+++ b/client/option.go
@@ -0,0 +1,18 @@
+package client
+
+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/commitment/commitment.go b/commitment/commitment.go
deleted file mode 100644
index c958987..0000000
--- a/commitment/commitment.go
+++ /dev/null
@@ -1,59 +0,0 @@
-// Implements the data structures and methods for
-// creating a commitment for the SEAL protocol
-package commitment
-
-import (
- "fmt"
-
- "kesim.org/seal/curve"
-)
-
-type Scalar = curve.Curve25519Scalar
-type Point = curve.Curve25519Point
-
-var Curve = curve.Curve25519
-
-type Bidder struct {
- private struct {
- id *Scalar
- }
- Id *Point
-}
-
-type Bid struct {
- Bidder *Point
- zbid uint64 // bigendian encoding of the bid
- n uint8 // number of bits encoded in zbid.
- bits []Bit // derived from zbid
-}
-
-type Bit struct {
- set bool
- a *Scalar
- b *Scalar
- com *BitCommitment
-}
-
-type BitCommitment struct {
- Gab *Point
- A *Point
- B *Point
-
- Proofs struct {
- A *Proof
- B *Proof
- }
-}
-
-type Proof struct {
- V *Point `json:"V"`
- R *Scalar `json:"r"`
-}
-
-func NewBid(price uint64, bitlength uint8) (*Bidder, error) {
- if bitlength > 63 {
- return nil, fmt.Errorf("bitlength too large, maximum is 63")
- }
-
- return nil, fmt.Errorf("NewBid not implemented")
-} \ No newline at end of file
diff --git a/main.go b/main.go
deleted file mode 100644
index 4d497a8..0000000
--- a/main.go
+++ /dev/null
@@ -1,35 +0,0 @@
-package seal
-
-import (
- "crypto"
- "time"
-)
-
-// Auction describes the asset of an auction and other
-// relevant meta-data
-type Auction struct {
- // Start date
- Start time.Time
- // End date
- End time.Time
- // Timeout per round by which all responses must have arrived
- RoundTimeout time.Duration
-
- // Sha512 Hash of the Asset
- AssetHash string
-
- // Public key of the Seller
- SellerPublicKey crypto.PublicKey
-}
-
-// The SignedAuction contains an Auction and the signature,
-// signed by the seller's public key off the SHA512 hash of
-// the normalized JSON-object. TODO(oec): normalized?
-type SignedAuction struct {
- Auction
- SellerSignature string
-}
-
-// The published commiment of a participant
-type Commitment struct {
-}