Skip to content

Commit

Permalink
Putting ballots in separate memory
Browse files Browse the repository at this point in the history
  • Loading branch information
ineiti committed Jan 25, 2024
1 parent f6045da commit b310ea8
Show file tree
Hide file tree
Showing 18 changed files with 462 additions and 187 deletions.
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

0 comments on commit b310ea8

Please sign in to comment.