diff options
author | Özgür Kesim <oec@codeblau.de> | 2024-04-07 18:38:33 +0200 |
---|---|---|
committer | Özgür Kesim <oec@codeblau.de> | 2024-04-07 18:38:33 +0200 |
commit | 03d3f676c36ccd36bb201d317bd2350ada6ba451 (patch) | |
tree | 92e2d7e80b62c770b46b4f8e245c6f15083d120a | |
parent | efdafce2cca00591371338d20ee456770216a829 (diff) |
nizk, bidder: introduced schnorr-signatures as proof for commitments of A=G^a and B=G^b
-rw-r--r-- | bidder/bid.go | 28 | ||||
-rw-r--r-- | nizk/commit/commit.go | 62 | ||||
-rw-r--r-- | nizk/commit/commit_test.go | 19 |
3 files changed, 62 insertions, 47 deletions
diff --git a/bidder/bid.go b/bidder/bid.go index 55feaf8..5a87aa1 100644 --- a/bidder/bid.go +++ b/bidder/bid.go @@ -1,7 +1,6 @@ package bidder import ( - "crypto/ed25519" "fmt" . "kesim.org/seal/nizk" @@ -10,8 +9,9 @@ import ( ) type bid struct { - id ed25519.PrivateKey - ID ed25519.PublicKey + // TODO: These should probably become ed25519.(Private|Public)Key's + id *Scalar + Id *Point price uint64 // bigendian encoding of the bid n uint8 // number of bits encoded in zbid. @@ -29,18 +29,14 @@ func NewBid(price uint64, bitlength uint8) (*bid, error) { 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 := &bid{ + price: price, + n: bitlength, } + bid.id = Curve.RandomScalar() + bid.Id = G.Exp(bid.id) + bid.bits = make([]*commit.Statement, bitlength) for i := bitlength; i > 0; i-- { set := (price>>(i-1)&1 != 0) @@ -53,12 +49,12 @@ func NewBid(price uint64, bitlength uint8) (*bid, error) { // 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) { +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() + c[i] = bid.bits[i].Commit(bid.Id) } - return c, bid.ID, nil + return c } func (bid *bid) Result() { diff --git a/nizk/commit/commit.go b/nizk/commit/commit.go index 085d9a2..c2a6848 100644 --- a/nizk/commit/commit.go +++ b/nizk/commit/commit.go @@ -2,6 +2,7 @@ package commit import ( . "kesim.org/seal/nizk" + "kesim.org/seal/nizk/schnorr" ) // This is a construction of a proof of a statement of the form @@ -18,9 +19,10 @@ type Statement struct { } type Commitment struct { - C *Point - A *Point - B *Point + C *Point + A *Point + B *Point + Proof *Proof } func NewStatement(a, b *Scalar, plus bool) *Statement { @@ -48,16 +50,22 @@ func commitment(a, b *Scalar, plus bool) *Commitment { } } -func (s *Statement) Commit() *Commitment { +func (s *Statement) Commit(id *Point) *Commitment { + s.Commitment.Proof = s.Proof(id) return s.Commitment } type Proof struct { - Ch [2]*Scalar - R [2]*Scalar + Id *Point + A *schnorr.Proof // Proof for knowledge of a in A = G^a + B *schnorr.Proof // Proof for knowledge of b in B = G^b + C struct { // Proof for knowledge of statement above + Ch [2]*Scalar + R [2]*Scalar + } } -func (s *Statement) Proof() *Proof { +func (s *Statement) Proof(id *Point) *Proof { var e [2][2]*Point var r1, r2, w *Scalar r1 = Curve.RandomScalar() @@ -76,30 +84,36 @@ func (s *Statement) Proof() *Proof { e[1][1] = s.B.Exp(r2).Mul(s.C.Div(G).Exp(w)) } - ch := Challenge(G, s.C, s.A, s.B, e[0][0], e[0][1], e[1][0], e[1][1]) - pr := &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 { - pr.Ch[0] = w - pr.Ch[1] = ch.Sub(w) - pr.R[0] = r1.Sub(s.a.Mul(pr.Ch[0])) - pr.R[1] = r2.Sub(s.a.Mul(pr.Ch[1])) + 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])) + pr.C.R[1] = r2.Sub(s.a.Mul(pr.C.Ch[1])) } else { - pr.Ch[0] = ch.Sub(w) - pr.Ch[1] = w - pr.R[0] = r1.Sub(s.a.Mul(pr.Ch[0])) - pr.R[1] = r2 + pr.C.Ch[0] = ch.Sub(w) + pr.C.Ch[1] = w + pr.C.R[0] = r1.Sub(s.a.Mul(pr.C.Ch[0])) + pr.C.R[1] = r2 } + pr.A = (*schnorr.Statement)(s.a).Proof(id) + pr.B = (*schnorr.Statement)(s.b).Proof(id) return pr } -func (c *Commitment) Verify(p *Proof) bool { +func (c *Commitment) Verify() bool { var e [2][2]*Point - e[0][0] = G.Exp(p.R[0]).Mul(c.A.Exp(p.Ch[0])) - e[0][1] = c.B.Exp(p.R[0]).Mul(c.C.Exp(p.Ch[0])) - e[1][0] = G.Exp(p.R[1]).Mul(c.A.Exp(p.Ch[1])) - e[1][1] = c.B.Exp(p.R[1]).Mul(c.C.Div(G).Exp(p.Ch[1])) - ch := Challenge(G, c.C, c.A, c.B, e[0][0], e[0][1], e[1][0], e[1][1]) - return p.Ch[0].Add(p.Ch[1]).Equal(ch) + p := c.Proof + + e[0][0] = G.Exp(p.C.R[0]).Mul(c.A.Exp(p.C.Ch[0])) + e[0][1] = c.B.Exp(p.C.R[0]).Mul(c.C.Exp(p.C.Ch[0])) + e[1][0] = G.Exp(p.C.R[1]).Mul(c.A.Exp(p.C.Ch[1])) + e[1][1] = c.B.Exp(p.C.R[1]).Mul(c.C.Div(G).Exp(p.C.Ch[1])) + ch := Challenge(G, c.C, c.A, c.B, e[0][0], e[0][1], e[1][0], e[1][1], p.Id) + return p.C.Ch[0].Add(p.C.Ch[1]).Equal(ch) && + (*schnorr.Commitment)(c.A).Verify(p.A, p.Id) && + (*schnorr.Commitment)(c.B).Verify(p.B, p.Id) } diff --git a/nizk/commit/commit_test.go b/nizk/commit/commit_test.go index 916ba0e..de5d22e 100644 --- a/nizk/commit/commit_test.go +++ b/nizk/commit/commit_test.go @@ -7,15 +7,20 @@ import ( ) func TestStatement(t *testing.T) { - var α, β = Curve.RandomScalar(), Curve.RandomScalar() + var α, β, id = Curve.RandomScalar(), Curve.RandomScalar(), Curve.RandomScalar() + + Id := G.Exp(id) st1, st2 := NewStatement(α, β, true), NewStatement(α, β, false) - c1, c2 := st1.Commit(), st2.Commit() - pr1, pr2 := st1.Proof(), st2.Proof() - if !c1.Verify(pr1) { - t.Fatal("Could not verify st1 with c1 and pr1, plus=true case") + c1, c2 := st1.Commit(Id), st2.Commit(Id) + if !c1.Verify() { + t.Fatal("Could not verify st1 with c1, plus=true case") + } + if !c2.Verify() { + t.Fatal("Could not verify st2 with c2, plus=false case") } - if !c2.Verify(pr2) { - t.Fatal("Could not verify st2 with c2 and pr2, plus=false case") + c2.Proof = c1.Proof + if c2.Verify() { + t.Fatal("Verify with wrong proof should have failed!") } } |