test state chain

node v6.17.1
version: 7.0.0
endpointsharetweet
const crypto = require('crypto') var Rsa = require('node-rsa')
Encryption libs -- ursa https://github.com/JoshKaufman/ursa https://coolaj86.com/articles/asymmetric-public--private-key-encryption-in-node-js/ https://www.npmjs.com/package/ursa Encryption libs -- rsa https://github.com/rzcoder/node-rsa State Channels http://www.jeffcoleman.ca/state-channels/ https://blog.stephantual.com/what-are-state-channels-32a81f7accab
function hash(obj){ const text = typeof obj == 'string' ? obj : JSON.stringify(obj) const hash = crypto.createHash('sha256') hash.update(text) return hash.digest('hex') }
function expectString(obj){ if( typeof obj != 'string' ) throw new Error("Expected string") }
class Wallet { constructor(){ this.privateKey = new Rsa({b:1024}) this.publicKey = new Rsa() this.publicKey.importKey( this.privateKey.exportKey("pkcs8-public-pem") , 'public') } encrypt(txt){ return this.privateKey.encryptPrivate(txt, 'base64') } decrypt(base64){ return this.publicKey.decryptPublic(base64, 'utf8') } } class StateChain { constructor(publicKeyA,publicKeyB){ this.publicKeyA = publicKeyA this.publicKeyB = publicKeyB this.states = [] } pushState(state){ this.states.push(state) } get lastEncryptedHash(){ return this.encryptedHash(this.states.length - 1) } encryptedHash(i){ return hash(this.states[i].e) } get lastState(){ return this.states[ this.states.length - 1 ] } verifyLastState(verbose=false){ if (verbose) console.log("Verifying state "+(this.states.length - 1)) this.verify( this.lastState, verbose ) } verifyAll(verbose=false){ if (verbose) console.log("verifying all states:") for(const i in this.states){ const state = this.states[i] if (!this.verify(state,verbose)) return false if(state.s.seqnum!=i){ if (verbose) console.log("state sequence is wrong") if (verbose) console.log(state.s) return false } if(state.s.seqnum==0){ if(state.s.prev!=""){ if (verbose) console.log("state[0] should have empty prev field") if (verbose) console.log(state.s) return false } }else{ if(state.s.prev!=this.encryptedHash(i-1)){ if (verbose) console.log("stateprev link does not match previous state") if (verbose) console.log(state.s) return false } } } return true } verify(state,verbose=false){ return state.verify(this.publicKeyA,this.publicKeyB,verbose) } } class State { constructor(s,eA,eB){ this.s = s this.eA = eA this.eB = eB } get e(){ return [this.eA,this.eB] } verify(keyA,keyB,verbose=false){ console.log(this) const hA = keyA.decryptPublic(this.eA,'utf8') const hB = keyB.decryptPublic(this.eB,'utf8') const h = hash(this.s) if (hA != hB){ if (verbose) console.log("The signature of A and B is different.") return false } if (hA != h){ if (verbose) console.log("The signature of A is not the signature of the state.") return false } if (hB != h){ if (verbose) console.log("The signature of B is not the signature of the state.") return false } if (hA == hB && hB == h){ if (verbose) console.log("The state is validated by the signatures of both A and B!") if (verbose) console.log(this.s) return true } return false // this shouldn't happen -- put exception here } }
const playerA = new Wallet() const playerB = new Wallet() let chain = new StateChain(playerA.publicKey,playerB.publicKey) const s0 = { seqnum:0, prev:"", data:{ nextPlayer: "X", winner: "", board: [ ['-','-','-'], ['-','-','-'], ['-','-','-'], ] } } const h0 = hash(s0) chain.pushState( new State(s0,playerA.encrypt(h0),playerB.encrypt(h0)) ) chain.verifyLastState(true) const s1 = { seqnum:1, prev:chain.lastEncryptedHash, data:{ nextPlayer: "O", winner: "", board: [ ['-','-','-'], ['-','-','X'], ['-','-','-'], ] } } const h1 = hash(s1) chain.pushState( new State(s1,playerA.encrypt(h1),playerB.encrypt(h1)) ) chain.verifyLastState(true) const s2 = { seqnum:2, prev:chain.lastEncryptedHash, data:{ nextPlayer: "X", winner: "", board: [ ['-','-','-'], ['-','O','X'], ['-','-','-'], ] } } const h2 = hash(s2) chain.pushState( new State(s2,playerA.encrypt(h2),playerB.encrypt(h2)) ) chain.verifyLastState(true) chain.verifyAll(true)
Loading…

no comments

    sign in to comment