2019-04-22

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);
}

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 实验三 二叉树遍历(递归算法和非递归算法) 一.实验目的 1.掌握二叉树的存储结构与基本操作 2.掌握二叉树的遍历...
    落幕12阅读 1,009评论 0 1
  • 通天塔的怪物数值设计分为两部分:1.生命值--主要用来卡玩家升级,玩家需要拥有足够的输出,在规定时间内打完怪物血量...
    李宏阳Leo阅读 1,071评论 0 1
  • 当你喜欢一个女生的时候,你会付出你的所有,和我好像。 1.文本相似度计算——文本向量化 1.前言 在自然语言处理过...
    T_129e阅读 507评论 0 0
  • 1. 这是个什么词? 词:proximity 英英释义:nearness in distance or time ...
    静美的秋阅读 186评论 0 0
  • 三剑客老大之awk 创建测试环境 三剑客小切磋 awk过滤 环境 显示第二列以 i 结尾的行 显示第二列以i结尾的...
    七两三_e13f阅读 207评论 0 0