aboutsummaryrefslogtreecommitdiff
path: root/vote/vote.go
diff options
context:
space:
mode:
authorÖzgür Kesim <oec@codeblau.de>2024-03-20 22:24:18 +0100
committerÖzgür Kesim <oec@codeblau.de>2024-03-20 22:24:18 +0100
commit6017ace9301d0078e34bdbb3b29ef71e4ba408a5 (patch)
tree137b96ea2db013120287d5dab29992d336c99701 /vote/vote.go
parent60f58c25788c273caddd36dfc3bce44757170a67 (diff)
veto: commitment(round1), round2 and veto check implemented
The core elements to resemble the calculation of the AV-net protocol is ready, Votes generate Commitments, calculate the Proofs for the X's, R's, calculate the data for round2 and calculate the final vote, according to the paper.
Diffstat (limited to 'vote/vote.go')
-rw-r--r--vote/vote.go233
1 files changed, 0 insertions, 233 deletions
diff --git a/vote/vote.go b/vote/vote.go
deleted file mode 100644
index 97367c0..0000000
--- a/vote/vote.go
+++ /dev/null
@@ -1,233 +0,0 @@
-package vote
-
-import (
- "bytes"
- "crypto/rand"
- "crypto/sha512"
- "encoding/base64"
- "encoding/json"
- "fmt"
- "io"
-
- curve "filippo.io/edwards25519"
-)
-
-var b64 = base64.StdEncoding.WithPadding(base64.NoPadding)
-
-type point curve.Point
-type scalar curve.Scalar
-
-// Representation of a vote (true or false) of an individual.
-// The .Commitment is sent as data for round1 of the protocol.
-type Vote struct {
- bit bool
- private struct {
- id *scalar
- x *scalar
- r *scalar
- }
-
- Commitment
-}
-
-// Commitment represents the public data sent by a participant
-// in round 1 of the protocol.
-type Commitment struct {
- Id *point `json:"index"`
- Points struct {
- X *point
- R *point
- } `json:"points"`
- Proofs struct {
- X *Proof
- R *Proof
- } `json:"proofs"`
-}
-
-// A Schnorr signature to prove knowledge of v for given g^v and i.
-// Choosing a scalar v randomly, the signature consists of (V, r) with
-//
-// V := g^v, with randomly chosen v
-// r := (v - x*h), with h := H(g, g^v, g^x, i), where i is given by the context.
-//
-// Verification of the signature is by comparing V =?= g^r * g^(x*h)
-type Proof struct {
- PV *point `json:"V"`
- Sr *scalar `json:"r"`
- Id *point `json:"id"`
-}
-
-func randomScalar(random io.Reader) (*scalar, error) {
- var buf [64]byte
- if random == nil {
- random = rand.Reader
- }
- random.Read(buf[:])
- s, e := new(curve.Scalar).SetUniformBytes(buf[:])
- return (*scalar)(s), e
-}
-
-func (s *scalar) point() *point {
- p := new(curve.Point).ScalarBaseMult((*curve.Scalar)(s))
- return (*point)(p)
-}
-
-// Generates the proof, aka Schnorr signature, for given priv and i.
-// Choosing a scalar v randomly, the signature consists of (V, r) with
-//
-// V := g^v, with randomly chosen v
-// r := (v - x*h), with h := H(g, g^v, g^x, i), where i is given by the context.
-//
-// Verification of the signature is by comparing V =?= g^r * g^(x*h)
-func (x *scalar) proof(id *point) (pr *Proof, e error) {
- pr = &Proof{Id: id}
-
- // choose random v
- v, e := randomScalar(nil)
- if e != nil {
- return nil, e
- }
-
- // calculate g^v
- pr.PV = v.point()
-
- // calculate g^x
- gx := x.point()
-
- // calculate h := H(g, g^v, g^x, i)
- h, e := hash(pr.PV, gx, id)
- if e != nil {
- return nil, e
- }
-
- // Calculate r := v - x*h
- xh := new(curve.Scalar).Multiply((*curve.Scalar)(x), h)
- r := new(curve.Scalar).Subtract((*curve.Scalar)(v), xh)
- pr.Sr = (*scalar)(r)
-
- return pr, nil
-}
-
-// Calculate h := H(g, g^v, g^x, i)
-func hash(gv, gx *point, id *point) (*curve.Scalar, error) {
- h512 := sha512.New()
- h512.Write(curve.NewGeneratorPoint().Bytes())
- h512.Write(((*curve.Point)(gv)).Bytes())
- h512.Write(((*curve.Point)(gx)).Bytes())
- h512.Write(((*curve.Point)(id)).Bytes())
- hb := h512.Sum(nil)
- return new(curve.Scalar).SetUniformBytes(hb)
-}
-
-// Generate the proofs for both, the g^x and g^r points.
-func (v *Vote) genProofs() (e error) {
- v.Proofs.X, e = v.private.x.proof(v.Id)
- if e != nil {
- return e
- }
- v.Proofs.R, e = v.private.r.proof(v.Id)
- return e
-}
-
-// Verifies that g^v == g^r*g^(x*h)
-func verifyProof(V *point, Gx *point, r *scalar, id *point) (ok bool) {
- // Calculate h = H(g, g^v, g^x, id)
- h, e := hash(V, Gx, id)
- if e != nil {
- return false
- }
-
- // Calculate g^(x*h) = (g^x)^h
- gxh := new(curve.Point).ScalarMult(h, (*curve.Point)(Gx))
-
- // Calculate g^r
- gr := r.point()
-
- // Calculate g^r*g^(x*h)
- // Note that the edwards25519 package uses Addtion as the group
- grgxh := new(curve.Point).Add((*curve.Point)(gr), gxh)
-
- // Return true if g^v == g^r*g^(x*h)
- return ((*curve.Point)(V)).Equal(grgxh) == 1
-}
-
-func combineErr(e1, e2 error) error {
- if e1 == nil && e2 == nil {
- return nil
- } else if e1 != nil {
- if e2 == nil {
- return e1
- }
- return fmt.Errorf("%v and %v", e1, e2)
- }
- return e2
-}
-
-// Verify verifies the proofs for both, g^x and g^r
-func (v *Vote) VerifyProofs() (ok bool) {
- okX := verifyProof(v.Proofs.X.PV, v.Points.X, v.Proofs.X.Sr, v.Id)
- okR := verifyProof(v.Proofs.R.PV, v.Points.R, v.Proofs.R.Sr, v.Id)
- return okX && okR
-}
-
-// Generates a vote with commitments and proofs and takes the input for
-// the randomness from the given io.Reader
-func newVoteWithRand(bit bool, rand io.Reader) (vote *Vote, e error) {
- vote = &Vote{
- bit: bit,
- }
-
- vote.private.id, e = randomScalar(rand)
- if e != nil {
- return nil, e
- }
- vote.private.x, e = randomScalar(rand)
- if e != nil {
- return nil, e
- }
- vote.private.r, e = randomScalar(rand)
- if e != nil {
- return nil, e
- }
-
- vote.Commitment.Id = vote.private.id.point()
- vote.Commitment.Points.X = vote.private.x.point()
- vote.Commitment.Points.R = vote.private.r.point()
-
- e = vote.genProofs()
-
- return vote, nil
-}
-
-// NewVote generates a vote for given bit and index, taking crypt/Reader as
-// source for randomness
-func NewVote(bit bool) (vote *Vote, e error) {
- return newVoteWithRand(bit, nil)
-}
-
-func (p *point) String() string {
- return b64.EncodeToString(((*curve.Point)(p)).Bytes())
-}
-
-func (s *scalar) String() string {
- return b64.EncodeToString(((*curve.Scalar)(s)).Bytes())
-}
-
-func (s *scalar) MarshalJSON() ([]byte, error) {
- return []byte(fmt.Sprintf(`"%s"`, s)), nil
-
-}
-func (p *point) MarshalJSON() ([]byte, error) {
- return []byte(fmt.Sprintf(`"%s"`, p)), nil
-}
-
-func (c *Commitment) String() string {
- buf := &bytes.Buffer{}
- dec := json.NewEncoder(buf)
- dec.SetIndent("", " ")
- e := dec.Encode(c)
- if e != nil {
- return fmt.Sprintf("<error encoding: %v>", e)
- }
- return buf.String()
-}