diff options
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 |
commit | 4adec77feea7e9ec45ca43084383d85de450518b (patch) | |
tree | 446ecf80204c6a1b755547e121f1f8450c99f6ae /nizk/commit.go | |
parent | 7813100e5429ca486d6310f8a04d7a0d11325f2e (diff) |
refactoring in progress
Diffstat (limited to 'nizk/commit.go')
-rw-r--r-- | nizk/commit.go | 120 |
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) +} |