diff --git a/README.md b/README.md index 810a4a37..b2abd2cb 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,8 @@ TODO: - [x] Backend assigns vote tokens and emails invitation to voters - [x] Password protect - [x] Voter interface to cast vote -- [ ] Encrypt voters vote +- [x] Encrypt voters vote + - [ ] Error handling - [ ] Walk voters through extra private mode - [ ] Health / Antivirus on browser checker - [ ] Submit Voters vote diff --git a/src/demo-election/EncryptionReceipt.tsx b/src/demo-election/EncryptionReceipt.tsx index 39616401..a8791cce 100644 --- a/src/demo-election/EncryptionReceipt.tsx +++ b/src/demo-election/EncryptionReceipt.tsx @@ -19,8 +19,8 @@ export function EncryptionReceipt({ Encrypted @ ${new Date().toString()} Encryption Formula - sealed_data = encoded * (sealing_target ^ randomizer) % modulo - sealing_factor = (generator ^ randomizer) % modulo + message = encoded * (recipient ^ randomizer) % modulo + unlock = (generator ^ randomizer) % modulo Public Key ${map(public_key, (v, k) => `${k}: ${v.toString()}`).join('\n ')} diff --git a/src/protocol/EncryptionReceipt.tsx b/src/protocol/EncryptionReceipt.tsx index 555fde5d..4e36d672 100644 --- a/src/protocol/EncryptionReceipt.tsx +++ b/src/protocol/EncryptionReceipt.tsx @@ -16,8 +16,8 @@ export function EncryptionReceipt(): JSX.Element { Encrypted @ ${new Date().toString()} Encryption Formula - sealed_data = encoded * (sealing_target ^ randomizer) % modulo - sealing_factor = (generator ^ randomizer) % modulo + message = encoded * (recipient ^ randomizer) % modulo + unlock = (generator ^ randomizer) % modulo Public Key ${map(public_key, (v, k) => `${k}: ${v.toString()}`).join('\n ')} diff --git a/src/protocol/VoteContext.tsx b/src/protocol/VoteContext.tsx index 80abe7f2..5c7dbbb9 100644 --- a/src/protocol/VoteContext.tsx +++ b/src/protocol/VoteContext.tsx @@ -8,7 +8,7 @@ import { Big, big } from './crypto/types' import { candidates, public_key, voters } from './election-parameters' const rand = () => pickRandomInteger(public_key.modulo).toString().padStart(public_key.modulo.toString().length, '0') -export const randEncrypted = () => `{ sealed_data: ${rand()}, sealing_factor: ${rand()} }` +export const randEncrypted = () => `{ message: ${rand()}, unlock: ${rand()} }` const initState = { encrypted: { token: voters[0].token }, diff --git a/src/protocol/crypto/decrypt.ts b/src/protocol/crypto/decrypt.ts index 87969a2d..aa08a082 100644 --- a/src/protocol/crypto/decrypt.ts +++ b/src/protocol/crypto/decrypt.ts @@ -1,12 +1,12 @@ import { Big, Cipher_Text, Public_Key } from './types' export default function decrypt(public_key: Public_Key, secret_key: Big, ciphertext: Cipher_Text): string { - const { sealed_data, sealing_factor } = ciphertext + const { message, unlock } = ciphertext const { modulo } = public_key - const shared_secret = sealing_factor.modPow(secret_key, modulo) + const shared_secret = unlock.modPow(secret_key, modulo) const s_inverse = shared_secret.modInverse(modulo) - const message = sealed_data.multiply(s_inverse).mod(modulo) + const decrypted = message.multiply(s_inverse).mod(modulo) - return message.toString() + return decrypted.toString() } diff --git a/src/protocol/crypto/encrypt.ts b/src/protocol/crypto/encrypt.ts index edd82ae8..b3281654 100644 --- a/src/protocol/crypto/encrypt.ts +++ b/src/protocol/crypto/encrypt.ts @@ -1,14 +1,14 @@ import { Big, Cipher_Text, Public_Key } from './types' -export default function encrypt(public_key: Public_Key, random_sealing_key: Big, message: Big): Cipher_Text { - const { generator, modulo, sealing_target } = public_key +export default function encrypt(public_key: Public_Key, randomizer: Big, encoded_message: Big): Cipher_Text { + const { generator, modulo, recipient } = public_key // Calculate our encrypted message - const shared_secret = sealing_target.modPow(random_sealing_key, modulo) - const sealed_data = message.multiply(shared_secret).mod(modulo) + const shared_secret = recipient.modPow(randomizer, modulo) + const message = encoded_message.multiply(shared_secret).mod(modulo) - // This sealing factor lets someone with the unsealing key reverse the encryption - const sealing_factor = generator.modPow(random_sealing_key, modulo) + // This lets the recipient's private key reverse the encryption + const unlock = generator.modPow(randomizer, modulo) - return { sealed_data, sealing_factor } + return { message, unlock } } diff --git a/src/protocol/crypto/shuffle.ts b/src/protocol/crypto/shuffle.ts index 74264b63..74fe0dc9 100644 --- a/src/protocol/crypto/shuffle.ts +++ b/src/protocol/crypto/shuffle.ts @@ -4,7 +4,7 @@ import pick_random_integer from './pick-random-integer' import { Cipher_Text, Public_Key } from './types' export default function shuffle(pub_key: Public_Key, cipher_texts: Cipher_Text[]): Cipher_Text[] { - const { generator, modulo, sealing_target } = pub_key + const { generator, modulo, recipient } = pub_key // First, we permute the incoming cipher_texts // TODO: Replace lodash.shuffle with cryptographically random permutation @@ -12,18 +12,18 @@ export default function shuffle(pub_key: Public_Key, cipher_texts: Cipher_Text[] // Now we'll re-encrypt each of them... const reencrypted = permuted.map((cipher) => { - const { sealed_data, sealing_factor } = cipher + const { message, unlock } = cipher // Generate a unique random re-encryption factor for each cipher const reencryption_factor = pick_random_integer(modulo) - const data_multiplier = sealing_target.modPow(reencryption_factor, modulo) - const new_sealing_data = sealed_data.multiply(data_multiplier).mod(modulo) + const message_multiplier = recipient.modPow(reencryption_factor, modulo) + const new_message = message.multiply(message_multiplier).mod(modulo) - const factor_multiplier = generator.modPow(reencryption_factor, modulo) - const new_sealing_factor = sealing_factor.multiply(factor_multiplier).mod(modulo) + const unlock_multiplier = generator.modPow(reencryption_factor, modulo) + const new_unlock = unlock.multiply(unlock_multiplier).mod(modulo) - return { sealed_data: new_sealing_data, sealing_factor: new_sealing_factor } + return { message: new_message, unlock: new_unlock } }) return reencrypted diff --git a/src/protocol/crypto/types.ts b/src/protocol/crypto/types.ts index 3ec120ed..e5e7a4f9 100644 --- a/src/protocol/crypto/types.ts +++ b/src/protocol/crypto/types.ts @@ -4,14 +4,14 @@ import { reduce } from 'lodash' export { BigInteger as Big } from 'jsbn' export type Cipher_Text = { - sealed_data: Big - sealing_factor: Big + message: Big + unlock: Big } export type Public_Key = { generator: Big modulo: Big - sealing_target: Big + recipient: Big } // Add Big helper methods greaterThan/lessThan diff --git a/src/protocol/election-parameters.ts b/src/protocol/election-parameters.ts index 309f533f..a52469e4 100644 --- a/src/protocol/election-parameters.ts +++ b/src/protocol/election-parameters.ts @@ -3,7 +3,7 @@ import { Public_Key, bigPubKey } from './crypto/types' export const public_key: Public_Key = bigPubKey({ generator: '2', modulo: '1083210858721378763', // 60 bit key - sealing_target: '119677511493916793', + recipient: '119677511493916793', }) export const decryption_key = '170121057240471299'