@@ -0,0 +1,50 @@
1+import { hex2patp } from 'urbit-ob';
2+import { createRing } from 'lib/keys';
3+
4+import jssha256 from 'js-sha256';
5+
6+function shax(buf) {
7+ const hashed = jssha256.sha256.array(buf);
8+ return Buffer.from(hashed);
9+}
10+
11+function hex2buf(hex) {
12+ return Buffer.from(hex, 'hex').reverse();
13+}
14+
15+function buf2hex(buf) {
16+ return Buffer.from(buf)
17+ .reverse()
18+ .toString('hex');
19+}
20+
21+function shas(buf, salt) {
22+ return shax(xor(salt, shax(buf)));
23+}
24+
25+function xor(a, b) {
26+ const length = Math.max(a.byteLength, b.byteLength);
27+ const result = new Uint8Array(length);
28+ for (let i = 0; i < length; i++) {
29+ result[i] = a[i] ^ b[i];
30+ }
31+ return result;
32+}
33+
34+function shaf(buf, salt) {
35+ const result = shas(buf, salt);
36+ const halfway = result.length / 2;
37+ const front = result.slice(0, halfway);
38+ const back = result.slice(halfway, result.length);
39+ return xor(front, back);
40+}
41+
42+export const generateCode = pair => {
43+ const ring = hex2buf(createRing(pair));
44+ const salt = hex2buf('73736170'); // salt is the noun %pass
45+ const hash = shax(ring);
46+ const result = shaf(hash, salt);
47+ const half = result.slice(0, result.length / 2);
48+
49+ return hex2patp(buf2hex(half));
50+};