aboutsummaryrefslogtreecommitdiff
path: root/nizk/commit.go
diff options
context:
space:
mode:
authorÖzgür Kesim <oec@kesim.org>2024-11-11 21:28:12 +0100
committerÖzgür Kesim <oec@kesim.org>2024-11-11 21:28:12 +0100
commit4adec77feea7e9ec45ca43084383d85de450518b (patch)
tree446ecf80204c6a1b755547e121f1f8450c99f6ae /nizk/commit.go
parent7813100e5429ca486d6310f8a04d7a0d11325f2e (diff)
refactoring in progress
Diffstat (limited to 'nizk/commit.go')
-rw-r--r--nizk/commit.go120
1 files changed, 120 insertions, 0 deletions
diff --git a/nizk/commit.go b/nizk/commit.go
new file mode 100644
index 0000000..7f46d36
--- /dev/null
+++ b/nizk/commit.go
@@ -0,0 +1,120 @@
+package nizk
+
+import (
+ . "kesim.org/seal/common"
+ "kesim.org/seal/nizk/schnorr"
+)
+
+// This is a construction of a proof of a statement of the form
+// [(C = g^(αβ)) && (A = g^α) && (Β = g^β)]
+// || [(C = g^(αβ+1)) && (A = g^α) && (Β = g^β)]
+//
+// for given C, A and B
+
+type Bid struct {
+ bitSet bool
+ α *Scalar
+ β *Scalar
+}
+
+type Commitment struct {
+ A *Point // g^α
+ B *Point // g^β
+ C *Point // g^(ab)g^(bitSet)
+}
+
+func NewBid(bitSet bool) *Bid {
+ α, β := Curve.RandomScalar(), Curve.RandomScalar()
+ return NewBidFromScalars(bitSet, α, β)
+}
+
+func NewBidFromScalars(bitSet bool, α, β *Scalar) *Bid {
+ return &Bid{
+ α: α,
+ β: β,
+ bitSet: bitSet,
+ }
+}
+
+func commitment(α, β *Scalar, bitSet bool) *Commitment {
+ var C *Point
+ c := α.Mul(β)
+
+ if bitSet {
+ C = G.Exp(c.Add(One))
+ } else {
+ C = G.Exp(c)
+ }
+ return &Commitment{
+ C: C,
+ A: G.Exp(α),
+ B: G.Exp(β),
+ }
+}
+
+type Proof struct {
+ Id Bytes
+ A *schnorr.Proof // Proof for knowledge of α in A = G^α
+ B *schnorr.Proof // Proof for knowledge of β in B = G^β
+ C struct { // Proof for knowledge of statement above
+ Ch [2]*Scalar
+ R [2]*Scalar
+ }
+}
+
+func (s *Bid) proof(id Bytes, c *Commitment) *Proof {
+ var e [2][2]*Point
+ var r1, r2, w *Scalar
+ r1 = Curve.RandomScalar()
+ r2 = Curve.RandomScalar()
+ w = Curve.RandomScalar()
+
+ if s.bitSet {
+ e[0][0] = G.Exp(r1)
+ e[0][1] = c.B.Exp(r1).Mul(G.Exp(w))
+ e[1][0] = G.Exp(r2)
+ e[1][1] = c.B.Exp(r2)
+ } else {
+ e[0][0] = G.Exp(r1)
+ e[0][1] = c.B.Exp(r1)
+ e[1][0] = G.Exp(r2).Mul(c.A.Exp(w))
+ e[1][1] = c.B.Exp(r2).Mul(c.C.Div(G).Exp(w))
+ }
+
+ ch := Challenge(G, c.C, c.A, c.B, e[0][0], e[0][1], e[1][0], e[1][1], id)
+ pr := &Proof{Id: id}
+
+ if s.bitSet {
+ pr.C.Ch[0] = w
+ pr.C.Ch[1] = ch.Sub(w)
+ pr.C.R[0] = r1.Sub(s.α.Mul(pr.C.Ch[0]))
+ pr.C.R[1] = r2.Sub(s.α.Mul(pr.C.Ch[1]))
+ } else {
+ pr.C.Ch[0] = ch.Sub(w)
+ pr.C.Ch[1] = w
+ pr.C.R[0] = r1.Sub(s.α.Mul(pr.C.Ch[0]))
+ pr.C.R[1] = r2
+ }
+ pr.A = (*schnorr.Statement)(s.α).Proof(id)
+ pr.B = (*schnorr.Statement)(s.β).Proof(id)
+
+ return pr
+}
+
+func (s *Bid) Commit(id Bytes) (*Commitment, *Proof) {
+ c := commitment(s.α, s.β, s.bitSet)
+ return c, s.proof(id, c)
+}
+
+func (c *Commitment) Verify(p *Proof) bool {
+ var e [2][2]*Point
+
+ 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)
+}