Crypto API placeholders with best-effort implementations.
We need code for generating a 0 or 1 vote, and proving that it contains either 0 or 1. ElectionGuard uses prime fields; not clear that we would also need to do so if we were using a different library, but I have left them in that form for now.
There are two important desiderata, which may be a question of "how much do we have to change?" rather than "can we be exactly the same?"
- Can the Right To Ask server continue to run the ElectionGuard decryption/aggregation/verification steps?
- Can ElectionGuard Verifiers continue to work?
A good benchmark example verifier this one by MITRE.
Based on Version 1.0 of the EG Spec.
We need a special case of Ballot Encryption in which each ballot (which is an up-vote or dismiss-vote on a question) has only one entry, which is either 0 or 1.
Unfortunately, Microsoft uses an extra ciphertext as a 'placeholder' value, because this simplifies the whole ballot-validity proof - they only need to prove that the total number of ones is equal to the limit. So in order to be exactly compliant with the EG standard, we would effectively have a (1,0) ciphertext tuple for an up-vote and a (0,1) ciphertext tuple for a dismiss-vote.
This placeholder is not necessary for our actual ballot proofs, because the single Chaum-Pedersen proof suffices (it's either a zero or a one).
TODO: Consider whether according with EG spec is worth doubling the work.
###El Gamal encryption, exponential form
An El Gamal encryption of a zero is computed from public key
Encryption of one is
Implemented in EG here.
###DisjunctiveChaumPedersenProof
C++ implementation here.
Like (the rest of) ElectionGuard, I don't think we actually need a proof for either disjunct, i.e. we never need to prove that it's a 0 or prove that it's a 1 - we only need the disjunctions.
###Summary of what EG would do For a single-option ballot, EG would have two ciphertexts and three Chaum-Pedersen proofs:
- a ciphertext C for the chosen selection: 1 for 'selected' and 0 for 'not selected.'
- a placeholder ciphertext P, the complement of the actual choice
- a Chaum-Pedersen proof, for each of C and P, that they contain either a 0 or a 1.
- a Chaum-Pedersen proof that the homomorphic combination C.P contains a 1.
###Possible simplification of ballot
The obvious simplification for our ballots, which would make us noncompliant with EG but save us more than a factor of two of work, storage and communication, is to have one ciphertext and one proof:
- a ciphertext C for the chosen selection: 1 for 'selected' and 0 for 'not selected.'
- a Chaum-Pedersen proof, for C, that it contains either a 0 or a 1.
In terms of defining the interface, what is required is the actual method signatures, as this will define where the parameters are coming from. For example:
BallotObj createBallot(PublicKeyObject, Choice(Boolean))
This is EG's ballot object, which includes both a ciphertext and a placeholder. Both C and P have to be proven to be in {0,1}, then their homomorphic sum has to be proven exactly equal to 1.
BallotObject:
- Ciphertext C
- Ciphertext P
- Proof C
- Proof P
- Proof C.P
Choice:
- True for 1
- False for 0
PublicKeyObject:
- g
- pk
- p
- q
It needs to define what parameters will be passed in and what object/values will be returned. Depending on how it is currently implemented it might be easy to just replace with a single method as above, or if it currently calls multiple methods in ElectionGuard then the granularity of of the method calls could be increased to match.
Questions:
- EG has two different CP versions - one with an explicit seed and one without. Which one do we need?
- How does the client receive the server public key? In what format?
- What will the format for the returned ballot including proofs and ciphertexts be?
Most of the hashing, randomness, etc is internal.
Use BouncyCastle BigInteger class
Option 1: Keep to EG format; use some special cases
The following shows EG ballot formats, from an example EG ballot, with annotations about how they'd correspond to RTA data. Candidates correspond to questions, which get either up-voted (+1) or not (0). We could coalesce a person's up/dismiss votes in several ways:
- make each ballot a single contest with a single 'candidate' i.e. question
- make each ballot a single contest with multiple 'candidates' i.e. questions (CJC points out that this is likely to make trouble, because it will be very hard to add candidates later.
- make each ballot multiple contests, each with a single 'candidate' i.e. question (this seems like a good way to do it).
The example below shows case (2) with two 'candidates' i.e. questions and two corresponding placeholders. TODO redo so that we're using a case 3 example rather than case 2.
{
"object_id": "03a29d15-667c-4ac8-afd7-549f19b8e4eb", // I think the object_id is unique to the ballot, so RTA's would be unique also.
"style_id": "jefferson-county-ballot-style", // Probably redundant/blank for RTA since there are no collected lists of questions
"manifest_hash": "C2DB999CFEC53C050F14E776A4203BAAC1E76E1A959C7281A63C2EC110D3B87D", // Not sure what this is - possibly for auditing and therefore not needed?
"code_seed": "A8C60067311F4A9E98936B1E1FD4DC6F9EF15EA61288B1E46BC444617F9DF636", // Not sure what this is
"contests": [ // Need to decide whether a person's collected up/dismiss votes should be gathered into one ballot with multiple
{ // contests, or separated into single-contest ballots. Suggest case 2: one contest with many candidates.
"object_id": "justice-supreme-court", // This object_id would be redundant. However (case 1), we could alternatively use the RTA question_id here instead of per-candidate
"sequence_order": 0, // We would never have more than one contest per ballot (except with case 3, which seems silly).
"description_hash": "DFE30A201F1842B73522980854D7814C8B688698E6EF33533616C31F038067EF", // Not sure what this is
"ballot_selections": [
{
"object_id": "john-adams-selection", // Important: object_id == RTA question_id
"sequence_order": 0, // Depending on whether we opt for case 1 or case 2, we may have either two objects (a real one and a placeholder)
// or multiple pairs (case 2)
"description_hash": "A26D9AC2530AB54774A1FF11F4FD77F6A527AFCDF44A05A8BFBBC299A081984F", // Not sure what this is
"ciphertext": { // RTA ciphertexts would be the same as EG's, including CP disjunctive {0,1} proof
"pad": "8ED5AC2CBA25BCA328A4856ABD6EC3F7AB6D88DC71C6ED47C1E3F766657781BB9E735A774576A2A45126251F7DD6220C4FC9472E2CB72CFB1F10407667CB47C58D4BFCCFC504C67E4A9E09959972CD25909ED2AB9AB1FC42DD10E422D93F9F652C8A6FB384920A90E950B37D2AC7CD834B95FF9E6745AC8E0587BCB677FA86BBB09C48111A7BF797729880CFD5F4F6FBC7C9EF5E149DB1B849BE25322EA0091D311DB5B39E9DE8524BBEB71665B16340C65F98D30A3BE4CBC416F0F21BEF1DFD61C6D15076A692A8E1A13FA84F5E2A2B6C6024FB382A79814625DC50CE0515042E2A4E1754409958AA501D0776B9604FB91D421535D70306704067A9EEEAED6D728C5DB837434134557356E5E1F5C6043F03E69E470DB9FBCF38FA2EDCE588491B611F267FF40DEEFAA015FB2D9054D37C3C9022B464141F926D8D93E59D5A0A3395B962D644DF373BAC81CCAF2F023E70E124D8AABA9F038DF24A5A41D335E9B0D9C63A2D1970E1A3DD74B21F477F4E5E0E5FD00C2C69C93A1242AE9E8DF14A017C65E7C3B599CDDE5805529F650617DF81C1F570E3171168E0D88BC4D977F76BB87AA459F7179E205DFE1189BEEC6E129728616E9D35600437985B2314B5ACFBD6AE06529DD8256EAAC147A6C4AA3750C5C7059A5D68F0793DC469C1FCED532C56662FFEADF5AF5145F92FB5727977D43C1D52E457AD63F549D1DA13FB52D5",
"data": "446935F985D8B4F7A8CA0C512487E5DFE3BB4C6385B66557D8E72DB8E74B2D92E7238F97A2B2B0962D2B7FB3780D9EF08970ABDEEEF4F45EC8751D58E3339D3465822982CB4D46A61DA9D8839537759EAECD7C3EF97282F1D58438B2A9571DFDF8690FB64EC874A80CADC8765ACBA40007EABA171545883DFA40AA3FDF7254C688F370B822EE6BC9634C18763B4950F39E6A26D59A321588F0665C2461999849BFFD0021F503E69B02BA6DCD875F2B2C09DA28962F9072DA2636B76408D7BDA723AA2FD835A7B1C07784D366B0220EBF8F8AA8495B12DA1956BD805461AC98C4036344F7CCC2E1677FFD9A67F12337B8008C1A203A5459BE737E31822B6F3923167D8D9B48370B2A400F3A3E4FAF0493E88240BF156F5F9CB8138A7759E10F806BFAD7FBCAB48791A3521D5BD8814CBEF734172E4AE1B57462A84E0F84BF640CDF21DF846831ABCF3105B2675911E1C2DC4AFDF1E0AF8D493869BEC8424D849C43F34A7E68A3E4704A4A23B1479F7FFBEA01C9EAD4958446D9F226C43625CC9D287FF04051BD0E735470D9E7DA86BE5DAD54E07D5B3291D6A559DCFD19AAB10A7A8FFB13B5B60E45A5303AB3C67486222A83ACE0C7166BA2D4830F7A5B935D98F2739B48D5F4D712E1704DC275303469179D06B11F3E5BECF7201671248FB8FA78AA07C50C052467AB7648A8B97CAAC81D197D8464461B062A81D9BA92AD98E2"
},
"crypto_hash": "162E9693DAA4665AD265F2EF28AAEADF2236B75271E52792DCC3136E1DCF8B22",
"is_placeholder_selection": false,
"nonce": null,
"proof": {
"proof_zero_pad": "30BCAC17811555A1B847C38DC181FC45A041E81243F5DEDA6CD54449618ADEF5F676459B94B8F685D094EB344E5DDD9C75946302DB68BF5FFA063A7621A531E89DE4E6B3EE0BF396BC21FE3286F774D956A2E8A8F920B1F9751848B64B955AC0C5586AC039F95CB10C007D7D095C9E540917DB0F48170639835DA14ED8FDAE4FD793E2F54A881BBB1E72AF4D5C968B1F51FC0315ABA17A0AFF2FF81A39D7CD83E854CE8EBCB3494E0DDCFB1A407EC7A15DA4112BB4AA21A38A5C4281D4574C71C048947A45B403142D05999CE8F23294E0F61E28D991BDEB2A9EB2AF86DFE8D11D30DE469B43652ED266609A7CF493AB66ABD003F71676B01A81421FCE8DF0F2B44D5E1A18313B192CAFCC7AFE1B3FFBE3DC6F8C857EC90F825B7B22056376407D7A7B150B23C6F102D9BD1B13C19D2583618A5946D6D6387F1940015FE64AD459C64409A34330B4471E0C648B12AC926393E61E27ABFAA73806AD7F34A1BB295CD6A635B028FF42432073A936867CB59618929B55A4F304A0B24D5A5B00945297A4CE2540D1CCE9548B8FFF5DC0BAA2E2421D808D66182A02E717260B95837154F5E3155F9757112FDB9AAE91CCA44EB43925C62FDAF08D7991293EC3546A967224A49A07C254D9136F849C8D194316BBB9094C1C9A974023D22A859300D5E637A71CE91E89FB56DA7B7A0FFF192E64ED43C27796A61EB395C9F2810098A981",
"proof_zero_data": "09E568F84D1C11F6C9FF936E4CA4EBF717C9031A33D521F172EDCF13E5F6D5FCD93C20AC5A3B16D632DE76D840D33FA113D03815002D1474A5CA4FD217ACBEF645F95DA4D92FB6569041DD6E117105453B3E1733F6EACE64E6FFB80A733EB818E0CA66DB7BE24B1A8AB6FAD994BA7E538452790FF880205E49CA9941D936D9B3074C5D86048CEE7C966E932510D4913E7ADDA557F9331E4116029AEE19C1B1B304D9108B217F4F4BCC53C4611A7F19FDA1E8CDBA5DA9B0555F6BAB8B8CB17FAA4724A5A596BC2DCE2BD7C2C1CC8988B424A34B1C82B1DB7882E6CB240CB51343B754B400C58633E1FE63F24B06872A7699EA67566F5BDCB10ABF36A785E1EBA628A968A86D3AA81B4A64EF74EA25E86A2D5A7B19C8F6FF46A16E3283E6384EAD97FD1EF796697679B62EF8CEC080103395711B6A3AE87F36CFC4CE99DCDC6C66377AE85D1113A0B9BB562239D2E7E26B09B88ED82404485D29C36F0E87DFD47C5665AC5DE40C838E8AC78B02A0BCB3592772CD4FF12B06599C395C3A9BBDCD9FB1C3FD3D956B6029F3F3A430917DDC7F98B8BE5D321CD8BE3876155614FC1DFDBAD738A9AE2BF66B06229319529A935EA2A3DD53D2A0111ED2DF6F40C8F55B1BD434B8D1350A06AEF469E1734857DB4D41B1CBF5800F6928DBFA586EC9A8000B26F3377C326B1FECBCE5B9F96E43D8E42F481CF05961F87CA3EB4591584E8ECD",
"proof_one_pad": "9F108A578D4E0ED8891D55B9B5865FF9C1D3B13532DE7D8EA0FC7B40C3220050F18E03056F7A929FA454E3773839E071CC7E28F91A0B2BA29968E36F2F529C3CF4CDB4DF040336E06C34578AD632C2FB8C1161361C2E8B8D7216CC347789F771694EF59FD7CC4448DA56D4CFD17049B066EB180676F47B05351393B76AD546E6135289033A9EB3789C25116A86212DE260F45D5DEF7E2199BB30612E81AFB744299B9F68B6B070C4572E927B0819EC1BA17DC186F13428E3BC096FF6D50FFF9857B39A7D171904D1B45FDF25C1B7078BBB866AA69120047FE48C4A9E8F6FAC04129F29949F7B5D6F77CD73F5E5AE1D53DF0A90B0C9DCD40508E73764562A0B83CAB0E618C2CEB9C5BB7675A833BD9CF0C6D2B740E8C67AF9A4496C0277295A91D40F5F1E0EAD47B10D3707B2839F4900808E11C9AF8B85253223D424E9E22D26821EE2510DF36661BA99005DDECE2755BF66C99B745C7A53DBDD2B53D20EFB4F06DD32583DCF12B108E22D53B76DCCE291510E746C598B2A5CA35EB028B8474BC1A58704035A589D76506425A6C7720BCDD0AA06227561D9BE08AD826ECC7B5A42D83029F63F852CF1A4F7278D71661E8F4C104E8DDD525F5CBAC08E33825D0EAAAA125EAA5505D90D668A61F4E1341AEF81D32D6465DFEC1EDD1257DB871CB370FB125A285882B4E86785A74BF40B0FC8497E2261634CC8C04EED543B6E6868",
"proof_one_data": "30881D2B2C639BD1C1385FAEF3075B06CB521672911D8A4EC765FFB6A45ED822401AA777BFFE6E2FD7A6B05B919566E7CCE94267F349919562CFCA79CEEE6DDC6B956E40B2976F8EFDB586D25CD31B462D81F9F2F08596CC5C7BA81634335CC7316D3887EFAFFE373E3DAE5673D00CDAC1C51CFCEF11115A459A1AE0E47A39C9FE86EDCEA122DAC60730D8CC3FB9368FD9517E7B035D924B855BED28B720F53C49D5229236E17C6370A5F94D7AC10B051273F31F851B5CC07B6EB8D08429CC9664F090DEC7D4651273441E7B0E5ADEE9D462716D03049E4207D6FA98791C0250541FCB4324CD7D719D2270C9057998ED05FEEA25AA79080269D23B5F38AA10C827C0CC8ADE9642BF8B7841541FC3CBBD8C7477559F9199377BADC038F73039A4E5D088F368E43DF464C8B090F086F377A6D5ACB91F65FF7DBFA71E339DD3ACD11B622EC1D50F7AABDE51024C07394CC41EBEEA716089066F412C5F9168FFB2C99647EFD1714E1472C7F3475E1EC0D80ECAF9D12ACDB72187C2BEDFA5A509D73154A180A8CAF1AC6AB88D572E2D4E4C34719C1F6D23EA72182F7D22A7C79DCBAD5E0ABE63C8A15EA1FC8B91668C752A2CCA4D53189BEE9682156289A8E4E8872F7E8D824562F8DC96919EDF8BB7A0720CBCD30CCDA45ECA7E9C42AA36F7D09646FC8C1128A5BFB93CAB7F324BD3196A713CA846BEAC0D7BE547E42CAFE697D29A",
"proof_zero_challenge": "44F7B4DA536B980A451D2D0E32465065EC1A4ED4D78149AEE0CD955E7BD78D06",
"proof_one_challenge": "391FFC636B6F492E200D12A423B14ADB7EC01957E41F7186439BF9B54F74A1FA",
"challenge": "7E17B13DBEDAE138652A3FB255F79B416ADA682CBBA0BB3524698F13CB4C2F00",
"proof_zero_response": "9FD40940DBE4045E44726CC8DD02A5A75821497F6A7AA460FAAE1F0071F95A79",
"proof_one_response": "9CE794024093DCC4BF893490C2A39661DFF53BA5C559BABBC20275014B92C531",
"usage": "Prove selection's value (0 or 1)"
},
"extended_data": null // Not sure what this is
},
{
"object_id": "benjamin-franklin-selection", // If we choose case 2, we may have multiple other selections representing other questions. object_id == RTA question_id
"sequence_order": 1,
// [A lot more data left out - same format as previous object]
"is_placeholder_selection": false,
// [A lot more data left out - same format as previous object]
},
{
"object_id": "justice-supreme-court-2-placeholder", // We need a placeholder for each 'real' ciphertext. Each is a ciphertext, same format as others.
"sequence_order": 2,
// [A lot more data left out - same format as previous object]
"is_placeholder_selection": true,
// [A lot more data left out - same format as previous object]
},
{
"object_id": "justice-supreme-court-3-placeholder",
"sequence_order": 3,
// [A lot more data left out - same format as previous object]
"is_placeholder_selection": true,
// [A lot more data left out - same format as previous object]
}
],
"ciphertext_accumulation": { // We would need exactly the same ciphertext accumulation.
"pad": "CCF1ABBB18BCDE304F37684FD88AFD2E086A1E0919563A5A769B8543A12535874C427D39B672D55B576D477A5FAE9FE044DCA2A8700251C7D3E8F3C43210B0681AF7D39BDB7734D4F983CA67F0C588441D863DC1CDCF5A581983AACEF2D569D6E32A5C4ACCFE3CBDBC5EF14FB840AA2F8BC5E46F00003FEFD2B3E69E6DADB70407EE74BF646AC1F2AEBFCF17F946AE35BB7FEEE1D91E656D068B4C61B9A0BDD94EE422D047FF9324A643EE49E62C3B8D239728610A35E9416460F93A1A3AC8A63C6D4D4CF6C92F24F0A54C13ACDD576BAAB51628ECE2FCCF7901E3AFAB03A9646F772652E074B82D7A0CC5BA77DFFF5923B8749F926DA4A8A024271BDB9329151B9E3CF27025960202B115C6001AB38B1F7A1E71EACD0C80BBB0FF590F0DA36A8C8A972872A93DC48126FF4BCA5C7F92BD3C2FDE87DE67A2ACFC802CCAAAC45FA18C58556F160AF09C39590F804370CBAF2E009A35B444F1415721C9B18F7812342C25D15D0EDBDBC5699A5F805EE73ACA76E3538FFDDD5ACAD15AEBAEB0A73D120D66BE13B8F5500B1F2D8C6F8A920231D191231CCB6CB847FA425E76A89C90BEF631C494A3DA500964784340A572C58C40D3EE6299E8CC135096724F51CFAC6B5FD7F1ACBBD7F986E99D9142BEB3FAC7E272BA9EFF43ADEAA76081F8BE40E4B853F444669C3709A8FA5CB7BE9D54EFCD31FD9DEC7E8CE45BCB25554C2BB839",
"data": "029A2E59A39138FE977F1AD44103F08D3D3AFB698F47F2E980B7B81FF9ACC9D17D33F906421A601532FD17055827377A65BB35C7E2B4C2EFB8D964CA97121238FEF0C4B07A099980864A908693B428D56B093C63662CD009B5375F6B3D6C8EDE1096F82B7A80F7BE4810B29533AC00107379673969F4E528EE4B0DF233BB3B68B4B0BB3E935AB1D061FACE9E885DB3CA08D6263B1C63464FF4B4E869C7622543D4238DA7BC3390FFE29B240C3CAEAEB8D8F9C1AB1C2AE604976E07AD5E4C3A4380446DAE3DCEE112D088ED70D788D7DEBFDFA326F60B1A4DE96C3B11B5A7E7EC2C26237CA765B651F75FD65CE0C12612ED1EE272A5F1867E395F9671A3C0CB80C4F2A4B38DA315861C3FAE91D8E44C67AA6463D145CB5307868FB27A654549F8B46903D81D9ABD5120940087D067C3D4992FCA850B3703AE507FBFB0F33EDC87986D061129D7E4C490DE5F37DAFB54E5A949032A8A0E5C249A98D2D62F762179DAA2DD7AAC5632463020CF977805F8974FB4737E1838502814CFE6E6A1DDCF353E9C0C33085E3E084C021FA07E305C19130361229AC8793817C31AAC280E4CE9DBFA06AEFF3489739B6CC9DC6B835D1C562A1A2674E335A38F587A3D8875A8C4273C4718DDCE1DC3B7E46237D8C6823AEF11F7EBBEAE0EC9C1F224A43333E6C5547B8B8E9F2551D5A46C73E99DEDC0A691DF420B49F025CC4D0180DE5124E008"
},
"crypto_hash": "022286613F657B1FD1F60AB65A012D8EF8E3AE89E152F9C75B2C088BA7CA3C86",
"nonce": null,
"proof": {
"pad": "1F760CB334F13D82840B57D49689C332E9264FFB0DF7E9D6676F93FC29F2A979C20AF617781E8B247BD30BFD2A54A76DBD92AEAAF8FA9907E3CC57064F18940AD466DA1A74EF6EF37049E0B12F4E2D3820B1FFF8D5777CE124178ACE97E354685839B234B09449452C14917FA744EFF148DA257C028BAA70D9A3C60691ED572033CDCCC83ADEF5480357B06ACE8234A5BA4A721FB47DD2DE2D9E68F7BBAC865B0C549B8D153E9FC378923B78697F2A79DE7AA72D933FDBA50C6B40C727E29D8B818CA1B1D512C6854EADCD82A1834A1F756E6C37FFA9670EA1668DA983892D9116387437FE736E5B61DE862F6FB2344D7B8A876FC3404D09AF1928D588C61564AF467373E07E331D53CC8FD3FC88FA077665BF3CF8C865A591366A350D64C25222207E315424E978C55E6419F29CD93F6A04A375AB73A6506A54D2D37A812250E897F4BED4A28356235DB048434E8E4184AF82E30AD1C21A96BAE5D95980B7382910CA14806853AAA31FB5A1AC4EB8036732E8B73E645F37A336564E6DCCE3EFB86025A223BB9386BFAAFAEE87C7ECD46A17842961E719BB3D815125F6B959627D7D4070601E965441191085750397D1C69B67BC33862C90DB2C3876F0F9E5608818B77D5006AFD3983215AA69B6DF40A6210D0DA5421E6CC0BDC637702A36EB7C2A3A4CC57CDAC3677A3E64681E0A145F6018B4157D5035F3DBAE3F61DEFD15",
"data": "9A31F5110F66EF4715FBB2AD0554280AD86F934E4848C159F0CCDEE9F535F2102A02C7A20EC941A78F0D3E3D9784ACA26EBB0972B4D9CC5A6B418281DADF8BFDB0DE6A1DFBECA61401B3DE5737997DCF9384136DCEF5C40308AD0AC70193452527F84939034F108DA04E6D10AB687CE05C6D5D62052C62C1926C7F53A492982F3F54142906C29A72EB4A4BFF55089B7787503ABBEFF8E6B9A8F55B68AE8F1A7E7CEE56F8590866D496A7BAA23F5B8C1CD102141B5331ED957CD51327D671F5C4B07F7D4A971AABAD41D5CF5C3E8EE5210AA42CFFE9FFF0681551A18C0BC2E8C756402ACD5F1934F3D273DC1C50C31A407AB0D09815B1918D45C4795A79DA447DD26539058E6FF5A5CE00F1103FB486A9D5371D8CBE389309323FBC340D695D2A0ADBFB485194623B640402CCFBFAFA56450FC849AA9BB06A707D16346F9CCD412A65DC68DF5A754D5EDEDA81E1911D1CDFD483BAF1334618BF774D0A0A5E77B0E2D27290EADB2048B7D0B421C17F971D28D50E311C3718CEF871ACD972832C84E1525DDE1857E89071C4AC381A11A502711D70C2865D2FADD616210793502840A3BA68F5C9EFE9DA1F04F3FDA5D9EED4EDE1034F853BC438D9C9B39ACB7E251CBFC532F640005F7A329D712C037A80F98C5EEB4BDEC6F84D48B1CEDCD60440B2BCCF7F6527C58D74F6727DC1D66A83E370936BF7AEDE5107E8A3F5C65364F2C9",
"challenge": "4F763A00FE4D1A00AD4D982CEA0A2BA1A2620D5675FA0248933E895CAA7CE74F",
"response": "D162E1C8196B39FABA85D98D7CC1DE76774F698CFD65DE8D8B39DD9CE26A13DA",
"constant": 2, // I *think* this constant is the value the accumulation is claimed to add to, which in our case would be the number of 'real' ciphertexts.
"usage": "Prove value within selection's limit"
},
"extended_data": null
}
],
"code": "694305AD5D80032C40326AD34F3EF074E10C55D60C3195EFA016FAE1FBF164E0", // Not sure what any of this other data at the end is.
"timestamp": 1650657324,
"crypto_hash": "92C9B221AF952541EBFE3CFFD4BB5F777A7F4F8EECA78B0C05185E3A57F97181",
"nonce": null,
"state": 1
}
Thoughts about this: we end up with twice as many ciphertexts as we need, because we'd need a placeholder for every real ciphertext. The placeholders don't really do anything for RTA - we don't need them except for EG compliance.
Brainstorming alternative options: We could consider having no placeholders, but instead insisting that half of the votes be dismiss-votes. Then the constant in the accumulation proof is always half the number of ciphertexts. This is great for privacy but the usability is awful. Alternatively, we could allow any accumulation constant, and thus reveal the number of up-votes, but not which ones they were. This is great for usability but awful for privacy.
Option 2: Break EG format; use one ciphertext per up-vote
Alternatively, we could omit all the placeholders, the accumulation ciphertext and the proof that the accumulation is a particular value.
This would take somewhat less than half the data size and work to produce.
All the rest of the ballot structure, including the array of contests and the ballot selections, would stay the same. (It's unclear how much we need the various hash values, most of which I don't fully understand, but they're probably harmless and it's nice to get EG verifiers to work).
This would mean that an EG verifier would almost work, but we'd have to suppress the warning that the accumulation proof failed. (We may not be the only ones.)
Note also that the server-side decryption would probably also break, assuming that the servers / guardians verify ballot validity before they decrypt. So this seems like a bad choice.