Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Benchmark 10000 votes #95

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions contracts/evoting/controller/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,8 @@ func (a *scenarioTestAction) Execute(ctx node.Context) error {
return xerrors.Errorf(getFormErr, err)
}

encryptedBallots := form.Suffragia.Ciphervotes
suff, err := form.Suffragia(serdecontext, service.GetStore())
encryptedBallots := suff.Ciphervotes
dela.Logger.Info().Msg("Length encrypted ballots: " + strconv.Itoa(len(encryptedBallots)))
dela.Logger.Info().Msgf("Ballot of user1: %s", encryptedBallots[0])
dela.Logger.Info().Msgf("Ballot of user2: %s", encryptedBallots[1])
Expand Down Expand Up @@ -485,7 +486,8 @@ func (a *scenarioTestAction) Execute(ctx node.Context) error {

logFormStatus(form)
dela.Logger.Info().Msg("Number of shuffled ballots : " + strconv.Itoa(len(form.ShuffleInstances)))
dela.Logger.Info().Msg("Number of encrypted ballots : " + strconv.Itoa(len(form.Suffragia.Ciphervotes)))
suff, err = form.Suffragia(serdecontext, service.GetStore())
dela.Logger.Info().Msg("Number of encrypted ballots : " + strconv.Itoa(len(suff.Ciphervotes)))

// ###################################### REQUEST PUBLIC SHARES ############

Expand Down
16 changes: 11 additions & 5 deletions contracts/evoting/evoting.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

102 changes: 37 additions & 65 deletions contracts/evoting/json/forms.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package json

import (
"encoding/hex"
"encoding/json"

"github.com/c4dt/d-voting/contracts/evoting/types"
Expand Down Expand Up @@ -35,9 +36,14 @@ func (formFormat) Encode(ctx serde.Context, message serde.Message) ([]byte, erro
}
}

suffragia, err := encodeSuffragia(ctx, m.Suffragia)
if err != nil {
return nil, xerrors.Errorf("failed to encode suffragia: %v", err)
suffragias := make([]string, len(m.SuffragiaIDs))
for i, suf := range m.SuffragiaIDs {
suffragias[i] = hex.EncodeToString(suf)
}

suffragiaHashes := make([]string, len(m.SuffragiaHashes))
for i, sufH := range m.SuffragiaHashes {
suffragiaHashes[i] = hex.EncodeToString(sufH)
}

shuffleInstances, err := encodeShuffleInstances(ctx, m.ShuffleInstances)
Expand All @@ -62,7 +68,9 @@ func (formFormat) Encode(ctx serde.Context, message serde.Message) ([]byte, erro
Status: uint16(m.Status),
Pubkey: pubkey,
BallotSize: m.BallotSize,
Suffragia: suffragia,
Suffragias: suffragias,
SuffragiaHashes: suffragiaHashes,
BallotCount: m.BallotCount,
ShuffleInstances: shuffleInstances,
ShuffleThreshold: m.ShuffleThreshold,
PubsharesUnits: pubsharesUnits,
Expand Down Expand Up @@ -100,9 +108,20 @@ func (formFormat) Decode(ctx serde.Context, data []byte) (serde.Message, error)
}
}

suffragia, err := decodeSuffragia(ctx, formJSON.Suffragia)
if err != nil {
return nil, xerrors.Errorf("failed to decode suffragia: %v", err)
suffragias := make([][]byte, len(formJSON.Suffragias))
for i, suff := range formJSON.Suffragias {
suffragias[i], err = hex.DecodeString(suff)
if err != nil {
return nil, xerrors.Errorf("failed to decode suffragia-address: %v", err)
}
}

suffragiaHashes := make([][]byte, len(formJSON.SuffragiaHashes))
for i, suffH := range formJSON.SuffragiaHashes {
suffragiaHashes[i], err = hex.DecodeString(suffH)
if err != nil {
return nil, xerrors.Errorf("failed to decode suffragia-hash: %v", err)
}
}

shuffleInstances, err := decodeShuffleInstances(ctx, formJSON.ShuffleInstances)
Expand Down Expand Up @@ -132,7 +151,9 @@ func (formFormat) Decode(ctx serde.Context, data []byte) (serde.Message, error)
Status: types.Status(formJSON.Status),
Pubkey: pubKey,
BallotSize: formJSON.BallotSize,
Suffragia: suffragia,
SuffragiaIDs: suffragias,
SuffragiaHashes: suffragiaHashes,
BallotCount: formJSON.BallotCount,
ShuffleInstances: shuffleInstances,
ShuffleThreshold: formJSON.ShuffleThreshold,
PubsharesUnits: pubSharesSubmissions,
Expand All @@ -157,7 +178,14 @@ type FormJSON struct {
// to pad smaller ballots such that all ballots cast have the same size
BallotSize int

Suffragia SuffragiaJSON
// Suffragias are the hex-encoded addresses of the Suffragia storages.
Suffragias []string

// BallotCount represents the total number of ballots cast.
BallotCount uint32

// SuffragiaHashes are the hex-encoded sha256-hashes of the ballots in every Suffragia.
SuffragiaHashes []string

// ShuffleInstances is all the shuffles, along with their proof and identity
// of shuffler.
Expand All @@ -179,62 +207,6 @@ type FormJSON struct {
RosterBuf []byte
}

// SuffragiaJSON defines the JSON representation of a suffragia.
type SuffragiaJSON struct {
UserIDs []string
Ciphervotes []json.RawMessage
}

func encodeSuffragia(ctx serde.Context, suffragia types.Suffragia) (SuffragiaJSON, error) {
ciphervotes := make([]json.RawMessage, len(suffragia.Ciphervotes))

for i, ciphervote := range suffragia.Ciphervotes {
buff, err := ciphervote.Serialize(ctx)
if err != nil {
return SuffragiaJSON{}, xerrors.Errorf("failed to serialize ciphervote: %v", err)
}

ciphervotes[i] = buff
}
return SuffragiaJSON{
UserIDs: suffragia.UserIDs,
Ciphervotes: ciphervotes,
}, nil
}

func decodeSuffragia(ctx serde.Context, suffragiaJSON SuffragiaJSON) (types.Suffragia, error) {
var res types.Suffragia
fac := ctx.GetFactory(types.CiphervoteKey{})

factory, ok := fac.(types.CiphervoteFactory)
if !ok {
return res, xerrors.Errorf("invalid ciphervote factory: '%T'", fac)
}

ciphervotes := make([]types.Ciphervote, len(suffragiaJSON.Ciphervotes))

for i, ciphervoteJSON := range suffragiaJSON.Ciphervotes {
msg, err := factory.Deserialize(ctx, ciphervoteJSON)
if err != nil {
return res, xerrors.Errorf("failed to deserialize ciphervote json: %v", err)
}

ciphervote, ok := msg.(types.Ciphervote)
if !ok {
return res, xerrors.Errorf("wrong type: '%T'", msg)
}

ciphervotes[i] = ciphervote
}

res = types.Suffragia{
UserIDs: suffragiaJSON.UserIDs,
Ciphervotes: ciphervotes,
}

return res, nil
}

// ShuffleInstanceJSON defines the JSON representation of a shuffle instance
type ShuffleInstanceJSON struct {
// ShuffledBallots contains the list of shuffled ciphertext for this round
Expand Down
1 change: 1 addition & 0 deletions contracts/evoting/json/mod.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

func init() {
types.RegisterFormFormat(serde.FormatJSON, formFormat{})
types.RegisterSuffragiaFormat(serde.FormatJSON, suffragiaFormat{})
types.RegisterCiphervoteFormat(serde.FormatJSON, ciphervoteFormat{})
types.RegisterTransactionFormat(serde.FormatJSON, transactionFormat{})
}
97 changes: 97 additions & 0 deletions contracts/evoting/json/suffragia.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package json

import (
"encoding/json"

"github.com/c4dt/d-voting/contracts/evoting/types"
"go.dedis.ch/dela/serde"
"golang.org/x/xerrors"
)

type suffragiaFormat struct{}

func (suffragiaFormat) Encode(ctx serde.Context, msg serde.Message) ([]byte, error) {
switch m := msg.(type) {
case types.Suffragia:
sJson, err := encodeSuffragia(ctx, m)
if err != nil {
return nil, xerrors.Errorf("couldn't encode suffragia: %v", err)
}

buff, err := ctx.Marshal(&sJson)
if err != nil {
return nil, xerrors.Errorf("failed to marshal form: %v", err)
}

return buff, nil
default:
return nil, xerrors.Errorf("Unknown format: %T", msg)
}
}

func (suffragiaFormat) Decode(ctx serde.Context, data []byte) (serde.Message, error) {
var sJson SuffragiaJSON

err := ctx.Unmarshal(data, &sJson)
if err != nil {
return nil, xerrors.Errorf("failed to unmarshal form: %v", err)
}

return decodeSuffragia(ctx, sJson)
}

// SuffragiaJSON defines the JSON representation of a suffragia.
type SuffragiaJSON struct {
UserIDs []string
Ciphervotes []json.RawMessage
}

func encodeSuffragia(ctx serde.Context, suffragia types.Suffragia) (SuffragiaJSON, error) {
ciphervotes := make([]json.RawMessage, len(suffragia.Ciphervotes))

for i, ciphervote := range suffragia.Ciphervotes {
buff, err := ciphervote.Serialize(ctx)
if err != nil {
return SuffragiaJSON{}, xerrors.Errorf("failed to serialize ciphervote: %v", err)
}

ciphervotes[i] = buff
}
return SuffragiaJSON{
UserIDs: suffragia.UserIDs,
Ciphervotes: ciphervotes,
}, nil
}

func decodeSuffragia(ctx serde.Context, suffragiaJSON SuffragiaJSON) (types.Suffragia, error) {
var res types.Suffragia
fac := ctx.GetFactory(types.CiphervoteKey{})

factory, ok := fac.(types.CiphervoteFactory)
if !ok {
return res, xerrors.Errorf("invalid ciphervote factory: '%T'", fac)
}

ciphervotes := make([]types.Ciphervote, len(suffragiaJSON.Ciphervotes))

for i, ciphervoteJSON := range suffragiaJSON.Ciphervotes {
msg, err := factory.Deserialize(ctx, ciphervoteJSON)
if err != nil {
return res, xerrors.Errorf("failed to deserialize ciphervote json: %v", err)
}

ciphervote, ok := msg.(types.Ciphervote)
if !ok {
return res, xerrors.Errorf("wrong type: '%T'", msg)
}

ciphervotes[i] = ciphervote
}

res = types.Suffragia{
UserIDs: suffragiaJSON.UserIDs,
Ciphervotes: ciphervotes,
}

return res, nil
}
23 changes: 12 additions & 11 deletions contracts/evoting/mod_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,11 +295,13 @@ func TestCommand_CastVote(t *testing.T) {
form, ok := message.(types.Form)
require.True(t, ok)

require.Len(t, form.Suffragia.Ciphervotes, 1)
require.True(t, castVote.Ballot.Equal(form.Suffragia.Ciphervotes[0]))
require.Len(t, form.BallotCount, 1)
suff, err := form.Suffragia(ctx, snap)
require.NoError(t, err)
require.True(t, castVote.Ballot.Equal(suff.Ciphervotes[0]))

require.Equal(t, castVote.UserID, form.Suffragia.UserIDs[0])
require.Equal(t, float64(len(form.Suffragia.Ciphervotes)), testutil.ToFloat64(PromFormBallots))
require.Equal(t, castVote.UserID, suff.UserIDs[0])
require.Equal(t, float64(form.BallotCount), testutil.ToFloat64(PromFormBallots))
}

func TestCommand_CloseForm(t *testing.T) {
Expand Down Expand Up @@ -364,8 +366,8 @@ func TestCommand_CloseForm(t *testing.T) {
err = cmd.closeForm(snap, makeStep(t, FormArg, string(data)))
require.EqualError(t, err, "at least two ballots are required")

dummyForm.Suffragia.CastVote("dummyUser1", types.Ciphervote{})
dummyForm.Suffragia.CastVote("dummyUser2", types.Ciphervote{})
require.NoError(t, dummyForm.CastVote(ctx, snap, "dummyUser1", types.Ciphervote{}))
require.NoError(t, dummyForm.CastVote(ctx, snap, "dummyUser2", types.Ciphervote{}))

formBuf, err = dummyForm.Serialize(ctx)
require.NoError(t, err)
Expand Down Expand Up @@ -697,7 +699,6 @@ func TestCommand_ShuffleBallotsFormatErrors(t *testing.T) {
form.Pubkey = pubKey
shuffleBallots.Round = 0
form.ShuffleInstances = make([]types.ShuffleInstance, 0)
form.Suffragia.Ciphervotes = make([]types.Ciphervote, 0)

data, err = shuffleBallots.Serialize(ctx)
require.NoError(t, err)
Expand All @@ -713,9 +714,9 @@ func TestCommand_ShuffleBallotsFormatErrors(t *testing.T) {

// > With only one shuffled ballot the shuffling can't happen

form.Suffragia.CastVote("user1", types.Ciphervote{
require.NoError(t, form.CastVote(ctx, snap, "user1", types.Ciphervote{
types.EGPair{K: suite.Point(), C: suite.Point()},
})
}))

data, err = shuffleBallots.Serialize(ctx)
require.NoError(t, err)
Expand Down Expand Up @@ -1118,7 +1119,6 @@ func initFormAndContract() (types.Form, Contract) {
FormID: fakeFormID,
Status: 0,
Pubkey: nil,
Suffragia: types.Suffragia{},
ShuffleInstances: make([]types.ShuffleInstance, 0),
DecryptedBallots: nil,
ShuffleThreshold: 0,
Expand Down Expand Up @@ -1156,12 +1156,13 @@ func initGoodShuffleBallot(t *testing.T, k int) (types.Form, types.ShuffleBallot
shuffleBallots.Round = 0
form.ShuffleInstances = make([]types.ShuffleInstance, 0)

snap := fake.InMemorySnapshot{}
for i := 0; i < k; i++ {
ballot := types.Ciphervote{types.EGPair{
K: Ks[i],
C: Cs[i],
}}
form.Suffragia.CastVote(fmt.Sprintf("user%d", i), ballot)
form.CastVote(ctx, &snap, fmt.Sprintf("user%d", i), ballot)
}

// Valid Signature of shuffle
Expand Down
Loading
Loading