library LamportVerify{ function getBit(bytes32 data, uint256 index) constant returns(uint8) { // gets bit `i` from data return uint8(uint256(data) / (2**((255-index)))) & 0x01; } function verify_sig(bytes32 msgHash, bytes32[2][256] pubKey, bytes32[256] signature) returns(bool){ for(uint i; i < 256; i++){ if(!(pubKey[getBit(msgHash,i)][i] == sha3(signature[i]))) return false; } return true; } } contract qETH { LamportVerify LamportLib; struct account { bool _init; // Has pubKey been set? uint _nonce; // Account nonce for rederiving privKeys. newPrivKey = sha3(masterKey + nonce) bytes32[2][256] _pubKey; // Current public key uint _balance; } mapping(address => account) public accounts; function qETH(address lib){ if (lib == 0) LamportLib = new LamportVerify(); // if no library exists, make new library else LamportLib = LamportVerify(lib); } function hashMsg(address from, address to, uint amount, bytes32[2][256] newKey) public constant returns(bytes32) { // Helper function to construct msg hash return sha3(from,to,amount); } function balanceOf(address addr) constant returns(uint){ return accounts[addr]._balance; } function setPubKey (bytes32[2][256] pubKey) public { accounts[msg.sender]._balance += msg.value; if(accounts[msg.sender]._init == true) throw; accounts[msg.sender]._pubKey = pubKey; accounts[msg.sender]._init = true; } function sendVerify(address from, address to, uint amount, bytes32[2][256] newKey, bytes32[256] sig) { //sig is signature of msgHash bytes32 msgHash = hashMsg(from,to,amount, newKey); if (accounts[from]._init == false || !LamportLib.verify_sig(msgHash,accounts[from]._pubKey,sig)) throw; //Check initialization and Lamport signature if (accounts[from]._balance < amount || accounts[to]._balance + amount < accounts[to]._balance) throw; //Check overflow and underflow accounts[from]._balance -= amount; accounts[from]._nonce++; accounts[from]._pubKey = newKey; } function transferFrom(address from, address to, uint amount, bytes32[2][256] newKey, bytes32[256] sig) public { sendVerify(from, to, amount, newKey, sig); accounts[to]._balance += amount; } function transfer(address to, uint amount, bytes32[2][256] newKey, bytes32[256] sig){ sendVerify(msg.sender, to, amount, newKey, sig); accounts[to]._balance += amount; } function withdraw(address from, address to, uint amount, bytes32[2][256] newKey, bytes32[256] sig) public { sendVerify(from, to, amount, newKey, sig); to.send(amount); } function(){ accounts[msg.sender]._balance += msg.value; } }