4354297443921806682861743161735094062
38632140595220392354280998614525578145353818029287874088356304829962854601866
pragma solidity ^0.5;
contract Ballot{
uint Publickey_n;
event e_get_pk(
uint pk
);
event e_get_D(
uint d
);
//voter
struct voter {
uint vote;
}
//candidate
struct candidate {
uint count;
bool win;
}
//chairperson init voting
address chairperson;
mapping(address => voter) voters;
mapping(address => candidate) candidates;
address[] candidate_add;
constructor() public {
}
function initPk(uint pk) public {
Publickey_n = pk;
Publickey(pk);
emit e_get_pk(pk);
}
function initVoter(address[] memory voter_address) public {
for (uint i=0;i<voter_address.length;i++){
voters[voter_address[i]].vote = 1;
}
}
//chu shi hua bei xuan zhe
function initCandidate(address[] memory candidate_address) public {
for (uint i=0;i<candidate_address.length;i++){
candidate_add.push(candidate_address[i]);
candidates[candidate_address[i]].count = 0;
candidates[candidate_address[i]].win = false;
}
}
function vote(address candidate_address,uint Evote,uint r) public returns(uint){
require(voters[msg.sender].vote > 0);
Evote = E(Evote,r);
uint e = Evote;
if (candidates[candidate_address].count != 0)
candidates[candidate_address].count = e_add(candidates[candidate_address].count,Evote);
else
candidates[candidate_address].count = Evote;
voters[msg.sender].vote = 0;
return(e);
}
function votes(address[] memory candidate_address,uint[] memory Evotes,uint[] memory r) public {
require(voters[msg.sender].vote > 0);
for (uint i=0;i<candidate_address.length;i++){
uint Evote = E(Evotes[i],r[i]);
if (candidates[candidate_address[i]].count != 0)
candidates[candidate_address[i]].count = e_add(candidates[candidate_address[i]].count,Evote);
else
candidates[candidate_address[i]].count = Evote;
voters[msg.sender].vote = 0;
}
}
function tally(uint sk) public returns(uint,address){
uint winner_count;
address winner;
for (uint i=0;i<candidate_add.length;i++){
uint Dcount = D(candidates[candidate_add[i]].count,sk);
if (winner_count<D(candidates[candidate_add[i]].count,sk)){
winner_count = Dcount;
winner = candidate_add[i];
}
}
return(winner_count,winner);
}
function getvote(uint i) public returns(uint) {
return(candidates[candidate_add[i]].count);
}
int private x;
int private y;
uint public time;
uint _output;
uint Publickey_n_sq;
uint Publickey_g; //G
event timeStamper(uint timestamp, address sender, uint _output);
/*Publickey*/
/*
设置公钥
*/
function Publickey(uint _input) public {
Publickey_n = uint(_input);
Publickey_n_sq = Publickey_n * Publickey_n;
//Publickey_g = Publickey_n + 1;
Publickey_g = 2;
}
function gcd(int a,int b) public returns(int){
if (b == 0) {
x = 1;
y = 0;
return a;
} else {
int d = gcd(b,a%b);
int temp = y;
y = x-(a/b)*y;
x = temp;
return d;
}
}
function getgcd_y() public returns(int){
return y;
}
function init_x_y() public {
x = 0;
y = 0;
}
function invmod(uint a, uint p) public pure returns(uint){
uint r;
uint d;
if (a == 0)
revert('0 has no inverse mod this prime');
r = a;
d = 1;
for(uint i=p; i<1000000; i++) {
d = mulmod((p / r + 1), d, p);
r = mulmod(d, a, p);
if(r == 1) break;
}
return d;
}
/*
Modular exponent:
c = b ^ e mod m
Returns c.
*/
function modpow(uint _base, uint _exponent, uint _modulus) public pure returns(uint) {
uint result;
result = 1;
while(_exponent > 0){
if((_exponent & 1) == 1) result = mulmod(result, _base, _modulus);
_exponent = _exponent >> 1;
_base = mulmod(_base, _base, _modulus);
}
return result;
}
//加密 {(g**m mod n*n)*(r**n mod n*n)}mod n*n
function E(uint m,uint r) public view returns(uint) {
return mulmod(modpow(Publickey_g,m,Publickey_n_sq),modpow(r,Publickey_n,Publickey_n_sq),Publickey_n_sq);
}
//解密
function D(uint c,uint sk) public returns(uint) {
init_x_y;
if (y<0) y += int(Publickey_n);
gcd(int(Publickey_n),int((modpow(Publickey_g,sk,Publickey_n_sq)-1)/Publickey_n));
uint res = mulmod(((modpow(c,sk,Publickey_n_sq)-1)/Publickey_n),uint(y),Publickey_n);
emit e_get_D(res);
return res;
}
function D1(uint c,uint sk) public returns(uint) {
return ((modpow(c,sk,Publickey_n_sq)-1)/Publickey_n);
//gcd(int(Publickey_n),int((modpow(c,sk,Publickey_n_sq)-1)/Publickey_n));
//return mulmod(((modpow(c,sk,Publickey_n_sq)-1)/Publickey_n),uint(y),Publickey_n);
}
function D2(uint c,uint sk) public returns(uint) {
return ((modpow(Publickey_g,sk,Publickey_n_sq)-1)/Publickey_n);
//return mulmod(((modpow(c,sk,Publickey_n_sq)-1)/Publickey_n)/((modpow(Publickey_g,sk,Publickey_n_sq)-1)/Publickey_n),1,Publickey_n);
}
function e_add(uint a, uint b) public returns(uint) {
/*Add one encrypted uinteger to another*/
emit timeStamper(time, msg.sender, mulmod(a, b, Publickey_n_sq));
return mulmod(a, b, Publickey_n_sq);
}
function e_add_const(uint a, uint n, uint _input_Publickey) public returns(uint) {
/*Add constant n to an encrypted uinteger*/
Publickey(_input_Publickey);
emit timeStamper(time, msg.sender, mulmod(a, modpow(Publickey_g, n, Publickey_n_sq), Publickey_n_sq));
return mulmod(a, modpow(Publickey_g, n, Publickey_n_sq), Publickey_n_sq);
}
function e_mul_const(uint a, uint n, uint _input_Publickey) public returns(uint) {
/*Multiplies an encrypted uinteger by a constant*/
Publickey(_input_Publickey);
emit timeStamper(time, msg.sender, modpow(a, n, Publickey_n_sq));
return modpow(a, n, Publickey_n_sq);
}
}