-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathprovable.js
106 lines (85 loc) · 2.54 KB
/
provable.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
var crypto = require('crypto');
var assert = require('assert')
var defaults = require('lodash/defaults')
var isFunction = require('lodash/isFunction')
var utils = require('./utils')
function Engine(options,change){
function defaultState(options){
return defaults({},options,{
id:utils.createSeed(), //unique id for this hash series
index:0, //point in hash we are at
count:1, //number of hashes in series
seed:utils.createSeed(), //starting seed
publicSeed:null, //additional client side for extra security
maxHex:8, //max characters to slice from hash to generate integer
})
}
var state = {}
var hashes = null
function onChange(state){
change(state)
}
//random js calls this
function engine(){
return utils.toInt(engine.next(state.publicSeed),state.maxHex)
}
engine.state = function(){
return state
}
//query hash array
engine.hashes = function(start,end,includeSeed,reverse){
start = start || 0
if(includeSeed){
end = end || state.count + 1
}else{
end = end || state.count
}
var list = hashes
if(includeSeed){
list = hashes.concat([state.seed])
}
list = list.slice(start,end)
if(reverse){
return list.reverse()
}else{
return list
}
}
engine.last = function(publicSeed){
return engine.peek(state.index-1,publicSeed)
}
engine.peek = function(index,publicSeed){
if(index !== 0 && index == null) index = state.index
publicSeed = publicSeed || state.publicSeed
return utils.rehash(crypto,hashes[index],publicSeed)
}
engine.next = function(publicSeed){
var hash = engine.peek(null,publicSeed)
assert(hash,'end of hash series')
state.index++
onChange(state)
return hash
}
function init(){
state = defaultState(options)
state.maxInt = Math.pow(2,state.maxHex * 4) //maximum sized integer we can get from single hash
assert(state.seed,'requires seed value')
if(!isFunction(change)){
change = function(){}
}
hashes = utils.generate(crypto,state.count,state.seed)
onChange(state)
return engine
}
return init()
}
//add helper static functions
Engine.generate = utils.generate.bind(null,crypto)
Engine.createSeed = utils.createSeed.bind(null,crypto)
Engine.rehash = utils.rehash.bind(null,crypto)
Engine.sha256 = utils.sha256.bind(null,crypto)
//some basic hash parsing
Engine.toInt = utils.toInt
Engine.toFloat = utils.toFloat
Engine.toBool = utils.toBool
module.exports = Engine