UNPKG

urbit-key-generation

Version:

Key derivation and HD wallet generation functions for Urbit.

169 lines (139 loc) 3.46 kB
/* istanbul ignore file */ var noun = require('./noun.js'), list = require('./list.js'), Cell = noun.Cell, bits = require('./bits.js'), zero = noun.Atom.yes, one = noun.Atom.no, i = noun.Atom.fromInt, two = i(2), three = i(3), NounMap = require('./hamt.js').NounMap; function rub(a, b) { var c, d, e, w, x, y, z, p, q, m; m = bits.add(a, i(bits.met(0, b))); x = a; while ( zero.equals(bits.cut(zero, x, one, b)) ) { y = bits.add(one, x); // Sanity check: crash if decoding more bits than available if ( bits.gth(x, m) ) { throw new Error("Bail"); } x = y; } if ( a.equals(x) ) { return new Cell(one, zero); } c = bits.sub(x, a); d = bits.add(x, one); x = bits.dec(c); y = bits.bex(x); z = bits.cut(zero, d, x, b); e = bits.add(y, z); w = bits.add(c, c); y = bits.add(w, e); z = bits.add(d, x); p = bits.add(w, e); q = bits.cut(zero, z, e, b); return new Cell(p, q); } function cue_in(m, a, b) { var c,l,u,v,w,y,p,q,d,x; if ( zero.equals(bits.cut(zero, b, one, a)) ) { x = bits.add(b, one); c = rub(x, a); p = bits.add(c.head, one); q = c.tail; m.insert(b, q); } else { c = bits.add(two, b); l = bits.add(one, b); if ( zero.equals(bits.cut(zero, l, one, a)) ) { u = cue_in(m, a, c); x = bits.add(u.head, c); v = cue_in(m, a, x); w = new Cell(u.tail.head, v.tail.head); y = bits.add(u.head, v.head); p = bits.add(two, y); q = w; m.insert(b, q); } else { d = rub(c, a); x = m.get(d.tail); if ( undefined === x ) { throw new Error("Bail"); } p = bits.add(two, d.head); q = x; } } return new Cell(p, new Cell(q, zero)); } function cue(a) { return cue_in(new NounMap(), a, zero).tail.head; } function mat(a) { if ( zero.equals(a) ) { return noun.dwim(1, 1); } else { var b = noun.dwim(bits.met(0, a)), c = noun.dwim(bits.met(0, b)), u = bits.dec(c), v = bits.add(c, c), x = bits.end(zero, u, b), w = bits.bex(c), y = bits.lsh(zero, u, a), z = bits.mix(x, y), p = bits.add(v, b), q = bits.cat(zero, w, z); return noun.dwim(p, q); } } function _jam_in_pair(m, h_a, t_a, b, l) { var w = noun.dwim([2, 1], l), x = bits.add(two, b), d = _jam_in(m, h_a, x, w), y = bits.add(x, d.head), e = _jam_in(m, t_a, y, d.tail.head), z = bits.add(d.head, e.head); return noun.dwim(bits.add(two, z), e.tail.head, zero); } function _jam_in_ptr(m, u_c, l) { var d = mat(u_c), x = bits.lsh(zero, two, d.tail), y = bits.add(two, d.head); return noun.dwim(y, [[y, bits.mix(three, x)], l], zero); } function _jam_in_flat(m, a, l) { var d = mat(a), x = bits.add(one, d.head); return noun.dwim(x, [[x, bits.lsh(zero, one, d.tail)], l], zero); } function _jam_in(m, a, b, l) { var c = m.get(a); if ( undefined === c ) { m.insert(a, b); return a.deep ? _jam_in_pair(m, a.head, a.tail, b, l) : _jam_in_flat(m, a, l); } else if ( !a.deep && bits.met(0, a) <= bits.met(0, c) ) { return _jam_in_flat(m, a, l); } else { return _jam_in_ptr(m, c, l); } } function jam(n) { var x = _jam_in(new NounMap(), n, zero, zero), q = list.flop(x.tail.head); return bits.can(zero, q); } module.exports = { cue: cue, mat: mat, jam: jam };