-
Notifications
You must be signed in to change notification settings - Fork 34
/
roulettesingle_new.html
118 lines (114 loc) · 4.67 KB
/
roulettesingle_new.html
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
107
108
109
110
111
112
113
114
115
116
117
118
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Roulette Single Verify</title>
<link rel="stylesheet" href="./lib/main.css">
<link rel="stylesheet" href="./lib/bootstrap/css/bootstrap.min.css">
<script src="./lib/react.production.min.js"></script>
<script src="./lib/react-dom.production.min.js"></script>
<script src="./lib/crypto-js.js"></script>
<script src="./lib/tools.js"></script>
<script src="./lib/hooks.js"></script>
<script src="./lib/babel.min.js"></script>
<script src="./lib/utils.js"></script>
</head>
<body>
<div id="app"></div>
<script type="text/babel">
let qs = tools.queryString();
let { useEffect, useMemo } = React;
const { useSetState } = hooks;
function useInputControl (initState) {
const [state, setState] = useSetState(initState);
const bind = key => ({
value: state[key],
onChange: v => setState({[key]: v})
});
return [
state,
setState,
bind
];
}
function Input ({value, onChange, ...others}) {
return (
<div class="form-group">
<input value={value}
onChange={e => onChange(e.target.value)}
class="form-control"
{...others}
/>
</div>
);
}
function getResult (hash) {
return Math.floor(slideWindowNumber(hash, 37));
}
function RouletteSingle () {
const [state, setState, bind] = useInputControl({
clientSeed: qs.c||'',
serverSeed: qs.s||'',
nonce: qs.n||''
});
const result = useMemo(() => {
const serverSeedHash = tools.sha256(state.serverSeed);
const resultArr = [state.clientSeed, state.nonce];
const hmacSha256Result = String(CryptoJS.HmacSHA256(resultArr.join(":"), state.serverSeed));
const finalResult = getResult(hmacSha256Result);
const baseHash = hmacSha256Result.substring(0, 15);
const index = Number(BigInt('0x' + baseHash) % BigInt(47));
const newHash = hmacSha256Result.substring(index, index + 14);
return {
serverSeedHash,
hmacSha256Result,
finalResult,
resultList,
baseHash,
index,
newHash,
}
}, [state]);
const {resultList, finalResult} = result;
return (
<div className="main">
<h1 className="text-center pb-5">Roulette single verify</h1>
<hr />
<h2 class="text-center">Input</h2>
<form className="py-5">
<Input placeholder="Server Seed" {...bind('serverSeed')} />
<Input placeholder="Client Seed (Hashed)" {...bind('clientSeed')} />
<Input placeholder="Nonce" {...bind('nonce')} />
</form>
<form className="py-5">
<h2 className="text-center pb-5">Results</h2>
<h5>Final Result</h5>
<Input placeholder="HmacSHA256(clientSeed, serverSeed)" readOnly value={result.hmacSha256Result} />
<Input placeholder="Result" readOnly value={result.finalResult} />
<h5 style={{ marginTop: 20 }}>Calculation Process</h5>
<p>Using the formula `hmac_sha256(client_seed:nonce, server_seed)`,</p>
<p>We get the hash result:</p>
<p>{result.hmacSha256Result}.</p>
<br />
<ol>
<li>Take the first 15 characters, resulting in {result.baseHash}.</li>
<li>Convert this to decimal, which gives: {BigInt('0x' + result.baseHash)}.</li>
<li>Perform modulus 47(47 is fixed constant), and we get a remainder of {result.index}.</li>
<li>Starting from the index, take 14 characters, resulting in <span className="text-danger">{result.newHash}</span>.</li>
<li>Convert this to decimal, resulting in: {BigInt('0x' + result.newHash)}.</li>
<li>Divide by 8(8 is a fixed constant), resulting in: {BigInt('0x' + result.newHash) / BigInt(8)}.</li>
<li>Multiply by 2^-53(2^-53 is a fixed constant), resulting in: {Number(BigInt('0x' + result.newHash) / BigInt(8)) * Math.pow(2, -53)}.</li>
<li>Multiply by 37(37 is a fixed constant), resulting in: {Number(BigInt('0x' + result.newHash) / BigInt(8)) * Math.pow(2, -53) * 37}.</li>
<li>Finally, take the integer part of the result, which gives: <span class="text-success">{result.finalResult}</span>.</li>
</ol>
<div></div>
</form>
</div>
);
}
ReactDOM.render(<RouletteSingle />, document.getElementById("app"));
</script>
</body>
</html>